]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/mifarecmd.c
added 'hf 15 cmd sysinfo' using Adrian's second patch from issue 20
[proxmark3-svn] / armsrc / mifarecmd.c
CommitLineData
8556b852
M
1//-----------------------------------------------------------------------------\r
2// Merlok - June 2011\r
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
38 iso14a_clear_tracelen();\r
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
81 UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
82 memcpy(ack.d.asBytes, dataoutbuf, 16);\r
83 \r
84 LED_B_ON();\r
85 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
86 LED_B_OFF();\r
87\r
88\r
89 // Thats it...\r
90 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
91 LEDsoff();\r
92// iso14a_set_tracing(TRUE);\r
93\r
94}\r
95\r
96//-----------------------------------------------------------------------------\r
97// Select, Authenticaate, Read an MIFARE tag. \r
98// read sector (data = 4 x 16 bytes = 64 bytes)\r
99//-----------------------------------------------------------------------------\r
100void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
101{\r
102 // params\r
103 uint8_t sectorNo = arg0;\r
104 uint8_t keyType = arg1;\r
105 uint64_t ui64Key = 0;\r
106 ui64Key = bytes_to_num(datain, 6);\r
107 \r
108 // variables\r
109 byte_t isOK = 0;\r
110 byte_t dataoutbuf[16 * 4];\r
111 uint8_t uid[8];\r
112 uint32_t cuid;\r
113 struct Crypto1State mpcs = {0, 0};\r
114 struct Crypto1State *pcs;\r
115 pcs = &mpcs;\r
116\r
117 // clear trace\r
118 iso14a_clear_tracelen();\r
119// iso14a_set_tracing(false);\r
120\r
121 iso14443a_setup();\r
122\r
123 LED_A_ON();\r
124 LED_B_OFF();\r
125 LED_C_OFF();\r
126\r
127 while (true) {\r
128 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
129 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
130 break;\r
131 };\r
132\r
133 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {\r
134 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
135 break;\r
136 };\r
137 \r
138 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf + 16 * 0)) {\r
139 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");\r
140 break;\r
141 };\r
142 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf + 16 * 1)) {\r
143 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");\r
144 break;\r
145 };\r
146 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf + 16 * 2)) {\r
147 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");\r
148 break;\r
149 };\r
150 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf + 16 * 3)) {\r
151 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");\r
152 break;\r
153 };\r
154 \r
155 if(mifare_classic_halt(pcs, cuid)) {\r
156 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
157 break;\r
158 };\r
159\r
160 isOK = 1;\r
161 break;\r
162 }\r
163 \r
164 // ----------------------------- crypto1 destroy\r
165 crypto1_destroy(pcs);\r
166 \r
167 if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
168\r
169 // add trace trailer\r
170 memset(uid, 0x44, 4);\r
171 LogTrace(uid, 4, 0, 0, TRUE);\r
172\r
173 UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
174 memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
175 \r
176 LED_B_ON();\r
177 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
178\r
179 SpinDelay(100);\r
180 \r
181 memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
182 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
183 LED_B_OFF(); \r
184\r
185 // Thats it...\r
186 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
187 LEDsoff();\r
188// iso14a_set_tracing(TRUE);\r
189\r
190}\r
191\r
192//-----------------------------------------------------------------------------\r
193// Select, Authenticaate, Read an MIFARE tag. \r
194// read block\r
195//-----------------------------------------------------------------------------\r
196void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
197{\r
198 // params\r
199 uint8_t blockNo = arg0;\r
200 uint8_t keyType = arg1;\r
201 uint64_t ui64Key = 0;\r
202 byte_t blockdata[16];\r
203\r
204 ui64Key = bytes_to_num(datain, 6);\r
205 memcpy(blockdata, datain + 10, 16);\r
206 \r
207 // variables\r
208 byte_t isOK = 0;\r
209 uint8_t uid[8];\r
210 uint32_t cuid;\r
211 struct Crypto1State mpcs = {0, 0};\r
212 struct Crypto1State *pcs;\r
213 pcs = &mpcs;\r
214\r
215 // clear trace\r
216 iso14a_clear_tracelen();\r
217// iso14a_set_tracing(false);\r
218\r
219 iso14443a_setup();\r
220\r
221 LED_A_ON();\r
222 LED_B_OFF();\r
223 LED_C_OFF();\r
224\r
225 while (true) {\r
226 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
227 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
228 break;\r
229 };\r
230\r
231 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
232 if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
233 break;\r
234 };\r
235 \r
236 if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {\r
237 if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
238 break;\r
239 };\r
240\r
241 if(mifare_classic_halt(pcs, cuid)) {\r
242 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
243 break;\r
244 };\r
245 \r
246 isOK = 1;\r
247 break;\r
248 }\r
249 \r
250 // ----------------------------- crypto1 destroy\r
251 crypto1_destroy(pcs);\r
252 \r
253 if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
254\r
255 // add trace trailer\r
256 memset(uid, 0x44, 4);\r
257 LogTrace(uid, 4, 0, 0, TRUE);\r
258\r
259 UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
260 \r
261 LED_B_ON();\r
262 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
263 LED_B_OFF(); \r
264\r
265\r
266 // Thats it...\r
267 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
268 LEDsoff();\r
269// iso14a_set_tracing(TRUE);\r
270\r
271}\r
272\r
273// Return 1 if the nonce is invalid else return 0\r
274int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {\r
275 return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \\r
276 (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \\r
277 (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;\r
278}\r
279\r
280//-----------------------------------------------------------------------------\r
281// MIFARE nested authentication. \r
282// \r
283//-----------------------------------------------------------------------------\r
284void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)\r
285{\r
286 // params\r
287 uint8_t blockNo = arg0;\r
288 uint8_t keyType = arg1;\r
289 uint8_t targetBlockNo = arg2 & 0xff;\r
290 uint8_t targetKeyType = (arg2 >> 8) & 0xff;\r
291 uint64_t ui64Key = 0;\r
292\r
293 ui64Key = bytes_to_num(datain, 6);\r
294 \r
295 // variables\r
296 int rtr, i, j, m, len;\r
297 int davg, dmin, dmax;\r
298 uint8_t uid[8];\r
299 uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;\r
300 uint8_t par_array[4];\r
23487cd2 301 nestedVector nvector[NES_MAX_INFO + 1][11];\r
8556b852
M
302 int nvectorcount[NES_MAX_INFO + 1];\r
303 int ncount = 0;\r
304 UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
305 struct Crypto1State mpcs = {0, 0};\r
306 struct Crypto1State *pcs;\r
307 pcs = &mpcs;\r
308 uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
309\r
310 //init\r
311 for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11; // 11 - empty block;\r
312 \r
313 // clear trace\r
314 iso14a_clear_tracelen();\r
315 iso14a_set_tracing(false);\r
316 \r
317 iso14443a_setup();\r
318\r
319 LED_A_ON();\r
320 LED_B_ON();\r
321 LED_C_OFF();\r
322\r
323 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
324 SpinDelay(200);\r
325 \r
326 davg = dmax = 0;\r
327 dmin = 2000;\r
328\r
329 // test nonce distance\r
330 for (rtr = 0; rtr < 10; rtr++) {\r
331 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
332 SpinDelay(100);\r
333 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
334\r
335 // Test if the action was cancelled\r
336 if(BUTTON_PRESS()) {\r
337 break;\r
338 }\r
339\r
340 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
341 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
342 break;\r
343 };\r
344 \r
345 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {\r
346 if (MF_DBGLEVEL >= 1) Dbprintf("Auth1 error");\r
347 break;\r
348 };\r
349\r
350 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2)) {\r
351 if (MF_DBGLEVEL >= 1) Dbprintf("Auth2 error");\r
352 break;\r
353 };\r
354 \r
355 nttmp = prng_successor(nt1, 500);\r
356 for (i = 501; i < 2000; i++) {\r
357 nttmp = prng_successor(nttmp, 1);\r
358 if (nttmp == nt2) break;\r
359 }\r
360 \r
361 if (i != 2000) {\r
362 davg += i;\r
363 if (dmin > i) dmin = i;\r
364 if (dmax < i) dmax = i;\r
365 if (MF_DBGLEVEL >= 4) Dbprintf("r=%d nt1=%08x nt2=%08x distance=%d", rtr, nt1, nt2, i);\r
366 }\r
367 }\r
368 \r
369 if (rtr == 0) return;\r
370\r
371 davg = davg / rtr;\r
372 if (MF_DBGLEVEL >= 3) Dbprintf("distance: min=%d max=%d avg=%d", dmin, dmax, davg);\r
373\r
374 LED_B_OFF();\r
375\r
376// ------------------------------------------------------------------------------------------------- \r
377 \r
378 LED_C_ON();\r
379\r
380 // get crypted nonces for target sector\r
381 for (rtr = 0; rtr < NS_RETRIES_GETNONCE; rtr++) {\r
382 if (MF_DBGLEVEL >= 4) Dbprintf("------------------------------");\r
383\r
384 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
385 SpinDelay(100);\r
386 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
387\r
388 // Test if the action was cancelled\r
389 if(BUTTON_PRESS()) {\r
390 break;\r
391 }\r
392\r
393 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
394 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
395 break;\r
396 };\r
397 \r
398 if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {\r
399 if (MF_DBGLEVEL >= 1) Dbprintf("Auth1 error");\r
400 break;\r
401 };\r
402\r
403 // nested authentication\r
404 len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par);\r
405 if (len != 4) {\r
406 if (MF_DBGLEVEL >= 1) Dbprintf("Auth2 error len=%d", len);\r
407 break;\r
408 };\r
409 \r
410 nt2 = bytes_to_num(receivedAnswer, 4); \r
411 if (MF_DBGLEVEL >= 4) Dbprintf("r=%d nt1=%08x nt2enc=%08x nt2par=%08x", rtr, nt1, nt2, par);\r
412 \r
413 // Parity validity check\r
414 for (i = 0; i < 4; i++) {\r
415 par_array[i] = (oddparity(receivedAnswer[i]) != ((par & 0x08) >> 3));\r
416 par = par << 1;\r
417 }\r
418 \r
419 ncount = 0;\r
420 for (m = dmin - NS_TOLERANCE; m < dmax + NS_TOLERANCE; m++) {\r
421 nttest = prng_successor(nt1, m);\r
422 ks1 = nt2 ^ nttest;\r
423\r
424 if (valid_nonce(nttest, nt2, ks1, par_array) && (ncount < 11)){\r
425 \r
426 nvector[NES_MAX_INFO][ncount].nt = nttest;\r
427 nvector[NES_MAX_INFO][ncount].ks1 = ks1;\r
428 ncount++;\r
429 nvectorcount[NES_MAX_INFO] = ncount;\r
430 if (MF_DBGLEVEL >= 4) Dbprintf("valid m=%d ks1=%08x nttest=%08x", m, ks1, nttest);\r
431 }\r
432\r
433 }\r
434 \r
435 // select vector with length less than got\r
436 if (nvectorcount[NES_MAX_INFO] != 0) {\r
437 m = NES_MAX_INFO;\r
438 \r
439 for (i = 0; i < NES_MAX_INFO; i++)\r
440 if (nvectorcount[i] > 10) {\r
441 m = i;\r
442 break;\r
443 }\r
444 \r
445 if (m == NES_MAX_INFO)\r
446 for (i = 0; i < NES_MAX_INFO; i++)\r
447 if (nvectorcount[NES_MAX_INFO] < nvectorcount[i]) {\r
448 m = i;\r
449 break;\r
450 }\r
451 \r
452 if (m != NES_MAX_INFO) {\r
453 for (i = 0; i < nvectorcount[m]; i++) {\r
454 nvector[m][i] = nvector[NES_MAX_INFO][i];\r
455 }\r
456 nvectorcount[m] = nvectorcount[NES_MAX_INFO];\r
457 }\r
458 }\r
459 }\r
460\r
461 LED_C_OFF();\r
462 \r
463 // ----------------------------- crypto1 destroy\r
464 crypto1_destroy(pcs);\r
465 \r
466 // add trace trailer\r
467 memset(uid, 0x44, 4);\r
468 LogTrace(uid, 4, 0, 0, TRUE);\r
469\r
470 for (i = 0; i < NES_MAX_INFO; i++) {\r
471 if (nvectorcount[i] > 10) continue;\r
472 \r
473 for (j = 0; j < nvectorcount[i]; j += 5) {\r
474 ncount = nvectorcount[i] - j;\r
475 if (ncount > 5) ncount = 5; \r
476\r
477 ack.arg[0] = 0; // isEOF = 0\r
478 ack.arg[1] = ncount;\r
479 ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
480 memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
481 \r
482 memcpy(ack.d.asBytes, &cuid, 4);\r
483 for (m = 0; m < ncount; m++) {\r
484 memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
485 memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
486 }\r
487 \r
488 LED_B_ON();\r
489 SpinDelay(100);\r
490 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
491 LED_B_OFF(); \r
492 }\r
493 }\r
494\r
495 // finalize list\r
496 ack.arg[0] = 1; // isEOF = 1\r
497 ack.arg[1] = 0;\r
498 ack.arg[2] = 0;\r
499 memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
500 \r
501 LED_B_ON();\r
502 SpinDelay(300);\r
503 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
504 LED_B_OFF(); \r
505\r
506 if (MF_DBGLEVEL >= 4) DbpString("NESTED FINISHED");\r
507\r
508 // Thats it...\r
509 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
510 LEDsoff();\r
511 \r
512 iso14a_set_tracing(TRUE);\r
513}\r
514\r
515//-----------------------------------------------------------------------------\r
516// MIFARE check keys. key count up to 8. \r
517// \r
518//-----------------------------------------------------------------------------\r
519void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
520{\r
521 // params\r
522 uint8_t blockNo = arg0;\r
523 uint8_t keyType = arg1;\r
524 uint8_t keyCount = arg2;\r
525 uint64_t ui64Key = 0;\r
526 \r
527 // variables\r
528 int i;\r
529 byte_t isOK = 0;\r
530 uint8_t uid[8];\r
531 uint32_t cuid;\r
532 struct Crypto1State mpcs = {0, 0};\r
533 struct Crypto1State *pcs;\r
534 pcs = &mpcs;\r
535 \r
536 // clear debug level\r
537 int OLD_MF_DBGLEVEL = MF_DBGLEVEL; \r
538 MF_DBGLEVEL = MF_DBG_NONE;\r
539 \r
540 // clear trace\r
541 iso14a_clear_tracelen();\r
542 iso14a_set_tracing(TRUE);\r
543\r
544 iso14443a_setup();\r
545\r
546 LED_A_ON();\r
547 LED_B_OFF();\r
548 LED_C_OFF();\r
549\r
550 SpinDelay(300);\r
551 for (i = 0; i < keyCount; i++) {\r
552 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
553 SpinDelay(100);\r
554 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
555\r
556 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
557 if (OLD_MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
558 break;\r
559 };\r
560\r
561 ui64Key = bytes_to_num(datain + i * 6, 6);\r
562 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
563 continue;\r
564 };\r
565 \r
566 isOK = 1;\r
567 break;\r
568 }\r
569 \r
570 // ----------------------------- crypto1 destroy\r
571 crypto1_destroy(pcs);\r
572 \r
573 // add trace trailer\r
574 memset(uid, 0x44, 4);\r
575 LogTrace(uid, 4, 0, 0, TRUE);\r
576\r
577 UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
578 if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
579 \r
580 LED_B_ON();\r
581 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
582 LED_B_OFF();\r
583\r
584 // Thats it...\r
585 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
586 LEDsoff();\r
587\r
588 // restore debug level\r
589 MF_DBGLEVEL = OLD_MF_DBGLEVEL; \r
590}\r
591\r
592//-----------------------------------------------------------------------------\r
593// MIFARE commands set debug level\r
594// \r
595//-----------------------------------------------------------------------------\r
596void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
597 MF_DBGLEVEL = arg0;\r
598 Dbprintf("Debug level: %d", MF_DBGLEVEL);\r
599}\r
600\r
601//-----------------------------------------------------------------------------\r
602// Work with emulator memory\r
603// \r
604//-----------------------------------------------------------------------------\r
605void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
606 emlClearMem();\r
607}\r
608\r
609void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
610 emlSetMem(datain, arg0, arg1); // data, block num, blocks count\r
611}\r
612\r
613void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
614 UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
615\r
616 emlGetMem(ack.d.asBytes, arg0, arg1); // data, block num, blocks count\r
617\r
618 LED_B_ON();\r
619 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
620 LED_B_OFF();\r
621}\r
622\r
623//-----------------------------------------------------------------------------\r
624// Load a card into the emulator memory\r
625// \r
626//-----------------------------------------------------------------------------\r
627void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
628 int i;\r
629 uint8_t sectorNo = 0;\r
630 uint8_t keyType = arg1;\r
631 uint64_t ui64Key = 0;\r
632 uint32_t cuid;\r
633 struct Crypto1State mpcs = {0, 0};\r
634 struct Crypto1State *pcs;\r
635 pcs = &mpcs;\r
636\r
637 // variables\r
638 byte_t dataoutbuf[16];\r
ab8b654e 639 byte_t dataoutbuf2[16];\r
8556b852
M
640 uint8_t uid[8];\r
641\r
642 // clear trace\r
643 iso14a_clear_tracelen();\r
644 iso14a_set_tracing(false);\r
645 \r
646 iso14443a_setup();\r
647\r
648 LED_A_ON();\r
649 LED_B_OFF();\r
650 LED_C_OFF();\r
651 \r
652 while (true) {\r
653 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
654 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
655 break;\r
656 };\r
657 \r
658 for (i = 0; i < 16; i++) {\r
659 sectorNo = i;\r
660 ui64Key = emlGetKey(sectorNo, keyType);\r
661 \r
662 if (!i){\r
663 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {\r
664 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth error", i);\r
665 break;\r
666 }\r
667 } else {\r
668 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_NESTED)) {\r
669 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth nested error", i);\r
670 break;\r
671 }\r
672 }\r
673 \r
674 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf)) {\r
675 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");\r
676 break;\r
677 };\r
678 emlSetMem(dataoutbuf, sectorNo * 4 + 0, 1);\r
679 \r
680 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf)) {\r
681 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");\r
682 break;\r
683 };\r
684 emlSetMem(dataoutbuf, sectorNo * 4 + 1, 1);\r
685\r
686 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf)) {\r
687 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");\r
688 break;\r
689 };\r
690 emlSetMem(dataoutbuf, sectorNo * 4 + 2, 1);\r
ab8b654e
M
691\r
692 // get block 3 bytes 6-9\r
693 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf)) {\r
694 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");\r
695 break;\r
696 };\r
697 emlGetMem(dataoutbuf2, sectorNo * 4 + 3, 1);\r
698 memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);\r
699 emlSetMem(dataoutbuf2, sectorNo * 4 + 3, 1);\r
8556b852
M
700 }\r
701\r
702 if(mifare_classic_halt(pcs, cuid)) {\r
703 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
704 break;\r
705 };\r
706 \r
707 break;\r
708 } \r
709\r
710 // ----------------------------- crypto1 destroy\r
711 crypto1_destroy(pcs);\r
ab8b654e
M
712\r
713 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
714 LEDsoff();\r
8556b852
M
715 \r
716 if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");\r
717\r
718 // add trace trailer\r
719 memset(uid, 0x44, 4);\r
720 LogTrace(uid, 4, 0, 0, TRUE);\r
8556b852
M
721}\r
722\r
723//-----------------------------------------------------------------------------\r
724// MIFARE 1k emulator\r
725// \r
726//-----------------------------------------------------------------------------\r
727\r
Impressum, Datenschutz