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