mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-23 22:55: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...
|
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]
|
## [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)
|
- 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 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)
|
- 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;
|
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
|
if (resp.oldarg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
|
||||||
// get ATS
|
// get ATS
|
||||||
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
|
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];
|
gs_frame_len = atsFSC[fsci];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (card) {
|
||||||
|
card->ats_len = resp.oldarg[0];
|
||||||
|
memcpy(card->ats, resp.data.asBytes, card->ats_len);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// get frame length from ATS in card data structure
|
// 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) {
|
if (vcard->ats_len > 1) {
|
||||||
uint8_t fsci = vcard->ats[1] & 0x0f;
|
uint8_t fsci = vcard->ats[1] & 0x0f;
|
||||||
if (fsci < ARRAYLEN(atsFSC)) {
|
if (fsci < ARRAYLEN(atsFSC)) {
|
||||||
gs_frame_len = atsFSC[fsci];
|
gs_frame_len = atsFSC[fsci];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card) {
|
|
||||||
memcpy(card, vcard, sizeof(iso14a_card_select_t));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetISODEPState(ISODEP_NFCA);
|
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) {
|
static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) {
|
||||||
*chainingout = false;
|
*chainingout = false;
|
||||||
|
|
||||||
|
size_t timeout = 1500;
|
||||||
if (activateField) {
|
if (activateField) {
|
||||||
// select with no disconnect and set gs_frame_len
|
// select with no disconnect and set gs_frame_len
|
||||||
int selres = SelectCard14443A_4(false, true, NULL);
|
iso14a_card_select_t card;
|
||||||
if (selres != PM3_SUCCESS)
|
int selres = SelectCard14443A_4(false, true, &card);
|
||||||
|
if (selres != PM3_SUCCESS) {
|
||||||
return selres;
|
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;
|
uint16_t cmdc = 0;
|
||||||
|
@ -1082,7 +1120,7 @@ static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, timeout)) {
|
||||||
uint8_t *recv = resp.data.asBytes;
|
uint8_t *recv = resp.data.asBytes;
|
||||||
int iLen = resp.oldarg[0];
|
int iLen = resp.oldarg[0];
|
||||||
uint8_t res = resp.oldarg[1];
|
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;
|
int isMagic = 0;
|
||||||
if (isMifareClassic) {
|
if (isMifareClassic) {
|
||||||
isMagic = detect_mf_magic(true, MF_KEY_A, 0);
|
isMagic = detect_mf_magic(true, MF_KEY_B, 0xFFFFFFFFFFFF);
|
||||||
}
|
}
|
||||||
if (isMifareUltralight) {
|
if (isMifareUltralight) {
|
||||||
isMagic = (detect_mf_magic(false, MF_KEY_A, 0) == MAGIC_NTAG21X);
|
isMagic = (detect_mf_magic(false, MF_KEY_A, 0) == MAGIC_NTAG21X);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue