diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 70dc54f1..07bbd37d 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2329,6 +2329,7 @@ typedef struct { * FLAG_7B_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that * FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section not finished * FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later + * FLAG_RANDOM_NONCE - means we should generate some pseudo-random nonce data *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ... * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted) */ @@ -2387,7 +2388,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * uint8_t mM = 0; //moebius_modifier for collection storage // Authenticate response - nonce - uint32_t nonce = bytes_to_num(rAUTH_NT, 4); + uint32_t nonce; + if (flags & FLAG_RANDOM_NONCE) { + nonce = prand(); + } else { + nonce = bytes_to_num(rAUTH_NT, 4); + } //-- Determine the UID // Can be set from emulator memory, incoming data @@ -2535,6 +2541,11 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * LED_C_OFF(); crypto1_destroy(pcs); cardAUTHKEY = 0xff; + if (flags & FLAG_RANDOM_NONCE) { + nonce = prand(); + } else { + nonce++; + } continue; } @@ -2656,7 +2667,11 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * // switch to moebius collection gettingMoebius = true; mM = ATTACK_KEY_COUNT; - nonce = nonce*7; + if (flags & FLAG_RANDOM_NONCE) { + nonce = prand(); + } else { + nonce = nonce*7; + } break; } } else { diff --git a/armsrc/util.c b/armsrc/util.c index 1dd8dc75..be41bad8 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -431,3 +431,19 @@ uint32_t RAMFUNC GetCountSspClk(){ } } +static uint64_t next_random = 1; + +/* Generates a (non-cryptographically secure) 32-bit random number. + * + * We don't have an implementation of the "rand" function or a clock to seed it + * with, so we just call GetTickCount the first time to seed ourselves. + */ +uint32_t prand() { + if (next_random == 1) { + next_random = GetTickCount(); + } + + next_random = next_random * 6364136223846793005 + 1; + return (uint32_t)(next_random >> 32) % 0xffffffff; +} + diff --git a/armsrc/util.h b/armsrc/util.h index bf5d0cc8..e919764b 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -54,4 +54,6 @@ uint32_t RAMFUNC GetDeltaCountUS(); void StartCountSspClk(); uint32_t RAMFUNC GetCountSspClk(); +uint32_t prand(); + #endif diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 36c8e6c3..2b14c763 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1100,6 +1100,7 @@ int usage_hf14_mf1ksim(void) { PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)"); PrintAndLog(" e (Optional) set keys found from 'reader attack' to emulator memory (implies x and i)"); PrintAndLog(" f (Optional) get UIDs to use for 'reader attack' from file 'f ' (implies x and i)"); + PrintAndLog(" r (Optional) Generate random nonces instead of sequential nonces."); PrintAndLog("samples:"); PrintAndLog(" hf mf sim u 0a0a0a0a"); PrintAndLog(" hf mf sim u 11223344556677"); @@ -1164,6 +1165,11 @@ int CmdHF14AMf1kSim(const char *Cmd) { exitAfterNReads = param_get8(Cmd, pnr+1); cmdp += 2; break; + case 'r': + case 'R': + flags |= FLAG_RANDOM_NONCE; + cmdp++; + break; case 'u': case 'U': param_gethex_ex(Cmd, cmdp+1, uid, &uidlen); diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 66e6cf91..16d1c5dd 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -217,6 +217,7 @@ typedef struct{ #define FLAG_7B_UID_IN_DATA 0x04 #define FLAG_10B_UID_IN_DATA 0x08 #define FLAG_NR_AR_ATTACK 0x10 +#define FLAG_RANDOM_NONCE 0x20 //Iclass reader flags