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