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