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