From 8a6948858268c87ca4c5e093950356aab8c9725a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Dec 2017 19:53:41 +0100 Subject: [PATCH] fix: 'hf mf mifare - wrongly executed the parity-zero when not needed. --- client/mfkey.c | 7 +++---- client/mifarehost.c | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/client/mfkey.c b/client/mfkey.c index 374199b8c..7cffd8046 100644 --- a/client/mfkey.c +++ b/client/mfkey.c @@ -33,8 +33,8 @@ uint32_t intersection(uint64_t *listA, uint64_t *listB) { p2++; } else { - while (compare_uint64(p1, p2) == -1) ++p1; - while (compare_uint64(p1, p2) == 1) ++p2; + while (compare_uint64(p1, p2) < 0) ++p1; + while (compare_uint64(p1, p2) > 0) ++p2; } } *p3 = -1; @@ -70,7 +70,6 @@ uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, ui states = lfsr_common_prefix(nr, rr, ks3x, par, (par_info == 0)); if (!states) { - printf("Failed getting states\n"); *keys = NULL; return 0; } @@ -78,7 +77,7 @@ uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, ui keylist = (uint64_t*)states; for (i = 0; keylist[i]; i++) { - lfsr_rollback_word(states+i, uid^nt, 0); + lfsr_rollback_word(states+i, uid ^ nt, 0); crypto1_get_lfsr(states+i, &key_recovered); keylist[i] = key_recovered; } diff --git a/client/mifarehost.c b/client/mifarehost.c index 37c0a8a26..ad3008098 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -51,10 +51,10 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { return isOK; uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4); - nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4); + nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4); par_list = bytes_to_num(resp.d.asBytes + 8, 8); ks_list = bytes_to_num(resp.d.asBytes + 16, 8); - nr = bytes_to_num(resp.d.asBytes + 24, 4); + nr = (uint32_t)bytes_to_num(resp.d.asBytes + 24, 4); break; } } @@ -73,12 +73,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { continue; } - qsort(keylist, keycount, sizeof(*keylist), compare_uint64); - keycount = intersection(last_keylist, keylist); - if (keycount == 0) { - free(last_keylist); - last_keylist = keylist; - continue; + // only parity zero attack + if (par_list == 0 ) { + qsort(keylist, keycount, sizeof(*keylist), compare_uint64); + keycount = intersection(last_keylist, keylist); + if (keycount == 0) { + free(last_keylist); + last_keylist = keylist; + continue; + } } if (keycount > 1) { @@ -112,6 +115,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { PrintAndLog("Test authentication failed. Restarting darkside attack"); free(last_keylist); last_keylist = keylist; + c.arg[0] = true; } } return 0; @@ -183,8 +187,7 @@ int Compare16Bits(const void * a, const void * b) { } // wrapper function for multi-threaded lfsr_recovery32 -void* nested_worker_thread(void *arg) -{ +void* nested_worker_thread(void *arg) { struct Crypto1State *p1; StateList_t *statelist = arg; statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt ^ statelist->uid); @@ -198,8 +201,7 @@ void* nested_worker_thread(void *arg) return statelist->head.slhead; } -int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) -{ +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 uid; UsbCommand resp;