mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-10 23:42:40 -07:00
mf chk queue up the next set of keys to check (#1)
This commit is contained in:
parent
24683e5381
commit
766c978bd0
5 changed files with 70 additions and 20 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue