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