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