From: iceman1001 Date: Sun, 29 Jan 2017 09:41:48 +0000 (+0100) Subject: CHG: the mifare Auth command can make use of a random nonce aswell. X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/e99acd00cc0ef24aa685b86eb4623c397e082368 CHG: the mifare Auth command can make use of a random nonce aswell. CHG: since sim commands are timing critical, I'm testing a smaller prand prng function from Intel --- diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index d0695501..2b4f9ea1 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -850,6 +850,8 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack() + // init pseudorand + fast_prand(); uint8_t sak = 0; uint32_t cuid = 0; @@ -869,7 +871,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { uint8_t cardAUTHKEY = 0xff; // no authentication // allow collecting up to 8 sets of nonces to allow recovery of up to 8 keys - nonces_t ar_nr_resp[ATTACK_KEY_COUNT*2]; // for 2 separate attack types (nml, moebius) + nonces_t ar_nr_resp[ATTACK_KEY_COUNT*2]; // for 2 separate attack types (std, moebius) memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp)); uint8_t ar_nr_collected[ATTACK_KEY_COUNT*2]; // for 2nd attack type (moebius) @@ -976,8 +978,6 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { // Tag NONCE. uint8_t response5[4]; - nonce = prand(); - num_to_bytes(nonce, 4, response5); uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS: // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, @@ -1187,57 +1187,53 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { ) { // if first auth for sector, or matches sector and keytype of previous auth - if (ar_nr_collected[i+mM] < 2) { - // if we haven't already collected 2 nonces for this sector - if (ar_nr_resp[ar_nr_collected[i+mM]].ar != ar) { - // Avoid duplicates... probably not necessary, ar should vary. - if (ar_nr_collected[i+mM]==0) { - // first nonce collect - ar_nr_resp[i+mM].cuid = cuid; - ar_nr_resp[i+mM].sector = cardAUTHSC; - ar_nr_resp[i+mM].keytype = cardAUTHKEY; - ar_nr_resp[i+mM].nonce = nonce; - ar_nr_resp[i+mM].nr = nr; - ar_nr_resp[i+mM].ar = ar; - nonce1_count++; - // add this nonce to first moebius nonce - ar_nr_resp[i+ATTACK_KEY_COUNT].cuid = cuid; - ar_nr_resp[i+ATTACK_KEY_COUNT].sector = cardAUTHSC; - ar_nr_resp[i+ATTACK_KEY_COUNT].keytype = cardAUTHKEY; - ar_nr_resp[i+ATTACK_KEY_COUNT].nonce = nonce; - ar_nr_resp[i+ATTACK_KEY_COUNT].nr = nr; - ar_nr_resp[i+ATTACK_KEY_COUNT].ar = ar; - ar_nr_collected[i+ATTACK_KEY_COUNT]++; - } else { // second nonce collect (std and moebius) - ar_nr_resp[i+mM].nonce2 = nonce; - ar_nr_resp[i+mM].nr2 = nr; - ar_nr_resp[i+mM].ar2 = ar; - if (!gettingMoebius) { - nonce2_count++; - // check if this was the last second nonce we need for std attack - if ( nonce2_count == nonce1_count ) { - // done collecting std test switch to moebius - // first finish incrementing last sample - ar_nr_collected[i+mM]++; - // switch to moebius collection - gettingMoebius = true; - mM = ATTACK_KEY_COUNT; - break; - } - } else { - moebius_n_count++; - // if we've collected all the nonces we need - finish. - if (nonce1_count == moebius_n_count) { - cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,0,0,&ar_nr_resp,sizeof(ar_nr_resp)); - nonce1_count = 0; - nonce2_count = 0; - moebius_n_count = 0; - gettingMoebius = false; - } + if (ar_nr_collected[i+mM] > 1) continue; + + // if we haven't already collected 2 nonces for this sector + if (ar_nr_resp[ar_nr_collected[i+mM]].ar != ar) { + // Avoid duplicates... probably not necessary, ar should vary. + if (ar_nr_collected[i+mM]==0) { + // first nonce collect + nonce1_count++; + // add this nonce to first moebius nonce + ar_nr_resp[i+ATTACK_KEY_COUNT].cuid = cuid; + ar_nr_resp[i+ATTACK_KEY_COUNT].sector = cardAUTHSC; + ar_nr_resp[i+ATTACK_KEY_COUNT].keytype = cardAUTHKEY; + ar_nr_resp[i+ATTACK_KEY_COUNT].nonce = nonce; + ar_nr_resp[i+ATTACK_KEY_COUNT].nr = nr; + ar_nr_resp[i+ATTACK_KEY_COUNT].ar = ar; + ar_nr_collected[i+ATTACK_KEY_COUNT]++; + } else { + // second nonce collect (std and moebius) + ar_nr_resp[i+mM].nonce2 = nonce; + ar_nr_resp[i+mM].nr2 = nr; + ar_nr_resp[i+mM].ar2 = ar; + + if (!gettingMoebius) { + nonce2_count++; + // check if this was the last second nonce we need for std attack + if ( nonce2_count == nonce1_count ) { + // done collecting std test switch to moebius + // first finish incrementing last sample + ar_nr_collected[i+mM]++; + // switch to moebius collection + gettingMoebius = true; + mM = ATTACK_KEY_COUNT; + break; + } + } else { + moebius_n_count++; + // if we've collected all the nonces we need - finish. + if (nonce1_count == moebius_n_count) { + cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,0,0,&ar_nr_resp,sizeof(ar_nr_resp)); + nonce1_count = 0; + nonce2_count = 0; + moebius_n_count = 0; + gettingMoebius = false; } } - ar_nr_collected[i+mM]++; } + ar_nr_collected[i+mM]++; } // we found right spot for this nonce stop looking break; @@ -1372,6 +1368,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { LED_A_OFF(); if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1) { + /* for ( uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { if (ar_nr_collected[i] == 2) { Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i= 4) Dbprintf("Re-read after previous NR_AR_ATTACK, resetting buffer"); memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp)); memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected)); mM = 0; @@ -3116,7 +3120,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen()); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,1,0,0,0,0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(FALSE); } diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 4795a7ec..4100ef54 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -121,7 +121,10 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN // "random" reader nonce: //byte_t nr[4] = {0x55, 0x41, 0x49, 0x92}; - byte_t nr[4] = {0x01, 0x01, 0x01, 0x01}; + fast_prand(); + byte_t nr[4]; + num_to_bytes(prand(), 4, nr); + //byte_t nr[4] = {0x01, 0x01, 0x01, 0x01}; uint32_t nt, ntpp; // Supplied tag nonce diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 041da212..c07bc579 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -21,6 +21,7 @@ #include "iso14443a.h" #include "crapto1.h" #include "des.h" +#include "random.h" // fast_prand, prand // mifare authentication #define CRYPT_NONE 0 diff --git a/common/random.c b/common/random.c index df549968..5658683d 100644 --- a/common/random.c +++ b/common/random.c @@ -1,6 +1,6 @@ #include "random.h" - uint64_t next_random = 1; +static uint32_t g_nextrandom; /* Generates a (non-cryptographically secure) 32-bit random number. * @@ -8,14 +8,23 @@ * method of seeding with the time it took to call "autoseed" from first run. * * https://github.com/Proxmark/proxmark3/pull/209/commits/f9c1dcd9f6e68a8c07cffed697a9c4c8caed6015 + * + * Iceman, rand needs to be fast. + * https://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/ */ + +inline void fast_prand(){ + fast_prandEx(GetTickCount()); +} +inline void fast_prandEx(uint32_t seed) { + g_nextrandom = seed; +} + uint32_t prand() { - if (next_random == 1) - next_random = GetTickCount(); - - next_random *= 6364136223846793005; - next_random += 1; - - return (uint32_t)(next_random >> 32) % 0xffffffff; +// g_nextrandom *= 6364136223846793005; +// g_nextrandom += 1; +//return (uint32_t)(g_nextrandom >> 32) % 0xffffffff; + g_nextrandom = (214013 * g_nextrandom + 2531011); + return (g_nextrandom>>16) & 0xFFFF; } diff --git a/common/random.h b/common/random.h index 45f176d3..800ad810 100644 --- a/common/random.h +++ b/common/random.h @@ -15,7 +15,7 @@ #include "common.h" #include "ticks.h" - +void fast_prand(); +void fast_prandEx(uint32_t seed); uint32_t prand(); - #endif \ No newline at end of file