mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 15:26:13 +08:00
Rework Cmd exposed API, use more static and fix [-Wmissing-prototypes]
This commit is contained in:
parent
65305f361f
commit
05374fce07
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
864
client/cmdhf15.c
864
client/cmdhf15.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -26,7 +26,5 @@
|
|||
|
||||
|
||||
int CmdHFEPA(const char *Cmd);
|
||||
int CmdHFEPACollectPACENonces(const char *Cmd);
|
||||
int CmdHFEPAPACEReplay(const char *Cmd);
|
||||
|
||||
#endif // CMDHFEPA_H__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue