Rework Cmd exposed API, use more static and fix [-Wmissing-prototypes]

This commit is contained in:
Philippe Teuwen 2019-04-12 18:41:14 +02:00
parent 65305f361f
commit 05374fce07
30 changed files with 1230 additions and 1367 deletions

View file

@ -43,36 +43,30 @@ int CmdHFSearch(const char *Cmd) {
PrintAndLogEx(INFO, "Checking for known tags...\n");
int ans = CmdHF14AInfo("s");
if (ans > 0) {
if (infoHF14A(false, false) > 0) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n");
return ans;
return 1;
}
ans = HF15Reader("", false);
if (ans) {
if (readHF15Uid(false) == 1) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n");
return ans;
return 1;
}
ans = HFLegicReader("", false);
if (ans == 0) {
if (readLegicUid(false) == 0) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n");
return 1;
}
ans = CmdHFTopazReader("s");
if (ans == 0) {
if (readTopazUid() == 0) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n");
return 1;
}
// 14b and iclass is the longest test (put last)
ans = HF14BReader(false); //CmdHF14BReader("s");
if (ans) {
if (readHF14B(false) == 1) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n");
return ans;
return 1;
}
ans = HFiClassReader("", false, false);
if (ans) {
if (readIclass(false, false) == 1) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n");
return ans;
return 1;
}
/*

View file

@ -220,7 +220,7 @@ static int usage_hf_14a_info(void) {
return 0;
}
int CmdHF14AList(const char *Cmd) {
static int CmdHF14AList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list 14a' instead");
CmdTraceList("14a");
@ -266,7 +266,7 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
return 0;
}
int CmdHF14AReader(const char *Cmd) {
static int CmdHF14AReader(const char *Cmd) {
uint32_t cm = ISO14A_CONNECT;
bool disconnectAfter = true, silent = false;
@ -354,312 +354,18 @@ int CmdHF14AReader(const char *Cmd) {
return 0;
}
int CmdHF14AInfo(const char *Cmd) {
static int CmdHF14AInfo(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_hf_14a_info();
bool silent = (Cmd[0] == 's' || Cmd[0] == 'S');
bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S');
bool do_nack_test = (Cmd[0] == 'n' || Cmd[0] == 'N');
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}, {{0}}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed");
DropField();
return 0;
}
iso14a_card_select_t card;
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
/*
0: couldn't read
1: OK, with ATS
2: OK, no ATS
3: proprietary Anticollision
*/
uint64_t select_status = resp.arg[0];
if (select_status == 0) {
if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed");
DropField();
return 0;
}
if (select_status == 3) {
PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision");
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
DropField();
return select_status;
}
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.arg[0]);
bool isMifareClassic = true;
switch (card.sak) {
case 0x00:
isMifareClassic = false;
// ******** is card of the MFU type (UL/ULC/NTAG/ etc etc)
DropField();
uint32_t tagT = GetHF14AMfU_Type();
if (tagT != UL_ERROR)
ul_print_type(tagT, 0);
else
PrintAndLogEx(NORMAL, "TYPE: Possible AZTEK (iso14443a compliant)");
// reconnect for further tests
c.arg[0] = ISO14A_CONNECT | ISO14A_NO_DISCONNECT;
c.arg[1] = 0;
c.arg[2] = 0;
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK, &resp);
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
if (select_status == 0) {
DropField();
return 0;
}
break;
case 0x01:
PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance");
break;
case 0x04:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)");
isMifareClassic = false;
break;
case 0x08:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1");
break;
case 0x09:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k");
break;
case 0x0A:
PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)");
break;
case 0x10:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2");
break;
case 0x11:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2");
break;
case 0x18:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1");
break;
case 0x20:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41");
isMifareClassic = false;
break;
case 0x24:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire | DESFire EV1");
isMifareClassic = false;
break;
case 0x28:
PrintAndLogEx(NORMAL, "TYPE : JCOP31 or JCOP41 v2.3.1");
break;
case 0x38:
PrintAndLogEx(NORMAL, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K");
break;
case 0x88:
PrintAndLogEx(NORMAL, "TYPE : Infineon MIFARE CLASSIC 1K");
break;
case 0x98:
PrintAndLogEx(NORMAL, "TYPE : Gemplus MPCOS");
break;
default:
;
}
// Double & triple sized UID, can be mapped to a manufacturer.
if (card.uidlen > 4) {
PrintAndLogEx(NORMAL, "MANUFACTURER : %s", getTagInfo(card.uid[0]));
}
// try to request ATS even if tag claims not to support it
if (select_status == 2) {
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;
c.arg[1] = 2;
c.arg[2] = 0;
memcpy(c.d.asBytes, rats, 2);
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK, &resp);
memcpy(card.ats, resp.d.asBytes, resp.arg[0]);
card.ats_len = resp.arg[0]; // note: ats_len includes CRC Bytes
}
if (card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
bool ta1 = 0, tb1 = 0, tc1 = 0;
int pos;
if (select_status == 2) {
PrintAndLogEx(NORMAL, "SAK incorrectly claims that card doesn't support RATS");
}
PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len));
PrintAndLogEx(NORMAL, " - TL : length is %d bytes", card.ats[0]);
if (card.ats[0] != card.ats_len - 2) {
PrintAndLogEx(NORMAL, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len);
}
if (card.ats[0] > 1) { // there is a format byte (T0)
ta1 = (card.ats[1] & 0x10) == 0x10;
tb1 = (card.ats[1] & 0x20) == 0x20;
tc1 = (card.ats[1] & 0x40) == 0x40;
int16_t fsci = card.ats[1] & 0x0f;
PrintAndLogEx(NORMAL, " - T0 : TA1 is%s present, TB1 is%s present, "
"TC1 is%s present, FSCI is %d (FSC = %ld)",
(ta1 ? "" : " NOT"),
(tb1 ? "" : " NOT"),
(tc1 ? "" : " NOT"),
fsci,
fsci < sizeof(atsFSC) / sizeof(atsFSC[0]) ? atsFSC[fsci] : -1
);
}
pos = 2;
if (ta1) {
char dr[16], ds[16];
dr[0] = ds[0] = '\0';
if (card.ats[pos] & 0x10) strcat(ds, "2, ");
if (card.ats[pos] & 0x20) strcat(ds, "4, ");
if (card.ats[pos] & 0x40) strcat(ds, "8, ");
if (card.ats[pos] & 0x01) strcat(dr, "2, ");
if (card.ats[pos] & 0x02) strcat(dr, "4, ");
if (card.ats[pos] & 0x04) strcat(dr, "8, ");
if (strlen(ds) != 0) ds[strlen(ds) - 2] = '\0';
if (strlen(dr) != 0) dr[strlen(dr) - 2] = '\0';
PrintAndLogEx(NORMAL, " - TA1 : different divisors are%s supported, "
"DR: [%s], DS: [%s]",
((card.ats[pos] & 0x80) ? " NOT" : ""),
dr,
ds
);
pos++;
}
if (tb1) {
uint32_t sfgi = card.ats[pos] & 0x0F;
uint32_t fwi = card.ats[pos] >> 4;
PrintAndLogEx(NORMAL, " - TB1 : SFGI = %d (SFGT = %s%ld/fc), FWI = %d (FWT = %ld/fc)",
(sfgi),
sfgi ? "" : "(not needed) ",
sfgi ? (1 << 12) << sfgi : 0,
fwi,
(1 << 12) << fwi
);
pos++;
}
if (tc1) {
PrintAndLogEx(NORMAL, " - TC1 : NAD is%s supported, CID is%s supported",
(card.ats[pos] & 0x01) ? "" : " NOT",
(card.ats[pos] & 0x02) ? "" : " NOT");
pos++;
}
if (card.ats[0] > pos && card.ats[0] < card.ats_len - 2) {
const char *tip = "";
if (card.ats[0] - pos >= 7) {
if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x01\xBC\xD6", 7) == 0) {
tip = "-> MIFARE Plus X 2K or 4K";
} else if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) {
tip = "-> MIFARE Plus S 2K or 4K";
}
}
PrintAndLogEx(NORMAL, " - HB : %s%s", sprint_hex(card.ats + pos, card.ats[0] - pos), tip);
if (card.ats[pos] == 0xC1) {
PrintAndLogEx(NORMAL, " c1 -> Mifare or (multiple) virtual cards of various type");
PrintAndLogEx(NORMAL, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]);
switch (card.ats[pos + 2] & 0xf0) {
case 0x10:
PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus");
break;
}
switch (card.ats[pos + 2] & 0x0f) {
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> <1 kByte");
break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> 1 kByte");
break;
case 0x02:
PrintAndLogEx(NORMAL, " x2 -> 2 kByte");
break;
case 0x03:
PrintAndLogEx(NORMAL, " x3 -> 4 kByte");
break;
case 0x04:
PrintAndLogEx(NORMAL, " x4 -> 8 kByte");
break;
}
switch (card.ats[pos + 3] & 0xf0) {
case 0x00:
PrintAndLogEx(NORMAL, " 0x -> Engineering sample");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> Released");
break;
}
switch (card.ats[pos + 3] & 0x0f) {
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> Generation 1");
break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> Generation 2");
break;
case 0x02:
PrintAndLogEx(NORMAL, " x2 -> Generation 3");
break;
}
switch (card.ats[pos + 4] & 0x0f) {
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported");
break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> VCS, VCSL, and SVC supported");
break;
case 0x0E:
PrintAndLogEx(NORMAL, " xE -> no VCS command supported");
break;
}
}
}
} else {
PrintAndLogEx(INFO, "proprietary non iso14443-4 card found, RATS not supported");
}
detect_classic_magic();
if (isMifareClassic) {
int res = detect_classic_prng();
if (res == 1)
PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("WEAK"));
else if (res == 0)
PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("HARD"));
else
PrintAndLogEx(FAILED, "prng detection: " _RED_("Fail"));
if (do_nack_test)
detect_classic_nackbug(silent);
}
return select_status;
infoHF14A(verbose, do_nack_test);
return 0;
}
// Collect ISO14443 Type A UIDs
int CmdHF14ACUIDs(const char *Cmd) {
static int CmdHF14ACUIDs(const char *Cmd) {
// requested number of UIDs
int n = atoi(Cmd);
// collect at least 1 (e.g. if no parameter was given)
@ -701,7 +407,6 @@ int CmdHF14ACUIDs(const char *Cmd) {
PrintAndLogEx(SUCCESS, "end: %" PRIu64 " seconds", (msclock() - t1) / 1000);
return 1;
}
// ## simulate iso14443a tag
int CmdHF14ASim(const char *Cmd) {
bool errors = false;
@ -981,7 +686,7 @@ int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) {
return 0;
}
int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) {
static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) {
*chainingout = false;
if (activateField) {
@ -1138,7 +843,7 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea
}
// ISO14443-4. 7. Half-duplex block transmission protocol
int CmdHF14AAPDU(const char *Cmd) {
static int CmdHF14AAPDU(const char *Cmd) {
uint8_t data[USB_CMD_DATA_SIZE];
int datalen = 0;
bool activateField = false;
@ -1185,7 +890,7 @@ int CmdHF14AAPDU(const char *Cmd) {
return 0;
}
int CmdHF14ACmdRaw(const char *Cmd) {
static int CmdHF14ACmdRaw(const char *Cmd) {
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}, {{0}}};
bool reply = 1;
bool crc = false;
@ -1369,7 +1074,7 @@ static int waitCmd(uint8_t iSelect) {
return 0;
}
int CmdHF14AAntiFuzz(const char *Cmd) {
static int CmdHF14AAntiFuzz(const char *Cmd) {
CLIParserInit("hf 14a antifuzz",
"Tries to fuzz the ISO14443a anticollision phase",
@ -1398,7 +1103,7 @@ int CmdHF14AAntiFuzz(const char *Cmd) {
return 0;
}
int CmdHF14AChaining(const char *Cmd) {
static int CmdHF14AChaining(const char *Cmd) {
CLIParserInit("hf 14a chaining",
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
@ -1444,13 +1149,312 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
}
int CmdHF14A(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
int infoHF14A(bool verbose, bool do_nack_test) {
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}, {{0}}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
if (verbose) PrintAndLogEx(WARNING, "iso14443a card select failed");
DropField();
return 0;
}
iso14a_card_select_t card;
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
/*
0: couldn't read
1: OK, with ATS
2: OK, no ATS
3: proprietary Anticollision
*/
uint64_t select_status = resp.arg[0];
if (select_status == 0) {
if (verbose) PrintAndLogEx(WARNING, "iso14443a card select failed");
DropField();
return select_status;
}
if (select_status == 3) {
PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision");
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
DropField();
return select_status;
}
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.arg[0]);
bool isMifareClassic = true;
switch (card.sak) {
case 0x00:
isMifareClassic = false;
// ******** is card of the MFU type (UL/ULC/NTAG/ etc etc)
DropField();
uint32_t tagT = GetHF14AMfU_Type();
if (tagT != UL_ERROR)
ul_print_type(tagT, 0);
else
PrintAndLogEx(NORMAL, "TYPE: Possible AZTEK (iso14443a compliant)");
// reconnect for further tests
c.arg[0] = ISO14A_CONNECT | ISO14A_NO_DISCONNECT;
c.arg[1] = 0;
c.arg[2] = 0;
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK, &resp);
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
if (select_status == 0) {
DropField();
return select_status;
}
break;
case 0x01:
PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance");
break;
case 0x04:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)");
isMifareClassic = false;
break;
case 0x08:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1");
break;
case 0x09:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k");
break;
case 0x0A:
PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)");
break;
case 0x10:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2");
break;
case 0x11:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2");
break;
case 0x18:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1");
break;
case 0x20:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41");
isMifareClassic = false;
break;
case 0x24:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire | DESFire EV1");
isMifareClassic = false;
break;
case 0x28:
PrintAndLogEx(NORMAL, "TYPE : JCOP31 or JCOP41 v2.3.1");
break;
case 0x38:
PrintAndLogEx(NORMAL, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K");
break;
case 0x88:
PrintAndLogEx(NORMAL, "TYPE : Infineon MIFARE CLASSIC 1K");
break;
case 0x98:
PrintAndLogEx(NORMAL, "TYPE : Gemplus MPCOS");
break;
default:
;
}
// Double & triple sized UID, can be mapped to a manufacturer.
if (card.uidlen > 4) {
PrintAndLogEx(NORMAL, "MANUFACTURER : %s", getTagInfo(card.uid[0]));
}
// try to request ATS even if tag claims not to support it
if (select_status == 2) {
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;
c.arg[1] = 2;
c.arg[2] = 0;
memcpy(c.d.asBytes, rats, 2);
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK, &resp);
memcpy(card.ats, resp.d.asBytes, resp.arg[0]);
card.ats_len = resp.arg[0]; // note: ats_len includes CRC Bytes
}
if (card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
bool ta1 = 0, tb1 = 0, tc1 = 0;
int pos;
if (select_status == 2) {
PrintAndLogEx(NORMAL, "SAK incorrectly claims that card doesn't support RATS");
}
PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len));
PrintAndLogEx(NORMAL, " - TL : length is %d bytes", card.ats[0]);
if (card.ats[0] != card.ats_len - 2) {
PrintAndLogEx(NORMAL, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len);
}
if (card.ats[0] > 1) { // there is a format byte (T0)
ta1 = (card.ats[1] & 0x10) == 0x10;
tb1 = (card.ats[1] & 0x20) == 0x20;
tc1 = (card.ats[1] & 0x40) == 0x40;
int16_t fsci = card.ats[1] & 0x0f;
PrintAndLogEx(NORMAL, " - T0 : TA1 is%s present, TB1 is%s present, "
"TC1 is%s present, FSCI is %d (FSC = %ld)",
(ta1 ? "" : " NOT"),
(tb1 ? "" : " NOT"),
(tc1 ? "" : " NOT"),
fsci,
fsci < sizeof(atsFSC) / sizeof(atsFSC[0]) ? atsFSC[fsci] : -1
);
}
pos = 2;
if (ta1) {
char dr[16], ds[16];
dr[0] = ds[0] = '\0';
if (card.ats[pos] & 0x10) strcat(ds, "2, ");
if (card.ats[pos] & 0x20) strcat(ds, "4, ");
if (card.ats[pos] & 0x40) strcat(ds, "8, ");
if (card.ats[pos] & 0x01) strcat(dr, "2, ");
if (card.ats[pos] & 0x02) strcat(dr, "4, ");
if (card.ats[pos] & 0x04) strcat(dr, "8, ");
if (strlen(ds) != 0) ds[strlen(ds) - 2] = '\0';
if (strlen(dr) != 0) dr[strlen(dr) - 2] = '\0';
PrintAndLogEx(NORMAL, " - TA1 : different divisors are%s supported, "
"DR: [%s], DS: [%s]",
((card.ats[pos] & 0x80) ? " NOT" : ""),
dr,
ds
);
pos++;
}
if (tb1) {
uint32_t sfgi = card.ats[pos] & 0x0F;
uint32_t fwi = card.ats[pos] >> 4;
PrintAndLogEx(NORMAL, " - TB1 : SFGI = %d (SFGT = %s%ld/fc), FWI = %d (FWT = %ld/fc)",
(sfgi),
sfgi ? "" : "(not needed) ",
sfgi ? (1 << 12) << sfgi : 0,
fwi,
(1 << 12) << fwi
);
pos++;
}
if (tc1) {
PrintAndLogEx(NORMAL, " - TC1 : NAD is%s supported, CID is%s supported",
(card.ats[pos] & 0x01) ? "" : " NOT",
(card.ats[pos] & 0x02) ? "" : " NOT");
pos++;
}
if (card.ats[0] > pos && card.ats[0] < card.ats_len - 2) {
const char *tip = "";
if (card.ats[0] - pos >= 7) {
if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x01\xBC\xD6", 7) == 0) {
tip = "-> MIFARE Plus X 2K or 4K";
} else if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) {
tip = "-> MIFARE Plus S 2K or 4K";
}
}
PrintAndLogEx(NORMAL, " - HB : %s%s", sprint_hex(card.ats + pos, card.ats[0] - pos), tip);
if (card.ats[pos] == 0xC1) {
PrintAndLogEx(NORMAL, " c1 -> Mifare or (multiple) virtual cards of various type");
PrintAndLogEx(NORMAL, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]);
switch (card.ats[pos + 2] & 0xf0) {
case 0x10:
PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus");
break;
}
switch (card.ats[pos + 2] & 0x0f) {
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> <1 kByte");
break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> 1 kByte");
break;
case 0x02:
PrintAndLogEx(NORMAL, " x2 -> 2 kByte");
break;
case 0x03:
PrintAndLogEx(NORMAL, " x3 -> 4 kByte");
break;
case 0x04:
PrintAndLogEx(NORMAL, " x4 -> 8 kByte");
break;
}
switch (card.ats[pos + 3] & 0xf0) {
case 0x00:
PrintAndLogEx(NORMAL, " 0x -> Engineering sample");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> Released");
break;
}
switch (card.ats[pos + 3] & 0x0f) {
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> Generation 1");
break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> Generation 2");
break;
case 0x02:
PrintAndLogEx(NORMAL, " x2 -> Generation 3");
break;
}
switch (card.ats[pos + 4] & 0x0f) {
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported");
break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> VCS, VCSL, and SVC supported");
break;
case 0x0E:
PrintAndLogEx(NORMAL, " xE -> no VCS command supported");
break;
}
}
}
} else {
PrintAndLogEx(INFO, "proprietary non iso14443-4 card found, RATS not supported");
}
detect_classic_magic();
if (isMifareClassic) {
int res = detect_classic_prng();
if (res == 1)
PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("WEAK"));
else if (res == 0)
PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("HARD"));
else
PrintAndLogEx(FAILED, "prng detection: " _RED_("Fail"));
if (do_nack_test)
detect_classic_nackbug(!verbose);
}
return select_status;
}

