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