]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhf14a.c
1. fixed hf 14a mifare. added functionality to ignore one Nt
[proxmark3-svn] / client / cmdhf14a.c
CommitLineData
a553f267 1//-----------------------------------------------------------------------------
f89c7050 2// 2011, Merlok
534983d7 3// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
a553f267 4//
5// This code is licensed to you under the terms of the GNU GPL, version 2 or,
6// at your option, any later version. See the LICENSE.txt file for the text of
7// the license.
8//-----------------------------------------------------------------------------
9// High frequency ISO14443A commands
10//-----------------------------------------------------------------------------
11
7fe9b0b7 12#include <stdio.h>
590f8ff9 13#include <stdlib.h>
7fe9b0b7 14#include <string.h>
f397b5cc
M
15#include <unistd.h>
16#include <ctype.h>
20f9a2a1 17#include "util.h"
7fe9b0b7 18#include "iso14443crc.h"
19#include "data.h"
20#include "proxusb.h"
21#include "ui.h"
22#include "cmdparser.h"
23#include "cmdhf14a.h"
534983d7 24#include "common.h"
20f9a2a1 25#include "cmdmain.h"
f89c7050
M
26#include "nonce2key/nonce2key.h"
27#include "nonce2key/crapto1.h"
f397b5cc 28#include "mifarehost.h"
7fe9b0b7 29
30static int CmdHelp(const char *Cmd);
31
32int CmdHF14AList(const char *Cmd)
33{
34 uint8_t got[1920];
35 GetFromBigBuf(got, sizeof(got));
36
37 PrintAndLog("recorded activity:");
38 PrintAndLog(" ETU :rssi: who bytes");
39 PrintAndLog("---------+----+----+-----------");
40
41 int i = 0;
42 int prev = -1;
43
44 for (;;) {
45 if(i >= 1900) {
46 break;
47 }
48
49 bool isResponse;
50 int timestamp = *((uint32_t *)(got+i));
51 if (timestamp & 0x80000000) {
52 timestamp &= 0x7fffffff;
53 isResponse = 1;
54 } else {
55 isResponse = 0;
56 }
57
58 int metric = 0;
59 int parityBits = *((uint32_t *)(got+i+4));
60 // 4 bytes of additional information...
61 // maximum of 32 additional parity bit information
62 //
63 // TODO:
64 // at each quarter bit period we can send power level (16 levels)
65 // or each half bit period in 256 levels.
66
67
68 int len = got[i+8];
69
70 if (len > 100) {
71 break;
72 }
73 if (i + len >= 1900) {
74 break;
75 }
76
77 uint8_t *frame = (got+i+9);
78
79 // Break and stick with current result if buffer was not completely full
80 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
81
82 char line[1000] = "";
83 int j;
84 for (j = 0; j < len; j++) {
85 int oddparity = 0x01;
86 int k;
87
88 for (k=0;k<8;k++) {
89 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
90 }
91
92 //if((parityBits >> (len - j - 1)) & 0x01) {
93 if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
94 sprintf(line+(j*4), "%02x! ", frame[j]);
95 }
96 else {
97 sprintf(line+(j*4), "%02x ", frame[j]);
98 }
99 }
100
101 char *crc;
102 crc = "";
103 if (len > 2) {
104 uint8_t b1, b2;
105 for (j = 0; j < (len - 1); j++) {
106 // gives problems... search for the reason..
107 /*if(frame[j] == 0xAA) {
108 switch(frame[j+1]) {
109 case 0x01:
110 crc = "[1] Two drops close after each other";
111 break;
112 case 0x02:
113 crc = "[2] Potential SOC with a drop in second half of bitperiod";
114 break;
115 case 0x03:
116 crc = "[3] Segment Z after segment X is not possible";
117 break;
118 case 0x04:
119 crc = "[4] Parity bit of a fully received byte was wrong";
120 break;
121 default:
122 crc = "[?] Unknown error";
123 break;
124 }
125 break;
126 }*/
127 }
128
129 if (strlen(crc)==0) {
130 ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);
131 if (b1 != frame[len-2] || b2 != frame[len-1]) {
132 crc = (isResponse & (len < 6)) ? "" : " !crc";
133 } else {
134 crc = "";
135 }
136 }
137 } else {
138 crc = ""; // SHORT
139 }
140
141 char metricString[100];
142 if (isResponse) {
143 sprintf(metricString, "%3d", metric);
144 } else {
145 strcpy(metricString, " ");
146 }
147
148 PrintAndLog(" +%7d: %s: %s %s %s",
149 (prev < 0 ? 0 : (timestamp - prev)),
150 metricString,
151 (isResponse ? "TAG" : " "), line, crc);
152
153 prev = timestamp;
154 i += (len + 9);
155 }
f89c7050 156 return 0;
7fe9b0b7 157}
158
534983d7 159void iso14a_set_timeout(uint32_t timeout) {
160 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}};
161 SendCommand(&c);
162}
163
7fe9b0b7 164int CmdHF14AMifare(const char *Cmd)
165{
f89c7050
M
166 uint32_t uid = 0;
167 uint32_t nt = 0;
168 uint64_t par_list = 0, ks_list = 0, r_key = 0;
169 uint8_t isOK = 0;
f397b5cc 170 uint8_t keyBlock[6] = {0,0,0,0,0,0};
f89c7050 171
f397b5cc
M
172 if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, keyBlock, 8)) {
173 PrintAndLog("Nt must include 8 HEX symbols");
174 return 1;
175 }
176
177 UsbCommand c = {CMD_READER_MIFARE, {(uint32_t)bytes_to_num(keyBlock, 4), 0, 0}};
f89c7050
M
178 SendCommand(&c);
179
180 //flush queue
f397b5cc 181 while (ukbhit()) getchar();
f89c7050
M
182
183 // message
184 printf("-------------------------------------------------------------------------\n");
185 printf("Executing command. It may take up to 30 min.\n");
186 printf("Press the key on proxmark3 device to abort proxmark3.\n");
187 printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
188 printf("-------------------------------------------------------------------------\n");
189
190 // wait cycle
191 while (true) {
192 printf(".");
f397b5cc 193 if (ukbhit()) {
f89c7050
M
194 getchar();
195 printf("\naborted via keyboard!\n");
196 break;
197 }
198
199 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
200 if (resp != NULL) {
201 isOK = resp->arg[0] & 0xff;
202
203 uid = (uint32_t)bytes_to_num(resp->d.asBytes + 0, 4);
204 nt = (uint32_t)bytes_to_num(resp->d.asBytes + 4, 4);
205 par_list = bytes_to_num(resp->d.asBytes + 8, 8);
206 ks_list = bytes_to_num(resp->d.asBytes + 16, 8);
207
208 printf("\n\n");
209 PrintAndLog("isOk:%02x", isOK);
210 if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");
211 break;
212 }
213 }
214 printf("\n");
215
216 // error
217 if (isOK != 1) return 1;
218
219 // execute original function from util nonce2key
220 if (nonce2key(uid, nt, par_list, ks_list, &r_key)) return 2;
f397b5cc 221 printf("------------------------------------------------------------------\n");
f89c7050 222 PrintAndLog("Key found:%012llx \n", r_key);
f397b5cc
M
223
224 num_to_bytes(r_key, 6, keyBlock);
225 isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
226 if (!isOK)
227 PrintAndLog("Found valid key:%012llx", r_key);
228 else
229 PrintAndLog("Found invalid key. (");
230
f89c7050
M
231
232 return 0;
7fe9b0b7 233}
234
20f9a2a1
M
235int CmdHF14AMfWrBl(const char *Cmd)
236{
20f9a2a1
M
237 uint8_t blockNo = 0;
238 uint8_t keyType = 0;
239 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
240 uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
241
f397b5cc 242 char cmdp = 0x00;
20f9a2a1
M
243
244 if (strlen(Cmd)<3) {
245 PrintAndLog("Usage: hf 14 mfwrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
f397b5cc 246 PrintAndLog(" sample: hf 14a mfwrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
20f9a2a1
M
247 return 0;
248 }
20f9a2a1 249
f397b5cc
M
250 blockNo = param_get8(Cmd, 0);
251 cmdp = param_getchar(Cmd, 1);
252 if (cmdp == 0x00) {
253 PrintAndLog("Key type must be A or B");
254 return 1;
20f9a2a1 255 }
f397b5cc
M
256 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
257 if (param_gethex(Cmd, 2, key, 12)) {
258 PrintAndLog("Key must include 12 HEX symbols");
259 return 1;
20f9a2a1 260 }
f397b5cc
M
261 if (param_gethex(Cmd, 3, bldata, 32)) {
262 PrintAndLog("Block data must include 32 HEX symbols");
263 return 1;
264 }
265 PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6));
266 PrintAndLog("--data: %s", sprint_hex(bldata, 16));
20f9a2a1
M
267
268 UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
269 memcpy(c.d.asBytes, key, 6);
270 memcpy(c.d.asBytes + 10, bldata, 16);
271 SendCommand(&c);
272 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
273
274 if (resp != NULL) {
275 uint8_t isOK = resp->arg[0] & 0xff;
276
277 PrintAndLog("isOk:%02x", isOK);
278 } else {
279 PrintAndLog("Command execute timeout");
280 }
281
282 return 0;
283}
284
285int CmdHF14AMfRdBl(const char *Cmd)
286{
20f9a2a1
M
287 uint8_t blockNo = 0;
288 uint8_t keyType = 0;
289 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
290
f397b5cc 291 char cmdp = 0x00;
20f9a2a1
M
292
293
294 if (strlen(Cmd)<3) {
295 PrintAndLog("Usage: hf 14 mfrdbl <block number> <key A/B> <key (12 hex symbols)>");
f397b5cc 296 PrintAndLog(" sample: hf 14a mfrdbl 0 A FFFFFFFFFFFF ");
20f9a2a1
M
297 return 0;
298 }
299
f397b5cc
M
300 blockNo = param_get8(Cmd, 0);
301 cmdp = param_getchar(Cmd, 1);
302 if (cmdp == 0x00) {
303 PrintAndLog("Key type must be A or B");
304 return 1;
20f9a2a1 305 }
f397b5cc
M
306 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
307 if (param_gethex(Cmd, 2, key, 12)) {
308 PrintAndLog("Key must include 12 HEX symbols");
309 return 1;
20f9a2a1 310 }
f397b5cc 311 PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
20f9a2a1
M
312
313 UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
314 memcpy(c.d.asBytes, key, 6);
315 SendCommand(&c);
316 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
317
318 if (resp != NULL) {
319 uint8_t isOK = resp->arg[0] & 0xff;
320 uint8_t * data = resp->d.asBytes;
321
f397b5cc
M
322 if (isOK)
323 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
324 else
325 PrintAndLog("isOk:%02x", isOK);
20f9a2a1
M
326 } else {
327 PrintAndLog("Command execute timeout");
328 }
329
330 return 0;
331}
332
333int CmdHF14AMfRdSc(const char *Cmd)
334{
f397b5cc 335 int i;
20f9a2a1
M
336 uint8_t sectorNo = 0;
337 uint8_t keyType = 0;
338 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
339
f397b5cc
M
340 uint8_t isOK = 0;
341 uint8_t * data = NULL;
20f9a2a1 342
f397b5cc 343 char cmdp = 0x00;
20f9a2a1
M
344
345 if (strlen(Cmd)<3) {
346 PrintAndLog("Usage: hf 14 mfrdsc <sector number> <key A/B> <key (12 hex symbols)>");
f397b5cc 347 PrintAndLog(" sample: hf 14a mfrdsc 0 A FFFFFFFFFFFF ");
20f9a2a1
M
348 return 0;
349 }
350
f397b5cc
M
351 sectorNo = param_get8(Cmd, 0);
352 if (sectorNo > 63) {
353 PrintAndLog("Sector number must be less than 64");
354 return 1;
20f9a2a1 355 }
f397b5cc
M
356 cmdp = param_getchar(Cmd, 1);
357 if (cmdp == 0x00) {
358 PrintAndLog("Key type must be A or B");
359 return 1;
20f9a2a1 360 }
f397b5cc
M
361 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
362 if (param_gethex(Cmd, 2, key, 12)) {
363 PrintAndLog("Key must include 12 HEX symbols");
364 return 1;
365 }
366 PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));
20f9a2a1
M
367
368 UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
369 memcpy(c.d.asBytes, key, 6);
370 SendCommand(&c);
371 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
372 PrintAndLog(" ");
373
374 if (resp != NULL) {
f397b5cc
M
375 isOK = resp->arg[0] & 0xff;
376 data = resp->d.asBytes;
20f9a2a1
M
377
378 PrintAndLog("isOk:%02x", isOK);
f397b5cc
M
379 if (isOK)
380 for (i = 0; i < 2; i++) {
381 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
382 }
20f9a2a1
M
383 } else {
384 PrintAndLog("Command1 execute timeout");
385 }
386
387 // response2
388 resp = WaitForResponseTimeout(CMD_ACK, 500);
389 PrintAndLog(" ");
390
391 if (resp != NULL) {
f397b5cc
M
392 isOK = resp->arg[0] & 0xff;
393 data = resp->d.asBytes;
20f9a2a1 394
f397b5cc
M
395 if (isOK)
396 for (i = 0; i < 2; i++) {
397 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
20f9a2a1
M
398 }
399 } else {
400 PrintAndLog("Command2 execute timeout");
401 }
402
403 return 0;
404}
405
4abe4f58
M
406int CmdHF14AMfNested(const char *Cmd)
407{
f397b5cc
M
408 int i, j, res, iterations;
409 sector * e_sector = NULL;
410 uint8_t blockNo = 0;
4abe4f58 411 uint8_t keyType = 0;
f397b5cc
M
412 uint8_t trgBlockNo = 0;
413 uint8_t trgKeyType = 0;
414 uint8_t blDiff = 0;
415 int SectorsCnt = 0;
4abe4f58 416 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
f397b5cc
M
417 uint8_t keyBlock[16 * 6];
418 uint64_t key64 = 0;
4abe4f58 419
f397b5cc 420 char cmdp, ctmp;
4abe4f58 421
4abe4f58 422 if (strlen(Cmd)<3) {
f397b5cc
M
423 PrintAndLog("Usage:");
424 PrintAndLog(" all sectors: hf 14a nested <card memory> <block number> <key A/B> <key (12 hex symbols)>");
425 PrintAndLog(" one sector: hf 14a nested o <block number> <key A/B> <key (12 hex symbols)>");
426 PrintAndLog(" <target block number> <target key A/B>");
427 PrintAndLog("card memory - 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
428 PrintAndLog(" ");
429 PrintAndLog(" sample1: hf 14a nested 1 0 A FFFFFFFFFFFF ");
430 PrintAndLog(" sample2: hf 14a nested o 0 A FFFFFFFFFFFF 4 A");
4abe4f58
M
431 return 0;
432 }
433
f397b5cc
M
434 cmdp = param_getchar(Cmd, 0);
435 blockNo = param_get8(Cmd, 1);
436 ctmp = param_getchar(Cmd, 2);
437 if (ctmp == 0x00) {
438 PrintAndLog("Key type must be A or B");
439 return 1;
4abe4f58 440 }
f397b5cc
M
441 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
442 if (param_gethex(Cmd, 3, key, 12)) {
443 PrintAndLog("Key must include 12 HEX symbols");
444 return 1;
4abe4f58
M
445 }
446
f397b5cc
M
447 if (cmdp =='o' || cmdp == 'O') {
448 cmdp = 'o';
449 trgBlockNo = param_get8(Cmd, 4);
450 ctmp = param_getchar(Cmd, 5);
451 if (ctmp == 0x00) {
452 PrintAndLog("Target key type must be A or B");
453 return 1;
454 }
455 if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;
456 } else {
457 switch (cmdp) {
458 case '1': SectorsCnt = 16; break;
459 case '2': SectorsCnt = 32; break;
460 case '4': SectorsCnt = 64; break;
461 default: SectorsCnt = 16;
462 }
463 }
4abe4f58 464
f397b5cc
M
465 PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
466 if (cmdp == 'o')
467 PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo, trgKeyType);
4abe4f58 468
f397b5cc
M
469 if (cmdp == 'o') {
470 if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) {
471 PrintAndLog("Nested error.");
472 return 2;
473 }
4abe4f58 474
f397b5cc
M
475 for (i = 0; i < 16; i++) {
476 PrintAndLog("cnt=%d key= %s", i, sprint_hex(keyBlock + i * 6, 6));
477 }
478
479 // test keys
480 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
481 if (res)
482 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
483 if (!res)
484 PrintAndLog("Found valid key:%012llx", key64);
485 else
486 PrintAndLog("No valid key found");
487 } else // ------------------------------------ multiple sectors working
488 {
489 blDiff = blockNo % 4;
490 PrintAndLog("Block shift=%d", blDiff);
491 e_sector = calloc(SectorsCnt, sizeof(sector));
492 if (e_sector == NULL) return 1;
493
494 //test current key 4 sectors
495 memcpy(keyBlock, key, 6);
496 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 1 * 6));
497 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 2 * 6));
498 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 3 * 6));
499 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 4 * 6));
500 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));
501
502 PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);
503 for (i = 0; i < SectorsCnt; i++) {
504 for (j = 0; j < 2; j++) {
505 if (e_sector[i].foundKey[j]) continue;
506
507 res = mfCheckKeys(i * 4 + blDiff, j, 6, keyBlock, &key64);
508
509 if (!res) {
510 e_sector[i].Key[j] = key64;
511 e_sector[i].foundKey[j] = 1;
512 }
513 }
514 }
515
516
517 // nested sectors
518 iterations = 0;
519 PrintAndLog("nested...");
520 for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
521 for (trgBlockNo = blDiff; trgBlockNo < SectorsCnt * 4; trgBlockNo = trgBlockNo + 4)
522 for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) {
523 if (e_sector[trgBlockNo / 4].foundKey[trgKeyType]) continue;
524 if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) continue;
525
526 iterations++;
527
528 //try keys from nested
529 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
530 if (res)
531 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
532 if (!res) {
533 PrintAndLog("Found valid key:%012llx", key64);
534 e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;
535 e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;
536 }
537 }
50193c1e
M
538 }
539
f397b5cc
M
540 PrintAndLog("Iterations count: %d", iterations);
541 //print them
542 PrintAndLog("|---|----------------|---|----------------|---|");
543 PrintAndLog("|blk|key A |res|key B |res|");
544 PrintAndLog("|---|----------------|---|----------------|---|");
545 for (i = 0; i < SectorsCnt; i++) {
546 PrintAndLog("|%03d| %012llx | %d | %012llx | %d |", i,
547 e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);
548 }
549 PrintAndLog("|---|----------------|---|----------------|---|");
550
551 free(e_sector);
552 }
50193c1e 553
f397b5cc
M
554 return 0;
555}
50193c1e 556
f397b5cc
M
557int CmdHF14AMfChk(const char *Cmd)
558{
559 int i, res;
560 int keycnt = 0;
561 char ctmp = 0x00;
562 uint8_t blockNo = 0;
563 uint8_t keyType = 0;
564 uint8_t keyBlock[8 * 6];
565 uint64_t key64 = 0;
50193c1e 566
f397b5cc 567 memset(keyBlock, 0x00, sizeof(keyBlock));
50193c1e 568
f397b5cc
M
569 if (strlen(Cmd)<3) {
570 PrintAndLog("Usage: hf 14a chk <block number> <key A/B> [<key (12 hex symbols)>]");
571 PrintAndLog(" sample: hf 14a chk 0 A FFFFFFFFFFFF a0a1a2a3a4a5 b01b2b3b4b5 ");
572 return 0;
573 }
574
575 blockNo = param_get8(Cmd, 0);
576 ctmp = param_getchar(Cmd, 1);
577 if (ctmp == 0x00) {
578 PrintAndLog("Key type must be A or B");
579 return 1;
580 }
581 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
582
583 for (i = 0; i < 6; i++) {
584 if (!isxdigit(param_getchar(Cmd, 2 + i))) break;
50193c1e 585
f397b5cc
M
586 if (param_gethex(Cmd, 2 + i, keyBlock + 6 * i, 12)) {
587 PrintAndLog("Key[%d] must include 12 HEX symbols", i);
588 return 1;
4abe4f58 589 }
f397b5cc 590 keycnt = i + 1;
4abe4f58 591 }
50193c1e 592
f397b5cc
M
593 if (keycnt == 0) {
594 PrintAndLog("There is must be at least one key");
595 return 1;
596 }
597
598 PrintAndLog("--block no:%02x key type:%02x key count:%d ", blockNo, keyType, keycnt);
50193c1e 599
f397b5cc
M
600 res = mfCheckKeys(blockNo, keyType, keycnt, keyBlock, &key64);
601 if (res !=1) {
602 if (!res)
603 PrintAndLog("isOk:%02x valid key:%012llx", 1, key64);
604 else
605 PrintAndLog("isOk:%02x", 0);
606 } else {
607 PrintAndLog("Command execute timeout");
608 }
4abe4f58
M
609
610 return 0;
611}
612
613int CmdHF14AMf1kSim(const char *Cmd)
614{
615 int i, temp;
616 uint8_t uid[4] = {0, 0, 0, 0};
617
618 const char *cmdp = Cmd;
619
620
621 if (strlen(Cmd)<3) {
622 PrintAndLog("Usage: hf 14a mfsim <uid (8 hex symbols)>");
623 PrintAndLog(" sample: hf 14a mfsim 0a0a0a0a ");
624 return 0;
625 }
626
627 // skip spaces
628 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
629
630 if (strlen(cmdp) != 8) {
631 PrintAndLog("Length of UID must be 8 hex symbols");
632 return 0;
633 }
634
635 for(i = 0; i < 4; i++) {
636 sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
637 uid[i] = temp & 0xff;
638 cmdp++;
639 cmdp++;
640 }
641 PrintAndLog(" uid:%s ", sprint_hex(uid, 4));
642
643 UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}};
644 memcpy(c.d.asBytes, uid, 6);
645 SendCommand(&c);
646
647 return 0;
648}
649
650
7fe9b0b7 651int CmdHF14AReader(const char *Cmd)
652{
534983d7 653 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
654 SendCommand(&c);
655 UsbCommand * resp = WaitForResponse(CMD_ACK);
656 uint8_t * uid = resp->d.asBytes;
657 iso14a_card_select_t * card = uid + 12;
658
659 if(resp->arg[0] == 0) {
660 PrintAndLog("iso14443a card select failed");
661 return 0;
662 }
663
664 PrintAndLog("ATQA : %02x %02x", card->atqa[0], card->atqa[1]);
665 PrintAndLog(" UID : %s", sprint_hex(uid, 12));
666 PrintAndLog(" SAK : %02x [%d]", card->sak, resp->arg[0]);
667 if(resp->arg[0] == 1)
668 PrintAndLog(" ATS : %s", sprint_hex(card->ats, card->ats_len));
669 else
670 PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
671
672 return resp->arg[0];
7fe9b0b7 673}
674
675// ## simulate iso14443a tag
676// ## greg - added ability to specify tag UID
677int CmdHF14ASim(const char *Cmd)
678{
679
680 unsigned int hi = 0, lo = 0;
681 int n = 0, i = 0;
682 while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
683 hi= (hi << 4) | (lo >> 28);
684 lo= (lo << 4) | (n & 0xf);
685 }
686
687 // c.arg should be set to *Cmd or convert *Cmd to the correct format for a uid
688 UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a, {hi, lo, 0}};
689 PrintAndLog("Emulating 14443A TAG with UID %x%16x", hi, lo);
690 SendCommand(&c);
691 return 0;
692}
693
694int CmdHF14ASnoop(const char *Cmd)
695{
696 UsbCommand c = {CMD_SNOOP_ISO_14443a};
697 SendCommand(&c);
698 return 0;
699}
700
701static command_t CommandTable[] =
702{
4abe4f58
M
703 {"help", CmdHelp, 1, "This help"},
704 {"list", CmdHF14AList, 0, "List ISO 14443a history"},
f89c7050 705 {"mifare", CmdHF14AMifare, 0, "Read out sector 0 parity error messages. param - <used card nonce>"},
4abe4f58
M
706 {"mfrdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
707 {"mfrdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
708 {"mfwrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},
709 {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
f397b5cc 710 {"chk", CmdHF14AMfChk, 0, "Test block up to 8 keys"},
4abe4f58
M
711 {"mfsim", CmdHF14AMf1kSim, 0, "Simulate MIFARE 1k card - NOT WORKING!!!"},
712 {"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
713 {"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
714 {"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
7fe9b0b7 715 {NULL, NULL, 0, NULL}
716};
717
718int CmdHF14A(const char *Cmd)
719{
f397b5cc
M
720 // flush
721 while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
722
723 // parse
7fe9b0b7 724 CmdsParse(CommandTable, Cmd);
725 return 0;
726}
727
728int CmdHelp(const char *Cmd)
729{
730 CmdsHelp(CommandTable);
731 return 0;
732}
Impressum, Datenschutz