mf chk queue up the next set of keys to check (#1)

This commit is contained in:
uzlonewolf 2019-12-29 06:10:51 -08:00 committed by pwpiwi
parent 24683e5381
commit 766c978bd0
5 changed files with 70 additions and 20 deletions

View file

@ -1001,9 +1001,18 @@ void MifareChkKeys(uint16_t arg0, uint32_t arg1, uint8_t arg2, uint8_t *datain)
bool multisectorCheck = arg1 & 0x02; bool multisectorCheck = arg1 & 0x02;
bool init = arg1 & 0x04; bool init = arg1 & 0x04;
bool drop_field = arg1 & 0x08; bool drop_field = arg1 & 0x08;
static bool reject_next = false;
uint32_t auth_timeout = arg1 >> 16; uint32_t auth_timeout = arg1 >> 16;
uint8_t keyCount = arg2; uint8_t keyCount = arg2;
if (reject_next) {
reject_next = false;
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
cmd_send(CMD_ACK, 0, -3, 0, NULL, 0);
return;
}
LED_A_ON(); LED_A_ON();
if (init) { if (init) {
@ -1024,19 +1033,25 @@ void MifareChkKeys(uint16_t arg0, uint32_t arg1, uint8_t arg2, uint8_t *datain)
TKeyIndex keyIndex = {{0}}; TKeyIndex keyIndex = {{0}};
uint8_t sectorCnt = blockNo; uint8_t sectorCnt = blockNo;
res = MifareMultisectorChk(datain, keyCount, sectorCnt, keyType, &auth_timeout, OLD_MF_DBGLEVEL, &keyIndex); res = MifareMultisectorChk(datain, keyCount, sectorCnt, keyType, &auth_timeout, OLD_MF_DBGLEVEL, &keyIndex);
if (res >= 0) {
if (res >= 0)
cmd_send(CMD_ACK, 1, res, 0, keyIndex, 80); cmd_send(CMD_ACK, 1, res, 0, keyIndex, 80);
} else { else
cmd_send(CMD_ACK, 0, res, 0, NULL, 0); cmd_send(CMD_ACK, 0, res, 0, NULL, 0);
}
if (res < 0 && usb_poll_validate_length()) // we want to exit but another set of keys has been queued!
reject_next = true;
} else { } else {
res = MifareChkBlockKeys(datain, keyCount, blockNo, keyType, &auth_timeout, OLD_MF_DBGLEVEL); res = MifareChkBlockKeys(datain, keyCount, blockNo, keyType, &auth_timeout, OLD_MF_DBGLEVEL);
if (res > 0) {
if (res != 0 && usb_poll_validate_length()) // we want to exit but another set of keys has been queued!
reject_next = true;
if (res > 0)
cmd_send(CMD_ACK, 1, res, 0, datain + (res - 1) * 6, 6); cmd_send(CMD_ACK, 1, res, 0, datain + (res - 1) * 6, 6);
} else { else
cmd_send(CMD_ACK, 0, res, 0, NULL, 0); cmd_send(CMD_ACK, 0, res, 0, NULL, 0);
} }
}
if (drop_field || res != 0) { if (drop_field || res != 0) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);

View file

@ -858,14 +858,16 @@ int MifareChkBlockKeys(uint8_t *keys, uint8_t keyCount, uint8_t blockNo, uint8_t
uint8_t cascade_levels = 0; uint8_t cascade_levels = 0;
uint64_t ui64Key = 0; uint64_t ui64Key = 0;
// Allow button press to interrupt device
if (BUTTON_PRESS()) {
Dbprintf("ChkKeys: Cancel operation. Exit...");
return -2;
}
int retryCount = 0; int retryCount = 0;
for (uint8_t i = 0; i < keyCount; i++) { for (uint8_t i = 0; i < keyCount; i++) {
// Allow button press / usb cmd to interrupt device // Allow button press / usb cmd to interrupt device
if (BUTTON_PRESS() && !usb_poll_validate_length()) {
Dbprintf("ChkKeys: Cancel operation. Exit...");
return -2;
}
ui64Key = bytes_to_num(keys + i * 6, 6); ui64Key = bytes_to_num(keys + i * 6, 6);
int res = MifareChkBlockKey(uid, &cuid, &cascade_levels, ui64Key, blockNo, keyType, auth_timeout, debugLevel); int res = MifareChkBlockKey(uid, &cuid, &cascade_levels, ui64Key, blockNo, keyType, auth_timeout, debugLevel);
@ -921,7 +923,7 @@ int MifareMultisectorChk(uint8_t *keys, uint8_t keyCount, uint8_t SectorCount, u
// Dbprintf("%d %d", GetCountSspClk() - clk, (GetCountSspClk() - clk)/(SectorCount*keyCount*(keyType==2?2:1))); // Dbprintf("%d %d", GetCountSspClk() - clk, (GetCountSspClk() - clk)/(SectorCount*keyCount*(keyType==2?2:1)));
return 0; return 1;
} }

View file

@ -675,7 +675,7 @@ int CmdHF14AMfNested(const char *Cmd) {
} }
// check if we can authenticate to sector // check if we can authenticate to sector
res = mfCheckKeys(blockNo, keyType, timeout14a, true, true, true, 1, key, &key64); res = mfCheckKeys(blockNo, keyType, timeout14a, true, true, true, false, 1, key, &key64);
if (res) { if (res) {
PrintAndLog("Can't authenticate to block:%3d key type:%c key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("Can't authenticate to block:%3d key type:%c key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));
return 3; return 3;
@ -1275,7 +1275,7 @@ int CmdHF14AMfChk(const char *Cmd) {
uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c; uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c;
bool init = (c == 0); bool init = (c == 0);
bool drop_field = (c + size == keycnt); bool drop_field = (c + size == keycnt);
res = mfCheckKeys(blockNo, keyAB & 0x01, timeout14a, true, init, drop_field, size, &keyBlock[6 * c], &key64); res = mfCheckKeys(blockNo, keyAB & 0x01, timeout14a, true, init, drop_field, false, size, &keyBlock[6 * c], &key64);
clearTraceLog = false; clearTraceLog = false;
if (res != 1) { if (res != 1) {

View file

@ -210,7 +210,7 @@ int mfDarkside(uint64_t *key) {
} }
bool init = (i == 0); bool init = (i == 0);
bool drop_field = (i + size == keycount); bool drop_field = (i + size == keycount);
if (!mfCheckKeys(0, 0, 0, false, init, drop_field, size, keyBlock, key)) { if (!mfCheckKeys(0, 0, 0, false, init, drop_field, false, size, keyBlock, key)) {
break; break;
} }
} }
@ -229,8 +229,7 @@ int mfDarkside(uint64_t *key) {
return 0; return 0;
} }
int mfCheckKeys(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, bool clear_trace, bool init, bool drop_field, bool dont_wait, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key) {
int mfCheckKeys(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, bool clear_trace, bool init, bool drop_field, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key) {
*key = -1; *key = -1;
bool multisectorCheck = false; bool multisectorCheck = false;
@ -240,6 +239,13 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, bool clea
memcpy(c.d.asBytes, keyBlock, 6 * keycnt); memcpy(c.d.asBytes, keyBlock, 6 * keycnt);
SendCommand(&c); SendCommand(&c);
if (dont_wait)
return 3;
return mfCheckKeysGetResponse(key);
}
int mfCheckKeysGetResponse(uint64_t *key) {
UsbCommand resp; UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) if (!WaitForResponseTimeout(CMD_ACK,&resp,3000))
return 1; return 1;
@ -251,7 +257,9 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, bool clea
return 2; return 2;
} }
if (key)
*key = bytes_to_num(resp.d.asBytes, 6); *key = bytes_to_num(resp.d.asBytes, 6);
return 0; return 0;
} }
@ -337,7 +345,7 @@ __attribute__((force_align_arg_pointer))
int mfnested(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) { int mfnested(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) {
uint32_t i, j; uint32_t i, j, last_count;
uint32_t uid; uint32_t uid;
UsbCommand resp; UsbCommand resp;
@ -484,6 +492,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, uint8_t *key
memset(resultKey, 0, 6); memset(resultKey, 0, 6);
start_time = msclock(); start_time = msclock();
next_print_time = start_time + 1 * 1000; next_print_time = start_time + 1 * 1000;
bool want_queue = (max_keys < statelists[0].len);
bool queued_next_set = false;
// The list may still contain several key candidates. Test each of them with mfCheckKeys // The list may still contain several key candidates. Test each of them with mfCheckKeys
for (i = 0; i < statelists[0].len; i += max_keys) { for (i = 0; i < statelists[0].len; i += max_keys) {
if (next_print_time <= msclock()) { if (next_print_time <= msclock()) {
@ -505,7 +515,13 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, uint8_t *key
bool init = (i == 0); bool init = (i == 0);
bool drop_field = (i + max_keys == statelists[0].len); bool drop_field = (i + max_keys == statelists[0].len);
isOK = mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, authentication_timeout, true, init, drop_field, max_keys, keyBlock, &key64); bool dont_wait = want_queue && !queued_next_set;
isOK = mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, authentication_timeout, true, init, drop_field, dont_wait, max_keys, keyBlock, &key64);
if (dont_wait && isOK == 3) {
queued_next_set = true;
continue;
}
if (isOK == 1) { // timeout if (isOK == 1) { // timeout
isOK = -1; isOK = -1;
@ -520,6 +536,22 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, uint8_t *key
} }
} }
if (queued_next_set) {
i -= max_keys; // fix the count from the last trip through the for() loop
if (!isOK) {
mfCheckKeysGetResponse(NULL); // we already have what we want, just consume the queued response
}
else {
isOK = mfCheckKeysGetResponse(&key64);
if (isOK == 1) // timeout
isOK = -1;
else if (!isOK)
num_to_bytes(key64, 6, resultKey);
}
}
if (isOK == 0 && statelists[0].len != 1) if (isOK == 0 && statelists[0].len != 1)
PrintAndLog("Key found in %0.2f seconds after checking %d keys\n", ((float)(msclock() - start_time)) / 1000.0, i+max_keys); PrintAndLog("Key found in %0.2f seconds after checking %d keys\n", ((float)(msclock() - start_time)) / 1000.0, i+max_keys);

View file

@ -40,7 +40,8 @@ extern char logHexFileName[FILE_PATH_SIZE];
extern int mfDarkside(uint64_t *key); extern int mfDarkside(uint64_t *key);
extern int mfnested(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *ResultKeys, bool calibrate); extern int mfnested(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *ResultKeys, bool calibrate);
extern int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, bool clear_trace, bool init, bool drop_field, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key); extern int mfCheckKeys(uint8_t blockNo, uint8_t keyType, uint16_t timeout14a, bool clear_trace, bool init, bool drop_field, bool dont_wait, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key);
extern int mfCheckKeysGetResponse(uint64_t *key);
extern int mfCheckKeysSec(uint8_t sectorCnt, uint8_t keyType, uint16_t timeout14a, bool clear_trace, bool init, bool drop_field, uint8_t keycnt, uint8_t * keyBlock, sector_t * e_sector); extern int mfCheckKeysSec(uint8_t sectorCnt, uint8_t keyType, uint16_t timeout14a, bool clear_trace, bool init, bool drop_field, uint8_t keycnt, uint8_t * keyBlock, sector_t * e_sector);
extern int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data); extern int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data);