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