changed -elf to -eabi in install-gnuarm4.sh ARMLIB suggestion
[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
7431536d 420 nttest = prng_successor(nt1, dmin - NS_TOLERANCE);\r
421 for (m = dmin - NS_TOLERANCE + 1; m < dmax + NS_TOLERANCE; m++) {\r
422 nttest = prng_successor(nttest, 1);\r
8556b852
M
423 ks1 = nt2 ^ nttest;\r
424\r
425 if (valid_nonce(nttest, nt2, ks1, par_array) && (ncount < 11)){\r
426 \r
427 nvector[NES_MAX_INFO][ncount].nt = nttest;\r
428 nvector[NES_MAX_INFO][ncount].ks1 = ks1;\r
429 ncount++;\r
430 nvectorcount[NES_MAX_INFO] = ncount;\r
431 if (MF_DBGLEVEL >= 4) Dbprintf("valid m=%d ks1=%08x nttest=%08x", m, ks1, nttest);\r
432 }\r
433\r
434 }\r
435 \r
436 // select vector with length less than got\r
437 if (nvectorcount[NES_MAX_INFO] != 0) {\r
438 m = NES_MAX_INFO;\r
439 \r
440 for (i = 0; i < NES_MAX_INFO; i++)\r
441 if (nvectorcount[i] > 10) {\r
442 m = i;\r
443 break;\r
444 }\r
445 \r
446 if (m == NES_MAX_INFO)\r
447 for (i = 0; i < NES_MAX_INFO; i++)\r
448 if (nvectorcount[NES_MAX_INFO] < nvectorcount[i]) {\r
449 m = i;\r
450 break;\r
451 }\r
452 \r
453 if (m != NES_MAX_INFO) {\r
454 for (i = 0; i < nvectorcount[m]; i++) {\r
455 nvector[m][i] = nvector[NES_MAX_INFO][i];\r
456 }\r
457 nvectorcount[m] = nvectorcount[NES_MAX_INFO];\r
458 }\r
459 }\r
460 }\r
461\r
462 LED_C_OFF();\r
463 \r
464 // ----------------------------- crypto1 destroy\r
465 crypto1_destroy(pcs);\r
466 \r
467 // add trace trailer\r
468 memset(uid, 0x44, 4);\r
469 LogTrace(uid, 4, 0, 0, TRUE);\r
470\r
471 for (i = 0; i < NES_MAX_INFO; i++) {\r
472 if (nvectorcount[i] > 10) continue;\r
473 \r
474 for (j = 0; j < nvectorcount[i]; j += 5) {\r
475 ncount = nvectorcount[i] - j;\r
476 if (ncount > 5) ncount = 5; \r
477\r
478 ack.arg[0] = 0; // isEOF = 0\r
479 ack.arg[1] = ncount;\r
480 ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
481 memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
482 \r
483 memcpy(ack.d.asBytes, &cuid, 4);\r
484 for (m = 0; m < ncount; m++) {\r
485 memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
486 memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
487 }\r
488 \r
489 LED_B_ON();\r
490 SpinDelay(100);\r
491 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
492 LED_B_OFF(); \r
493 }\r
494 }\r
495\r
496 // finalize list\r
497 ack.arg[0] = 1; // isEOF = 1\r
498 ack.arg[1] = 0;\r
499 ack.arg[2] = 0;\r
500 memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
501 \r
502 LED_B_ON();\r
503 SpinDelay(300);\r
504 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
505 LED_B_OFF(); \r
506\r
507 if (MF_DBGLEVEL >= 4) DbpString("NESTED FINISHED");\r
508\r
509 // Thats it...\r
510 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
511 LEDsoff();\r
512 \r
513 iso14a_set_tracing(TRUE);\r
514}\r
515\r
516//-----------------------------------------------------------------------------\r
517// MIFARE check keys. key count up to 8. \r
518// \r
519//-----------------------------------------------------------------------------\r
520void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
521{\r
522 // params\r
523 uint8_t blockNo = arg0;\r
524 uint8_t keyType = arg1;\r
525 uint8_t keyCount = arg2;\r
526 uint64_t ui64Key = 0;\r
527 \r
528 // variables\r
529 int i;\r
530 byte_t isOK = 0;\r
531 uint8_t uid[8];\r
532 uint32_t cuid;\r
533 struct Crypto1State mpcs = {0, 0};\r
534 struct Crypto1State *pcs;\r
535 pcs = &mpcs;\r
536 \r
537 // clear debug level\r
538 int OLD_MF_DBGLEVEL = MF_DBGLEVEL; \r
539 MF_DBGLEVEL = MF_DBG_NONE;\r
540 \r
541 // clear trace\r
542 iso14a_clear_tracelen();\r
543 iso14a_set_tracing(TRUE);\r
544\r
545 iso14443a_setup();\r
546\r
547 LED_A_ON();\r
548 LED_B_OFF();\r
549 LED_C_OFF();\r
550\r
551 SpinDelay(300);\r
552 for (i = 0; i < keyCount; i++) {\r
553 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
554 SpinDelay(100);\r
555 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
556\r
557 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
558 if (OLD_MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
559 break;\r
560 };\r
561\r
562 ui64Key = bytes_to_num(datain + i * 6, 6);\r
563 if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
564 continue;\r
565 };\r
566 \r
567 isOK = 1;\r
568 break;\r
569 }\r
570 \r
571 // ----------------------------- crypto1 destroy\r
572 crypto1_destroy(pcs);\r
573 \r
574 // add trace trailer\r
575 memset(uid, 0x44, 4);\r
576 LogTrace(uid, 4, 0, 0, TRUE);\r
577\r
578 UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
579 if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
580 \r
581 LED_B_ON();\r
582 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
583 LED_B_OFF();\r
584\r
585 // Thats it...\r
586 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
587 LEDsoff();\r
588\r
589 // restore debug level\r
590 MF_DBGLEVEL = OLD_MF_DBGLEVEL; \r
591}\r
592\r
593//-----------------------------------------------------------------------------\r
594// MIFARE commands set debug level\r
595// \r
596//-----------------------------------------------------------------------------\r
597void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
598 MF_DBGLEVEL = arg0;\r
599 Dbprintf("Debug level: %d", MF_DBGLEVEL);\r
600}\r
601\r
602//-----------------------------------------------------------------------------\r
603// Work with emulator memory\r
604// \r
605//-----------------------------------------------------------------------------\r
606void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
607 emlClearMem();\r
608}\r
609\r
610void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
611 emlSetMem(datain, arg0, arg1); // data, block num, blocks count\r
612}\r
613\r
614void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
615 UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
616\r
617 emlGetMem(ack.d.asBytes, arg0, arg1); // data, block num, blocks count\r
618\r
619 LED_B_ON();\r
620 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
621 LED_B_OFF();\r
622}\r
623\r
624//-----------------------------------------------------------------------------\r
625// Load a card into the emulator memory\r
626// \r
627//-----------------------------------------------------------------------------\r
628void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
629 int i;\r
630 uint8_t sectorNo = 0;\r
631 uint8_t keyType = arg1;\r
632 uint64_t ui64Key = 0;\r
633 uint32_t cuid;\r
634 struct Crypto1State mpcs = {0, 0};\r
635 struct Crypto1State *pcs;\r
636 pcs = &mpcs;\r
637\r
638 // variables\r
639 byte_t dataoutbuf[16];\r
ab8b654e 640 byte_t dataoutbuf2[16];\r
8556b852
M
641 uint8_t uid[8];\r
642\r
643 // clear trace\r
644 iso14a_clear_tracelen();\r
645 iso14a_set_tracing(false);\r
646 \r
647 iso14443a_setup();\r
648\r
649 LED_A_ON();\r
650 LED_B_OFF();\r
651 LED_C_OFF();\r
652 \r
653 while (true) {\r
654 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
655 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
656 break;\r
657 };\r
658 \r
659 for (i = 0; i < 16; i++) {\r
660 sectorNo = i;\r
661 ui64Key = emlGetKey(sectorNo, keyType);\r
662 \r
663 if (!i){\r
664 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {\r
665 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth error", i);\r
666 break;\r
667 }\r
668 } else {\r
669 if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_NESTED)) {\r
670 if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth nested error", i);\r
671 break;\r
672 }\r
673 }\r
674 \r
675 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf)) {\r
676 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");\r
677 break;\r
678 };\r
679 emlSetMem(dataoutbuf, sectorNo * 4 + 0, 1);\r
680 \r
681 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf)) {\r
682 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");\r
683 break;\r
684 };\r
685 emlSetMem(dataoutbuf, sectorNo * 4 + 1, 1);\r
686\r
687 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf)) {\r
688 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");\r
689 break;\r
690 };\r
691 emlSetMem(dataoutbuf, sectorNo * 4 + 2, 1);\r
ab8b654e
M
692\r
693 // get block 3 bytes 6-9\r
694 if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf)) {\r
695 if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");\r
696 break;\r
697 };\r
698 emlGetMem(dataoutbuf2, sectorNo * 4 + 3, 1);\r
699 memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);\r
700 emlSetMem(dataoutbuf2, sectorNo * 4 + 3, 1);\r
8556b852
M
701 }\r
702\r
703 if(mifare_classic_halt(pcs, cuid)) {\r
704 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
705 break;\r
706 };\r
707 \r
708 break;\r
709 } \r
710\r
711 // ----------------------------- crypto1 destroy\r
712 crypto1_destroy(pcs);\r
ab8b654e
M
713\r
714 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
715 LEDsoff();\r
8556b852
M
716 \r
717 if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");\r
718\r
719 // add trace trailer\r
720 memset(uid, 0x44, 4);\r
721 LogTrace(uid, 4, 0, 0, TRUE);\r
8556b852
M
722}\r
723\r
724//-----------------------------------------------------------------------------\r
725// MIFARE 1k emulator\r
726// \r
727//-----------------------------------------------------------------------------\r
728\r
0675f200
M
729\r
730//-----------------------------------------------------------------------------\r
731// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
732// \r
733//-----------------------------------------------------------------------------\r
734void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
735 \r
736 // params\r
737 uint8_t needWipe = arg0;\r
738 uint8_t needGetUID = arg1;\r
739 uint8_t blockNo = arg2;\r
740 \r
741 // card commands\r
742 uint8_t wupC1[] = { 0x40 }; \r
743 uint8_t wupC2[] = { 0x43 }; \r
744 uint8_t wipeC[] = { 0x41 }; \r
745 \r
746 // variables\r
747 byte_t isOK = 0;\r
748 uint8_t uid[8];\r
749 uint8_t d_block[18];\r
750 uint32_t cuid;\r
751 \r
752 memset(uid, 0x00, 8);\r
753 uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
754 \r
755 // clear trace\r
756 iso14a_clear_tracelen();\r
757 iso14a_set_tracing(TRUE);\r
758\r
759 iso14443a_setup();\r
760\r
761 LED_A_ON();\r
762 LED_B_OFF();\r
763 LED_C_OFF();\r
764 \r
765 SpinDelay(300);\r
766 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
767 SpinDelay(100);\r
768 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
769\r
770 while (true) {\r
771 // get UID from chip\r
772 if (needGetUID) {\r
773 if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
774 if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
775 break;\r
776 };\r
777\r
778 if(mifare_classic_halt(NULL, cuid)) {\r
779 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
780 break;\r
781 };\r
782 };\r
783 \r
784 // reset chip\r
785 if (needWipe){\r
786 ReaderTransmitShort(wupC1);\r
787 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
788 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
789 break;\r
790 };\r
791\r
792 ReaderTransmit(wipeC, sizeof(wipeC));\r
793 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
794 if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
795 break;\r
796 };\r
797\r
798 if(mifare_classic_halt(NULL, cuid)) {\r
799 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
800 break;\r
801 };\r
802 }; \r
803\r
804 // write UID block\r
805 ReaderTransmitShort(wupC1);\r
806 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
807 if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
808 break;\r
809 };\r
810\r
811 ReaderTransmit(wupC2, sizeof(wupC2));\r
812 if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
813 if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
814 break;\r
815 };\r
816\r
817 if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
818 if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
819 break;\r
820 };\r
821 \r
822 memcpy(d_block, datain, 16);\r
823 AppendCrc14443a(d_block, 16);\r
824 \r
825 ReaderTransmit(d_block, sizeof(d_block));\r
826 if ((ReaderReceive(receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
827 if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
828 break;\r
829 }; \r
830 \r
831 if(mifare_classic_halt(NULL, cuid)) {\r
832 if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
833 break;\r
834 };\r
835 \r
836 isOK = 1;\r
837 break;\r
838 }\r
839 \r
840 UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
841 if (isOK) memcpy(ack.d.asBytes, uid, 4);\r
842 \r
843 // add trace trailer\r
844 memset(uid, 0x44, 4);\r
845 LogTrace(uid, 4, 0, 0, TRUE);\r
846\r
847 LED_B_ON();\r
848 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
849 LED_B_OFF();\r
850\r
851 // Thats it...\r
852 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
853 LEDsoff();\r
854}\r
Impressum, Datenschutz