mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-01-06 16:27:22 +08:00
allowing user timeouts in 14b apdus
This commit is contained in:
parent
ef7a6bb166
commit
ffb1b662ac
4 changed files with 31 additions and 15 deletions
|
@ -1400,7 +1400,9 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void
|
|||
CodeAndTransmit14443bAsReader(real_cmd, msg_len + 3, &start_time, &eof_time);
|
||||
|
||||
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
|
||||
int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
|
||||
|
||||
// int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
|
||||
int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, iso14b_timeout, &eof_time);
|
||||
FpgaDisableTracing();
|
||||
|
||||
uint8_t *data_bytes = (uint8_t *) rxdata;
|
||||
|
|
|
@ -1415,7 +1415,7 @@ static int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) {
|
||||
static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout, int user_timeout) {
|
||||
*chainingout = false;
|
||||
|
||||
if (activateField) {
|
||||
|
@ -1430,13 +1430,24 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool
|
|||
if (chainingin)
|
||||
flags = ISO14B_SEND_CHAINING;
|
||||
|
||||
uint32_t time_wait = 0;
|
||||
if (user_timeout > 0) {
|
||||
#define MAX_14B_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
|
||||
flags |= ISO14B_SET_TIMEOUT;
|
||||
if (user_timeout > MAX_14B_TIMEOUT) {
|
||||
user_timeout = MAX_14B_TIMEOUT;
|
||||
PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
|
||||
}
|
||||
time_wait = 13560000 / 1000 / (8 * 16) * user_timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
|
||||
}
|
||||
|
||||
// "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes
|
||||
// https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size
|
||||
// here length PM3_CMD_DATA_SIZE=512
|
||||
if (datain)
|
||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, (datainlen & 0xFFFF), 0, datain, datainlen & 0xFFFF);
|
||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, (datainlen & 0xFFFF), time_wait, datain, datainlen & 0xFFFF);
|
||||
else
|
||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, 0, 0, NULL, 0);
|
||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, 0, time_wait, NULL, 0);
|
||||
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, APDU_TIMEOUT)) {
|
||||
|
@ -1489,7 +1500,7 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
|
||||
int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, int user_timeout) {
|
||||
*dataoutlen = 0;
|
||||
bool chaining = false;
|
||||
int res;
|
||||
|
@ -1506,7 +1517,7 @@ int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool
|
|||
bool chainBlockNotLast = ((clen + vlen) < datainlen);
|
||||
|
||||
*dataoutlen = 0;
|
||||
res = handle_14b_apdu(chainBlockNotLast, &datain[clen], vlen, v_activate_field, dataout, maxdataoutlen, dataoutlen, &chaining);
|
||||
res = handle_14b_apdu(chainBlockNotLast, &datain[clen], vlen, v_activate_field, dataout, maxdataoutlen, dataoutlen, &chaining, user_timeout);
|
||||
if (res) {
|
||||
if (leave_signal_on == false)
|
||||
switch_off_field_14b();
|
||||
|
@ -1535,7 +1546,7 @@ int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool
|
|||
|
||||
} else {
|
||||
|
||||
res = handle_14b_apdu(false, datain, datainlen, activate_field, dataout, maxdataoutlen, dataoutlen, &chaining);
|
||||
res = handle_14b_apdu(false, datain, datainlen, activate_field, dataout, maxdataoutlen, dataoutlen, &chaining, user_timeout);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (leave_signal_on == false) {
|
||||
switch_off_field_14b();
|
||||
|
@ -1546,7 +1557,7 @@ int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool
|
|||
|
||||
while (chaining) {
|
||||
// I-block with chaining
|
||||
res = handle_14b_apdu(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining);
|
||||
res = handle_14b_apdu(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining, user_timeout);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (leave_signal_on == false) {
|
||||
switch_off_field_14b();
|
||||
|
@ -1594,6 +1605,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
|
|||
arg_lit0("e", "extended", "make extended length apdu if `m` parameter included"),
|
||||
arg_int0("l", "le", "<int>", "Le apdu parameter if `m` parameter included"),
|
||||
arg_strx1(NULL, "hex", "<hex>", "<APDU | data> if `m` parameter included"),
|
||||
arg_int0(NULL, "timeout", "<dec>", "timeout in ms"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
@ -1653,6 +1665,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
|
|||
// len = data + PCB(1b) + CRC(2b)
|
||||
CLIGetHexBLessWithReturn(ctx, 8, data, &datalen, 1 + 2);
|
||||
}
|
||||
int user_timeout = arg_get_int_def(ctx, 9, -1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s",
|
||||
|
@ -1670,7 +1683,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
|
|||
PrintAndLogEx(WARNING, "can't decode APDU.");
|
||||
}
|
||||
|
||||
int res = exchange_14b_apdu(data, datalen, activate_field, leave_signal_on, data, PM3_CMD_DATA_SIZE, &datalen);
|
||||
int res = exchange_14b_apdu(data, datalen, activate_field, leave_signal_on, data, PM3_CMD_DATA_SIZE, &datalen, user_timeout);
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
@ -1709,7 +1722,7 @@ static int CmdHF14BNdef(const char *Cmd) {
|
|||
uint8_t aSELECT_AID[80];
|
||||
int aSELECT_AID_n = 0;
|
||||
param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
|
||||
int res = exchange_14b_apdu(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
int res = exchange_14b_apdu(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
|
||||
if (res) {
|
||||
goto out;
|
||||
}
|
||||
|
@ -1735,7 +1748,7 @@ static int CmdHF14BNdef(const char *Cmd) {
|
|||
uint8_t aSELECT_FILE_NDEF[30];
|
||||
int aSELECT_FILE_NDEF_n = 0;
|
||||
param_gethex_to_eol("00a4000c020001", 0, aSELECT_FILE_NDEF, sizeof(aSELECT_FILE_NDEF), &aSELECT_FILE_NDEF_n);
|
||||
res = exchange_14b_apdu(aSELECT_FILE_NDEF, aSELECT_FILE_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
res = exchange_14b_apdu(aSELECT_FILE_NDEF, aSELECT_FILE_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
|
@ -1750,7 +1763,7 @@ static int CmdHF14BNdef(const char *Cmd) {
|
|||
uint8_t aREAD_NDEF[30];
|
||||
int aREAD_NDEF_n = 0;
|
||||
param_gethex_to_eol("00b0000002", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n);
|
||||
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
|
||||
if (res) {
|
||||
goto out;
|
||||
}
|
||||
|
@ -1769,7 +1782,7 @@ static int CmdHF14BNdef(const char *Cmd) {
|
|||
aREAD_NDEF_n = 0;
|
||||
param_gethex_to_eol("00b00002", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n);
|
||||
aREAD_NDEF[4] = offset;
|
||||
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
|
||||
if (res) {
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
int CmdHF14B(const char *Cmd);
|
||||
|
||||
int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
|
||||
int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, int user_timeout);
|
||||
|
||||
int infoHF14B(bool verbose);
|
||||
int readHF14B(bool verbose);
|
||||
|
|
|
@ -92,7 +92,8 @@ static bool emrtd_exchange_commands(const char *cmd, uint8_t *dataout, int *data
|
|||
param_gethex_to_eol(cmd, 0, aCMD, sizeof(aCMD), &aCMD_n);
|
||||
int res;
|
||||
if (use_14b) {
|
||||
res = exchange_14b_apdu(aCMD, aCMD_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
// need to add a long timeout for passports with activated anti-bruteforce measure
|
||||
res = exchange_14b_apdu(aCMD, aCMD_n, activate_field, keep_field_on, response, sizeof(response), &resplen, 15000);
|
||||
} else {
|
||||
res = ExchangeAPDU14a(aCMD, aCMD_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue