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