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