View file

@ -39,15 +39,10 @@ typedef struct {
} manufactureName;
int CmdHF14A(const char *Cmd);
int CmdHF14AList(const char *Cmd);
int CmdHF14AReader(const char *Cmd);
int CmdHF14AInfo(const char *Cmd);
int CmdHF14ASim(const char *Cmd);
int CmdHF14ASniff(const char *Cmd);
int CmdHF14ACmdRaw(const char *Cmd);
int CmdHF14ACUIDs(const char *Cmd);
int CmdHF14AAntiFuzz(const char *Cmd);
int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff
int CmdHF14ASim(const char *Cmd); // used by hf mfu sim
int infoHF14A(bool verbose, bool do_nack_test);
const char *getTagInfo(uint8_t uid);
int Hf14443_4aGetCardData(iso14a_card_select_t *card);
int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);

View file

@ -121,13 +121,52 @@ static int switch_off_field_14b(void) {
return 0;
}
int CmdHF14BList(const char *Cmd) {
static bool waitCmd14b(bool verbose) {
bool crc = false;
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
uint8_t status = 0;
uint16_t len = 0;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
status = (resp.arg[0] & 0xFF);
if (status > 0) return false;
len = (resp.arg[1] & 0xFFFF);
memcpy(data, resp.d.asBytes, len);
if (verbose) {
if (len >= 3) {
crc = check_crc(CRC_14443_B, data, len);
PrintAndLogEx(NORMAL, "[LEN %u] %s[%02X %02X] %s",
len,
sprint_hex(data, len - 2),
data[len - 2],
data[len - 1],
(crc) ? "OK" : "FAIL"
);
} else {
PrintAndLogEx(NORMAL, "[LEN %u] %s", len, sprint_hex(data, len));
}
}
return true;
} else {
PrintAndLogEx(WARNING, "command execution timeout");
return false;
}
}
static int CmdHF14BList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdTraceList("14b");
return 0;
}
int CmdHF14BSim(const char *Cmd) {
static int CmdHF14BSim(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_sim();
@ -142,7 +181,7 @@ int CmdHF14BSim(const char *Cmd) {
return 0;
}
int CmdHF14BSniff(const char *Cmd) {
static int CmdHF14BSniff(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_sniff();
@ -153,7 +192,7 @@ int CmdHF14BSniff(const char *Cmd) {
return 0;
}
int CmdHF14BCmdRaw(const char *Cmd) {
static int CmdHF14BCmdRaw(const char *Cmd) {
bool reply = true, power = false, select = false, hasTimeout = false;
char buf[5] = "";
int i = 0;
@ -557,28 +596,13 @@ bool HF14B_ST_Info(bool verbose) {
return true;
}
// get and print all info known about any known 14b tag
bool HF14BInfo(bool verbose) {
// try std 14b (atqb)
if (HF14B_Std_Info(verbose)) return true;
// try ST 14b
if (HF14B_ST_Info(verbose)) return true;
// try unknown 14b read commands (to be identified later)
// could be read of calypso, CEPAS, moneo, or pico pass.
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
return false;
}
// menu command to get and print all info known about any known 14b tag
int CmdHF14Binfo(const char *Cmd) {
static int CmdHF14Binfo(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_info();
bool verbose = !(cmdp == 's');
return HF14BInfo(verbose);
return infoHF14B(verbose);
}
bool HF14B_ST_Reader(bool verbose) {
@ -721,37 +745,20 @@ bool HF14B_Other_Reader() {
return false;
}
// get and print general info about all known 14b chips
bool HF14BReader(bool verbose) {
// try std 14b (atqb)
if (HF14B_Std_Reader(verbose)) return true;
// try ST Microelectronics 14b
if (HF14B_ST_Reader(verbose)) return true;
// try unknown 14b read commands (to be identified later)
// could be read of calypso, CEPAS, moneo, or pico pass.
if (HF14B_Other_Reader()) return true;
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
return false;
}
// menu command to get and print general info about all known 14b chips
int CmdHF14BReader(const char *Cmd) {
static int CmdHF14BReader(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_reader();
bool verbose = !(cmdp == 's');
return HF14BReader(verbose);
return readHF14B(verbose);
}
/* New command to read the contents of a SRI512|SRIX4K tag
* SRI* tags are ISO14443-B modulated memory tags,
* this command just dumps the contents of the memory/
*/
int CmdHF14BReadSri(const char *Cmd) {
static int CmdHF14BReadSri(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_14b_read_srx();
@ -764,7 +771,7 @@ int CmdHF14BReadSri(const char *Cmd) {
return 0;
}
// New command to write a SRI512/SRIX4K tag.
int CmdHF14BWriteSri(const char *Cmd) {
static int CmdHF14BWriteSri(const char *Cmd) {
/*
* For SRIX4K blocks 00 - 7F
* hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
@ -831,7 +838,7 @@ int CmdHF14BWriteSri(const char *Cmd) {
}
// need to write to file
int CmdHF14BDump(const char *Cmd) {
static int CmdHF14BDump(const char *Cmd) {
uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0};
@ -1091,45 +1098,6 @@ int srix4kValid(const char *Cmd) {
return 0;
}
bool waitCmd14b(bool verbose) {
bool crc = false;
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
uint8_t status = 0;
uint16_t len = 0;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
status = (resp.arg[0] & 0xFF);
if (status > 0) return false;
len = (resp.arg[1] & 0xFFFF);
memcpy(data, resp.d.asBytes, len);
if (verbose) {
if (len >= 3) {
crc = check_crc(CRC_14443_B, data, len);
PrintAndLogEx(NORMAL, "[LEN %u] %s[%02X %02X] %s",
len,
sprint_hex(data, len - 2),
data[len - 2],
data[len - 1],
(crc) ? "OK" : "FAIL"
);
} else {
PrintAndLogEx(NORMAL, "[LEN %u] %s", len, sprint_hex(data, len));
}
}
return true;
} else {
PrintAndLogEx(WARNING, "command execution timeout");
return false;
}
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"dump", CmdHF14BDump, 0, "Read all memory pages of an ISO14443-B tag, save to file"},
@ -1145,14 +1113,47 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHF14B(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
// get and print all info known about any known 14b tag
int infoHF14B(bool verbose) {
// try std 14b (atqb)
if (HF14B_Std_Info(verbose)) return 1;
// try ST 14b
if (HF14B_ST_Info(verbose)) return 1;
// try unknown 14b read commands (to be identified later)
// could be read of calypso, CEPAS, moneo, or pico pass.
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
return 0;
}
// get and print general info about all known 14b chips
int readHF14B(bool verbose) {
// try std 14b (atqb)
if (HF14B_Std_Reader(verbose)) return 1;
// try ST Microelectronics 14b
if (HF14B_ST_Reader(verbose)) return 1;
// try unknown 14b read commands (to be identified later)
// could be read of calypso, CEPAS, moneo, or pico pass.
if (HF14B_Other_Reader()) return 1;
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
return 0;
}

View file

@ -30,22 +30,7 @@
#include "protocols.h" // definitions of ISO14B protocol
int CmdHF14B(const char *Cmd);
int CmdHF14BList(const char *Cmd);
int CmdHF14BInfo(const char *Cmd);
int CmdHF14BSim(const char *Cmd);
int CmdHF14BSniff(const char *Cmd);
int CmdHF14BWrite(const char *cmd);
int CmdHF14BReader(const char *Cmd);
int CmdHF14BDump(const char *Cmd);
bool HF14BInfo(bool verbose);
bool HF14BReader(bool verbose);
int CmdHF14BCmdRaw(const char *Cmd);
// SRi ST Microelectronics read/write
int CmdHF14BReadSri(const char *Cmd);
int CmdHF14BWriteSri(const char *Cmd);
bool waitCmd14b(bool verbose);
int infoHF14B(bool verbose);
int readHF14B(bool verbose);
#endif

View file

@ -284,6 +284,8 @@ static const char *TagErrorStr(uint8_t error) {
}
}
static int CmdHF15Help(const char *Cmd);
static int usage_15_demod(void) {
PrintAndLogEx(NORMAL, "Tries to demodulate / decode ISO15693, from downloaded samples.\n"
"Gather samples with 'hf 15 read' / 'hf 15 record'");
@ -410,9 +412,88 @@ static int usage_15_readmulti(void) {
"\tcount#: number of pages");
return 0;
}
/**
* parses common HF 15 CMD parameters and prepares some data structures
* Parameters:
* **cmd command line
*/
static int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd) {
int temp;
uint8_t *req = c->d.asBytes;
uint8_t uid[8] = {0x00};
uint32_t reqlen = 0;
// strip
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
if (strstr(*cmd, "-2") == *cmd) {
c->arg[1] = 0; // use 1of256
(*cmd) += 2;
}
// strip
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
if (strstr(*cmd, "-o") == *cmd) {
req[reqlen] = ISO15_REQ_OPTION;
(*cmd) += 2;
}
// strip
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
switch (**cmd) {
case 0:
PrintAndLogEx(WARNING, "missing addr");
return 0;
break;
case 'u':
case 'U':
// unaddressed mode may not be supported by all vendors
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY;
req[reqlen++] = iso15cmd;
break;
case '*':
// we scan for the UID ourself
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
req[reqlen++] = iso15cmd;
if (!getUID(uid)) {
PrintAndLogEx(WARNING, "No tag found");
return 0;
}
memcpy(&req[reqlen], uid, sizeof(uid));
PrintAndLogEx(NORMAL, "Detected UID %s", sprintUID(NULL, uid));
reqlen += sizeof(uid);
break;
default:
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
req[reqlen++] = iso15cmd;
// parse UID
for (int i = 0; i < 8 && (*cmd)[i * 2] && (*cmd)[i * 2 + 1]; i++) {
sscanf((char[]) {(*cmd)[i * 2], (*cmd)[i * 2 + 1], 0}, "%X", &temp);
uid[7 - i] = temp & 0xff;
}
PrintAndLogEx(NORMAL, "Using UID %s", sprintUID(NULL, uid));
memcpy(&req[reqlen], uid, sizeof(uid));
reqlen += sizeof(uid);
break;
}
// skip to next space
while (**cmd != ' ' && **cmd != '\t')(*cmd)++;
// skip over the space
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
c->arg[0] = reqlen;
return 1;
}
// Mode 3
//helptext
int CmdHF15Demod(const char *Cmd) {
static int CmdHF15Demod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_demod();
@ -492,7 +573,7 @@ int CmdHF15Demod(const char *Cmd) {
// * Acquire Samples as Reader (enables carrier, sends inquiry)
//helptext
int CmdHF15Samples(const char *Cmd) {
static int CmdHF15Samples(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_samples();
@ -508,7 +589,7 @@ int CmdHF15Samples(const char *Cmd) {
* Commandline handling: HF15 CMD SYSINFO
* get system information from tag/VICC
*/
int CmdHF15Info(const char *Cmd) {
static int CmdHF15Info(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_info();
@ -589,7 +670,7 @@ int CmdHF15Info(const char *Cmd) {
// Record Activity without enabeling carrier
//helptext
int CmdHF15Record(const char *Cmd) {
static int CmdHF15Record(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_record();
@ -599,31 +680,17 @@ int CmdHF15Record(const char *Cmd) {
return 0;
}
// used with 'hf search'
int HF15Reader(const char *Cmd, bool verbose) {
(void)Cmd; // Cmd is not used so far
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
if (!getUID(uid)) {
if (verbose) PrintAndLogEx(WARNING, "No tag found.");
return 0;
}
PrintAndLogEx(NORMAL, " UID : %s", sprintUID(NULL, uid));
PrintAndLogEx(NORMAL, " TYPE : %s", getTagInfo_15(uid));
return 1;
}
int CmdHF15Reader(const char *Cmd) {
static int CmdHF15Reader(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_reader();
HF15Reader(Cmd, true);
readHF15Uid(true);
return 0;
}
// Simulation is still not working very good
// helptext
int CmdHF15Sim(const char *Cmd) {
static int CmdHF15Sim(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_sim();
@ -645,7 +712,7 @@ int CmdHF15Sim(const char *Cmd) {
// finds the AFI (Application Family Idendifier) of a card, by trying all values
// (There is no standard way of reading the AFI, allthough some tags support this)
// helptext
int CmdHF15Afi(const char *Cmd) {
static int CmdHF15Afi(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_findafi();
@ -664,7 +731,7 @@ typedef struct {
// Reads all memory pages
// need to write to file
int CmdHF15Dump(const char *Cmd) {
static int CmdHF15Dump(const char *Cmd) {
uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0};
@ -780,7 +847,332 @@ int CmdHF15Dump(const char *Cmd) {
return 0;
}
int CmdHF15Restore(const char *Cmd) {
static int CmdHF15List(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//PrintAndLogEx(WARNING, "Deprecated command, use 'hf list 15' instead");
CmdTraceList("15");
return 0;
}
static int CmdHF15Raw(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_raw();
UsbCommand resp;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}}; // len,speed,recv?
int reply = 1, fast = 1, i = 0;
bool crc = false;
char buf[5] = "";
uint8_t data[100];
uint32_t datalen = 0, temp;
// strip
while (*Cmd == ' ' || *Cmd == '\t') Cmd++;
while (Cmd[i] != '\0') {
if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; }
if (Cmd[i] == '-') {
switch (Cmd[i + 1]) {
case 'r':
case 'R':
reply = 0;
break;
case '2':
fast = 0;
break;
case 'c':
case 'C':
crc = true;
break;
default:
PrintAndLogEx(WARNING, "Invalid option");
return 0;
}
i += 2;
continue;
}
if ((Cmd[i] >= '0' && Cmd[i] <= '9') ||
(Cmd[i] >= 'a' && Cmd[i] <= 'f') ||
(Cmd[i] >= 'A' && Cmd[i] <= 'F')) {
buf[strlen(buf) + 1] = 0;
buf[strlen(buf)] = Cmd[i];
i++;
if (strlen(buf) >= 2) {
sscanf(buf, "%x", &temp);
data[datalen] = (uint8_t)(temp & 0xff);
datalen++;
*buf = 0;
}
continue;
}
PrintAndLogEx(WARNING, "Invalid char on input");
return 0;
}
if (crc) {
AddCrc15(data, datalen);
datalen += 2;
}
c.arg[0] = datalen;
c.arg[1] = fast;
c.arg[2] = reply;
memcpy(c.d.asBytes, data, datalen);
clearCommandBuffer();
SendCommand(&c);
if (reply) {
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
uint8_t len = resp.arg[0];
PrintAndLogEx(NORMAL, "received %i octets", len);
PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.d.asBytes, len));
} else {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
}
}
return 0;
}
/**
* Commandline handling: HF15 CMD READMULTI
* Read multiple blocks at once (not all tags support this)
*/
static int CmdHF15Readmulti(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_readmulti();
UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}}; // len,speed,recv?
uint8_t *req = c.d.asBytes;
int reqlen = 0;
uint8_t pagenum, pagecount;
char cmdbuf[100] = {0};
char *cmd = cmdbuf;
strncpy(cmd, Cmd, sizeof(cmdbuf) - 1);
if (!prepareHF15Cmd(&cmd, &c, ISO15_CMD_READMULTI))
return 0;
// add OPTION flag, in order to get lock-info
req[0] |= ISO15_REQ_OPTION;
reqlen = c.arg[0];
// decimal
pagenum = param_get8ex(cmd, 0, 0, 10);
pagecount = param_get8ex(cmd, 1, 0, 10);
//PrintAndLogEx(NORMAL, "ice %d %d\n", pagenum, pagecount);
// 0 means 1 page,
// 1 means 2 pages, ...
if (pagecount > 0) pagecount--;
req[reqlen++] = pagenum;
req[reqlen++] = pagecount;
AddCrc15(req, reqlen);
c.arg[0] = reqlen + 2;
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(FAILED, "iso15693 card select failed");
return 1;
}
uint32_t status = resp.arg[0];
if (status < 2) {
PrintAndLogEx(FAILED, "iso15693 card select failed");
return 1;
}
recv = resp.d.asBytes;
if (!CheckCrc15(recv, status)) {
PrintAndLogEx(FAILED, "CRC failed");
return 2;
}
if (recv[0] & ISO15_RES_ERROR) {
PrintAndLogEx(FAILED, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
return 3;
}
int start = 1; // skip status byte
int stop = (pagecount + 1) * 5;
int currblock = pagenum;
// print response
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "block# | data |lck| ascii");
PrintAndLogEx(NORMAL, "---------+--------------+---+----------");
for (int i = start; i < stop; i += 5) {
PrintAndLogEx(NORMAL, "%3d/0x%02X | %s | %d | %s", currblock, currblock, sprint_hex(recv + i + 1, 4), recv[i], sprint_ascii(recv + i + 1, 4));
currblock++;
}
return 0;
}
/**
* Commandline handling: HF15 CMD READ
* Reads a single Block
*/
static int CmdHF15Read(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_read();
UsbCommand resp;
uint8_t *recv;
// UsbCommand arg: len, speed, recv?
// arg0 (datalen, cmd len? .arg0 == crc?)
// arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 )
// arg2 (recv == 1 == expect a response)
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}};
uint8_t *req = c.d.asBytes;
int reqlen = 0, blocknum;
char cmdbuf[100] = {0};
char *cmd = cmdbuf;
strncpy(cmd, Cmd, sizeof(cmdbuf) - 1);
if (!prepareHF15Cmd(&cmd, &c, ISO15_CMD_READ))
return 0;
// add OPTION flag, in order to get lock-info
req[0] |= ISO15_REQ_OPTION;
reqlen = c.arg[0];
blocknum = strtol(cmd, NULL, 0);
req[reqlen++] = (uint8_t)blocknum;
AddCrc15(req, reqlen);
c.arg[0] = reqlen + 2;
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(NORMAL, "iso15693 card select failed");
return 1;
}
uint32_t status = resp.arg[0];
if (status < 2) {
PrintAndLogEx(NORMAL, "iso15693 card select failed");
return 1;
}
recv = resp.d.asBytes;
if (!CheckCrc15(recv, status)) {
PrintAndLogEx(NORMAL, "CRC failed");
return 2;
}
if (recv[0] & ISO15_RES_ERROR) {
PrintAndLogEx(WARNING, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
return 3;
}
// print response
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "block #%3d |lck| ascii", blocknum);
PrintAndLogEx(NORMAL, "------------+---+------");
PrintAndLogEx(NORMAL, "%s| %d | %s", sprint_hex(recv + 2, status - 4), recv[1], sprint_ascii(recv + 2, status - 4));
PrintAndLogEx(NORMAL, "");
return 0;
}
/**
* Commandline handling: HF15 CMD WRITE
* Writes a single Block - might run into timeout, even when successful
*/
static int CmdHF15Write(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_write();
UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}}; // len,speed,recv?
uint8_t *req = c.d.asBytes;
int reqlen = 0, pagenum, temp;
char cmdbuf[100] = {0};
char *cmd = cmdbuf;
char *cmd2;
strncpy(cmd, Cmd, sizeof(cmdbuf) - 1);
if (!prepareHF15Cmd(&cmd, &c, ISO15_CMD_WRITE))
return 0;
reqlen = c.arg[0];
// *cmd -> page num ; *cmd2 -> data
cmd2 = cmd;
while (*cmd2 != ' ' && *cmd2 != '\t' && *cmd2) cmd2++;
*cmd2 = 0;
cmd2++;
pagenum = strtol(cmd, NULL, 0);
req[reqlen++] = (uint8_t)pagenum;
while (cmd2[0] && cmd2[1]) { // hexdata, read by 2 hexchars
if (*cmd2 == ' ') {
cmd2++;
continue;
}
sscanf((char[]) {cmd2[0], cmd2[1], 0}, "%X", &temp);
req[reqlen++] = temp & 0xff;
cmd2 += 2;
}
AddCrc15(req, reqlen);
c.arg[0] = reqlen + 2;
PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum);
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(FAILED, "iso15693 card timeout, data may be written anyway");
return 1;
}
uint32_t status = resp.arg[0];
if (status < 2) {
PrintAndLogEx(FAILED, "iso15693 card select failed");
return 1;
}
recv = resp.d.asBytes;
if (!CheckCrc15(recv, status)) {
PrintAndLogEx(FAILED, "CRC failed");
return 2;
}
if (recv[0] & ISO15_RES_ERROR) {
PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
return 3;
}
PrintAndLogEx(NORMAL, "OK");
return 0;
}
static int CmdHF15Restore(const char *Cmd) {
FILE *f;
uint8_t uid[8] = {0x00};
@ -901,409 +1293,6 @@ int CmdHF15Restore(const char *Cmd) {
return 0;
}
int CmdHF15List(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//PrintAndLogEx(WARNING, "Deprecated command, use 'hf list 15' instead");
CmdTraceList("15");
return 0;
}
int CmdHF15Raw(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_raw();
UsbCommand resp;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}}; // len,speed,recv?
int reply = 1, fast = 1, i = 0;
bool crc = false;
char buf[5] = "";
uint8_t data[100];
uint32_t datalen = 0, temp;
// strip
while (*Cmd == ' ' || *Cmd == '\t') Cmd++;
while (Cmd[i] != '\0') {
if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; }
if (Cmd[i] == '-') {
switch (Cmd[i + 1]) {
case 'r':
case 'R':
reply = 0;
break;
case '2':
fast = 0;
break;
case 'c':
case 'C':
crc = true;
break;
default:
PrintAndLogEx(WARNING, "Invalid option");
return 0;
}
i += 2;
continue;
}
if ((Cmd[i] >= '0' && Cmd[i] <= '9') ||
(Cmd[i] >= 'a' && Cmd[i] <= 'f') ||
(Cmd[i] >= 'A' && Cmd[i] <= 'F')) {
buf[strlen(buf) + 1] = 0;
buf[strlen(buf)] = Cmd[i];
i++;
if (strlen(buf) >= 2) {
sscanf(buf, "%x", &temp);
data[datalen] = (uint8_t)(temp & 0xff);
datalen++;
*buf = 0;
}
continue;
}
PrintAndLogEx(WARNING, "Invalid char on input");
return 0;
}
if (crc) {
AddCrc15(data, datalen);
datalen += 2;
}
c.arg[0] = datalen;
c.arg[1] = fast;
c.arg[2] = reply;
memcpy(c.d.asBytes, data, datalen);
clearCommandBuffer();
SendCommand(&c);
if (reply) {
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
uint8_t len = resp.arg[0];
PrintAndLogEx(NORMAL, "received %i octets", len);
PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.d.asBytes, len));
} else {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
}
}
return 0;
}
/**
* parses common HF 15 CMD parameters and prepares some data structures
* Parameters:
* **cmd command line
*/
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd) {
int temp;
uint8_t *req = c->d.asBytes;
uint8_t uid[8] = {0x00};
uint32_t reqlen = 0;
// strip
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
if (strstr(*cmd, "-2") == *cmd) {
c->arg[1] = 0; // use 1of256
(*cmd) += 2;
}
// strip
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
if (strstr(*cmd, "-o") == *cmd) {
req[reqlen] = ISO15_REQ_OPTION;
(*cmd) += 2;
}
// strip
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
switch (**cmd) {
case 0:
PrintAndLogEx(WARNING, "missing addr");
return 0;
break;
case 'u':
case 'U':
// unaddressed mode may not be supported by all vendors
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY;
req[reqlen++] = iso15cmd;
break;
case '*':
// we scan for the UID ourself
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
req[reqlen++] = iso15cmd;
if (!getUID(uid)) {
PrintAndLogEx(WARNING, "No tag found");
return 0;
}
memcpy(&req[reqlen], uid, sizeof(uid));
PrintAndLogEx(NORMAL, "Detected UID %s", sprintUID(NULL, uid));
reqlen += sizeof(uid);
break;
default:
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
req[reqlen++] = iso15cmd;
// parse UID
for (int i = 0; i < 8 && (*cmd)[i * 2] && (*cmd)[i * 2 + 1]; i++) {
sscanf((char[]) {(*cmd)[i * 2], (*cmd)[i * 2 + 1], 0}, "%X", &temp);
uid[7 - i] = temp & 0xff;
}
PrintAndLogEx(NORMAL, "Using UID %s", sprintUID(NULL, uid));
memcpy(&req[reqlen], uid, sizeof(uid));
reqlen += sizeof(uid);
break;
}
// skip to next space
while (**cmd != ' ' && **cmd != '\t')(*cmd)++;
// skip over the space
while (**cmd == ' ' || **cmd == '\t')(*cmd)++;
c->arg[0] = reqlen;
return 1;
}
/**
* Commandline handling: HF15 CMD READMULTI
* Read multiple blocks at once (not all tags support this)
*/
int CmdHF15Readmulti(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_readmulti();
UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}}; // len,speed,recv?
uint8_t *req = c.d.asBytes;
int reqlen = 0;
uint8_t pagenum, pagecount;
char cmdbuf[100] = {0};
char *cmd = cmdbuf;
strncpy(cmd, Cmd, sizeof(cmdbuf) - 1);
if (!prepareHF15Cmd(&cmd, &c, ISO15_CMD_READMULTI))
return 0;
// add OPTION flag, in order to get lock-info
req[0] |= ISO15_REQ_OPTION;
reqlen = c.arg[0];
// decimal
pagenum = param_get8ex(cmd, 0, 0, 10);
pagecount = param_get8ex(cmd, 1, 0, 10);
//PrintAndLogEx(NORMAL, "ice %d %d\n", pagenum, pagecount);
// 0 means 1 page,
// 1 means 2 pages, ...
if (pagecount > 0) pagecount--;
req[reqlen++] = pagenum;
req[reqlen++] = pagecount;
AddCrc15(req, reqlen);
c.arg[0] = reqlen + 2;
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(FAILED, "iso15693 card select failed");
return 1;
}
uint32_t status = resp.arg[0];
if (status < 2) {
PrintAndLogEx(FAILED, "iso15693 card select failed");
return 1;
}
recv = resp.d.asBytes;
if (!CheckCrc15(recv, status)) {
PrintAndLogEx(FAILED, "CRC failed");
return 2;
}
if (recv[0] & ISO15_RES_ERROR) {
PrintAndLogEx(FAILED, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
return 3;
}
int start = 1; // skip status byte
int stop = (pagecount + 1) * 5;
int currblock = pagenum;
// print response
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "block# | data |lck| ascii");
PrintAndLogEx(NORMAL, "---------+--------------+---+----------");
for (int i = start; i < stop; i += 5) {
PrintAndLogEx(NORMAL, "%3d/0x%02X | %s | %d | %s", currblock, currblock, sprint_hex(recv + i + 1, 4), recv[i], sprint_ascii(recv + i + 1, 4));
currblock++;
}
return 0;
}
/**
* Commandline handling: HF15 CMD READ
* Reads a single Block
*/
int CmdHF15Read(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_read();
UsbCommand resp;
uint8_t *recv;
// UsbCommand arg: len, speed, recv?
// arg0 (datalen, cmd len? .arg0 == crc?)
// arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 )
// arg2 (recv == 1 == expect a response)
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}};
uint8_t *req = c.d.asBytes;
int reqlen = 0, blocknum;
char cmdbuf[100] = {0};
char *cmd = cmdbuf;
strncpy(cmd, Cmd, sizeof(cmdbuf) - 1);
if (!prepareHF15Cmd(&cmd, &c, ISO15_CMD_READ))
return 0;
// add OPTION flag, in order to get lock-info
req[0] |= ISO15_REQ_OPTION;
reqlen = c.arg[0];
blocknum = strtol(cmd, NULL, 0);
req[reqlen++] = (uint8_t)blocknum;
AddCrc15(req, reqlen);
c.arg[0] = reqlen + 2;
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(NORMAL, "iso15693 card select failed");
return 1;
}
uint32_t status = resp.arg[0];
if (status < 2) {
PrintAndLogEx(NORMAL, "iso15693 card select failed");
return 1;
}
recv = resp.d.asBytes;
if (!CheckCrc15(recv, status)) {
PrintAndLogEx(NORMAL, "CRC failed");
return 2;
}
if (recv[0] & ISO15_RES_ERROR) {
PrintAndLogEx(WARNING, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
return 3;
}
// print response
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "block #%3d |lck| ascii", blocknum);
PrintAndLogEx(NORMAL, "------------+---+------");
PrintAndLogEx(NORMAL, "%s| %d | %s", sprint_hex(recv + 2, status - 4), recv[1], sprint_ascii(recv + 2, status - 4));
PrintAndLogEx(NORMAL, "");
return 0;
}
/**
* Commandline handling: HF15 CMD WRITE
* Writes a single Block - might run into timeout, even when successful
*/
int CmdHF15Write(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_write();
UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}, {{0}}}; // len,speed,recv?
uint8_t *req = c.d.asBytes;
int reqlen = 0, pagenum, temp;
char cmdbuf[100] = {0};
char *cmd = cmdbuf;
char *cmd2;
strncpy(cmd, Cmd, sizeof(cmdbuf) - 1);
if (!prepareHF15Cmd(&cmd, &c, ISO15_CMD_WRITE))
return 0;
reqlen = c.arg[0];
// *cmd -> page num ; *cmd2 -> data
cmd2 = cmd;
while (*cmd2 != ' ' && *cmd2 != '\t' && *cmd2) cmd2++;
*cmd2 = 0;
cmd2++;
pagenum = strtol(cmd, NULL, 0);
req[reqlen++] = (uint8_t)pagenum;
while (cmd2[0] && cmd2[1]) { // hexdata, read by 2 hexchars
if (*cmd2 == ' ') {
cmd2++;
continue;
}
sscanf((char[]) {cmd2[0], cmd2[1], 0}, "%X", &temp);
req[reqlen++] = temp & 0xff;
cmd2 += 2;
}
AddCrc15(req, reqlen);
c.arg[0] = reqlen + 2;
PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum);
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(FAILED, "iso15693 card timeout, data may be written anyway");
return 1;
}
uint32_t status = resp.arg[0];
if (status < 2) {
PrintAndLogEx(FAILED, "iso15693 card select failed");
return 1;
}
recv = resp.d.asBytes;
if (!CheckCrc15(recv, status)) {
PrintAndLogEx(FAILED, "CRC failed");
return 2;
}
if (recv[0] & ISO15_RES_ERROR) {
PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
return 3;
}
PrintAndLogEx(NORMAL, "OK");
return 0;
}
static command_t CommandTable15[] = {
{"help", CmdHF15Help, 1, "This help"},
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
@ -1323,14 +1312,27 @@ static command_t CommandTable15[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHF15Help(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable15);
return 0;
}
int CmdHF15(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable15, Cmd);
return 0;
}
int CmdHF15Help(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable15);
return 0;
// used with 'hf search'
int readHF15Uid(bool verbose) {
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
if (!getUID(uid)) {
if (verbose) PrintAndLogEx(WARNING, "No tag found.");
return 0;
}
PrintAndLogEx(NORMAL, " UID : %s", sprintUID(NULL, uid));
PrintAndLogEx(NORMAL, " TYPE : %s", getTagInfo_15(uid));
return 1;
}

