]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/mifarecmd.c
Merge branch 'master' of https://github.com/Proxmark/proxmark3
[proxmark3-svn] / armsrc / mifarecmd.c
CommitLineData
8556b852 1//-----------------------------------------------------------------------------\r
b62a5a84 2// Merlok - June 2011, 2012\r
8556b852
M
3// Gerhard de Koning Gans - May 2008\r
4// Hagen Fritsch - June 2010\r
3fe4ff4f 5// Midnitesnake - Dec 2013\r
6// Andy Davies - Apr 2014\r
7// Iceman - May 2014\r
8556b852
M
8//\r
9// This code is licensed to you under the terms of the GNU GPL, version 2 or,\r
10// at your option, any later version. See the LICENSE.txt file for the text of\r
11// the license.\r
12//-----------------------------------------------------------------------------\r
13// Routines to support ISO 14443 type A.\r
14//-----------------------------------------------------------------------------\r
15\r
16#include "mifarecmd.h"\r
17#include "apps.h"\r
787b5bd8 18#include "util.h"\r
0ec548dc 19//#include "../client/loclass/des.h"\r
20#include "des.h"\r
a631936e 21#include "crc.h"\r
22\r
8556b852 23//-----------------------------------------------------------------------------\r
baeaf579 24// Select, Authenticate, Read a MIFARE tag. \r
8556b852
M
25// read block\r
26//-----------------------------------------------------------------------------\r
27void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
28{\r
29 // params\r
30 uint8_t blockNo = arg0;\r
31 uint8_t keyType = arg1;\r
32 uint64_t ui64Key = 0;\r
33 ui64Key = bytes_to_num(datain, 6);\r
34 \r
35 // variables\r
36 byte_t isOK = 0;\r
37 byte_t dataoutbuf[16];\r
1c611bbd 38 uint8_t uid[10];\r
8556b852
M
39 uint32_t cuid;\r
40 struct Crypto1State mpcs = {0, 0};\r
41 struct Crypto1State *pcs;\r
42 pcs = &mpcs;\r
43\r
44 // clear trace\r
3000dc4e 45 clear_trace();\r
7bc95e2e 46 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
8556b852
M
47\r
48 LED_A_ON();\r
49 LED_B_OFF();\r
50 LED_C_OFF();\r
51\r
52 while (true) {\r
53 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
baeaf579 54 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
8556b852
M
55 break;\r
56 };\r
57\r
58 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
baeaf579 59 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
8556b852
M
60 break;\r
61 };\r
62 \r
63 if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {\r
baeaf579 64 if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");\r
8556b852
M
65 break;\r
66 };\r
67\r
68 if(mifare_classic_halt(pcs, cuid)) {\r
baeaf579 69 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
8556b852
M
70 break;\r
71 };\r
72 \r
73 isOK = 1;\r
74 break;\r
75 }\r
76 \r
77 // ----------------------------- crypto1 destroy\r
78 crypto1_destroy(pcs);\r
79 \r
80 if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");\r
81\r
8556b852 82 LED_B_ON();\r
baeaf579 83 cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
8556b852
M
84 LED_B_OFF();\r
85\r
a631936e 86 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
87 LEDsoff();\r
88}\r
89\r
90\r
91void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){\r
92\r
93 byte_t isOK = 0;\r
94 byte_t dataoutbuf[16] = {0x00};\r
95 uint8_t uid[10] = {0x00};\r
96 uint32_t cuid;\r
97\r
98 LED_A_ON();\r
99 LED_B_OFF();\r
100 LED_C_OFF();\r
101 \r
3000dc4e 102 clear_trace();\r
a631936e 103 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
104\r
105 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
106 if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
107 Dbprintf("Can't select card");\r
0ec548dc 108 OnError(0);\r
a631936e 109 return;\r
110 };\r
111 \r
112 if(mifare_ultra_auth1(cuid, dataoutbuf)){\r
113 if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
114 Dbprintf("Authentication part1: Fail.");\r
0ec548dc 115 OnError(1);\r
a631936e 116 return;\r
117 }\r
118\r
119 isOK = 1;\r
120 if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
121 DbpString("AUTH 1 FINISHED");\r
122 \r
123 cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11);\r
124 LEDsoff();\r
125}\r
126void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){\r
127\r
128 uint32_t cuid = arg0;\r
129 uint8_t key[16] = {0x00};\r
130 byte_t isOK = 0;\r
131 byte_t dataoutbuf[16] = {0x00};\r
132 \r
133 memcpy(key, datain, 16);\r
134 \r
135 LED_A_ON();\r
136 LED_B_OFF();\r
137 LED_C_OFF();\r
138 \r
139 if(mifare_ultra_auth2(cuid, key, dataoutbuf)){\r
140 if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
141 Dbprintf("Authentication part2: Fail...");\r
0ec548dc 142 OnError(1);\r
a631936e 143 return; \r
144 }\r
145 \r
146 isOK = 1;\r
147 if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
148 DbpString("AUTH 2 FINISHED");\r
149 \r
150 cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);\r
8556b852
M
151 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
152 LEDsoff();\r
7cc204bf 153}\r
154\r
0ec548dc 155void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)\r
7cc204bf 156{\r
7cc204bf 157 uint8_t blockNo = arg0;\r
787b5bd8 158 byte_t dataout[16] = {0x00};\r
159 uint8_t uid[10] = {0x00};\r
0ec548dc 160 uint8_t key[8] = {0x00};\r
7cc204bf 161 uint32_t cuid;\r
0ec548dc 162 bool usePwd = false;\r
163 \r
164 usePwd = (arg1 == 1);\r
165 \r
166 // use password\r
167 if ( usePwd )\r
168 memcpy(key, datain, 8);\r
169 \r
7cc204bf 170 LED_A_ON();\r
171 LED_B_OFF();\r
172 LED_C_OFF();\r
173 \r
3000dc4e 174 clear_trace();\r
787b5bd8 175 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
176 \r
177 int len = iso14443a_select_card(uid, NULL, &cuid);\r
178 if(!len) {\r
0ec548dc 179 if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);\r
180 OnError(1);\r
787b5bd8 181 return;\r
7cc204bf 182 };\r
0ec548dc 183 \r
184 // authenticate here.\r
185 if ( usePwd ) {\r
186\r
187 uint8_t a[8] = { 0x01 };\r
188 uint8_t b[8] = { 0x00 };\r
189 uint8_t enc_b[8] = { 0x00 };\r
190 uint8_t ab[16] = { 0x00 };\r
191 \r
192 uint8_t transKey[8] = { 0x00 };\r
193 \r
194 uint16_t len;\r
195 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
196 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
197 \r
198 len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);\r
199 if (len == 1) {\r
200 if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
201 Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
202 OnError(1);\r
203 return;\r
204 }\r
205 \r
206// memcpy(dataout, receivedAnswer, 11);\r
207 \r
208 // tag nonce.\r
209 memcpy(enc_b,receivedAnswer+1,8);\r
210\r
211 // decrypt nonce.\r
212 des_dec(enc_b, b, key );\r
213\r
214 Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", enc_b[0],enc_b[1],enc_b[2],enc_b[3],enc_b[4],enc_b[5],enc_b[6],enc_b[7] );\r
215\r
216 rol(b,8);\r
217 \r
218 memcpy(ab ,a,8);\r
219 memcpy(ab+8,b,8);\r
220\r
221 Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );\r
222 Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );\r
223\r
224 // encrypt\r
225 des_enc(ab, ab, key);\r
226\r
227 Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );\r
228 Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );\r
229\r
230 len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, ab, receivedAnswer, receivedAnswerPar, NULL);\r
231 if (len == 1) {\r
232 if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
233 Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
234 OnError(1);\r
235 return;\r
236 }\r
237 \r
238 // \r
239 memcpy(transKey, receivedAnswer+1, 8);\r
240 Dbprintf("TRANSACTIONKEY: %02x %02x %02x %02x %02x %02x %02x %02x", transKey[0],transKey[1],transKey[2],transKey[3],\r
241 transKey[4],transKey[5],transKey[6],transKey[7] );\r
242 }\r
243 \r
787b5bd8 244 len = mifare_ultra_readblock(cuid, blockNo, dataout);\r
245 if(len) {\r
246 if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");\r
0ec548dc 247 OnError(2);\r
787b5bd8 248 return;\r
7cc204bf 249 };\r
250 \r
787b5bd8 251 len = mifare_ultra_halt(cuid);\r
252 if(len) {\r
253 if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
0ec548dc 254 OnError(3);\r
787b5bd8 255 return;\r
7cc204bf 256 };\r
257 \r
787b5bd8 258 cmd_send(CMD_ACK,1,0,0,dataout,16);\r
7cc204bf 259 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
260 LEDsoff();\r
261}\r
262\r
263//-----------------------------------------------------------------------------\r
baeaf579 264// Select, Authenticate, Read a MIFARE tag. \r
265// read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes)\r
8556b852
M
266//-----------------------------------------------------------------------------\r
267void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
268{\r
269 // params\r
270 uint8_t sectorNo = arg0;\r
271 uint8_t keyType = arg1;\r
272 uint64_t ui64Key = 0;\r
273 ui64Key = bytes_to_num(datain, 6);\r
274 \r
275 // variables\r
3fe4ff4f 276 byte_t isOK = 0;\r
baeaf579 277 byte_t dataoutbuf[16 * 16];\r
1c611bbd 278 uint8_t uid[10];\r
8556b852
M
279 uint32_t cuid;\r
280 struct Crypto1State mpcs = {0, 0};\r
281 struct Crypto1State *pcs;\r
282 pcs = &mpcs;\r
283\r
284 // clear trace\r
3000dc4e 285 clear_trace();\r
8556b852 286\r
7bc95e2e 287 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
8556b852
M
288\r
289 LED_A_ON();\r
290 LED_B_OFF();\r
291 LED_C_OFF();\r
292\r
baeaf579 293 isOK = 1;\r
294 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
295 isOK = 0;\r
8556b852 296 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
baeaf579 297 }\r
8556b852 298\r
baeaf579 299 \r
300 if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {\r
301 isOK = 0;\r
8556b852 302 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
baeaf579 303 }\r
304 \r
305 for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
306 if(mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf + 16 * blockNo)) {\r
307 isOK = 0;\r
308 if (MF_DBGLEVEL >= 1) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo);\r
8556b852 309 break;\r
baeaf579 310 }\r
311 }\r
8556b852 312 \r
baeaf579 313 if(mifare_classic_halt(pcs, cuid)) {\r
8556b852 314 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
8556b852 315 }\r
baeaf579 316\r
8556b852
M
317 // ----------------------------- crypto1 destroy\r
318 crypto1_destroy(pcs);\r
319 \r
320 if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
321\r
8556b852 322 LED_B_ON();\r
baeaf579 323 cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo));\r
6e82300d 324 LED_B_OFF();\r
8556b852
M
325\r
326 // Thats it...\r
327 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
328 LEDsoff();\r
7cc204bf 329}\r
330\r
787b5bd8 331void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)\r
7cc204bf 332{\r
0ec548dc 333 // params\r
334 uint8_t sectorNo = arg0;\r
787b5bd8 335 int Pages = arg1;\r
336 int count_Pages = 0;\r
337 byte_t dataout[176] = {0x00};;\r
338 uint8_t uid[10] = {0x00};\r
31d1caa5 339 uint32_t cuid;\r
7cc204bf 340\r
31d1caa5
MHS
341 LED_A_ON();\r
342 LED_B_OFF();\r
343 LED_C_OFF();\r
7cc204bf 344\r
787b5bd8 345 if (MF_DBGLEVEL >= MF_DBG_ALL) \r
346 Dbprintf("Pages %d",Pages);\r
347 \r
3000dc4e 348 clear_trace();\r
787b5bd8 349 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
7cc204bf 350\r
787b5bd8 351 int len = iso14443a_select_card(uid, NULL, &cuid);\r
352 \r
353 if (!len) {\r
354 if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
0ec548dc 355 Dbprintf("Can't select card (RC:%d)",len);\r
356 OnError(1);\r
787b5bd8 357 return;\r
358 }\r
359 \r
360 for (int i = 0; i < Pages; i++){\r
361 \r
362 len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);\r
363 \r
364 if (len) {\r
365 if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
366 Dbprintf("Read block %d error",i);\r
0ec548dc 367 OnError(2);\r
787b5bd8 368 return;\r
369 } else {\r
370 count_Pages++;\r
371 }\r
372 }\r
373 \r
374 len = mifare_ultra_halt(cuid);\r
375 if (len) {\r
376 if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
377 Dbprintf("Halt error");\r
0ec548dc 378 OnError(3);\r
787b5bd8 379 return;\r
380 }\r
381 \r
382 if (MF_DBGLEVEL >= MF_DBG_ALL) {\r
383 Dbprintf("Pages read %d", count_Pages);\r
384 }\r
7cc204bf 385\r
787b5bd8 386 len = 16*4; //64 bytes\r
387 \r
388 // Read a UL-C\r
389 if (Pages == 44 && count_Pages > 16) \r
390 len = 176;\r
7cc204bf 391\r
787b5bd8 392 cmd_send(CMD_ACK, 1, 0, 0, dataout, len); \r
31d1caa5
MHS
393 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
394 LEDsoff();\r
7cc204bf 395}\r
396\r
397\r
398//-----------------------------------------------------------------------------\r
baeaf579 399// Select, Authenticate, Write a MIFARE tag. \r
7cc204bf 400// read block\r
8556b852
M
401//-----------------------------------------------------------------------------\r
402void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
403{\r
404 // params\r
405 uint8_t blockNo = arg0;\r
406 uint8_t keyType = arg1;\r
407 uint64_t ui64Key = 0;\r
408 byte_t blockdata[16];\r
409\r
410 ui64Key = bytes_to_num(datain, 6);\r
411 memcpy(blockdata, datain + 10, 16);\r
412 \r
413 // variables\r
414 byte_t isOK = 0;\r
1c611bbd 415 uint8_t uid[10];\r
8556b852
M
416 uint32_t cuid;\r
417 struct Crypto1State mpcs = {0, 0};\r
418 struct Crypto1State *pcs;\r
419 pcs = &mpcs;\r
420\r
421 // clear trace\r
3000dc4e 422 clear_trace();\r
8556b852 423\r
7bc95e2e 424 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
8556b852
M
425\r
426 LED_A_ON();\r
427 LED_B_OFF();\r
428 LED_C_OFF();\r
429\r
430 while (true) {\r
431 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
432 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
433 break;\r
434 };\r
435\r
436 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
437 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
438 break;\r
439 };\r
440 \r
441 if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {\r
442 if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
443 break;\r
444 };\r
445\r
446 if(mifare_classic_halt(pcs, cuid)) {\r
447 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
448 break;\r
449 };\r
450 \r
451 isOK = 1;\r
452 break;\r
453 }\r
454 \r
455 // ----------------------------- crypto1 destroy\r
456 crypto1_destroy(pcs);\r
457 \r
458 if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
459\r
8556b852 460 LED_B_ON();\r
9492e0b0 461 cmd_send(CMD_ACK,isOK,0,0,0,0);\r
6e82300d 462 LED_B_OFF();\r
8556b852
M
463\r
464\r
465 // Thats it...\r
466 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
467 LEDsoff();\r
7cc204bf 468}\r
469\r
470void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)\r
471{\r
472 // params\r
473 uint8_t blockNo = arg0;\r
787b5bd8 474 byte_t blockdata[16] = {0x00};\r
7cc204bf 475\r
7cc204bf 476 memcpy(blockdata, datain,16);\r
477 \r
478 // variables\r
479 byte_t isOK = 0;\r
787b5bd8 480 uint8_t uid[10] = {0x00};\r
7cc204bf 481 uint32_t cuid;\r
482\r
3000dc4e 483 clear_trace();\r
7bc95e2e 484 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
7cc204bf 485\r
486 LED_A_ON();\r
487 LED_B_OFF();\r
488 LED_C_OFF();\r
489\r
490 while (true) {\r
491 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
492 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
493 break;\r
494 };\r
495\r
496 if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {\r
497 if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
498 break;\r
499 };\r
500\r
501 if(mifare_ultra_halt(cuid)) {\r
502 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
503 break;\r
504 };\r
505 \r
506 isOK = 1;\r
507 break;\r
508 }\r
509 \r
510 if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
511\r
baeaf579 512 cmd_send(CMD_ACK,isOK,0,0,0,0);\r
7cc204bf 513 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
514 LEDsoff();\r
7cc204bf 515}\r
516\r
517void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)\r
518{\r
baeaf579 519 // params\r
520 uint8_t blockNo = arg0;\r
787b5bd8 521 byte_t blockdata[4] = {0x00};\r
baeaf579 522 \r
7cc204bf 523 memcpy(blockdata, datain,4);\r
524\r
baeaf579 525 // variables\r
526 byte_t isOK = 0;\r
787b5bd8 527 uint8_t uid[10] = {0x00};\r
baeaf579 528 uint32_t cuid;\r
7cc204bf 529\r
3000dc4e 530 clear_trace();\r
baeaf579 531 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
7cc204bf 532\r
baeaf579 533 LED_A_ON();\r
534 LED_B_OFF();\r
535 LED_C_OFF();\r
7cc204bf 536\r
baeaf579 537 while (true) {\r
538 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
539 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
540 break;\r
541 };\r
7cc204bf 542\r
baeaf579 543 if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {\r
544 if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
545 break;\r
546 };\r
7cc204bf 547\r
baeaf579 548 if(mifare_ultra_halt(cuid)) {\r
549 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
550 break;\r
551 };\r
7cc204bf 552\r
baeaf579 553 isOK = 1;\r
554 break;\r
555 }\r
7cc204bf 556\r
baeaf579 557 if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
7cc204bf 558\r
baeaf579 559 cmd_send(CMD_ACK,isOK,0,0,0,0);\r
baeaf579 560 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
561 LEDsoff();\r
7cc204bf 562}\r
563\r
564// Return 1 if the nonce is invalid else return 0\r
6a1f2d82 565int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {\r
7cc204bf 566 return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \\r
8556b852
M
567 (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \\r
568 (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;\r
569}\r
570\r
9492e0b0 571\r
8556b852
M
572//-----------------------------------------------------------------------------\r
573// MIFARE nested authentication. \r
574// \r
575//-----------------------------------------------------------------------------\r
9492e0b0 576void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *datain)\r
8556b852
M
577{\r
578 // params\r
9492e0b0 579 uint8_t blockNo = arg0 & 0xff;\r
580 uint8_t keyType = (arg0 >> 8) & 0xff;\r
581 uint8_t targetBlockNo = arg1 & 0xff;\r
582 uint8_t targetKeyType = (arg1 >> 8) & 0xff;\r
8556b852
M
583 uint64_t ui64Key = 0;\r
584\r
585 ui64Key = bytes_to_num(datain, 6);\r
586 \r
587 // variables\r
9492e0b0 588 uint16_t rtr, i, j, len;\r
589 uint16_t davg;\r
590 static uint16_t dmin, dmax;\r
1c611bbd 591 uint8_t uid[10];\r
6a1f2d82 592 uint32_t cuid, nt1, nt2, nttmp, nttest, ks1;\r
593 uint8_t par[1];\r
9492e0b0 594 uint32_t target_nt[2], target_ks[2];\r
595 \r
8556b852 596 uint8_t par_array[4];\r
9492e0b0 597 uint16_t ncount = 0;\r
8556b852
M
598 struct Crypto1State mpcs = {0, 0};\r
599 struct Crypto1State *pcs;\r
600 pcs = &mpcs;\r
f71f4deb 601 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
8556b852 602\r
9492e0b0 603 uint32_t auth1_time, auth2_time;\r
604 static uint16_t delta_time;\r
605\r
f71f4deb 606 // free eventually allocated BigBuf memory\r
607 BigBuf_free();\r
8556b852 608 // clear trace\r
3000dc4e
MHS
609 clear_trace();\r
610 set_tracing(false);\r
8556b852 611 \r
7bc95e2e 612 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
8556b852
M
613\r
614 LED_A_ON();\r
8556b852
M
615 LED_C_OFF();\r
616\r
8556b852 617\r
9492e0b0 618 // statistics on nonce distance\r
619 if (calibrate) { // for first call only. Otherwise reuse previous calibration\r
620 LED_B_ON();\r
3fe4ff4f 621 WDT_HIT();\r
8556b852 622\r
9492e0b0 623 davg = dmax = 0;\r
624 dmin = 2000;\r
625 delta_time = 0;\r
8556b852 626 \r
9492e0b0 627 for (rtr = 0; rtr < 17; rtr++) {\r
8556b852 628\r
9492e0b0 629 // prepare next select. No need to power down the card.\r
630 if(mifare_classic_halt(pcs, cuid)) {\r
631 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");\r
632 rtr--;\r
633 continue;\r
634 }\r
635\r
636 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
637 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
638 rtr--;\r
639 continue;\r
640 };\r
641\r
642 auth1_time = 0;\r
643 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {\r
644 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth1 error");\r
645 rtr--;\r
646 continue;\r
647 };\r
648\r
649 if (delta_time) {\r
650 auth2_time = auth1_time + delta_time;\r
651 } else {\r
652 auth2_time = 0;\r
653 }\r
654 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) {\r
655 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error");\r
656 rtr--;\r
657 continue;\r
658 };\r
659\r
b19bd5d6 660 nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160\r
661 for (i = 101; i < 1200; i++) {\r
9492e0b0 662 nttmp = prng_successor(nttmp, 1);\r
663 if (nttmp == nt2) break;\r
664 }\r
665\r
666 if (i != 1200) {\r
667 if (rtr != 0) {\r
668 davg += i;\r
669 dmin = MIN(dmin, i);\r
670 dmax = MAX(dmax, i);\r
671 }\r
672 else {\r
673 delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing\r
674 }\r
675 if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);\r
676 }\r
8556b852
M
677 }\r
678 \r
9492e0b0 679 if (rtr <= 1) return;\r
8556b852 680\r
9492e0b0 681 davg = (davg + (rtr - 1)/2) / (rtr - 1);\r
682 \r
683 if (MF_DBGLEVEL >= 3) Dbprintf("min=%d max=%d avg=%d, delta_time=%d", dmin, dmax, davg, delta_time);\r
8556b852 684\r
9492e0b0 685 dmin = davg - 2;\r
686 dmax = davg + 2;\r
687 \r
688 LED_B_OFF();\r
689 \r
690 }\r
8556b852
M
691// ------------------------------------------------------------------------------------------------- \r
692 \r
693 LED_C_ON();\r
694\r
695 // get crypted nonces for target sector\r
9492e0b0 696 for(i=0; i < 2; i++) { // look for exactly two different nonces\r
8556b852 697\r
9492e0b0 698 target_nt[i] = 0;\r
699 while(target_nt[i] == 0) { // continue until we have an unambiguous nonce\r
8556b852 700 \r
9492e0b0 701 // prepare next select. No need to power down the card.\r
702 if(mifare_classic_halt(pcs, cuid)) {\r
703 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");\r
704 continue;\r
705 }\r
8556b852 706\r
9492e0b0 707 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
708 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
709 continue;\r
710 };\r
8556b852 711 \r
9492e0b0 712 auth1_time = 0;\r
713 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {\r
714 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth1 error");\r
715 continue;\r
716 };\r
8556b852 717\r
9492e0b0 718 // nested authentication\r
719 auth2_time = auth1_time + delta_time;\r
6a1f2d82 720 len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);\r
9492e0b0 721 if (len != 4) {\r
722 if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len);\r
723 continue;\r
724 };\r
8556b852 725 \r
9492e0b0 726 nt2 = bytes_to_num(receivedAnswer, 4); \r
6a1f2d82 727 if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]);\r
8556b852 728 \r
9492e0b0 729 // Parity validity check\r
730 for (j = 0; j < 4; j++) {\r
6a1f2d82 731 par_array[j] = (oddparity(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));\r
9492e0b0 732 }\r
733 \r
734 ncount = 0;\r
735 nttest = prng_successor(nt1, dmin - 1);\r
736 for (j = dmin; j < dmax + 1; j++) {\r
737 nttest = prng_successor(nttest, 1);\r
738 ks1 = nt2 ^ nttest;\r
739\r
740 if (valid_nonce(nttest, nt2, ks1, par_array)){\r
741 if (ncount > 0) { // we are only interested in disambiguous nonces, try again\r
742 if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambigous), ntdist=%d", i+1, j);\r
743 target_nt[i] = 0;\r
744 break;\r
745 }\r
746 target_nt[i] = nttest;\r
747 target_ks[i] = ks1;\r
748 ncount++;\r
749 if (i == 1 && target_nt[1] == target_nt[0]) { // we need two different nonces\r
750 target_nt[i] = 0;\r
751 if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j);\r
8556b852
M
752 break;\r
753 }\r
9492e0b0 754 if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: valid, ntdist=%d", i+1, j);\r
8556b852 755 }\r
8556b852 756 }\r
9492e0b0 757 if (target_nt[i] == 0 && j == dmax+1 && MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i+1);\r
8556b852
M
758 }\r
759 }\r
760\r
761 LED_C_OFF();\r
762 \r
763 // ----------------------------- crypto1 destroy\r
764 crypto1_destroy(pcs);\r
765 \r
9492e0b0 766 byte_t buf[4 + 4 * 4];\r
767 memcpy(buf, &cuid, 4);\r
768 memcpy(buf+4, &target_nt[0], 4);\r
769 memcpy(buf+8, &target_ks[0], 4);\r
770 memcpy(buf+12, &target_nt[1], 4);\r
771 memcpy(buf+16, &target_ks[1], 4);\r
8556b852
M
772 \r
773 LED_B_ON();\r
9492e0b0 774 cmd_send(CMD_ACK, 0, 2, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
6e82300d 775 LED_B_OFF();\r
8556b852 776\r
9492e0b0 777 if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED");\r
8556b852 778\r
8556b852
M
779 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
780 LEDsoff();\r
3000dc4e 781 set_tracing(TRUE);\r
8556b852
M
782}\r
783\r
784//-----------------------------------------------------------------------------\r
9492e0b0 785// MIFARE check keys. key count up to 85. \r
8556b852
M
786// \r
787//-----------------------------------------------------------------------------\r
788void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
789{\r
790 // params\r
791 uint8_t blockNo = arg0;\r
792 uint8_t keyType = arg1;\r
793 uint8_t keyCount = arg2;\r
794 uint64_t ui64Key = 0;\r
795 \r
796 // variables\r
797 int i;\r
798 byte_t isOK = 0;\r
1c611bbd 799 uint8_t uid[10];\r
8556b852
M
800 uint32_t cuid;\r
801 struct Crypto1State mpcs = {0, 0};\r
802 struct Crypto1State *pcs;\r
803 pcs = &mpcs;\r
804 \r
805 // clear debug level\r
806 int OLD_MF_DBGLEVEL = MF_DBGLEVEL; \r
807 MF_DBGLEVEL = MF_DBG_NONE;\r
808 \r
809 // clear trace\r
3000dc4e
MHS
810 clear_trace();\r
811 set_tracing(TRUE);\r
8556b852 812\r
7bc95e2e 813 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
8556b852
M
814\r
815 LED_A_ON();\r
816 LED_B_OFF();\r
817 LED_C_OFF();\r
818\r
8556b852 819 for (i = 0; i < keyCount; i++) {\r
9492e0b0 820 if(mifare_classic_halt(pcs, cuid)) {\r
821 if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");\r
822 }\r
8556b852
M
823\r
824 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
9492e0b0 825 if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");\r
8556b852
M
826 break;\r
827 };\r
828\r
829 ui64Key = bytes_to_num(datain + i * 6, 6);\r
830 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
831 continue;\r
832 };\r
833 \r
834 isOK = 1;\r
835 break;\r
836 }\r
837 \r
838 // ----------------------------- crypto1 destroy\r
839 crypto1_destroy(pcs);\r
840 \r
8556b852 841 LED_B_ON();\r
6e82300d 842 cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);\r
8556b852
M
843 LED_B_OFF();\r
844\r
8556b852
M
845 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
846 LEDsoff();\r
847\r
848 // restore debug level\r
849 MF_DBGLEVEL = OLD_MF_DBGLEVEL; \r
850}\r
851\r
852//-----------------------------------------------------------------------------\r
853// MIFARE commands set debug level\r
854// \r
855//-----------------------------------------------------------------------------\r
856void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
857 MF_DBGLEVEL = arg0;\r
858 Dbprintf("Debug level: %d", MF_DBGLEVEL);\r
859}\r
860\r
861//-----------------------------------------------------------------------------\r
862// Work with emulator memory\r
863// \r
864//-----------------------------------------------------------------------------\r
865void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
866 emlClearMem();\r
867}\r
868\r
869void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
870 emlSetMem(datain, arg0, arg1); // data, block num, blocks count\r
871}\r
872\r
873void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
3fe4ff4f 874 byte_t buf[USB_CMD_DATA_SIZE];\r
baeaf579 875 emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4)\r
8556b852
M
876\r
877 LED_B_ON();\r
3fe4ff4f 878 cmd_send(CMD_ACK,arg0,arg1,0,buf,USB_CMD_DATA_SIZE);\r
8556b852
M
879 LED_B_OFF();\r
880}\r
881\r
882//-----------------------------------------------------------------------------\r
883// Load a card into the emulator memory\r
884// \r
885//-----------------------------------------------------------------------------\r
886void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
baeaf579 887 uint8_t numSectors = arg0;\r
8556b852
M
888 uint8_t keyType = arg1;\r
889 uint64_t ui64Key = 0;\r
890 uint32_t cuid;\r
891 struct Crypto1State mpcs = {0, 0};\r
892 struct Crypto1State *pcs;\r
893 pcs = &mpcs;\r
894\r
895 // variables\r
896 byte_t dataoutbuf[16];\r
ab8b654e 897 byte_t dataoutbuf2[16];\r
1c611bbd 898 uint8_t uid[10];\r
8556b852
M
899\r
900 // clear trace\r
3000dc4e
MHS
901 clear_trace();\r
902 set_tracing(false);\r
8556b852 903 \r
7bc95e2e 904 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
8556b852
M
905\r
906 LED_A_ON();\r
907 LED_B_OFF();\r
908 LED_C_OFF();\r
909 \r
baeaf579 910 bool isOK = true;\r
911\r
912 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
913 isOK = false;\r
914 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
915 }\r
8556b852 916 \r
baeaf579 917 for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {\r
918 ui64Key = emlGetKey(sectorNo, keyType);\r
919 if (sectorNo == 0){\r
920 if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {\r
921 isOK = false;\r
922 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo);\r
8556b852 923 break;\r
baeaf579 924 }\r
925 } else {\r
926 if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {\r
927 isOK = false;\r
928 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);\r
8556b852 929 break;\r
baeaf579 930 }\r
931 }\r
932 \r
933 for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
934 if(isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {\r
935 isOK = false;\r
936 if (MF_DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);\r
ab8b654e
M
937 break;\r
938 };\r
baeaf579 939 if (isOK) {\r
940 if (blockNo < NumBlocksPerSector(sectorNo) - 1) {\r
941 emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);\r
942 } else { // sector trailer, keep the keys, set only the AC\r
943 emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);\r
944 memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);\r
945 emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);\r
946 }\r
947 }\r
8556b852
M
948 }\r
949\r
baeaf579 950 }\r
951\r
952 if(mifare_classic_halt(pcs, cuid)) {\r
953 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
954 };\r
8556b852
M
955\r
956 // ----------------------------- crypto1 destroy\r
957 crypto1_destroy(pcs);\r
ab8b654e
M
958\r
959 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
960 LEDsoff();\r
8556b852
M
961 \r
962 if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");\r
963\r
8556b852
M
964}\r
965\r
0675f200
M
966\r
967//-----------------------------------------------------------------------------\r
968// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
969// \r
970//-----------------------------------------------------------------------------\r
971void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
972 \r
973 // params\r
974 uint8_t needWipe = arg0;\r
208a0166
M
975 // bit 0 - need get UID\r
976 // bit 1 - need wupC\r
977 // bit 2 - need HALT after sequence\r
978 // bit 3 - need init FPGA and field before sequence\r
979 // bit 4 - need reset FPGA and LED\r
980 uint8_t workFlags = arg1;\r
0675f200
M
981 uint8_t blockNo = arg2;\r
982 \r
983 // card commands\r
984 uint8_t wupC1[] = { 0x40 }; \r
985 uint8_t wupC2[] = { 0x43 }; \r
986 uint8_t wipeC[] = { 0x41 }; \r
987 \r
988 // variables\r
989 byte_t isOK = 0;\r
3fe4ff4f 990 uint8_t uid[10] = {0x00};\r
991 uint8_t d_block[18] = {0x00};\r
0675f200
M
992 uint32_t cuid;\r
993 \r
f71f4deb 994 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
995 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
6a1f2d82 996\r
3fe4ff4f 997 // reset FPGA and LED\r
208a0166 998 if (workFlags & 0x08) {\r
208a0166
M
999 LED_A_ON();\r
1000 LED_B_OFF();\r
1001 LED_C_OFF();\r
0675f200 1002 \r
3000dc4e
MHS
1003 clear_trace();\r
1004 set_tracing(TRUE);\r
3fe4ff4f 1005 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
208a0166 1006 }\r
0675f200
M
1007\r
1008 while (true) {\r
3fe4ff4f 1009\r
0675f200 1010 // get UID from chip\r
208a0166 1011 if (workFlags & 0x01) {\r
0675f200
M
1012 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
1013 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
3ac59c7f 1014 //break;\r
0675f200
M
1015 };\r
1016\r
1017 if(mifare_classic_halt(NULL, cuid)) {\r
1018 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
3ac59c7f 1019 //break;\r
0675f200
M
1020 };\r
1021 };\r
1022 \r
1023 // reset chip\r
1024 if (needWipe){\r
6a1f2d82 1025 ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
1026 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
0675f200
M
1027 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
1028 break;\r
1029 };\r
1030\r
9492e0b0 1031 ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
6a1f2d82 1032 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
0675f200
M
1033 if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
1034 break;\r
1035 };\r
1036\r
1037 if(mifare_classic_halt(NULL, cuid)) {\r
1038 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
1039 break;\r
1040 };\r
1041 }; \r
1042\r
545a1f38 1043 // write block\r
208a0166 1044 if (workFlags & 0x02) {\r
6a1f2d82 1045 ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
1046 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
208a0166
M
1047 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
1048 break;\r
1049 };\r
0675f200 1050\r
9492e0b0 1051 ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
6a1f2d82 1052 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
208a0166
M
1053 if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
1054 break;\r
1055 };\r
1056 }\r
0675f200 1057\r
6a1f2d82 1058 if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
0675f200
M
1059 if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
1060 break;\r
1061 };\r
1062 \r
1063 memcpy(d_block, datain, 16);\r
1064 AppendCrc14443a(d_block, 16);\r
1065 \r
9492e0b0 1066 ReaderTransmit(d_block, sizeof(d_block), NULL);\r
6a1f2d82 1067 if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
0675f200
M
1068 if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
1069 break;\r
1070 }; \r
1071 \r
208a0166
M
1072 if (workFlags & 0x04) {\r
1073 if (mifare_classic_halt(NULL, cuid)) {\r
1074 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
1075 break;\r
1076 };\r
1077 }\r
0675f200
M
1078 \r
1079 isOK = 1;\r
1080 break;\r
1081 }\r
1082 \r
0675f200 1083 LED_B_ON();\r
baeaf579 1084 cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
0675f200
M
1085 LED_B_OFF();\r
1086\r
545a1f38 1087 if ((workFlags & 0x10) || (!isOK)) {\r
208a0166
M
1088 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1089 LEDsoff();\r
1090 }\r
0675f200 1091}\r
545a1f38 1092\r
baeaf579 1093\r
545a1f38
M
1094void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
1095 \r
1096 // params\r
1097 // bit 1 - need wupC\r
1098 // bit 2 - need HALT after sequence\r
1099 // bit 3 - need init FPGA and field before sequence\r
1100 // bit 4 - need reset FPGA and LED\r
1101 uint8_t workFlags = arg0;\r
1102 uint8_t blockNo = arg2;\r
1103 \r
1104 // card commands\r
1105 uint8_t wupC1[] = { 0x40 }; \r
1106 uint8_t wupC2[] = { 0x43 }; \r
1107 \r
1108 // variables\r
1109 byte_t isOK = 0;\r
3fe4ff4f 1110 uint8_t data[18] = {0x00};\r
545a1f38
M
1111 uint32_t cuid = 0;\r
1112 \r
f71f4deb 1113 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
1114 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
545a1f38
M
1115 \r
1116 if (workFlags & 0x08) {\r
545a1f38
M
1117 LED_A_ON();\r
1118 LED_B_OFF();\r
1119 LED_C_OFF();\r
1120 \r
3000dc4e
MHS
1121 clear_trace();\r
1122 set_tracing(TRUE);\r
3fe4ff4f 1123 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
545a1f38
M
1124 }\r
1125\r
1126 while (true) {\r
1127 if (workFlags & 0x02) {\r
7bc95e2e 1128 ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
6a1f2d82 1129 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
545a1f38
M
1130 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
1131 break;\r
1132 };\r
1133\r
9492e0b0 1134 ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
6a1f2d82 1135 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
545a1f38
M
1136 if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
1137 break;\r
1138 };\r
1139 }\r
1140\r
1141 // read block\r
6a1f2d82 1142 if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {\r
545a1f38
M
1143 if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");\r
1144 break;\r
1145 };\r
1146 memcpy(data, receivedAnswer, 18);\r
1147 \r
1148 if (workFlags & 0x04) {\r
1149 if (mifare_classic_halt(NULL, cuid)) {\r
1150 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
1151 break;\r
1152 };\r
1153 }\r
1154 \r
1155 isOK = 1;\r
1156 break;\r
1157 }\r
1158 \r
545a1f38 1159 LED_B_ON();\r
baeaf579 1160 cmd_send(CMD_ACK,isOK,0,0,data,18);\r
545a1f38
M
1161 LED_B_OFF();\r
1162\r
1163 if ((workFlags & 0x10) || (!isOK)) {\r
545a1f38
M
1164 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1165 LEDsoff();\r
1166 }\r
1167}\r
1168\r
3fe4ff4f 1169void MifareCIdent(){\r
1170 \r
1171 // card commands\r
1172 uint8_t wupC1[] = { 0x40 }; \r
1173 uint8_t wupC2[] = { 0x43 }; \r
1174 \r
1175 // variables\r
1176 byte_t isOK = 1;\r
1177 \r
f71f4deb 1178 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
1179 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
3fe4ff4f 1180\r
1181 ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
1182 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
1183 isOK = 0;\r
1184 };\r
1185\r
1186 ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
1187 if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
1188 isOK = 0;\r
1189 };\r
1190\r
1191 if (mifare_classic_halt(NULL, 0)) {\r
1192 isOK = 0;\r
1193 };\r
1194\r
1195 cmd_send(CMD_ACK,isOK,0,0,0,0);\r
1196}\r
1197\r
1198 //\r
1199// DESFIRE\r
1200//\r
a631936e 1201\r
1202void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){\r
1203\r
1204 byte_t dataout[11] = {0x00};\r
1205 uint8_t uid[10] = {0x00};\r
1206 uint32_t cuid;\r
1207 \r
3000dc4e 1208 clear_trace();\r
a631936e 1209 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
1210\r
1211 int len = iso14443a_select_card(uid, NULL, &cuid);\r
1212 if(!len) {\r
1213 if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
1214 Dbprintf("Can't select card");\r
0ec548dc 1215 OnError(1);\r
a631936e 1216 return;\r
1217 };\r
1218\r
1219 if(mifare_desfire_des_auth1(cuid, dataout)){\r
1220 if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
1221 Dbprintf("Authentication part1: Fail.");\r
0ec548dc 1222 OnError(4);\r
a631936e 1223 return;\r
1224 }\r
1225\r
1226 if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");\r
1227 \r
1228 cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));\r
1229}\r
1230\r
1231void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){\r
1232\r
1233 uint32_t cuid = arg0;\r
1234 uint8_t key[16] = {0x00};\r
1235 byte_t isOK = 0;\r
1236 byte_t dataout[12] = {0x00};\r
1237 \r
1238 memcpy(key, datain, 16);\r
1239 \r
1240 isOK = mifare_desfire_des_auth2(cuid, key, dataout);\r
1241 \r
1242 if( isOK) {\r
1243 if (MF_DBGLEVEL >= MF_DBG_EXTENDED) \r
1244 Dbprintf("Authentication part2: Failed"); \r
0ec548dc 1245 OnError(4);\r
a631936e 1246 return;\r
1247 }\r
1248\r
1249 if (MF_DBGLEVEL >= MF_DBG_EXTENDED) \r
1250 DbpString("AUTH 2 FINISHED");\r
1251\r
1252 cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));\r
1253 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1254 LEDsoff();\r
3000dc4e 1255}\r
Impressum, Datenschutz