]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/mifarecmd.c
fixed stupid 64-bit formatting for x86/amd64 and unix/windows - part4
[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
5//\r
6// This code is licensed to you under the terms of the GNU GPL, version 2 or,\r
7// at your option, any later version. See the LICENSE.txt file for the text of\r
8// the license.\r
9//-----------------------------------------------------------------------------\r
10// Routines to support ISO 14443 type A.\r
11//-----------------------------------------------------------------------------\r
12\r
13#include "mifarecmd.h"\r
14#include "apps.h"\r
15\r
16//-----------------------------------------------------------------------------\r
17// Select, Authenticaate, Read an MIFARE tag. \r
18// read block\r
19//-----------------------------------------------------------------------------\r
20void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
21{\r
22 // params\r
23 uint8_t blockNo = arg0;\r
24 uint8_t keyType = arg1;\r
25 uint64_t ui64Key = 0;\r
26 ui64Key = bytes_to_num(datain, 6);\r
27 \r
28 // variables\r
29 byte_t isOK = 0;\r
30 byte_t dataoutbuf[16];\r
31 uint8_t uid[8];\r
32 uint32_t cuid;\r
33 struct Crypto1State mpcs = {0, 0};\r
34 struct Crypto1State *pcs;\r
35 pcs = &mpcs;\r
36\r
37 // clear trace\r
d19929cb 38 iso14a_clear_trace();\r
8556b852
M
39// iso14a_set_tracing(false);\r
40\r
41 iso14443a_setup();\r
42\r
43 LED_A_ON();\r
44 LED_B_OFF();\r
45 LED_C_OFF();\r
46\r
47 while (true) {\r
48 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
49 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
50 break;\r
51 };\r
52\r
53 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
54 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
55 break;\r
56 };\r
57 \r
58 if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {\r
59 if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");\r
60 break;\r
61 };\r
62\r
63 if(mifare_classic_halt(pcs, cuid)) {\r
64 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
65 break;\r
66 };\r
67 \r
68 isOK = 1;\r
69 break;\r
70 }\r
71 \r
72 // ----------------------------- crypto1 destroy\r
73 crypto1_destroy(pcs);\r
74 \r
75 if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");\r
76\r
77 // add trace trailer\r
78 memset(uid, 0x44, 4);\r
79 LogTrace(uid, 4, 0, 0, TRUE);\r
80\r
6e82300d 81// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
82// memcpy(ack.d.asBytes, dataoutbuf, 16);\r
8556b852
M
83 \r
84 LED_B_ON();\r
6e82300d 85 cmd_send(CMD_ACK,isOK,0,0,0,0);\r
86// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
8556b852
M
87 LED_B_OFF();\r
88\r
89\r
90 // Thats it...\r
91 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
92 LEDsoff();\r
93// iso14a_set_tracing(TRUE);\r
94\r
95}\r
96\r
97//-----------------------------------------------------------------------------\r
98// Select, Authenticaate, Read an MIFARE tag. \r
99// read sector (data = 4 x 16 bytes = 64 bytes)\r
100//-----------------------------------------------------------------------------\r
101void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
102{\r
103 // params\r
104 uint8_t sectorNo = arg0;\r
105 uint8_t keyType = arg1;\r
106 uint64_t ui64Key = 0;\r
107 ui64Key = bytes_to_num(datain, 6);\r
108 \r
109 // variables\r
110 byte_t isOK = 0;\r
111 byte_t dataoutbuf[16 * 4];\r
112 uint8_t uid[8];\r
113 uint32_t cuid;\r
114 struct Crypto1State mpcs = {0, 0};\r
115 struct Crypto1State *pcs;\r
116 pcs = &mpcs;\r
117\r
118 // clear trace\r
d19929cb 119 iso14a_clear_trace();\r
8556b852
M
120// iso14a_set_tracing(false);\r
121\r
122 iso14443a_setup();\r
123\r
124 LED_A_ON();\r
125 LED_B_OFF();\r
126 LED_C_OFF();\r
127\r
128 while (true) {\r
129 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
130 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
131 break;\r
132 };\r
133\r
134 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {\r
135 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
136 break;\r
137 };\r
138 \r
139 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf + 16 * 0)) {\r
140 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");\r
141 break;\r
142 };\r
143 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf + 16 * 1)) {\r
144 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");\r
145 break;\r
146 };\r
147 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf + 16 * 2)) {\r
148 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");\r
149 break;\r
150 };\r
151 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf + 16 * 3)) {\r
152 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");\r
153 break;\r
154 };\r
155 \r
156 if(mifare_classic_halt(pcs, cuid)) {\r
157 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
158 break;\r
159 };\r
160\r
161 isOK = 1;\r
162 break;\r
163 }\r
164 \r
165 // ----------------------------- crypto1 destroy\r
166 crypto1_destroy(pcs);\r
167 \r
168 if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
169\r
170 // add trace trailer\r
171 memset(uid, 0x44, 4);\r
172 LogTrace(uid, 4, 0, 0, TRUE);\r
173\r
6e82300d 174// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
175// memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
8556b852
M
176 \r
177 LED_B_ON();\r
6e82300d 178 cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,32);\r
179// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
180// SpinDelay(100);\r
8556b852 181 \r
6e82300d 182// memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
183// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
184 cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);\r
185 LED_B_OFF();\r
8556b852
M
186\r
187 // Thats it...\r
188 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
189 LEDsoff();\r
190// iso14a_set_tracing(TRUE);\r
191\r
192}\r
193\r
194//-----------------------------------------------------------------------------\r
195// Select, Authenticaate, Read an MIFARE tag. \r
196// read block\r
197//-----------------------------------------------------------------------------\r
198void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
199{\r
200 // params\r
201 uint8_t blockNo = arg0;\r
202 uint8_t keyType = arg1;\r
203 uint64_t ui64Key = 0;\r
204 byte_t blockdata[16];\r
205\r
206 ui64Key = bytes_to_num(datain, 6);\r
207 memcpy(blockdata, datain + 10, 16);\r
208 \r
209 // variables\r
210 byte_t isOK = 0;\r
211 uint8_t uid[8];\r
212 uint32_t cuid;\r
213 struct Crypto1State mpcs = {0, 0};\r
214 struct Crypto1State *pcs;\r
215 pcs = &mpcs;\r
216\r
217 // clear trace\r
d19929cb 218 iso14a_clear_trace();\r
8556b852
M
219// iso14a_set_tracing(false);\r
220\r
221 iso14443a_setup();\r
222\r
223 LED_A_ON();\r
224 LED_B_OFF();\r
225 LED_C_OFF();\r
226\r
227 while (true) {\r
228 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
229 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
230 break;\r
231 };\r
232\r
233 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
234 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
235 break;\r
236 };\r
237 \r
238 if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {\r
239 if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
240 break;\r
241 };\r
242\r
243 if(mifare_classic_halt(pcs, cuid)) {\r
244 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
245 break;\r
246 };\r
247 \r
248 isOK = 1;\r
249 break;\r
250 }\r
251 \r
252 // ----------------------------- crypto1 destroy\r
253 crypto1_destroy(pcs);\r
254 \r
255 if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
256\r
257 // add trace trailer\r
258 memset(uid, 0x44, 4);\r
259 LogTrace(uid, 4, 0, 0, TRUE);\r
260\r
6e82300d 261// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
8556b852
M
262 \r
263 LED_B_ON();\r
6e82300d 264 cmd_send(CMD_ACK,isOK,0,0,0,0);\r
265// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
266 LED_B_OFF();\r
8556b852
M
267\r
268\r
269 // Thats it...\r
270 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
271 LEDsoff();\r
272// iso14a_set_tracing(TRUE);\r
273\r
274}\r
275\r
276// Return 1 if the nonce is invalid else return 0\r
277int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {\r
278 return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \\r
279 (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \\r
280 (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;\r
281}\r
282\r
283//-----------------------------------------------------------------------------\r
284// MIFARE nested authentication. \r
285// \r
286//-----------------------------------------------------------------------------\r
287void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)\r
288{\r
289 // params\r
290 uint8_t blockNo = arg0;\r
291 uint8_t keyType = arg1;\r
292 uint8_t targetBlockNo = arg2 & 0xff;\r
293 uint8_t targetKeyType = (arg2 >> 8) & 0xff;\r
294 uint64_t ui64Key = 0;\r
295\r
296 ui64Key = bytes_to_num(datain, 6);\r
297 \r
298 // variables\r
299 int rtr, i, j, m, len;\r
300 int davg, dmin, dmax;\r
301 uint8_t uid[8];\r
302 uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;\r
303 uint8_t par_array[4];\r
23487cd2 304 nestedVector nvector[NES_MAX_INFO + 1][11];\r
8556b852
M
305 int nvectorcount[NES_MAX_INFO + 1];\r
306 int ncount = 0;\r
8556b852
M
307 struct Crypto1State mpcs = {0, 0};\r
308 struct Crypto1State *pcs;\r
309 pcs = &mpcs;\r
310 uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
311\r
312 //init\r
313 for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11; // 11 - empty block;\r
314 \r
315 // clear trace\r
d19929cb 316 iso14a_clear_trace();\r
8556b852
M
317 iso14a_set_tracing(false);\r
318 \r
319 iso14443a_setup();\r
320\r
321 LED_A_ON();\r
322 LED_B_ON();\r
323 LED_C_OFF();\r
324\r
325 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
326 SpinDelay(200);\r
327 \r
328 davg = dmax = 0;\r
329 dmin = 2000;\r
330\r
331 // test nonce distance\r
332 for (rtr = 0; rtr < 10; rtr++) {\r
333 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
334 SpinDelay(100);\r
335 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
336\r
337 // Test if the action was cancelled\r
338 if(BUTTON_PRESS()) {\r
339 break;\r
340 }\r
341\r
342 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
343 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
344 break;\r
345 };\r
346 \r
347 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {\r
348 if (MF_DBGLEVEL >= 1) Dbprintf("Auth1 error");\r
349 break;\r
350 };\r
351\r
352 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2)) {\r
353 if (MF_DBGLEVEL >= 1) Dbprintf("Auth2 error");\r
354 break;\r
355 };\r
356 \r
357 nttmp = prng_successor(nt1, 500);\r
358 for (i = 501; i < 2000; i++) {\r
359 nttmp = prng_successor(nttmp, 1);\r
360 if (nttmp == nt2) break;\r
361 }\r
362 \r
363 if (i != 2000) {\r
364 davg += i;\r
365 if (dmin > i) dmin = i;\r
366 if (dmax < i) dmax = i;\r
367 if (MF_DBGLEVEL >= 4) Dbprintf("r=%d nt1=%08x nt2=%08x distance=%d", rtr, nt1, nt2, i);\r
368 }\r
369 }\r
370 \r
371 if (rtr == 0) return;\r
372\r
373 davg = davg / rtr;\r
374 if (MF_DBGLEVEL >= 3) Dbprintf("distance: min=%d max=%d avg=%d", dmin, dmax, davg);\r
375\r
376 LED_B_OFF();\r
377\r
378// ------------------------------------------------------------------------------------------------- \r
379 \r
380 LED_C_ON();\r
381\r
382 // get crypted nonces for target sector\r
383 for (rtr = 0; rtr < NS_RETRIES_GETNONCE; rtr++) {\r
384 if (MF_DBGLEVEL >= 4) Dbprintf("------------------------------");\r
385\r
386 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
387 SpinDelay(100);\r
388 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
389\r
390 // Test if the action was cancelled\r
391 if(BUTTON_PRESS()) {\r
392 break;\r
393 }\r
394\r
395 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
396 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
397 break;\r
398 };\r
399 \r
400 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {\r
401 if (MF_DBGLEVEL >= 1) Dbprintf("Auth1 error");\r
402 break;\r
403 };\r
404\r
405 // nested authentication\r
406 len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par);\r
407 if (len != 4) {\r
408 if (MF_DBGLEVEL >= 1) Dbprintf("Auth2 error len=%d", len);\r
409 break;\r
410 };\r
411 \r
412 nt2 = bytes_to_num(receivedAnswer, 4); \r
413 if (MF_DBGLEVEL >= 4) Dbprintf("r=%d nt1=%08x nt2enc=%08x nt2par=%08x", rtr, nt1, nt2, par);\r
414 \r
415 // Parity validity check\r
416 for (i = 0; i < 4; i++) {\r
417 par_array[i] = (oddparity(receivedAnswer[i]) != ((par & 0x08) >> 3));\r
418 par = par << 1;\r
419 }\r
420 \r
421 ncount = 0;\r
7431536d 422 nttest = prng_successor(nt1, dmin - NS_TOLERANCE);\r
423 for (m = dmin - NS_TOLERANCE + 1; m < dmax + NS_TOLERANCE; m++) {\r
424 nttest = prng_successor(nttest, 1);\r
8556b852
M
425 ks1 = nt2 ^ nttest;\r
426\r
427 if (valid_nonce(nttest, nt2, ks1, par_array) && (ncount < 11)){\r
428 \r
429 nvector[NES_MAX_INFO][ncount].nt = nttest;\r
430 nvector[NES_MAX_INFO][ncount].ks1 = ks1;\r
431 ncount++;\r
432 nvectorcount[NES_MAX_INFO] = ncount;\r
433 if (MF_DBGLEVEL >= 4) Dbprintf("valid m=%d ks1=%08x nttest=%08x", m, ks1, nttest);\r
434 }\r
435\r
436 }\r
437 \r
438 // select vector with length less than got\r
439 if (nvectorcount[NES_MAX_INFO] != 0) {\r
440 m = NES_MAX_INFO;\r
441 \r
442 for (i = 0; i < NES_MAX_INFO; i++)\r
443 if (nvectorcount[i] > 10) {\r
444 m = i;\r
445 break;\r
446 }\r
447 \r
448 if (m == NES_MAX_INFO)\r
449 for (i = 0; i < NES_MAX_INFO; i++)\r
450 if (nvectorcount[NES_MAX_INFO] < nvectorcount[i]) {\r
451 m = i;\r
452 break;\r
453 }\r
454 \r
455 if (m != NES_MAX_INFO) {\r
456 for (i = 0; i < nvectorcount[m]; i++) {\r
457 nvector[m][i] = nvector[NES_MAX_INFO][i];\r
458 }\r
459 nvectorcount[m] = nvectorcount[NES_MAX_INFO];\r
460 }\r
461 }\r
462 }\r
463\r
464 LED_C_OFF();\r
465 \r
466 // ----------------------------- crypto1 destroy\r
467 crypto1_destroy(pcs);\r
468 \r
469 // add trace trailer\r
470 memset(uid, 0x44, 4);\r
471 LogTrace(uid, 4, 0, 0, TRUE);\r
472\r
6e82300d 473// UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
474\r
8556b852
M
475 for (i = 0; i < NES_MAX_INFO; i++) {\r
476 if (nvectorcount[i] > 10) continue;\r
477 \r
478 for (j = 0; j < nvectorcount[i]; j += 5) {\r
479 ncount = nvectorcount[i] - j;\r
480 if (ncount > 5) ncount = 5; \r
481\r
6e82300d 482// ack.arg[0] = 0; // isEOF = 0\r
483// ack.arg[1] = ncount;\r
484// ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
485// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
8556b852 486 \r
6e82300d 487 byte_t buf[48];\r
488 memset(buf, 0x00, sizeof(buf));\r
489 memcpy(buf, &cuid, 4);\r
8556b852 490 for (m = 0; m < ncount; m++) {\r
6e82300d 491 memcpy(buf + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
492 memcpy(buf + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
8556b852
M
493 }\r
494 \r
495 LED_B_ON();\r
6e82300d 496// SpinDelay(100);\r
497 cmd_send(CMD_ACK,0,ncount,targetBlockNo + (targetKeyType * 0x100),buf,48);\r
498// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
499 LED_B_OFF();\r
8556b852
M
500 }\r
501 }\r
502\r
503 // finalize list\r
6e82300d 504// ack.arg[0] = 1; // isEOF = 1\r
505// ack.arg[1] = 0;\r
506// ack.arg[2] = 0;\r
507// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
8556b852
M
508 \r
509 LED_B_ON();\r
6e82300d 510// SpinDelay(300);\r
511// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
512 cmd_send(CMD_ACK,1,0,0,0,0);\r
513 LED_B_OFF();\r
8556b852
M
514\r
515 if (MF_DBGLEVEL >= 4) DbpString("NESTED FINISHED");\r
516\r
517 // Thats it...\r
518 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
519 LEDsoff();\r
520 \r
521 iso14a_set_tracing(TRUE);\r
522}\r
523\r
524//-----------------------------------------------------------------------------\r
525// MIFARE check keys. key count up to 8. \r
526// \r
527//-----------------------------------------------------------------------------\r
528void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
529{\r
530 // params\r
531 uint8_t blockNo = arg0;\r
532 uint8_t keyType = arg1;\r
533 uint8_t keyCount = arg2;\r
534 uint64_t ui64Key = 0;\r
535 \r
536 // variables\r
537 int i;\r
538 byte_t isOK = 0;\r
539 uint8_t uid[8];\r
540 uint32_t cuid;\r
541 struct Crypto1State mpcs = {0, 0};\r
542 struct Crypto1State *pcs;\r
543 pcs = &mpcs;\r
544 \r
545 // clear debug level\r
546 int OLD_MF_DBGLEVEL = MF_DBGLEVEL; \r
547 MF_DBGLEVEL = MF_DBG_NONE;\r
548 \r
549 // clear trace\r
d19929cb 550 iso14a_clear_trace();\r
8556b852
M
551 iso14a_set_tracing(TRUE);\r
552\r
553 iso14443a_setup();\r
554\r
555 LED_A_ON();\r
556 LED_B_OFF();\r
557 LED_C_OFF();\r
558\r
559 SpinDelay(300);\r
560 for (i = 0; i < keyCount; i++) {\r
561 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
562 SpinDelay(100);\r
563 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
564\r
565 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
566 if (OLD_MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
567 break;\r
568 };\r
569\r
570 ui64Key = bytes_to_num(datain + i * 6, 6);\r
571 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
572 continue;\r
573 };\r
574 \r
575 isOK = 1;\r
576 break;\r
577 }\r
578 \r
579 // ----------------------------- crypto1 destroy\r
580 crypto1_destroy(pcs);\r
581 \r
582 // add trace trailer\r
583 memset(uid, 0x44, 4);\r
584 LogTrace(uid, 4, 0, 0, TRUE);\r
585\r
6e82300d 586// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
587// if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
8556b852
M
588 \r
589 LED_B_ON();\r
6e82300d 590 cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);\r
591// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
8556b852
M
592 LED_B_OFF();\r
593\r
594 // Thats it...\r
595 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
596 LEDsoff();\r
597\r
598 // restore debug level\r
599 MF_DBGLEVEL = OLD_MF_DBGLEVEL; \r
600}\r
601\r
602//-----------------------------------------------------------------------------\r
603// MIFARE commands set debug level\r
604// \r
605//-----------------------------------------------------------------------------\r
606void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
607 MF_DBGLEVEL = arg0;\r
608 Dbprintf("Debug level: %d", MF_DBGLEVEL);\r
609}\r
610\r
611//-----------------------------------------------------------------------------\r
612// Work with emulator memory\r
613// \r
614//-----------------------------------------------------------------------------\r
615void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
616 emlClearMem();\r
617}\r
618\r
619void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
620 emlSetMem(datain, arg0, arg1); // data, block num, blocks count\r
621}\r
622\r
623void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
6e82300d 624// UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
8556b852 625\r
6e82300d 626 byte_t buf[48];\r
627 emlGetMem(buf, arg0, arg1); // data, block num, blocks count\r
8556b852
M
628\r
629 LED_B_ON();\r
6e82300d 630 cmd_send(CMD_ACK,arg0,arg1,0,buf,48);\r
631// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
8556b852
M
632 LED_B_OFF();\r
633}\r
634\r
635//-----------------------------------------------------------------------------\r
636// Load a card into the emulator memory\r
637// \r
638//-----------------------------------------------------------------------------\r
639void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
640 int i;\r
641 uint8_t sectorNo = 0;\r
642 uint8_t keyType = arg1;\r
643 uint64_t ui64Key = 0;\r
644 uint32_t cuid;\r
645 struct Crypto1State mpcs = {0, 0};\r
646 struct Crypto1State *pcs;\r
647 pcs = &mpcs;\r
648\r
649 // variables\r
650 byte_t dataoutbuf[16];\r
ab8b654e 651 byte_t dataoutbuf2[16];\r
8556b852
M
652 uint8_t uid[8];\r
653\r
654 // clear trace\r
d19929cb 655 iso14a_clear_trace();\r
8556b852
M
656 iso14a_set_tracing(false);\r
657 \r
658 iso14443a_setup();\r
659\r
660 LED_A_ON();\r
661 LED_B_OFF();\r
662 LED_C_OFF();\r
663 \r
664 while (true) {\r
665 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
666 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
667 break;\r
668 };\r
669 \r
670 for (i = 0; i < 16; i++) {\r
671 sectorNo = i;\r
672 ui64Key = emlGetKey(sectorNo, keyType);\r
673 \r
674 if (!i){\r
675 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {\r
676 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth error", i);\r
677 break;\r
678 }\r
679 } else {\r
680 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_NESTED)) {\r
681 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth nested error", i);\r
682 break;\r
683 }\r
684 }\r
685 \r
686 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf)) {\r
687 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");\r
688 break;\r
689 };\r
690 emlSetMem(dataoutbuf, sectorNo * 4 + 0, 1);\r
691 \r
692 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf)) {\r
693 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");\r
694 break;\r
695 };\r
696 emlSetMem(dataoutbuf, sectorNo * 4 + 1, 1);\r
697\r
698 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf)) {\r
699 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");\r
700 break;\r
701 };\r
702 emlSetMem(dataoutbuf, sectorNo * 4 + 2, 1);\r
ab8b654e
M
703\r
704 // get block 3 bytes 6-9\r
705 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf)) {\r
706 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");\r
707 break;\r
708 };\r
709 emlGetMem(dataoutbuf2, sectorNo * 4 + 3, 1);\r
710 memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);\r
711 emlSetMem(dataoutbuf2, sectorNo * 4 + 3, 1);\r
8556b852
M
712 }\r
713\r
714 if(mifare_classic_halt(pcs, cuid)) {\r
715 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
716 break;\r
717 };\r
718 \r
719 break;\r
720 } \r
721\r
722 // ----------------------------- crypto1 destroy\r
723 crypto1_destroy(pcs);\r
ab8b654e
M
724\r
725 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
726 LEDsoff();\r
8556b852
M
727 \r
728 if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");\r
729\r
730 // add trace trailer\r
731 memset(uid, 0x44, 4);\r
732 LogTrace(uid, 4, 0, 0, TRUE);\r
8556b852
M
733}\r
734\r
735//-----------------------------------------------------------------------------\r
736// MIFARE 1k emulator\r
737// \r
738//-----------------------------------------------------------------------------\r
739\r
0675f200
M
740\r
741//-----------------------------------------------------------------------------\r
742// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
743// \r
744//-----------------------------------------------------------------------------\r
745void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
746 \r
747 // params\r
748 uint8_t needWipe = arg0;\r
208a0166
M
749 // bit 0 - need get UID\r
750 // bit 1 - need wupC\r
751 // bit 2 - need HALT after sequence\r
752 // bit 3 - need init FPGA and field before sequence\r
753 // bit 4 - need reset FPGA and LED\r
754 uint8_t workFlags = arg1;\r
0675f200
M
755 uint8_t blockNo = arg2;\r
756 \r
757 // card commands\r
758 uint8_t wupC1[] = { 0x40 }; \r
759 uint8_t wupC2[] = { 0x43 }; \r
760 uint8_t wipeC[] = { 0x41 }; \r
761 \r
762 // variables\r
763 byte_t isOK = 0;\r
764 uint8_t uid[8];\r
765 uint8_t d_block[18];\r
766 uint32_t cuid;\r
767 \r
768 memset(uid, 0x00, 8);\r
769 uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
770 \r
208a0166
M
771 if (workFlags & 0x08) {\r
772 // clear trace\r
d19929cb 773 iso14a_clear_trace();\r
208a0166 774 iso14a_set_tracing(TRUE);\r
0675f200 775\r
208a0166 776 iso14443a_setup();\r
0675f200 777\r
208a0166
M
778 LED_A_ON();\r
779 LED_B_OFF();\r
780 LED_C_OFF();\r
0675f200 781 \r
208a0166
M
782 SpinDelay(300);\r
783 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
784 SpinDelay(100);\r
785 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
786 }\r
0675f200
M
787\r
788 while (true) {\r
789 // get UID from chip\r
208a0166 790 if (workFlags & 0x01) {\r
0675f200
M
791 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
792 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
793 break;\r
794 };\r
795\r
796 if(mifare_classic_halt(NULL, cuid)) {\r
797 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
798 break;\r
799 };\r
800 };\r
801 \r
802 // reset chip\r
803 if (needWipe){\r
804 ReaderTransmitShort(wupC1);\r
805 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
806 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
807 break;\r
808 };\r
809\r
810 ReaderTransmit(wipeC, sizeof(wipeC));\r
811 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
812 if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
813 break;\r
814 };\r
815\r
816 if(mifare_classic_halt(NULL, cuid)) {\r
817 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
818 break;\r
819 };\r
820 }; \r
821\r
545a1f38 822 // write block\r
208a0166
M
823 if (workFlags & 0x02) {\r
824 ReaderTransmitShort(wupC1);\r
825 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
826 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
827 break;\r
828 };\r
0675f200 829\r
208a0166
M
830 ReaderTransmit(wupC2, sizeof(wupC2));\r
831 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
832 if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
833 break;\r
834 };\r
835 }\r
0675f200
M
836\r
837 if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
838 if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
839 break;\r
840 };\r
841 \r
842 memcpy(d_block, datain, 16);\r
843 AppendCrc14443a(d_block, 16);\r
844 \r
845 ReaderTransmit(d_block, sizeof(d_block));\r
846 if ((ReaderReceive(receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
847 if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
848 break;\r
849 }; \r
850 \r
208a0166
M
851 if (workFlags & 0x04) {\r
852 if (mifare_classic_halt(NULL, cuid)) {\r
853 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
854 break;\r
855 };\r
856 }\r
0675f200
M
857 \r
858 isOK = 1;\r
859 break;\r
860 }\r
861 \r
6e82300d 862// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
863// if (isOK) memcpy(ack.d.asBytes, uid, 4);\r
0675f200
M
864 \r
865 // add trace trailer\r
866 memset(uid, 0x44, 4);\r
867 LogTrace(uid, 4, 0, 0, TRUE);\r
868\r
869 LED_B_ON();\r
6e82300d 870 cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
871// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
0675f200
M
872 LED_B_OFF();\r
873\r
545a1f38 874 if ((workFlags & 0x10) || (!isOK)) {\r
208a0166
M
875 // Thats it...\r
876 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
877 LEDsoff();\r
878 }\r
0675f200 879}\r
545a1f38
M
880\r
881void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
882 \r
883 // params\r
884 // bit 1 - need wupC\r
885 // bit 2 - need HALT after sequence\r
886 // bit 3 - need init FPGA and field before sequence\r
887 // bit 4 - need reset FPGA and LED\r
888 uint8_t workFlags = arg0;\r
889 uint8_t blockNo = arg2;\r
890 \r
891 // card commands\r
892 uint8_t wupC1[] = { 0x40 }; \r
893 uint8_t wupC2[] = { 0x43 }; \r
894 \r
895 // variables\r
896 byte_t isOK = 0;\r
897 uint8_t data[18];\r
898 uint32_t cuid = 0;\r
899 \r
900 memset(data, 0x00, 18);\r
901 uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
902 \r
903 if (workFlags & 0x08) {\r
904 // clear trace\r
d19929cb 905 iso14a_clear_trace();\r
545a1f38
M
906 iso14a_set_tracing(TRUE);\r
907\r
908 iso14443a_setup();\r
909\r
910 LED_A_ON();\r
911 LED_B_OFF();\r
912 LED_C_OFF();\r
913 \r
914 SpinDelay(300);\r
915 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
916 SpinDelay(100);\r
917 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
918 }\r
919\r
920 while (true) {\r
921 if (workFlags & 0x02) {\r
922 ReaderTransmitShort(wupC1);\r
923 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
924 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
925 break;\r
926 };\r
927\r
928 ReaderTransmit(wupC2, sizeof(wupC2));\r
929 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
930 if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
931 break;\r
932 };\r
933 }\r
934\r
935 // read block\r
936 if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer) != 18)) {\r
937 if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");\r
938 break;\r
939 };\r
940 memcpy(data, receivedAnswer, 18);\r
941 \r
942 if (workFlags & 0x04) {\r
943 if (mifare_classic_halt(NULL, cuid)) {\r
944 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
945 break;\r
946 };\r
947 }\r
948 \r
949 isOK = 1;\r
950 break;\r
951 }\r
952 \r
6e82300d 953// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
954// if (isOK) memcpy(ack.d.asBytes, data, 18);\r
545a1f38
M
955 \r
956 // add trace trailer\r
957 memset(data, 0x44, 4);\r
958 LogTrace(data, 4, 0, 0, TRUE);\r
959\r
960 LED_B_ON();\r
6e82300d 961 cmd_send(CMD_ACK,isOK,0,0,data,18);\r
962// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
545a1f38
M
963 LED_B_OFF();\r
964\r
965 if ((workFlags & 0x10) || (!isOK)) {\r
966 // Thats it...\r
967 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
968 LEDsoff();\r
969 }\r
970}\r
971\r
Impressum, Datenschutz