diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 74caf51c1..1966c8c65 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2365,8 +2365,9 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive } // timeout already in ms + 100ms guard time - if (GetTickCountDelta(receive_timer) > timeout + 100) + if (GetTickCountDelta(receive_timer) > timeout + 100) { break; + } } return false; } @@ -2401,15 +2402,17 @@ void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing) { } static uint16_t ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t offset, uint8_t *par) { - if (!GetIso14443aAnswerFromTag(receivedAnswer, par, offset)) + if (GetIso14443aAnswerFromTag(receivedAnswer, par, offset) == false) { return 0; + } LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, par, false); return Demod.len; } uint16_t ReaderReceive(uint8_t *receivedAnswer, uint8_t *par) { - if (!GetIso14443aAnswerFromTag(receivedAnswer, par, 0)) + if (GetIso14443aAnswerFromTag(receivedAnswer, par, 0) == false) { return 0; + } LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, par, false); return Demod.len; } diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index ef6b6022f..ffe3182ba 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -73,9 +73,10 @@ int16_t mifare_cmd_readblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t read_c struct Crypto1State *pcs = &mpcs; iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); set_tracing(true); + + uint32_t timeout = iso14a_get_timeout(); LED_A_ON(); LED_B_OFF(); @@ -95,6 +96,10 @@ int16_t mifare_cmd_readblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t read_c goto OUT; }; + // frame waiting time (FWT) in 1/fc + uint32_t fwt = 256 * 16 * (1 << 6); + iso14a_set_timeout(fwt / (8 * 16)); + for (uint8_t i = 0; i < count; i++) { if (mifare_classic_readblock_ex(pcs, block_no + i, block_data + (i * 16), read_cmd)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Read block error"); @@ -112,11 +117,11 @@ int16_t mifare_cmd_readblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t read_c OUT: crypto1_deinit(pcs); + iso14a_set_timeout(timeout); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); BigBuf_free(); - return retval; } @@ -2072,6 +2077,12 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { int retval = PM3_SUCCESS; + // increase time-out. Magic card etc are slow + uint32_t timeout = iso14a_get_timeout(); + // frame waiting time (FWT) in 1/fc + uint32_t fwt = 256 * 16 * (1 << 7); + iso14a_set_timeout(fwt / (8 * 16)); + for (uint8_t s = 0; s < sectorcnt; s++) { uint64_t ui64Key = emlGetKey(s, keytype); @@ -2110,7 +2121,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { // Auth if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keytype, ui64Key, AUTH_FIRST)) { retval = PM3_EPARTIAL; - if (g_dbglevel > DBG_ERROR) { + if (g_dbglevel >= DBG_ERROR) { Dbprintf("Sector %2d - Auth error", s); } continue; @@ -2122,31 +2133,43 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { for (uint8_t b = 0; b < NumBlocksPerSector(s); b++) { memset(data, 0x00, sizeof(data)); + uint8_t tb = FirstBlockOfSector(s) + b; + uint8_t r = 0; + for (; r < MAX_RETRIES; r++) { - for (uint8_t r = 0; r < MAX_RETRIES; r++) { - - if (mifare_classic_readblock(pcs, FirstBlockOfSector(s) + b, data)) { + int res = mifare_classic_readblock(pcs, tb, data); + if (res == 1) { retval |= PM3_EPARTIAL; - if (g_dbglevel > DBG_ERROR) { - Dbprintf("Error reading sector %2d block %2d", s, b); + if (g_dbglevel >= DBG_ERROR) { + Dbprintf("Error No rights reading sector %2d block %2d", s, b); } + break; + } + // retry if wrong len. + if (res != 0) { continue; } // No need to copy empty if (memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) { - continue; + break; } - if (b < NumBlocksPerSector(s) - 1) { - emlSetMem(data, FirstBlockOfSector(s) + b, 1); - } else { + if (IsSectorTrailer(b)) { // sector trailer, keep the keys, set only the AC uint8_t st[16] = {0x00}; - emlGetMem(st, FirstBlockOfSector(s) + b, 1); + emlGetMem(st, tb, 1); memcpy(st + 6, data + 6, 4); - emlSetMem(st, FirstBlockOfSector(s) + b, 1); + emlSetMem(st, tb, 1); + } else { + emlSetMem(data, tb, 1); } + break; + } + + // if we failed all retries, notify client + if (r == MAX_RETRIES) { + retval |= PM3_EPARTIAL; } } } @@ -2154,6 +2177,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { int res = mifare_classic_halt(pcs); (void)res; + iso14a_set_timeout(timeout); crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); @@ -2322,6 +2346,12 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { set_tracing(true); } + // increase time-out. Magic card etc are slow + uint32_t timeout = iso14a_get_timeout(); + // frame waiting time (FWT) in 1/fc + uint32_t fwt = 256 * 16 * (1 << 7); + iso14a_set_timeout(fwt / (8 * 16)); + //loop doesn't loop just breaks out if error or done while (true) { if (workFlags & MAGIC_WUPC) { @@ -2343,7 +2373,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } // read block - if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) { + if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != MAX_MIFARE_FRAME_SIZE)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("read block send command error"); errormsg = 0; break; @@ -2371,6 +2401,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { if (workFlags & MAGIC_OFF) OnSuccessMagic(); + + iso14a_set_timeout(timeout); } void MifareCIdent(bool is_mfc) { diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 5dfbfd26b..25744aa96 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -116,7 +116,9 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t uint16_t len = ReaderReceive(answer, par); - if (answer_parity) *answer_parity = par[0]; + if (answer_parity) { + *answer_parity = par[0]; + } if (pcs && (crypted == CRYPT_ALL)) { if (len == 1) { @@ -127,8 +129,9 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 3)) << 3; answer[0] = res; } else { - for (pos = 0; pos < len; pos++) + for (pos = 0; pos < len; pos++) { answer[pos] = crypto1_byte(pcs, 0x00, 0) ^ answer[pos]; + } } } return len; @@ -238,11 +241,15 @@ int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint8 uint16_t len = mifare_sendcmd_short(pcs, 1, iso_byte, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error %02x", receivedAnswer[0]); + if (g_dbglevel >= DBG_ERROR) { + Dbprintf("Block " _YELLOW_("%3d") " Cmd 0x%02x Cmd Error %02x", blockNo, iso_byte, receivedAnswer[0]); + } return 1; } if (len != 18) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("wrong response len %d (expected 18)", len); + if (g_dbglevel >= DBG_ERROR) { + Dbprintf("Block " _YELLOW_("%3d") " Cmd 0x%02x Wrong response len, expected 18 got " _RED_("%d"), blockNo, iso_byte, len); + } return 2; } @@ -701,13 +708,15 @@ void emlClearMem(void) { uint8_t SectorTrailer(uint8_t blockNo) { if (blockNo <= MIFARE_2K_MAXBLOCK) { - if (g_dbglevel >= DBG_EXTENDED) + if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x03)); + } return (blockNo | 0x03); } else { - if (g_dbglevel >= DBG_EXTENDED) - Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x0f)); - return (blockNo | 0x0f); + if (g_dbglevel >= DBG_EXTENDED) { + Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x0F)); + } + return (blockNo | 0x0F); } }