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