mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
hf 14a config: better options
This commit is contained in:
parent
289f1c234c
commit
2fc36d73c9
3 changed files with 106 additions and 52 deletions
|
@ -124,8 +124,8 @@ static uint32_t LastProxToAirDuration;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Default HF 14a config is set to:
|
Default HF 14a config is set to:
|
||||||
forceanticol = false
|
forceanticol = 0 (auto)
|
||||||
obeybadbcc = false
|
forcebcc = 0 (expect valid BCC)
|
||||||
forcecl2 = 0 (auto)
|
forcecl2 = 0 (auto)
|
||||||
forcecl3 = 0 (auto)
|
forcecl3 = 0 (auto)
|
||||||
*/
|
*/
|
||||||
|
@ -133,10 +133,10 @@ static hf14a_config hf14aconfig = { 0, 0, 0, 0 } ;
|
||||||
|
|
||||||
void printHf14aConfig(void) {
|
void printHf14aConfig(void) {
|
||||||
DbpString(_CYAN_("HF 14a config"));
|
DbpString(_CYAN_("HF 14a config"));
|
||||||
Dbprintf("[a] Force std anticol.....%s", (hf14aconfig.forceanticol) ? _RED_("Yes") " (even if bad ATQA)" : _GREEN_("No"));
|
Dbprintf("[a] Anticol override......%s%s%s", (hf14aconfig.forceanticol==0) ? _GREEN_("No") " (follow standard)" : "", (hf14aconfig.forceanticol==1) ? _RED_("Yes: Always do anticol") : "", (hf14aconfig.forceanticol==2) ? _RED_("Yes: Always skip anticol") : "");
|
||||||
Dbprintf("[b] Force obey bad BCC....%s", (hf14aconfig.obeybadbcc) ? _RED_("Yes") : _GREEN_("No"));
|
Dbprintf("[b] BCC override..........%s%s%s", (hf14aconfig.forcebcc==0) ? _GREEN_("No") " (follow standard)" : "", (hf14aconfig.forcebcc==1) ? _RED_("Yes: Always do CL2") : "", (hf14aconfig.forcebcc==2) ? _RED_("Yes: Always use card BCC") : "");
|
||||||
Dbprintf("[2] Force CL2 override ...%s%s%s", (hf14aconfig.forcecl2==0) ? _GREEN_("No") : "", (hf14aconfig.forcecl2==1) ? _RED_("Yes: Always do CL2") : "", (hf14aconfig.forcecl2==-1) ? _RED_("Yes: Always skip CL2") : "");
|
Dbprintf("[2] CL2 override..........%s%s%s", (hf14aconfig.forcecl2==0) ? _GREEN_("No") " (follow standard)" : "", (hf14aconfig.forcecl2==1) ? _RED_("Yes: Always do CL2") : "", (hf14aconfig.forcecl2==2) ? _RED_("Yes: Always skip CL2") : "");
|
||||||
Dbprintf("[3] Force CL3 override ...%s%s%s", (hf14aconfig.forcecl3==0) ? _GREEN_("No") : "", (hf14aconfig.forcecl3==1) ? _RED_("Yes: Always do CL3") : "", (hf14aconfig.forcecl3==-1) ? _RED_("Yes: Always skip CL3") : "");
|
Dbprintf("[3] CL3 override..........%s%s%s", (hf14aconfig.forcecl3==0) ? _GREEN_("No") " (follow standard)" : "", (hf14aconfig.forcecl3==1) ? _RED_("Yes: Always do CL3") : "", (hf14aconfig.forcecl3==2) ? _RED_("Yes: Always skip CL3") : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,13 +149,13 @@ void printHf14aConfig(void) {
|
||||||
*/
|
*/
|
||||||
void setHf14aConfig(hf14a_config *hc) {
|
void setHf14aConfig(hf14a_config *hc) {
|
||||||
|
|
||||||
if (hc->forceanticol > -1)
|
if ((hc->forceanticol >= 0) && (hc->forceanticol <= 2))
|
||||||
hf14aconfig.forceanticol = (hc->forceanticol > 0) ? 1 : 0;
|
hf14aconfig.forceanticol = hc->forceanticol;
|
||||||
if (hc->obeybadbcc > -1)
|
if ((hc->forcebcc >= 0) && (hc->forcebcc <= 2))
|
||||||
hf14aconfig.obeybadbcc = (hc->obeybadbcc > 0) ? 1 : 0;
|
hf14aconfig.forcebcc = hc->forcebcc;
|
||||||
if ((hc->forcecl2 >= -1) && (hc->forcecl2 <= 1))
|
if ((hc->forcecl2 >= 0) && (hc->forcecl2 <= 2))
|
||||||
hf14aconfig.forcecl2 = hc->forcecl2;
|
hf14aconfig.forcecl2 = hc->forcecl2;
|
||||||
if ((hc->forcecl3 >= -1) && (hc->forcecl3 <= 1))
|
if ((hc->forcecl3 >= 0) && (hc->forcecl3 <= 2))
|
||||||
hf14aconfig.forcecl3 = hc->forcecl3;
|
hf14aconfig.forcecl3 = hc->forcecl3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2401,10 +2401,12 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
|
||||||
memset(uid_ptr, 0, 10);
|
memset(uid_ptr, 0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! hf14aconfig.forceanticol ) {
|
if ( hf14aconfig.forceanticol == 0 ) {
|
||||||
// check for proprietary anticollision:
|
// check for proprietary anticollision:
|
||||||
if ((resp[0] & 0x1F) == 0) return 3;
|
if ((resp[0] & 0x1F) == 0) return 3;
|
||||||
}
|
} else if ( hf14aconfig.forceanticol == 2 ) {
|
||||||
|
return 3; // force skipping anticol
|
||||||
|
} // else force executing
|
||||||
|
|
||||||
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
|
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
|
||||||
// which case we need to make a cascade 2 request and select - this is a long UID
|
// which case we need to make a cascade 2 request and select - this is a long UID
|
||||||
|
@ -2419,8 +2421,10 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
|
||||||
if (anticollision) {
|
if (anticollision) {
|
||||||
// SELECT_ALL
|
// SELECT_ALL
|
||||||
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
|
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
|
||||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
if (!ReaderReceive(resp, resp_par)) {
|
||||||
|
Dbprintf("Card didn't answer to CL%i select all", cascade_level + 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit
|
if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit
|
||||||
memset(uid_resp, 0, 5);
|
memset(uid_resp, 0, 5);
|
||||||
uint16_t uid_resp_bits = 0;
|
uint16_t uid_resp_bits = 0;
|
||||||
|
@ -2474,11 +2478,14 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
|
||||||
memcpy(sel_uid + 2, uid_resp, 5); // the UID received during anticollision with original BCC
|
memcpy(sel_uid + 2, uid_resp, 5); // the UID received during anticollision with original BCC
|
||||||
uint8_t bcc = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate BCC
|
uint8_t bcc = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate BCC
|
||||||
if (sel_uid[6] != bcc) {
|
if (sel_uid[6] != bcc) {
|
||||||
Dbprintf("BCC%d incorrect, got 0x%02x, expected 0x%02x. Will use " NOLF, cascade_level, sel_uid[6], bcc);
|
Dbprintf("BCC%d incorrect, got 0x%02x, expected 0x%02x", cascade_level, sel_uid[6], bcc);
|
||||||
if (! hf14aconfig.obeybadbcc) {
|
if (hf14aconfig.forcebcc==0) {
|
||||||
|
Dbprintf("Aborting");
|
||||||
|
return 0;
|
||||||
|
} else if (hf14aconfig.forcebcc==1) {
|
||||||
sel_uid[6] = bcc;
|
sel_uid[6] = bcc;
|
||||||
}
|
} // else use card BCC
|
||||||
Dbprintf("0x%02x", sel_uid[6]);
|
Dbprintf("Using BCC=" _YELLOW_("0x%02x") " to perform anticollision", sel_uid[6]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memcpy(sel_uid + 2, uid_resp, 4); // the provided UID
|
memcpy(sel_uid + 2, uid_resp, 4); // the provided UID
|
||||||
|
@ -2489,20 +2496,22 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
|
||||||
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
|
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
|
||||||
|
|
||||||
// Receive the SAK
|
// Receive the SAK
|
||||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
if (!ReaderReceive(resp, resp_par)) {
|
||||||
|
Dbprintf("Card didn't answer to select");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
sak = resp[0];
|
sak = resp[0];
|
||||||
|
|
||||||
// Test if more parts of the uid are coming
|
// Test if more parts of the uid are coming
|
||||||
do_cascade = (((sak & 0x04) /* && uid_resp[0] == 0x88 */) > 0);
|
do_cascade = (((sak & 0x04) /* && uid_resp[0] == 0x88 */) > 0);
|
||||||
if (cascade_level==0) {
|
if (cascade_level==0) {
|
||||||
if (hf14aconfig.forcecl2==-1) {
|
if (hf14aconfig.forcecl2==2) {
|
||||||
do_cascade = false;
|
do_cascade = false;
|
||||||
} else if (hf14aconfig.forcecl2==1) {
|
} else if (hf14aconfig.forcecl2==1) {
|
||||||
do_cascade = true;
|
do_cascade = true;
|
||||||
} // else 0==auto
|
} // else 0==auto
|
||||||
} else if (cascade_level==1) {
|
} else if (cascade_level==1) {
|
||||||
if (hf14aconfig.forcecl3==-1) {
|
if (hf14aconfig.forcecl3==2) {
|
||||||
do_cascade = false;
|
do_cascade = false;
|
||||||
} else if (hf14aconfig.forcecl3==1) {
|
} else if (hf14aconfig.forcecl3==1) {
|
||||||
do_cascade = true;
|
do_cascade = true;
|
||||||
|
|
|
@ -169,19 +169,19 @@ static uint16_t frameLength = 0;
|
||||||
uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
|
uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
|
||||||
|
|
||||||
static int usage_hf_14a_config(void) {
|
static int usage_hf_14a_config(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf 14a config [a 0|1] [b 0|1]");
|
PrintAndLogEx(NORMAL, "Usage: hf 14a config [a 0|1|2] [b 0|1|2] [2 0|1|2] [3 0|1|2]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h This help");
|
PrintAndLogEx(NORMAL, " h This help");
|
||||||
PrintAndLogEx(NORMAL, " a 0|1 Force standard anticollision sequence even if ATQA tells not to do it");
|
PrintAndLogEx(NORMAL, " a 0|1|2 ATQA<>anticollision: 0=follow standard 1=execute anticol 2=skip anticol");
|
||||||
PrintAndLogEx(NORMAL, " b 0|1 Obey bad BCC in anticollision sequence");
|
PrintAndLogEx(NORMAL, " b 0|1|2 BCC: 0=follow standard 1=use fixed BCC 2=use card BCC");
|
||||||
PrintAndLogEx(NORMAL, " 2 0|1|-1 Override CL2 decision: 0=auto, 1=always perform CL2, -1=never perform CL2");
|
PrintAndLogEx(NORMAL, " 2 0|1|2 SAK<>CL2: 0=follow standard 1=execute CL2 2=skip CL2");
|
||||||
PrintAndLogEx(NORMAL, " 3 0|1|-1 Override CL3 decision: 0=auto, 1=always perform CL3, -1=never perform CL3");
|
PrintAndLogEx(NORMAL, " 3 0|1|2 SAK<>CL3: 0=follow standard 1=execute CL3 2=skip CL3");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config ")" Print current configuration");
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config ")" Print current configuration");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a ")" Force standard anticollision");
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 1 ")" Force execution of anticollision");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 ")" Restore ATQA interpretation");
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 ")" Restore ATQA interpretation");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b ")" Force obey bad BCC in anticollision");
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b 1 ")" Force fix of bad BCC in anticollision");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b 0 ")" Restore BCC computation in anticollision");
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b 0 ")" Restore BCC check");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,41 +292,86 @@ static int CmdHf14AConfig(const char *Cmd) {
|
||||||
|
|
||||||
hf14a_config config = {
|
hf14a_config config = {
|
||||||
.forceanticol = -1,
|
.forceanticol = -1,
|
||||||
.obeybadbcc = -1,
|
.forcebcc = -1,
|
||||||
.forcecl2 = -2,
|
.forcecl2 = -1,
|
||||||
.forcecl3 = -2
|
.forcecl3 = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
char cl[3] = {0};
|
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (param_getchar(Cmd, cmdp)) {
|
switch (param_getchar(Cmd, cmdp)) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return usage_hf_14a_config();
|
return usage_hf_14a_config();
|
||||||
case 'a':
|
case 'a':
|
||||||
config.forceanticol = (param_getchar(Cmd, cmdp + 1) == '1');
|
switch (param_getchar(Cmd, cmdp + 1)) {
|
||||||
|
case '0':
|
||||||
|
config.forceanticol = 0;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
config.forceanticol = 1;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
config.forceanticol = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
|
||||||
|
errors = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
config.obeybadbcc = (param_getchar(Cmd, cmdp + 1) == '1');
|
switch (param_getchar(Cmd, cmdp + 1)) {
|
||||||
|
case '0':
|
||||||
|
config.forcebcc = 0;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
config.forcebcc = 1;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
config.forcebcc = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
|
||||||
|
errors = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
param_getstr(Cmd, cmdp + 1, cl, sizeof(cl));
|
switch (param_getchar(Cmd, cmdp + 1)) {
|
||||||
if (strcmp(cl, "-1") == 0) {
|
case '0':
|
||||||
config.forcecl2 = -1;
|
config.forcecl2 = 0;
|
||||||
} else {
|
break;
|
||||||
config.forcecl2 = strcmp(cl, "1") == 0;
|
case '1':
|
||||||
|
config.forcecl2 = 1;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
config.forcecl2 = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
|
||||||
|
errors = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case '3':
|
case '3':
|
||||||
param_getstr(Cmd, cmdp + 1, cl, sizeof(cl));
|
switch (param_getchar(Cmd, cmdp + 1)) {
|
||||||
if (strcmp(cl, "-1") == 0) {
|
case '0':
|
||||||
config.forcecl3 = -1;
|
config.forcecl3 = 0;
|
||||||
} else {
|
break;
|
||||||
config.forcecl3 = strcmp(cl, "1") == 0;
|
case '1':
|
||||||
|
config.forcecl3 = 1;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
config.forcecl3 = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
|
||||||
|
errors = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -124,10 +124,10 @@ typedef struct {
|
||||||
|
|
||||||
// A struct used to send hf14a-configs over USB
|
// A struct used to send hf14a-configs over USB
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t forceanticol; // bool but also -1 if to be ignored
|
int8_t forceanticol; // 0:auto 1:force executing anticol 2:force skipping anticol
|
||||||
int8_t obeybadbcc; // bool but also -1 if to be ignored
|
int8_t forcebcc; // 0:expect valid BCC 1:force using computed BCC 2:force using card BCC
|
||||||
int8_t forcecl2; // 0:auto 1:force executing CL2 -1:force skipping CL2
|
int8_t forcecl2; // 0:auto 1:force executing CL2 2:force skipping CL2
|
||||||
int8_t forcecl3; // 0:auto 1:force executing CL3 -1:force skipping CL3
|
int8_t forcecl3; // 0:auto 1:force executing CL3 2:force skipping CL3
|
||||||
} PACKED hf14a_config;
|
} PACKED hf14a_config;
|
||||||
|
|
||||||
// Tracelog Header struct
|
// Tracelog Header struct
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue