mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-13 00:23:17 -07:00
adapting hf mf cget* commands to longer timeouts. Same with the quick eload used in autopwn among others.\nAlso adapted the return codes, so its more accurate in its reporting back to the client. Also added some more informative messages
This commit is contained in:
parent
cb9ee94ed6
commit
1cb15c84c1
3 changed files with 70 additions and 26 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue