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