mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-04 20:13:38 +08:00
hf 14a apdu now uses the FWI and SGFI values from the ATS to determine an appropriate timeout.
This fixes issues when using the command against cards that indicate really slow times, such as card emulation by hf_cardhopper.
This commit is contained in:
parent
e9972bd060
commit
d156e48a83
2 changed files with 48 additions and 9 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
|||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Changed `hf 14a apdu` - It now uses the FWI and SGFI values from the ATS to determine an appropriate timeout (@nvx)
|
||||
- Added a thread to check when device comes online again. It will connect and update prompt (@iceman1001)
|
||||
- Changed CLI offline prompt - replaces the old prompt when offline is detected (@iceman100)
|
||||
- Changed `hf mf info` - it now uses found keys to try identify Gen2 cards (@iceman1001)
|
||||
|
|
|
@ -1006,6 +1006,11 @@ int SelectCard14443A_4_WithParameters(bool disconnect, bool verbose, iso14a_card
|
|||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
iso14a_card_select_t *vcard = (iso14a_card_select_t *) resp.data.asBytes;
|
||||
if (card) {
|
||||
memcpy(card, vcard, sizeof(iso14a_card_select_t));
|
||||
}
|
||||
|
||||
if (resp.oldarg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
|
||||
// get ATS
|
||||
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
|
||||
|
@ -1029,19 +1034,19 @@ int SelectCard14443A_4_WithParameters(bool disconnect, bool verbose, iso14a_card
|
|||
gs_frame_len = atsFSC[fsci];
|
||||
}
|
||||
}
|
||||
|
||||
if (card) {
|
||||
card->ats_len = resp.oldarg[0];
|
||||
memcpy(card->ats, resp.data.asBytes, card->ats_len);
|
||||
}
|
||||
} else {
|
||||
// get frame length from ATS in card data structure
|
||||
iso14a_card_select_t *vcard = (iso14a_card_select_t *) resp.data.asBytes;
|
||||
if (vcard->ats_len > 1) {
|
||||
uint8_t fsci = vcard->ats[1] & 0x0f;
|
||||
if (fsci < ARRAYLEN(atsFSC)) {
|
||||
gs_frame_len = atsFSC[fsci];
|
||||
}
|
||||
}
|
||||
|
||||
if (card) {
|
||||
memcpy(card, vcard, sizeof(iso14a_card_select_t));
|
||||
}
|
||||
}
|
||||
|
||||
SetISODEPState(ISODEP_NFCA);
|
||||
|
@ -1060,11 +1065,44 @@ int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card
|
|||
static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) {
|
||||
*chainingout = false;
|
||||
|
||||
size_t timeout = 1500;
|
||||
if (activateField) {
|
||||
// select with no disconnect and set gs_frame_len
|
||||
int selres = SelectCard14443A_4(false, true, NULL);
|
||||
if (selres != PM3_SUCCESS)
|
||||
iso14a_card_select_t card;
|
||||
int selres = SelectCard14443A_4(false, true, &card);
|
||||
if (selres != PM3_SUCCESS) {
|
||||
return selres;
|
||||
}
|
||||
|
||||
// Extract FWI and SFGI from ATS and increase timeout by the indicated values
|
||||
// for most cards these values are trivially small so will make no practical
|
||||
// difference but some "cards" like hf_cardhopper overwrite these to their
|
||||
// maximum values resulting in ~5 seconds each which can cause timeouts if we
|
||||
// just ignore it
|
||||
if (((card.ats[1] & 0x20) == 0x20) && card.ats_len > 2) {
|
||||
// TB is present in ATS
|
||||
|
||||
uint8_t tb;
|
||||
if ((card.ats[1] & 0x10) == 0x10 && card.ats_len > 3) {
|
||||
// TA is also present, so TB at ats[3]
|
||||
tb = card.ats[3];
|
||||
} else {
|
||||
// TA is not present, so TB is at ats[2]
|
||||
tb = card.ats[2];
|
||||
}
|
||||
|
||||
uint8_t fwi = (tb & 0xF0) >> 4;
|
||||
if (fwi != 0x0F) {
|
||||
uint32_t fwt = 256 * 16 * (1 << fwi);
|
||||
timeout += fwt;
|
||||
}
|
||||
|
||||
uint8_t sfgi = tb & 0x0F;
|
||||
if (sfgi != 0x0F) {
|
||||
uint32_t sgft = 256 * 16 * (1 << sfgi);
|
||||
timeout += sgft;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t cmdc = 0;
|
||||
|
@ -1082,7 +1120,7 @@ static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool
|
|||
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, timeout)) {
|
||||
uint8_t *recv = resp.data.asBytes;
|
||||
int iLen = resp.oldarg[0];
|
||||
uint8_t res = resp.oldarg[1];
|
||||
|
@ -2410,7 +2448,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
|||
|
||||
int isMagic = 0;
|
||||
if (isMifareClassic) {
|
||||
isMagic = detect_mf_magic(true, MF_KEY_A, 0);
|
||||
isMagic = detect_mf_magic(true, MF_KEY_B, 0xFFFFFFFFFFFF);
|
||||
}
|
||||
if (isMifareUltralight) {
|
||||
isMagic = (detect_mf_magic(false, MF_KEY_A, 0) == MAGIC_NTAG21X);
|
||||
|
|
Loading…
Reference in a new issue