View file

@ -28,22 +28,6 @@
int CmdHF15(const char *Cmd);
int HF15Reader(const char *Cmd, bool verbose);
int readHF15Uid(bool verbose);
int CmdHF15Demod(const char *Cmd);
int CmdHF15Samples(const char *Cmd);
int CmdHF15Info(const char *Cmd);
int CmdHF15Record(const char *Cmd);
int CmdHF15Reader(const char *Cmd);
int CmdHF15Sim(const char *Cmd);
int CmdHF15Afi(const char *Cmd);
int CmdHF15Dump(const char *Cmd);
int CmdHF15Raw(const char *Cmd);
int CmdHF15Readmulti(const char *Cmd);
int CmdHF15Read(const char *Cmd);
int CmdHF15Write(const char *Cmd);
int CmdHF15Help(const char *Cmd);
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd);
#endif

View file

@ -12,7 +12,7 @@
static int CmdHelp(const char *Cmd);
// Perform (part of) the PACE protocol
int CmdHFEPACollectPACENonces(const char *Cmd) {
static int CmdHFEPACollectPACENonces(const char *Cmd) {
// requested nonce size
uint32_t m = 0;
// requested number of Nonces
@ -59,7 +59,7 @@ int CmdHFEPACollectPACENonces(const char *Cmd) {
}
// perform the PACE protocol by replaying APDUs
int CmdHFEPAPACEReplay(const char *Cmd) {
static int CmdHFEPAPACEReplay(const char *Cmd) {
// the 4 APDUs which are replayed + their lengths
uint8_t msesa_apdu[41] = {0}, gn_apdu[8] = {0}, map_apdu[75] = {0};
uint8_t pka_apdu[75] = {0}, ma_apdu[18] = {0}, apdu_lengths[5] = {0};
@ -170,7 +170,7 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHelp(const char *Cmd) {
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;

View file

@ -26,7 +26,5 @@
int CmdHFEPA(const char *Cmd);
int CmdHFEPACollectPACENonces(const char *Cmd);
int CmdHFEPAPACEReplay(const char *Cmd);
#endif // CMDHFEPA_H__

View file

@ -64,66 +64,21 @@ static int usage_hf_felica_raw(void) {
return 0;
}
int CmdHFFelicaList(const char *Cmd) {
static int CmdHFFelicaList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead");
CmdTraceList("felica");
return 0;
}
int CmdHFFelicaReader(const char *Cmd) {
bool silent = (Cmd[0] == 's' || Cmd[0] == 'S');
//UsbCommand cDisconnect = {CMD_FELICA_COMMAND, {0,0,0}, {{0}}};
UsbCommand c = {CMD_FELICA_COMMAND, {FELICA_CONNECT, 0, 0}, {{0}}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
if (!silent) PrintAndLogEx(WARNING, "FeliCa card select failed");
//SendCommand(&cDisconnect);
return 0;
}
felica_card_select_t card;
memcpy(&card, (felica_card_select_t *)resp.d.asBytes, sizeof(felica_card_select_t));
uint64_t status = resp.arg[0];
switch (status) {
case 1: {
if (!silent)
PrintAndLogEx(WARNING, "card timeout");
break;
}
case 2: {
if (!silent)
PrintAndLogEx(WARNING, "card answered wrong");
break;
}
case 3: {
if (!silent)
PrintAndLogEx(WARNING, "CRC check failed");
break;
}
case 0: {
PrintAndLogEx(SUCCESS, "FeliCa tag info");
PrintAndLogEx(NORMAL, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
PrintAndLogEx(NORMAL, " - CODE %s", sprint_hex(card.code, sizeof(card.code)));
PrintAndLogEx(NORMAL, " - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid)));
PrintAndLogEx(NORMAL, "Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm)));
PrintAndLogEx(NORMAL, " - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode)));
PrintAndLogEx(NORMAL, " - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt)));
PrintAndLogEx(NORMAL, "SERVICE CODE %s", sprint_hex(card.servicecode, sizeof(card.servicecode)));
break;
}
}
return status;
static int CmdHFFelicaReader(const char *Cmd) {
bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S');
readFelicaUid(verbose);
return 0;
}
// simulate iso18092 / FeliCa tag
int CmdHFFelicaSim(const char *Cmd) {
static int CmdHFFelicaSim(const char *Cmd) {
bool errors = false;
uint8_t flags = 0;
uint8_t tagtype = 1;
@ -188,7 +143,7 @@ int CmdHFFelicaSim(const char *Cmd) {
return 0;
}
int CmdHFFelicaSniff(const char *Cmd) {
static int CmdHFFelicaSniff(const char *Cmd) {
uint8_t cmdp = 0;
uint64_t samples2skip = 0;
@ -226,7 +181,7 @@ int CmdHFFelicaSniff(const char *Cmd) {
}
// uid hex
int CmdHFFelicaSimLite(const char *Cmd) {
static int CmdHFFelicaSimLite(const char *Cmd) {
uint64_t uid = param_get64ex(Cmd, 0, 0, 16);
@ -390,7 +345,7 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) {
return tracepos + 19;
}
int CmdHFFelicaDumpLite(const char *Cmd) {
static int CmdHFFelicaDumpLite(const char *Cmd) {
char ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_hf_felica_dumplite();
@ -456,7 +411,22 @@ int CmdHFFelicaDumpLite(const char *Cmd) {
return 0;
}
int CmdHFFelicaCmdRaw(const char *Cmd) {
static void waitCmdFelica(uint8_t iSelect) {
UsbCommand resp;
uint16_t len = 0;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
len = iSelect ? (resp.arg[1] & 0xffff) : (resp.arg[0] & 0xffff);
PrintAndLogEx(NORMAL, "received %i octets", len);
if (!len)
return;
PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.d.asBytes, len));
} else {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
}
}
static int CmdHFFelicaCmdRaw(const char *Cmd) {
UsbCommand c = {CMD_FELICA_COMMAND, {0, 0, 0}, {{0}}};
bool reply = 1;
bool crc = false;
@ -572,21 +542,6 @@ int CmdHFFelicaCmdRaw(const char *Cmd) {
return 0;
}
void waitCmdFelica(uint8_t iSelect) {
UsbCommand resp;
uint16_t len = 0;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
len = iSelect ? (resp.arg[1] & 0xffff) : (resp.arg[0] & 0xffff);
PrintAndLogEx(NORMAL, "received %i octets", len);
if (!len)
return;
PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.d.asBytes, len));
} else {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
}
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"list", CmdHFFelicaList, 0, "List ISO 18092/FeliCa history"},
@ -600,14 +555,65 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFFelica(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
int readFelicaUid(bool verbose) {
//UsbCommand cDisconnect = {CMD_FELICA_COMMAND, {0,0,0}, {{0}}};
UsbCommand c = {CMD_FELICA_COMMAND, {FELICA_CONNECT, 0, 0}, {{0}}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
if (verbose) PrintAndLogEx(WARNING, "FeliCa card select failed");
//SendCommand(&cDisconnect);
return 0;
}
felica_card_select_t card;
memcpy(&card, (felica_card_select_t *)resp.d.asBytes, sizeof(felica_card_select_t));
uint64_t status = resp.arg[0];
switch (status) {
case 1: {
if (verbose)
PrintAndLogEx(WARNING, "card timeout");
break;
}
case 2: {
if (verbose)
PrintAndLogEx(WARNING, "card answered wrong");
break;
}
case 3: {
if (verbose)
PrintAndLogEx(WARNING, "CRC check failed");
break;
}
case 0: {
PrintAndLogEx(SUCCESS, "FeliCa tag info");
PrintAndLogEx(NORMAL, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
PrintAndLogEx(NORMAL, " - CODE %s", sprint_hex(card.code, sizeof(card.code)));
PrintAndLogEx(NORMAL, " - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid)));
PrintAndLogEx(NORMAL, "Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm)));
PrintAndLogEx(NORMAL, " - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode)));
PrintAndLogEx(NORMAL, " - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt)));
PrintAndLogEx(NORMAL, "SERVICE CODE %s", sprint_hex(card.servicecode, sizeof(card.servicecode)));
break;
}
}
return status;
}

View file

@ -26,16 +26,6 @@
#include "mifare.h" // felica_card_select_t struct
int CmdHFFelica(const char *Cmd);
int CmdHFFelicaList(const char *Cmd);
int CmdHFFelicaReader(const char *Cmd);
int CmdHFFelicaSim(const char *Cmd);
int CmdHFFelicaSniff(const char *Cmd);
int CmdHFFelicaCmdRaw(const char *Cmd);
void waitCmdFelica(uint8_t iSelect);
//temp
int CmdHFFelicaSimLite(const char *Cmd);
int CmdHFFelicaDumpLite(const char *Cmd);
int readFelicaUid(bool verbose);
#endif

View file

@ -49,13 +49,13 @@
static int CmdHelp(const char *Cmd);
int CmdHFFidoInfo(const char *cmd) {
static int CmdHFFidoInfo(const char *cmd) {
if (cmd && strlen(cmd) > 0)
PrintAndLog("WARNING: command don't have any parameters.\n");
// info about 14a part
CmdHF14AInfo("");
infoHF14A(false, false);
// FIDO info
PrintAndLog("--------------------------------------------");
@ -168,7 +168,7 @@ json_t *OpenJson(int paramnum, char *fname, void *argtable[], bool *err) {
return root;
}
int CmdHFFidoRegister(const char *cmd) {
static int CmdHFFidoRegister(const char *cmd) {
uint8_t data[64] = {0};
int chlen = 0;
uint8_t cdata[250] = {0};
@ -397,7 +397,7 @@ int CmdHFFidoRegister(const char *cmd) {
return 0;
};
int CmdHFFidoAuthenticate(const char *cmd) {
static int CmdHFFidoAuthenticate(const char *cmd) {
uint8_t data[512] = {0};
uint8_t hdata[250] = {0};
bool public_key_loaded = false;
@ -648,7 +648,7 @@ int GetExistsFileNameJson(const char *prefixDir, const char *reqestedFileName, c
return 0;
}
int CmdHFFido2MakeCredential(const char *cmd) {
static int CmdHFFido2MakeCredential(const char *cmd) {
json_error_t error;
json_t *root = NULL;
char fname[300] = {0};
@ -775,7 +775,7 @@ int CmdHFFido2MakeCredential(const char *cmd) {
return 0;
};
int CmdHFFido2GetAssertion(const char *cmd) {
static int CmdHFFido2GetAssertion(const char *cmd) {
json_error_t error;
json_t *root = NULL;
char fname[300] = {0};

View file

@ -270,14 +270,14 @@ int xorbits_8(uint8_t val) {
return res & 1;
}
int CmdHFiClassList(const char *Cmd) {
static int CmdHFiClassList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list iclass' instead");
CmdTraceList("iclass");
return 0;
}
int CmdHFiClassSniff(const char *Cmd) {
static int CmdHFiClassSniff(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_iclass_sniff();
UsbCommand c = {CMD_SNIFF_ICLASS, {0, 0, 0}, {{0}}};
@ -285,7 +285,7 @@ int CmdHFiClassSniff(const char *Cmd) {
return 0;
}
int CmdHFiClassSim(const char *Cmd) {
static int CmdHFiClassSim(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_iclass_sim();
@ -510,81 +510,14 @@ int CmdHFiClassSim(const char *Cmd) {
return 0;
}
int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
(void)Cmd; // Cmd is not used so far
bool tagFound = false;
uint32_t flags = FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_AIA |
FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_ONLY_ONCE |
FLAG_ICLASS_READER_ONE_TRY;
UsbCommand c = {CMD_READER_ICLASS, {flags, 0, 0}, {{0}}};
// loop in client not device - else on windows have a communication error
UsbCommand resp;
while (!ukbhit()) {
clearCommandBuffer();
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
uint8_t readStatus = resp.arg[0] & 0xff;
uint8_t *data = resp.d.asBytes;
if (verbose) PrintAndLogEx(NORMAL, "Readstatus:%02x", readStatus);
// no tag found or button pressed
if ((readStatus == 0 && !loop) || readStatus == 0xFF) {
// abort
if (verbose) {
PrintAndLogEx(FAILED, "Quitting...");
DropField();
return 0;
}
}
if (readStatus & FLAG_ICLASS_READER_CSN) {
PrintAndLogEx(NORMAL, " CSN: %s", sprint_hex(data, 8));
tagFound = true;
}
if (readStatus & FLAG_ICLASS_READER_CC) {
PrintAndLogEx(NORMAL, " CC: %s", sprint_hex(data + 16, 8));
}
if (readStatus & FLAG_ICLASS_READER_CONF) {
printIclassDumpInfo(data);
}
if (readStatus & FLAG_ICLASS_READER_AIA) {
bool legacy = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0);
bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0);
PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8));
if (legacy)
PrintAndLogEx(SUCCESS, " : Possible iClass (legacy credential tag)");
else if (se_enabled)
PrintAndLogEx(SUCCESS, " : Possible iClass (SE credential tag)");
else
PrintAndLogEx(WARNING, " : Possible iClass (NOT legacy tag)");
}
if (tagFound && !loop) {
DropField();
return 1;
}
} else {
if (verbose)
PrintAndLogEx(WARNING, "command execute timeout");
}
if (!loop) break;
}
DropField();
return 0;
}
int CmdHFiClassReader(const char *Cmd) {
static int CmdHFiClassReader(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_iclass_reader();
bool findone = (cmdp == '1') ? false : true;
return HFiClassReader(Cmd, findone, true);
return readIclass(findone, true);
}
int CmdHFiClassReader_Replay(const char *Cmd) {
static int CmdHFiClassReader_Replay(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_iclass_replay();
@ -612,7 +545,7 @@ int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
return 0;
}
int CmdHFiClassELoad(const char *Cmd) {
static int CmdHFiClassELoad(const char *Cmd) {
char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf_iclass_eload();
@ -704,7 +637,7 @@ static int readKeyfile(const char *filename, size_t len, uint8_t *buffer) {
return 0;
}
int CmdHFiClassDecrypt(const char *Cmd) {
static int CmdHFiClassDecrypt(const char *Cmd) {
char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt();
@ -808,7 +741,7 @@ static int iClassEncryptBlkData(uint8_t *blkData) {
return 1;
}
int CmdHFiClassEncryptBlk(const char *Cmd) {
static int CmdHFiClassEncryptBlk(const char *Cmd) {
uint8_t blkData[8] = {0};
char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_encrypt();
@ -900,7 +833,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
return true;
}
int CmdHFiClassReader_Dump(const char *Cmd) {
static int CmdHFiClassReader_Dump(const char *Cmd) {
uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1183,7 +1116,7 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c
return isOK;
}
int CmdHFiClass_WriteBlock(const char *Cmd) {
static int CmdHFiClass_WriteBlock(const char *Cmd) {
uint8_t blockno = 0;
uint8_t bldata[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1261,7 +1194,7 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
return ans;
}
int CmdHFiClassCloneTag(const char *Cmd) {
static int CmdHFiClassCloneTag(const char *Cmd) {
char filename[FILE_PATH_SIZE] = { 0x00 };
char tempStr[50] = {0};
uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1451,7 +1384,7 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite,
return 1;
}
int CmdHFiClass_ReadBlock(const char *Cmd) {
static int CmdHFiClass_ReadBlock(const char *Cmd) {
uint8_t blockno = 0;
uint8_t keyType = 0x88; //debit key
uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1523,7 +1456,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
return ReadBlock(KEY, blockno, keyType, elite, rawkey, verbose, auth);
}
int CmdHFiClass_loclass(const char *Cmd) {
static int CmdHFiClass_loclass(const char *Cmd) {
char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h')
@ -1582,7 +1515,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e
PrintAndLogEx(NORMAL, "------+--+-------------------------+\n");
}
int CmdHFiClassReadTagFile(const char *Cmd) {
static int CmdHFiClassReadTagFile(const char *Cmd) {
int startblock = 0;
int endblock = 0;
char tempnum[5];
@ -1674,7 +1607,7 @@ static void HFiClassCalcNewKey(uint8_t *CSN, uint8_t *OLDKEY, uint8_t *NEWKEY, u
}
}
int CmdHFiClassCalcNewKey(const char *Cmd) {
static int CmdHFiClassCalcNewKey(const char *Cmd) {
uint8_t OLDKEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t NEWKEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t xor_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1821,7 +1754,7 @@ static int printKeys(void) {
return 0;
}
int CmdHFiClassManageKeys(const char *Cmd) {
static int CmdHFiClassManageKeys(const char *Cmd) {
uint8_t keyNbr = 0;
uint8_t dataLen = 0;
uint8_t KEY[8] = {0};
@ -1911,7 +1844,7 @@ int CmdHFiClassManageKeys(const char *Cmd) {
return 0;
}
int CmdHFiClassCheckKeys(const char *Cmd) {
static int CmdHFiClassCheckKeys(const char *Cmd) {
// empty string
if (strlen(Cmd) == 0) return usage_hf_iclass_chk();
@ -2132,7 +2065,7 @@ static int cmp_uint32(const void *a, const void *b) {
// this method tries to identify in which configuration mode a iClass / iClass SE reader is in.
// Standard or Elite / HighSecurity mode. It uses a default key dictionary list in order to work.
int CmdHFiClassLookUp(const char *Cmd) {
static int CmdHFiClassLookUp(const char *Cmd) {
uint8_t CSN[8];
uint8_t EPURSE[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -2455,7 +2388,7 @@ static void generate(uint8_t *data, uint8_t len) {
free(pkey);
}
int CmdHFiClassPermuteKey(const char *Cmd) {
static int CmdHFiClassPermuteKey(const char *Cmd) {
uint8_t key[8] = {0};
uint8_t key_std_format[8] = {0};
@ -2511,14 +2444,81 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFiClass(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
int readIclass(bool loop, bool verbose) {
bool tagFound = false;
uint32_t flags = FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_AIA |
FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_ONLY_ONCE |
FLAG_ICLASS_READER_ONE_TRY;
UsbCommand c = {CMD_READER_ICLASS, {flags, 0, 0}, {{0}}};
// loop in client not device - else on windows have a communication error
UsbCommand resp;
while (!ukbhit()) {
clearCommandBuffer();
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
uint8_t readStatus = resp.arg[0] & 0xff;
uint8_t *data = resp.d.asBytes;
if (verbose) PrintAndLogEx(NORMAL, "Readstatus:%02x", readStatus);
// no tag found or button pressed
if ((readStatus == 0 && !loop) || readStatus == 0xFF) {
// abort
if (verbose) {
PrintAndLogEx(FAILED, "Quitting...");
DropField();
return 0;
}
}
if (readStatus & FLAG_ICLASS_READER_CSN) {
PrintAndLogEx(NORMAL, " CSN: %s", sprint_hex(data, 8));
tagFound = true;
}
if (readStatus & FLAG_ICLASS_READER_CC) {
PrintAndLogEx(NORMAL, " CC: %s", sprint_hex(data + 16, 8));
}
if (readStatus & FLAG_ICLASS_READER_CONF) {
printIclassDumpInfo(data);
}
if (readStatus & FLAG_ICLASS_READER_AIA) {
bool legacy = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0);
bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0);
PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8));
if (legacy)
PrintAndLogEx(SUCCESS, " : Possible iClass (legacy credential tag)");
else if (se_enabled)
PrintAndLogEx(SUCCESS, " : Possible iClass (SE credential tag)");
else
PrintAndLogEx(WARNING, " : Possible iClass (NOT legacy tag)");
}
if (tagFound && !loop) {
DropField();
return 1;
}
} else {
if (verbose)
PrintAndLogEx(WARNING, "command execute timeout");
}
if (!loop) break;
}
DropField();
return 0;
}

View file

@ -52,30 +52,7 @@ typedef struct iclass_prekey {
int CmdHFiClass(const char *Cmd);
int CmdHFiClassCalcNewKey(const char *Cmd);
int CmdHFiClassCloneTag(const char *Cmd);
int CmdHFiClassDecrypt(const char *Cmd);
int CmdHFiClassEncryptBlk(const char *Cmd);
int CmdHFiClassELoad(const char *Cmd);
int CmdHFiClassList(const char *Cmd);
int HFiClassReader(const char *Cmd, bool loop, bool verbose);
int CmdHFiClassReader(const char *Cmd);
int CmdHFiClassReader_Dump(const char *Cmd);
int CmdHFiClassReader_Replay(const char *Cmd);
int CmdHFiClassReadKeyFile(const char *filename);
int CmdHFiClassReadTagFile(const char *Cmd);
int CmdHFiClass_ReadBlock(const char *Cmd);
int CmdHFiClass_TestMac(const char *Cmd);
int CmdHFiClassManageKeys(const char *Cmd);
int CmdHFiClass_loclass(const char *Cmd);
int CmdHFiClassSniff(const char *Cmd);
int CmdHFiClassSim(const char *Cmd);
int CmdHFiClassWriteKeyFile(const char *Cmd);
int CmdHFiClass_WriteBlock(const char *Cmd);
int CmdHFiClassCheckKeys(const char *Cmd);
int CmdHFiClassLookUp(const char *Cmd);
int CmdHFiClassPermuteKey(const char *Cmd);
int readIclass(bool loop, bool verbose);
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);

View file

@ -160,7 +160,7 @@ static int usage_legic_wipe(void) {
* This is based on information given in the talk held
* by Henryk Ploetz and Karsten Nohl at 26c3
*/
int CmdLegicInfo(const char *Cmd) {
static int CmdLegicInfo(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_legic_info();
@ -485,7 +485,7 @@ out:
// params:
// offset in data memory
// number of bytes to read
int CmdLegicRdmem(const char *Cmd) {
static int CmdLegicRdmem(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_legic_rdmem();
@ -519,7 +519,7 @@ int CmdLegicRdmem(const char *Cmd) {
return status;
}
int CmdLegicRfSim(const char *Cmd) {
static int CmdLegicRfSim(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_legic_sim();
@ -531,7 +531,7 @@ int CmdLegicRfSim(const char *Cmd) {
return 0;
}
int CmdLegicRfWrite(const char *Cmd) {
static int CmdLegicRfWrite(const char *Cmd) {
uint8_t *data = NULL;
uint8_t cmdp = 0;
@ -670,7 +670,7 @@ int CmdLegicRfWrite(const char *Cmd) {
return 0;
}
int CmdLegicCalcCrc(const char *Cmd) {
static int CmdLegicCalcCrc(const char *Cmd) {
uint8_t *data = NULL;
uint8_t cmdp = 0, uidcrc = 0, type = 0;
@ -849,33 +849,14 @@ void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
}
}
int HFLegicReader(const char *Cmd, bool verbose) {
static int CmdLegicReader(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_legic_reader();
legic_card_select_t card;
switch (legic_get_type(&card)) {
case 1:
return 2;
case 2:
if (verbose) PrintAndLogEx(WARNING, "command execution time out");
return 1;
case 3:
if (verbose) PrintAndLogEx(WARNING, "legic card select failed");
return 2;
default:
break;
}
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
legic_print_type(card.cardsize, 0);
return 0;
}
int CmdLegicReader(const char *Cmd) {
return HFLegicReader(Cmd, true);
return readLegicUid(true);
}
int CmdLegicDump(const char *Cmd) {
static int CmdLegicDump(const char *Cmd) {
FILE *f;
char filename[FILE_PATH_SIZE] = {0x00};
@ -980,7 +961,7 @@ int CmdLegicDump(const char *Cmd) {
return 0;
}
int CmdLegicRestore(const char *Cmd) {
static int CmdLegicRestore(const char *Cmd) {
FILE *f;
char filename[FILE_PATH_SIZE] = {0x00};
@ -1106,7 +1087,7 @@ int CmdLegicRestore(const char *Cmd) {
return 0;
}
int CmdLegicELoad(const char *Cmd) {
static int CmdLegicELoad(const char *Cmd) {
FILE *f;
char filename[FILE_PATH_SIZE];
char *fnameptr = filename;
@ -1176,7 +1157,7 @@ int CmdLegicELoad(const char *Cmd) {
return 0;
}
int CmdLegicESave(const char *Cmd) {
static int CmdLegicESave(const char *Cmd) {
char filename[FILE_PATH_SIZE];
char *fnameptr = filename;
@ -1236,7 +1217,7 @@ int CmdLegicESave(const char *Cmd) {
return 0;
}
int CmdLegicWipe(const char *Cmd) {
static int CmdLegicWipe(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
@ -1299,7 +1280,7 @@ int CmdLegicWipe(const char *Cmd) {
return 0;
}
int CmdLegicList(const char *Cmd) {
static int CmdLegicList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdTraceList("legic");
return 0;
@ -1322,14 +1303,34 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFLegic(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
int readLegicUid(bool verbose) {
legic_card_select_t card;
switch (legic_get_type(&card)) {
case 1:
return 2;
case 2:
if (verbose) PrintAndLogEx(WARNING, "command execution time out");
return 1;
case 3:
if (verbose) PrintAndLogEx(WARNING, "legic card select failed");
return 2;
default:
break;
}
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
legic_print_type(card.cardsize, 0);
return 0;
}

View file

@ -26,21 +26,7 @@
int CmdHFLegic(const char *Cmd);
int CmdLegicInfo(const char *Cmd);
int CmdLegicRdmem(const char *Cmd);
int CmdLegicLoad(const char *Cmd);
int CmdLegicRfSim(const char *Cmd);
int CmdLegicRfWrite(const char *Cmd);
int CmdLegicCalcCrc(const char *Cmd);
int CmdLegicDump(const char *Cmd);
int CmdLegicRestore(const char *Cmd);
int CmdLegicReader(const char *Cmd);
int CmdLegicELoad(const char *Cmd);
int CmdLegicESave(const char *Cmd);
int CmdLegicList(const char *Cmd);
int CmdLegicWipe(const char *Cmd);
int HFLegicReader(const char *Cmd, bool verbose);
int readLegicUid(bool verbose);
int legic_print_type(uint32_t tagtype, uint8_t spaces);
int legic_get_type(legic_card_select_t *card);
void legic_chk_iv(uint32_t *iv);

View file

@ -100,7 +100,8 @@ static int usage_hf14_dbg(void) {
PrintAndLogEx(NORMAL, " hf mf dbg 3");
return 0;
}
static int usage_hf14_sniff(void) {
/*
* static int usage_hf14_sniff(void) {
PrintAndLogEx(NORMAL, "It continuously gets data from the field and saves it to: log, emulator, emulator file.");
PrintAndLogEx(NORMAL, "Usage: hf mf sniff [h] [l] [d] [f]");
PrintAndLogEx(NORMAL, "Options:");
@ -113,6 +114,7 @@ static int usage_hf14_sniff(void) {
PrintAndLogEx(NORMAL, " hf mf sniff l d f");
return 0;
}
*/
static int usage_hf14_nested(void) {
PrintAndLogEx(NORMAL, "Usage:");
PrintAndLogEx(NORMAL, " all sectors: hf mf nested <card memory> <block number> <key A/B> <key (12 hex symbols)> [t,d]");
@ -443,7 +445,7 @@ char *GenerateFilename(const char *prefix, const char *suffix) {
return fptr;
}
int CmdHF14AMfDarkside(const char *Cmd) {
static int CmdHF14AMfDarkside(const char *Cmd) {
uint8_t blockno = 0, key_type = MIFARE_AUTH_KEYA;
uint64_t key = 0;
@ -483,7 +485,7 @@ int CmdHF14AMfDarkside(const char *Cmd) {
return 0;
}
int CmdHF14AMfWrBl(const char *Cmd) {
static int CmdHF14AMfWrBl(const char *Cmd) {
uint8_t blockNo = 0;
uint8_t keyType = 0;
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
@ -537,7 +539,7 @@ int CmdHF14AMfWrBl(const char *Cmd) {
return 0;
}
int CmdHF14AMfRdBl(const char *Cmd) {
static int CmdHF14AMfRdBl(const char *Cmd) {
uint8_t blockNo = 0;
uint8_t keyType = 0;
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
@ -601,7 +603,7 @@ int CmdHF14AMfRdBl(const char *Cmd) {
return 0;
}
int CmdHF14AMfRdSc(const char *Cmd) {
static int CmdHF14AMfRdSc(const char *Cmd) {
int i;
uint8_t sectorNo = 0;
uint8_t keyType = 0;
@ -717,7 +719,7 @@ uint8_t NumBlocksPerSector(uint8_t sectorNo) {
}
}
int CmdHF14AMfDump(const char *Cmd) {
static int CmdHF14AMfDump(const char *Cmd) {
uint8_t sectorNo, blockNo;
uint8_t keyA[40][6];
@ -923,7 +925,7 @@ int CmdHF14AMfDump(const char *Cmd) {
return 0;
}
int CmdHF14AMfRestore(const char *Cmd) {
static int CmdHF14AMfRestore(const char *Cmd) {
uint8_t sectorNo, blockNo;
uint8_t keyType = 0;
uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
@ -1064,7 +1066,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
return 0;
}
int CmdHF14AMfNested(const char *Cmd) {
static int CmdHF14AMfNested(const char *Cmd) {
int i, res, iterations;
sector_t *e_sector = NULL;
uint8_t blockNo = 0;
@ -1328,7 +1330,7 @@ int CmdHF14AMfNested(const char *Cmd) {
return 0;
}
int CmdHF14AMfNestedHard(const char *Cmd) {
static int CmdHF14AMfNestedHard(const char *Cmd) {
uint8_t blockNo = 0;
uint8_t keyType = 0;
uint8_t trgBlockNo = 0;
@ -1529,7 +1531,7 @@ void shuffle(uint8_t *array, uint16_t len) {
}
}
int CmdHF14AMfChk_fast(const char *Cmd) {
static int CmdHF14AMfChk_fast(const char *Cmd) {
char ctmp = 0x00;
ctmp = tolower(param_getchar(Cmd, 0));
@ -1780,7 +1782,7 @@ out:
return 0;
}
int CmdHF14AMfChk(const char *Cmd) {
static int CmdHF14AMfChk(const char *Cmd) {
char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 3 || ctmp == 'h') return usage_hf14_chk();
@ -2132,7 +2134,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
}
}
int CmdHF14AMf1kSim(const char *Cmd) {
static int CmdHF14AMf1kSim(const char *Cmd) {
uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t exitAfterNReads = 0;
@ -2244,8 +2246,8 @@ int CmdHF14AMf1kSim(const char *Cmd) {
}
return 0;
}
int CmdHF14AMfSniff(const char *Cmd) {
/*
static int CmdHF14AMfSniff(const char *Cmd) {
bool wantLogToFile = false;
bool wantDecrypt = false;
//bool wantSaveToEml = false; TODO
@ -2405,7 +2407,7 @@ int CmdHF14AMfSniff(const char *Cmd) {
free(buf);
return 0;
}
*/
int CmdHF14AMfDbg(const char *Cmd) {
char ctmp = tolower(param_getchar(Cmd, 0));
@ -2419,7 +2421,7 @@ int CmdHF14AMfDbg(const char *Cmd) {
return 0;
}
int CmdHF14AMfKeyBrute(const char *Cmd) {
static int CmdHF14AMfKeyBrute(const char *Cmd) {
uint8_t blockNo = 0, keytype = 0;
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
@ -2478,7 +2480,7 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) {
}
// EMULATOR COMMANDS
int CmdHF14AMfEGet(const char *Cmd) {
static int CmdHF14AMfEGet(const char *Cmd) {
uint8_t blockNo = 0;
uint8_t data[16] = {0x00};
char c = tolower(param_getchar(Cmd, 0));
@ -2496,7 +2498,7 @@ int CmdHF14AMfEGet(const char *Cmd) {
return 0;
}
int CmdHF14AMfEClear(const char *Cmd) {
static int CmdHF14AMfEClear(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h') return usage_hf14_eclr();
@ -2506,7 +2508,7 @@ int CmdHF14AMfEClear(const char *Cmd) {
return 0;
}
int CmdHF14AMfESet(const char *Cmd) {
static int CmdHF14AMfESet(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
uint8_t memBlock[16];
uint8_t blockNo = 0;
@ -2620,7 +2622,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
return 0;
}
int CmdHF14AMfESave(const char *Cmd) {
static int CmdHF14AMfESave(const char *Cmd) {
char filename[FILE_PATH_SIZE];
char *fnameptr = filename;
@ -2666,7 +2668,7 @@ int CmdHF14AMfESave(const char *Cmd) {
return 0;
}
int CmdHF14AMfECFill(const char *Cmd) {
static int CmdHF14AMfECFill(const char *Cmd) {
uint8_t keyType = 0;
uint8_t numSectors = 16;
char c = tolower(param_getchar(Cmd, 0));
@ -2691,7 +2693,7 @@ int CmdHF14AMfECFill(const char *Cmd) {
return 0;
}
int CmdHF14AMfEKeyPrn(const char *Cmd) {
static int CmdHF14AMfEKeyPrn(const char *Cmd) {
int i;
uint8_t numSectors;
uint8_t data[16];
@ -2720,7 +2722,7 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) {
}
// CHINESE MAGIC COMMANDS
int CmdHF14AMfCSetUID(const char *Cmd) {
static int CmdHF14AMfCSetUID(const char *Cmd) {
uint8_t wipeCard = 0;
uint8_t uid[8] = {0x00};
uint8_t oldUid[8] = {0x00};
@ -2780,7 +2782,7 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
return 0;
}
int CmdHF14AMfCSetBlk(const char *Cmd) {
static int CmdHF14AMfCSetBlk(const char *Cmd) {
uint8_t block[16] = {0x00};
uint8_t blockNo = 0;
uint8_t params = MAGIC_SINGLE;
@ -2807,7 +2809,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd) {
return 0;
}
int CmdHF14AMfCLoad(const char *Cmd) {
static int CmdHF14AMfCLoad(const char *Cmd) {
uint8_t buf8[16] = {0x00};
uint8_t fillFromEmulator = 0;
@ -2922,7 +2924,7 @@ int CmdHF14AMfCLoad(const char *Cmd) {
return 0;
}
int CmdHF14AMfCGetBlk(const char *Cmd) {
static int CmdHF14AMfCGetBlk(const char *Cmd) {
uint8_t data[16] = {0};
uint8_t blockNo = 0;
int res;
@ -2959,7 +2961,7 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
return 0;
}
int CmdHF14AMfCGetSc(const char *Cmd) {
static int CmdHF14AMfCGetSc(const char *Cmd) {
uint8_t data[16] = {0};
uint8_t sector = 0;
int i, res, flags;
@ -2998,7 +3000,7 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
return 0;
}
int CmdHF14AMfCSave(const char *Cmd) {
static int CmdHF14AMfCSave(const char *Cmd) {
char filename[FILE_PATH_SIZE];
char *fnameptr = filename;
@ -3101,7 +3103,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
}
//needs nt, ar, at, Data to decrypt
int CmdHf14AMfDecryptBytes(const char *Cmd) {
static int CmdHf14AMfDecryptBytes(const char *Cmd) {
char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_decryptbytes();
@ -3128,7 +3130,7 @@ int CmdHf14AMfDecryptBytes(const char *Cmd) {
return 0;
}
int CmdHf14AMfSetMod(const char *Cmd) {
static int CmdHf14AMfSetMod(const char *Cmd) {
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
uint8_t mod = 2;
@ -3165,7 +3167,7 @@ int CmdHf14AMfSetMod(const char *Cmd) {
}
// Mifare NACK bug detection
int CmdHf14AMfNack(const char *Cmd) {
static int CmdHf14AMfNack(const char *Cmd) {
bool verbose = false;
char ctmp = tolower(param_getchar(Cmd, 0));
@ -3179,7 +3181,7 @@ int CmdHf14AMfNack(const char *Cmd) {
return 0;
}
int CmdHF14AMfice(const char *Cmd) {
static int CmdHF14AMfice(const char *Cmd) {
uint8_t blockNo = 0;
uint8_t keyType = 0;
@ -3287,7 +3289,7 @@ out:
return 0;
}
int CmdHF14AMfAuth4(const char *Cmd) {
static int CmdHF14AMfAuth4(const char *Cmd) {
uint8_t keyn[20] = {0};
int keynlen = 0;
uint8_t key[16] = {0};
@ -3324,7 +3326,7 @@ int CmdHF14AMfAuth4(const char *Cmd) {
}
// https://www.nxp.com/docs/en/application-note/AN10787.pdf
int CmdHF14AMfMAD(const char *Cmd) {
static int CmdHF14AMfMAD(const char *Cmd) {
CLIParserInit("hf mf mad",
"Checks and prints Mifare Application Directory (MAD)",
@ -3414,7 +3416,7 @@ int CmdHF14AMfMAD(const char *Cmd) {
return 0;
}
int CmdHFMFNDEF(const char *Cmd) {
static int CmdHFMFNDEF(const char *Cmd) {
CLIParserInit("hf mf ndef",
"Prints NFC Data Exchange Format (NDEF)",
@ -3518,7 +3520,7 @@ int CmdHFMFNDEF(const char *Cmd) {
return 0;
}
int CmdHF14AMfList(const char *Cmd) {
static int CmdHF14AMfList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdTraceList("mf");
return 0;
@ -3569,14 +3571,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFMF(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}

View file

@ -33,40 +33,8 @@
#include "hardnested/hardnested_bf_core.h" // SetSIMDInstr
int CmdHFMF(const char *Cmd);
int CmdHF14AMfList(const char *Cmd);
int CmdHF14AMfDbg(const char *Cmd);
int CmdHF14AMfRdBl(const char *Cmd);
int CmdHF14AMfURdBl(const char *Cmd);
int CmdHF14AMfRdSc(const char *Cmd);
int CmdHF14SMfURdCard(const char *Cmd);
int CmdHF14AMfDump(const char *Cmd);
int CmdHF14AMfRestore(const char *Cmd);
int CmdHF14AMfWrBl(const char *Cmd);
int CmdHF14AMfUWrBl(const char *Cmd);
int CmdHF14AMfChk(const char *Cmd);
int CmdHF14AMfDarkside(const char *Cmd);
int CmdHF14AMfNested(const char *Cmd);
int CmdHF14AMfNestedHard(const char *Cmd);
//int CmdHF14AMfSniff(const char* Cmd);
int CmdHF14AMf1kSim(const char *Cmd);
int CmdHF14AMfKeyBrute(const char *Cmd);
int CmdHF14AMfEClear(const char *Cmd);
int CmdHF14AMfEGet(const char *Cmd);
int CmdHF14AMfESet(const char *Cmd);
int CmdHF14AMfELoad(const char *Cmd);
int CmdHF14AMfESave(const char *Cmd);
int CmdHF14AMfECFill(const char *Cmd);
int CmdHF14AMfEKeyPrn(const char *Cmd);
int CmdHF14AMfCSetUID(const char *Cmd);
int CmdHF14AMfCSetBlk(const char *Cmd);
int CmdHF14AMfCGetBlk(const char *Cmd);
int CmdHF14AMfCGetSc(const char *Cmd);
int CmdHF14AMfCLoad(const char *Cmd);
int CmdHF14AMfCSave(const char *Cmd);
int CmdHf14MfDecryptBytes(const char *Cmd);
int CmdHf14AMfSetMod(const char *Cmd);
int CmdHf14AMfNack(const char *Cmd);
int CmdHF14AMfELoad(const char *Cmd); // used by cmd hf mfu eload
int CmdHF14AMfDbg(const char *Cmd); // used by cmd hf mfu dbg
void showSectorTable(void);
void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose);

View file

@ -19,7 +19,7 @@ uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x
static int CmdHelp(const char *Cmd);
int CmdHF14ADesWb(const char *Cmd) {
static int CmdHF14ADesWb(const char *Cmd) {
/* uint8_t blockNo = 0;
uint8_t keyType = 0;
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
@ -67,7 +67,7 @@ int CmdHF14ADesWb(const char *Cmd) {
return 0;
}
int CmdHF14ADesRb(const char *Cmd) {
static int CmdHF14ADesRb(const char *Cmd) {
// uint8_t blockNo = 0;
// uint8_t keyType = 0;
// uint8_t key[6] = {0, 0, 0, 0, 0, 0};
@ -114,7 +114,7 @@ int CmdHF14ADesRb(const char *Cmd) {
return 0;
}
int CmdHF14ADesInfo(const char *Cmd) {
static int CmdHF14ADesInfo(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
UsbCommand c = {CMD_MIFARE_DESFIRE_INFO, {0, 0, 0}, {{0}}};
@ -152,21 +152,21 @@ int CmdHF14ADesInfo(const char *Cmd) {
PrintAndLogEx(NORMAL, " Vendor Id : %s", getTagInfo(resp.d.asBytes[7]));
PrintAndLogEx(NORMAL, " Type : 0x%02X", resp.d.asBytes[8]);
PrintAndLogEx(NORMAL, " Subtype : 0x%02X", resp.d.asBytes[9]);
PrintAndLogEx(NORMAL, " Version : %s", GetVersionStr(resp.d.asBytes[10], resp.d.asBytes[11]));
PrintAndLogEx(NORMAL, " Storage size : %s", GetCardSizeStr(resp.d.asBytes[12]));
PrintAndLogEx(NORMAL, " Protocol : %s", GetProtocolStr(resp.d.asBytes[13]));
PrintAndLogEx(NORMAL, " Version : %s", getVersionStr(resp.d.asBytes[10], resp.d.asBytes[11]));
PrintAndLogEx(NORMAL, " Storage size : %s", getCardSizeStr(resp.d.asBytes[12]));
PrintAndLogEx(NORMAL, " Protocol : %s", getProtocolStr(resp.d.asBytes[13]));
PrintAndLogEx(NORMAL, " -----------------------------------------------------------");
PrintAndLogEx(NORMAL, " Software Information");
PrintAndLogEx(NORMAL, " Vendor Id : %s", getTagInfo(resp.d.asBytes[14]));
PrintAndLogEx(NORMAL, " Type : 0x%02X", resp.d.asBytes[15]);
PrintAndLogEx(NORMAL, " Subtype : 0x%02X", resp.d.asBytes[16]);
PrintAndLogEx(NORMAL, " Version : %d.%d", resp.d.asBytes[17], resp.d.asBytes[18]);
PrintAndLogEx(NORMAL, " storage size : %s", GetCardSizeStr(resp.d.asBytes[19]));
PrintAndLogEx(NORMAL, " Protocol : %s", GetProtocolStr(resp.d.asBytes[20]));
PrintAndLogEx(NORMAL, " storage size : %s", getCardSizeStr(resp.d.asBytes[19]));
PrintAndLogEx(NORMAL, " Protocol : %s", getProtocolStr(resp.d.asBytes[20]));
PrintAndLogEx(NORMAL, "-------------------------------------------------------------");
// Master Key settings
GetKeySettings(NULL);
getKeySettings(NULL);
// Free memory on card
c.cmd = CMD_MIFARE_DESFIRE;
@ -207,7 +207,7 @@ int CmdHF14ADesInfo(const char *Cmd) {
and set to '1' if the storage size is between 2^n and 2^(n+1).
For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'.
*/
char *GetCardSizeStr(uint8_t fsize) {
char *getCardSizeStr(uint8_t fsize) {
static char buf[30] = {0x00};
char *retStr = buf;
@ -223,7 +223,7 @@ char *GetCardSizeStr(uint8_t fsize) {
return buf;
}
char *GetProtocolStr(uint8_t id) {
char *getProtocolStr(uint8_t id) {
static char buf[30] = {0x00};
char *retStr = buf;
@ -235,7 +235,7 @@ char *GetProtocolStr(uint8_t id) {
return buf;
}
char *GetVersionStr(uint8_t major, uint8_t minor) {
char *getVersionStr(uint8_t major, uint8_t minor) {
static char buf[30] = {0x00};
char *retStr = buf;
@ -251,7 +251,7 @@ char *GetVersionStr(uint8_t major, uint8_t minor) {
return buf;
}
void GetKeySettings(uint8_t *aid) {
void getKeySettings(uint8_t *aid) {
char messStr[512] = {0x00};
const char *str = messStr;
@ -421,7 +421,7 @@ void GetKeySettings(uint8_t *aid) {
}
}
int CmdHF14ADesEnumApplications(const char *Cmd) {
static int CmdHF14ADesEnumApplications(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
uint8_t isOK = 0x00;
@ -459,7 +459,7 @@ int CmdHF14ADesEnumApplications(const char *Cmd) {
aid[0] = resp.d.asBytes[i];
aid[1] = resp.d.asBytes[i + 1];
aid[2] = resp.d.asBytes[i + 2];
GetKeySettings(aid);
getKeySettings(aid);
// Select Application
c.arg[CMDPOS] = INIT;
@ -533,7 +533,7 @@ int CmdHF14ADesEnumApplications(const char *Cmd) {
// MIAFRE DesFire Authentication
//
#define BUFSIZE 256
int CmdHF14ADesAuth(const char *Cmd) {
static int CmdHF14ADesAuth(const char *Cmd) {
// NR DESC KEYLENGHT
// ------------------------
@ -651,6 +651,12 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFMFDes(const char *Cmd) {
// flush
clearCommandBuffer();
@ -658,10 +664,3 @@ int CmdHFMFDes(const char *Cmd) {
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}

View file

@ -25,16 +25,11 @@
#include "mbedtls/des.h"
int CmdHFMFDes(const char *Cmd);
int CmdHF14ADesAuth(const char *Cmd);
int CmdHF14ADesRb(const char *Cmd);
int CmdHF14ADesWb(const char *Cmd);
int CmdHF14ADesInfo(const char *Cmd);
int CmdHF14ADesEnumApplications(const char *Cmd);
char *GetCardSizeStr(uint8_t fsize);
char *GetProtocolStr(uint8_t id);
char *GetVersionStr(uint8_t major, uint8_t minor);
void GetKeySettings(uint8_t *aid);
char *getCardSizeStr(uint8_t fsize);
char *getProtocolStr(uint8_t id);
char *getVersionStr(uint8_t major, uint8_t minor);
void getKeySettings(uint8_t *aid);
// Command options for Desfire behavior.
enum {

View file

@ -26,7 +26,7 @@ static int CmdHelp(const char *Cmd);
//n'r=rol(r5)
//verify n'r=nr
int CmdHF14AMfDESAuth(const char *Cmd) {
static int CmdHF14AMfDESAuth(const char *Cmd) {
uint8_t blockNo = 0;
//keyNo=0;
@ -119,7 +119,7 @@ int CmdHF14AMfDESAuth(const char *Cmd) {
// Card 2 Reader : 02AF, 16 Bytes(b0), CRC1 CRC2
// Reader 2 Card : 03AF, 16 Bytes(b1),16Bytes(b2) CRC1 CRC2
// Card 2 Reader : 0300, 16 bytes(b3), CRC1 CRC2 ; success
int CmdHF14AMfAESAuth(const char *Cmd) {
static int CmdHF14AMfAESAuth(const char *Cmd) {
uint8_t blockNo = 0;
//keyNo=0;
@ -233,14 +233,14 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
}
int CmdHFMFDesfire(const char *Cmd) {
// flush
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
}

View file

@ -6,8 +6,6 @@
#include "mbedtls/des.h"
#include "mbedtls/aes.h"
int CmdHF14AMfDESAuth(const char *Cmd);
int CmdHFMFDesfire(const char *Cmd);
int CmdHelp(const char *Cmd);
#endif

View file

@ -33,13 +33,13 @@ static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
static int CmdHelp(const char *Cmd);
int CmdHFMFPInfo(const char *cmd) {
static int CmdHFMFPInfo(const char *cmd) {
if (cmd && strlen(cmd) > 0)
PrintAndLogEx(WARNING, "command don't have any parameters.\n");
// info about 14a part
CmdHF14AInfo("");
infoHF14A(false, false);
// Mifare Plus info
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}, {{0}}};
@ -112,7 +112,7 @@ int CmdHFMFPInfo(const char *cmd) {
return 0;
}
int CmdHFMFPWritePerso(const char *cmd) {
static int CmdHFMFPWritePerso(const char *cmd) {
uint8_t keyNum[64] = {0};
int keyNumLen = 0;
uint8_t key[64] = {0};
@ -178,7 +178,7 @@ int CmdHFMFPWritePerso(const char *cmd) {
uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001};
int CmdHFMFPInitPerso(const char *cmd) {
static int CmdHFMFPInitPerso(const char *cmd) {
int res;
uint8_t key[256] = {0};
int keyLen = 0;
@ -252,7 +252,7 @@ int CmdHFMFPInitPerso(const char *cmd) {
return 0;
}
int CmdHFMFPCommitPerso(const char *cmd) {
static int CmdHFMFPCommitPerso(const char *cmd) {
CLIParserInit("hf mfp commitp",
"Executes Commit Perso command. Can be used in SL0 mode only.",
"Usage:\n\thf mfp commitp -> \n");
@ -293,7 +293,7 @@ int CmdHFMFPCommitPerso(const char *cmd) {
return 0;
}
int CmdHFMFPAuth(const char *cmd) {
static int CmdHFMFPAuth(const char *cmd) {
uint8_t keyn[250] = {0};
int keynlen = 0;
uint8_t key[250] = {0};
@ -331,7 +331,7 @@ int CmdHFMFPAuth(const char *cmd) {
return MifareAuth4(NULL, keyn, key, true, false, verbose);
}
int CmdHFMFPRdbl(const char *cmd) {
static int CmdHFMFPRdbl(const char *cmd) {
uint8_t keyn[2] = {0};
uint8_t key[250] = {0};
int keylen = 0;
@ -443,7 +443,7 @@ int CmdHFMFPRdbl(const char *cmd) {
return 0;
}
int CmdHFMFPRdsc(const char *cmd) {
static int CmdHFMFPRdsc(const char *cmd) {
uint8_t keyn[2] = {0};
uint8_t key[250] = {0};
int keylen = 0;
@ -539,7 +539,7 @@ int CmdHFMFPRdsc(const char *cmd) {
return 0;
}
int CmdHFMFPWrbl(const char *cmd) {
static int CmdHFMFPWrbl(const char *cmd) {
uint8_t keyn[2] = {0};
uint8_t key[250] = {0};
int keylen = 0;
@ -641,7 +641,7 @@ int CmdHFMFPWrbl(const char *cmd) {
return 0;
}
int CmdHFMFPMAD(const char *cmd) {
static int CmdHFMFPMAD(const char *cmd) {
CLIParserInit("hf mfp mad",
"Checks and prints Mifare Application Directory (MAD)",
@ -735,7 +735,7 @@ int CmdHFMFPMAD(const char *cmd) {
return 0;
}
int CmdHFMFPNDEF(const char *cmd) {
static int CmdHFMFPNDEF(const char *cmd) {
CLIParserInit("hf mfp ndef",
"Prints NFC Data Exchange Format (NDEF)",
@ -854,14 +854,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFMFP(const char *Cmd) {
(void)WaitForResponseTimeout(CMD_ACK, NULL, 100);
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}

View file

@ -1117,7 +1117,7 @@ uint32_t GetHF14AMfU_Type(void) {
//
// extended tag information
//
int CmdHF14AMfUInfo(const char *Cmd) {
static int CmdHF14AMfUInfo(const char *Cmd) {
uint8_t authlim = 0xff;
uint8_t data[16] = {0x00};
@ -1223,7 +1223,7 @@ int CmdHF14AMfUInfo(const char *Cmd) {
// if we called info with key, just return
if (hasAuthKey) return 1;
// also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys
// also try to diversify default keys.. look into CmdHF14AMfGenDiverseKeys
PrintAndLogEx(INFO, "Trying some default 3des keys");
for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i) {
key = default_3des_keys[i];
@ -1380,7 +1380,7 @@ out:
//
// Write Single Block
//
int CmdHF14AMfUWrBl(const char *Cmd) {
static int CmdHF14AMfUWrBl(const char *Cmd) {
int blockNo = -1;
bool errors = false;
@ -1501,7 +1501,7 @@ int CmdHF14AMfUWrBl(const char *Cmd) {
//
// Read Single Block
//
int CmdHF14AMfURdBl(const char *Cmd) {
static int CmdHF14AMfURdBl(const char *Cmd) {
int blockNo = -1;
bool errors = false;
@ -1759,7 +1759,7 @@ void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage) {
//
// Mifare Ultralight / Ultralight-C / Ultralight-EV1
// Read and Dump Card Contents, using auto detection of tag size.
int CmdHF14AMfUDump(const char *Cmd) {
static int CmdHF14AMfUDump(const char *Cmd) {
uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0x00};
@ -1995,7 +1995,7 @@ static void wait4response(uint8_t b) {
//
// Restore dump file onto tag
//
int CmdHF14AMfURestore(const char *Cmd) {
static int CmdHF14AMfURestore(const char *Cmd) {
char tempStr[50] = {0};
char filename[FILE_PATH_SIZE] = {0};
@ -2227,7 +2227,7 @@ int CmdHF14AMfURestore(const char *Cmd) {
//
// Load emulator with dump file
//
int CmdHF14AMfUeLoad(const char *Cmd) {
static int CmdHF14AMfUeLoad(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_mfu_eload();
return CmdHF14AMfELoad(Cmd);
@ -2235,7 +2235,7 @@ int CmdHF14AMfUeLoad(const char *Cmd) {
//
// Simulate tag
//
int CmdHF14AMfUSim(const char *Cmd) {
static int CmdHF14AMfUSim(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_mfu_sim();
return CmdHF14ASim(Cmd);
@ -2248,7 +2248,7 @@ int CmdHF14AMfUSim(const char *Cmd) {
//
// Ultralight C Authentication Demo {currently uses hard-coded key}
//
int CmdHF14AMfucAuth(const char *Cmd) {
static int CmdHF14AMfUCAuth(const char *Cmd) {
uint8_t keyNo = 3;
bool errors = false;
@ -2280,7 +2280,7 @@ A test function to validate that the polarssl-function works the same
was as the openssl-implementation.
Commented out, since it requires openssl
int CmdTestDES(const char * cmd)
static int CmdTestDES(const char * cmd)
{
uint8_t key[16] = {0x00};
@ -2375,7 +2375,7 @@ int CmdTestDES(const char * cmd)
//
// Mifare Ultralight C - Set password
//
int CmdHF14AMfucSetPwd(const char *Cmd) {
static int CmdHF14AMfUCSetPwd(const char *Cmd) {
uint8_t pwd[16] = {0x00};
char cmdp = tolower(param_getchar(Cmd, 0));
@ -2410,7 +2410,7 @@ int CmdHF14AMfucSetPwd(const char *Cmd) {
//
// Magic UL / UL-C tags - Set UID
//
int CmdHF14AMfucSetUid(const char *Cmd) {
static int CmdHF14AMfUCSetUid(const char *Cmd) {
UsbCommand c = {CMD_MIFAREU_READBL, {0, 0, 0}, {{0}}};
UsbCommand resp;
@ -2479,7 +2479,7 @@ int CmdHF14AMfucSetUid(const char *Cmd) {
return 0;
}
int CmdHF14AMfuGenDiverseKeys(const char *Cmd) {
static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
uint8_t uid[4];
char cmdp = tolower(param_getchar(Cmd, 0));
@ -2592,7 +2592,7 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd) {
return 0;
}
int CmdHF14AMfuPwdGen(const char *Cmd) {
static int CmdHF14AMfUPwdGen(const char *Cmd) {
uint8_t uid[7] = {0x00};
char cmdp = tolower(param_getchar(Cmd, 0));
@ -2654,23 +2654,24 @@ static command_t CommandTable[] = {
{"eload", CmdHF14AMfUeLoad, 0, "load Ultralight .eml dump file into emulator memory"},
{"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
{"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
{"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
{"setpwd", CmdHF14AMfucSetPwd, 0, "Set 3des password - Ultralight-C"},
{"setuid", CmdHF14AMfucSetUid, 0, "Set UID - MAGIC tags only"},
{"cauth", CmdHF14AMfUCAuth, 0, "Authentication - Ultralight C"},
{"setpwd", CmdHF14AMfUCSetPwd, 0, "Set 3des password - Ultralight-C"},
{"setuid", CmdHF14AMfUCSetUid, 0, "Set UID - MAGIC tags only"},
{"sim", CmdHF14AMfUSim, 0, "Simulate Ultralight from emulator memory"},
{"gen", CmdHF14AMfuGenDiverseKeys, 1, "Generate 3des mifare diversified keys"},
{"pwdgen", CmdHF14AMfuPwdGen, 1, "Generate pwd from known algos"},
{"gen", CmdHF14AMfUGenDiverseKeys, 1, "Generate 3des mifare diversified keys"},
{"pwdgen", CmdHF14AMfUPwdGen, 1, "Generate pwd from known algos"},
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFMFUltra(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}

View file

@ -25,23 +25,6 @@ typedef struct {
uint8_t data[1024];
} mfu_dump_t;
int CmdHF14AMfUWrBl(const char *Cmd);
int CmdHF14AMfURdBl(const char *Cmd);
//Crypto Cards
int CmdHF14AMfucAuth(const char *Cmd);
int CmdHF14AMfucSetPwd(const char *Cmd);
int CmdHF14AMfucSetUid(const char *Cmd);
int CmdHF14AMfuGenDiverseKeys(const char *Cmd);
int CmdHF14AMfuPwdGen(const char *Cmd);
//general stuff
int CmdHF14AMfUDump(const char *Cmd);
int CmdHF14AMfURestore(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd);
int CmdHF14AMfUeLoad(const char *Cmd);
int CmdHF14AMfUSim(const char *Cmd);
uint32_t GetHF14AMfU_Type(void);
int ul_print_type(uint32_t tagtype, uint8_t spaces);

View file

@ -371,7 +371,7 @@ static void topaz_print_NDEF(uint8_t *data) {
}
// read a Topaz tag and print some useful information
int CmdHFTopazReader(const char *Cmd) {
static int CmdHFTopazReader(const char *Cmd) {
int status;
uint8_t atqa[2];
uint8_t rid_response[8];
@ -487,19 +487,19 @@ int CmdHFTopazReader(const char *Cmd) {
return 0;
}
int CmdHFTopazSim(const char *Cmd) {
static int CmdHFTopazSim(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
PrintAndLogEx(NORMAL, "not yet implemented");
return 0;
}
int CmdHFTopazCmdRaw(const char *Cmd) {
static int CmdHFTopazCmdRaw(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
PrintAndLogEx(NORMAL, "not yet implemented. Use hf 14 raw with option -T.");
return 0;
}
int CmdHFTopazList(const char *Cmd) {
static int CmdHFTopazList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdTraceList("topaz");
return 0;
@ -517,16 +517,18 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHFTopaz(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHFTopaz(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int readTopazUid(void) {
return CmdHFTopazReader("s");
}

View file

@ -26,9 +26,6 @@
#include "cmdhf.h"
int CmdHFTopaz(const char *Cmd);
int CmdHFTopazReader(const char *Cmd);
int CmdHFTopazSim(const char *Cmd);
int CmdHFTopazCmdRaw(const char *Cmd);
int CmdHFTopazList(const char *Cmd);
int readTopazUid(void);
#endif

View file

@ -42,7 +42,7 @@ static int usage_lf_nedap_sim(void) {
//NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream)
//print NEDAP Prox ID, encoding, encrypted ID,
int CmdLFNedapDemod(const char *Cmd) {
static int CmdLFNedapDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//raw ask demod no start bit finding just get binary from wave
if (!ASKbiphaseDemod("0 64 1 0", false)) {
@ -162,12 +162,12 @@ lf t55xx wr b 4 d 4c0003ff
*/
int CmdLFNedapRead(const char *Cmd) {
static int CmdLFNedapRead(const char *Cmd) {
lf_read(true, 12000);
return CmdLFNedapDemod(Cmd);
}
/*
int CmdLFNedapClone(const char *Cmd) {
static int CmdLFNedapClone(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_nedap_clone();
@ -219,7 +219,7 @@ int CmdLFNedapClone(const char *Cmd) {
}
*/
int CmdLFNedapSim(const char *Cmd) {
static int CmdLFNedapSim(const char *Cmd) {
uint32_t cardnumber = 0, cn = 0;
@ -255,7 +255,7 @@ int CmdLFNedapSim(const char *Cmd) {
return 0;
}
int CmdLFNedapChk(const char *Cmd) {
static int CmdLFNedapChk(const char *Cmd) {
//301600714021BE
uint8_t data[256] = { 0x30, 0x16, 0x00, 0x71, 0x40, 0x21, 0xBE};
int len = 0;
@ -312,15 +312,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFNedap(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
int CmdLFNedap(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}

View file

@ -54,7 +54,7 @@ void PrintChannel(EMVCommandChannel channel) {
}
}
int CmdEMVSelect(const char *Cmd) {
static int CmdEMVSelect(const char *Cmd) {
uint8_t data[APDU_AID_LEN] = {0};
int datalen = 0;
@ -105,7 +105,7 @@ int CmdEMVSelect(const char *Cmd) {
return 0;
}
int CmdEMVSearch(const char *Cmd) {
static int CmdEMVSearch(const char *Cmd) {
CLIParserInit("emv search",
"Tries to select all applets from applet list:\n",
@ -155,7 +155,7 @@ int CmdEMVSearch(const char *Cmd) {
return 0;
}
int CmdEMVPPSE(const char *Cmd) {
static int CmdEMVPPSE(const char *Cmd) {
CLIParserInit("emv pse",
"Executes PSE/PPSE select command. It returns list of applet on the card:\n",
@ -210,7 +210,7 @@ int CmdEMVPPSE(const char *Cmd) {
return 0;
}
int CmdEMVGPO(const char *Cmd) {
static int CmdEMVGPO(const char *Cmd) {
uint8_t data[APDU_RES_LEN] = {0};
int datalen = 0;
@ -317,7 +317,7 @@ int CmdEMVGPO(const char *Cmd) {
return 0;
}
int CmdEMVReadRecord(const char *Cmd) {
static int CmdEMVReadRecord(const char *Cmd) {
uint8_t data[APDU_RES_LEN] = {0};
int datalen = 0;
@ -372,7 +372,7 @@ int CmdEMVReadRecord(const char *Cmd) {
return 0;
}
int CmdEMVAC(const char *Cmd) {
static int CmdEMVAC(const char *Cmd) {
uint8_t data[APDU_RES_LEN] = {0};
int datalen = 0;
@ -493,7 +493,7 @@ int CmdEMVAC(const char *Cmd) {
return 0;
}
int CmdEMVGenerateChallenge(const char *Cmd) {
static int CmdEMVGenerateChallenge(const char *Cmd) {
CLIParserInit("emv challenge",
"Executes Generate Challenge command. It returns 4 or 8-byte random number from card.\nNeeds a EMV applet to be selected and GPO to be executed.",
@ -538,7 +538,7 @@ int CmdEMVGenerateChallenge(const char *Cmd) {
return 0;
}
int CmdEMVInternalAuthenticate(const char *Cmd) {
static int CmdEMVInternalAuthenticate(const char *Cmd) {
uint8_t data[APDU_RES_LEN] = {0};
int datalen = 0;
@ -749,7 +749,7 @@ void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, b
}
}
int CmdEMVExec(const char *Cmd) {
static int CmdEMVExec(const char *Cmd) {
uint8_t buf[APDU_RES_LEN] = {0};
size_t len = 0;
uint16_t sw = 0;
@ -1346,7 +1346,7 @@ int CmdEMVExec(const char *Cmd) {
return 0;
}
int CmdEMVScan(const char *Cmd) {
static int CmdEMVScan(const char *Cmd) {
uint8_t AID[APDU_AID_LEN] = {0};
size_t AIDlen = 0;
uint8_t buf[APDU_RES_LEN] = {0};
@ -1700,17 +1700,17 @@ int CmdEMVScan(const char *Cmd) {
return 0;
}
int CmdEMVList(const char *Cmd) {
static int CmdEMVList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return CmdTraceList("7816");
}
int CmdEMVTest(const char *Cmd) {
static int CmdEMVTest(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return ExecuteCryptoTests(true);
}
int CmdEMVRoca(const char *Cmd) {
static int CmdEMVRoca(const char *Cmd) {
uint8_t AID[APDU_AID_LEN] = {0};
size_t AIDlen = 0;
uint8_t buf[APDU_RES_LEN] = {0};
@ -1966,13 +1966,14 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
}
int CmdEMV(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
}

View file

@ -29,12 +29,4 @@
int CmdEMV(const char *Cmd);
int CmdEMVSelect(const char *Cmd);
int CmdEMVSearch(const char *Cmd);
int CmdEMVPPSE(const char *Cmd);
int CmdEMVExec(const char *Cmd);
int CmdEMVGetrng(const char *Cmd);
int CmdEMVList(const char *Cmd);
int CmdEMVRoca(const char *Cmd);
#endif