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