mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-14 02:26:59 -07:00
modify mfCheckKeys() to pass button press events upstream, don't abort nested when a static nonce is encountered, and modify nested to try multiple keys in a single operation
This commit is contained in:
parent
b461e6e367
commit
3772d1651a
2 changed files with 73 additions and 22 deletions
|
@ -236,8 +236,16 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t key
|
|||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) return 1;
|
||||
if ((resp.arg[0] & 0xff) != 0x01) return 2;
|
||||
if (!WaitForResponseTimeout(CMD_ACK,&resp,3000))
|
||||
return 1;
|
||||
|
||||
if ((resp.arg[0] & 0xff) != 0x01) {
|
||||
if (((int)resp.arg[1]) < 0)
|
||||
return (int)resp.arg[1];
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
*key = bytes_to_num(resp.d.asBytes, 6);
|
||||
return 0;
|
||||
}
|
||||
|
@ -321,13 +329,20 @@ __attribute__((force_align_arg_pointer))
|
|||
|
||||
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t i, j;
|
||||
uint32_t uid;
|
||||
UsbCommand resp;
|
||||
|
||||
int num_unique_nonces;
|
||||
|
||||
StateList_t statelists[2];
|
||||
struct Crypto1State *p1, *p2, *p3, *p4;
|
||||
|
||||
uint8_t *keyBlock = NULL;
|
||||
uint64_t key64;
|
||||
|
||||
int isOK = -6;
|
||||
|
||||
// flush queue
|
||||
(void)WaitForResponseTimeout(CMD_ACK,NULL,100);
|
||||
|
||||
|
@ -358,8 +373,15 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
|||
statelists[i].uid = uid;
|
||||
memcpy(&statelists[i].nt, (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4);
|
||||
memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4);
|
||||
|
||||
PrintAndLog("statelist %d: %02X %x %08X %08X", i, statelists[i].blockNo, statelists[i].keyType, statelists[i].nt, statelists[i].ks1);
|
||||
}
|
||||
|
||||
if (statelists[0].nt == statelists[1].nt && statelists[0].ks1 == statelists[1].ks1)
|
||||
num_unique_nonces = 1;
|
||||
else
|
||||
num_unique_nonces = 2;
|
||||
|
||||
// calc keys
|
||||
|
||||
pthread_t thread_id[2];
|
||||
|
@ -413,27 +435,59 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
|||
// the statelists now contain possible keys. The key we are searching for must be in the
|
||||
// intersection of both lists. Create the intersection:
|
||||
qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compare_uint64);
|
||||
qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64);
|
||||
statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead);
|
||||
|
||||
if (num_unique_nonces > 1) {
|
||||
qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64);
|
||||
statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead);
|
||||
}
|
||||
else {
|
||||
PrintAndLog("Nonce 1 and 2 are the same!");
|
||||
}
|
||||
|
||||
if (statelists[0].len > 100) {
|
||||
PrintAndLog("We have %d keys to check. This will take a very long time!", statelists[0].len);
|
||||
PrintAndLog("Press button to abort.");
|
||||
}
|
||||
|
||||
uint32_t max_keys = (statelists[0].len > (USB_CMD_DATA_SIZE / 6)) ? (USB_CMD_DATA_SIZE / 6) : statelists[0].len;
|
||||
keyBlock = calloc(max_keys, 6);
|
||||
if (keyBlock == NULL) return -5;
|
||||
|
||||
memset(resultKey, 0, 6);
|
||||
// The list may still contain several key candidates. Test each of them with mfCheckKeys
|
||||
for (i = 0; i < statelists[0].len; i++) {
|
||||
uint8_t keyBlock[6];
|
||||
uint64_t key64;
|
||||
crypto1_get_lfsr(statelists[0].head.slhead + i, &key64);
|
||||
num_to_bytes(key64, 6, keyBlock);
|
||||
for (i = 0; i < statelists[0].len; i+=max_keys) {
|
||||
PrintAndLog("Keys left to check: %d", statelists[0].len - i);
|
||||
if ((i+max_keys) >= statelists[0].len)
|
||||
max_keys = statelists[0].len - i;
|
||||
|
||||
for (j = 0; j < max_keys; j++) {
|
||||
crypto1_get_lfsr(statelists[0].head.slhead + i + j, &key64);
|
||||
num_to_bytes(key64, 6, keyBlock+(j*6));
|
||||
}
|
||||
|
||||
key64 = 0;
|
||||
if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, 1, keyBlock, &key64)) {
|
||||
isOK = mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, true, max_keys, keyBlock, &key64);
|
||||
|
||||
if (isOK == 1) { // timeout
|
||||
isOK = -1;
|
||||
break;
|
||||
}
|
||||
else if (isOK < 0) { // -2 is button pressed
|
||||
break;
|
||||
}
|
||||
else if (!isOK) {
|
||||
num_to_bytes(key64, 6, resultKey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOK)
|
||||
PrintAndLog("Key found after checking %d keys\n", i+max_keys);
|
||||
|
||||
free(statelists[0].head.slhead);
|
||||
free(statelists[1].head.slhead);
|
||||
|
||||
return 0;
|
||||
return isOK;
|
||||
}
|
||||
|
||||
// MIFARE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue