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