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