mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-23 14:45:37 -07:00
Merge pull request #2226 from nvx/bugfix/14a_apdu_ats_timeout
hf 14a apdu now uses the FWI and SGFI values from the ATS to determine an appropriate timeout.
This commit is contained in:
commit
2e7be4faba
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…
Add table
Add a link
Reference in a new issue