diff --git a/armsrc/crypto1.c b/armsrc/crypto1.c index 993c05e7f..68cb9b4e5 100644 --- a/armsrc/crypto1.c +++ b/armsrc/crypto1.c @@ -149,4 +149,5 @@ uint32_t prng_successor_one(uint32_t x) x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31; return SWAPENDIAN(x); -} \ No newline at end of file +} + diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c7fc06ec3..c4298fcb4 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -750,7 +750,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len) { - uint8_t par[MAX_PARITY_SIZE]; + uint8_t par[MAX_PARITY_SIZE] = {0}; GetParity(cmd, len, par); CodeIso14443aAsTagPar(cmd, len, par); @@ -1428,24 +1428,26 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) // of bits specified in the delay parameter. void PrepareDelayedTransfer(uint16_t delay) { + delay &= 0x07; + if (!delay) return; + uint8_t bitmask = 0; uint8_t bits_to_shift = 0; uint8_t bits_shifted = 0; + uint16_t i = 0; + + for (i = 0; i < delay; ++i) + bitmask |= (0x01 << i); - delay &= 0x07; - if (delay) { - for (uint16_t i = 0; i < delay; i++) { - bitmask |= (1 << i); - } ToSend[++ToSendMax] = 0x00; - for (uint16_t i = 0; i < ToSendMax; i++) { + + for (i = 0; i < ToSendMax; ++i) { bits_to_shift = ToSend[i] & bitmask; ToSend[i] = ToSend[i] >> delay; ToSend[i] = ToSend[i] | (bits_shifted << (8 - delay)); bits_shifted = bits_to_shift; } } -} //------------------------------------------------------------------------------------- @@ -1463,18 +1465,27 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing uint32_t ThisTransferTime = 0; if (timing) { - if(*timing == 0) { // Measure time + + if (*timing != 0) + // Delay transfer (fine tuning - up to 7 MF clock ticks) + PrepareDelayedTransfer(*timing & 0x00000007); + else + // Measure time *timing = (GetCountSspClk() + 8) & 0xfffffff8; - } else { - PrepareDelayedTransfer(*timing & 0x00000007); // Delay transfer (fine tuning - up to 7 MF clock ticks) - } - if(MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) Dbprintf("TransmitFor14443a: Missed timing"); + - while(GetCountSspClk() < (*timing & 0xfffffff8)); // Delay transfer (multiple of 8 MF clock ticks) + if (MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) + Dbprintf("TransmitFor14443a: Missed timing"); + + // Delay transfer (multiple of 8 MF clock ticks) + while (GetCountSspClk() < (*timing & 0xfffffff8)); + LastTimeProxToAirStart = *timing; } else { ThisTransferTime = ((MAX(NextTransferTime, GetCountSspClk()) & 0xfffffff8) + 8); + while(GetCountSspClk() < ThisTransferTime); + LastTimeProxToAirStart = ThisTransferTime; } @@ -2197,33 +2208,62 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) { if (nt1 == nt2) return 0; + uint16_t i; uint32_t nttmp1 = nt1; uint32_t nttmp2 = nt2; - for (uint16_t i = 1; i < 0xFFFF; i += 8) { - nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i; - nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -i; - - nttmp1 = prng_successor(nttmp1, 2); if (nttmp1 == nt2) return i+1; - nttmp2 = prng_successor(nttmp2, 2); if (nttmp2 == nt1) return -i-1; - - nttmp1 = prng_successor(nttmp1, 3); if (nttmp1 == nt2) return i+2; - nttmp2 = prng_successor(nttmp2, 3); if (nttmp2 == nt1) return -i-2; - - nttmp1 = prng_successor(nttmp1, 4); if (nttmp1 == nt2) return i+3; - nttmp2 = prng_successor(nttmp2, 4); if (nttmp2 == nt1) return -i-3; + for (i = 1; i < 0xFFFF; i += 8) { + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i; - nttmp1 = prng_successor(nttmp1, 5); if (nttmp1 == nt2) return i+4; - nttmp2 = prng_successor(nttmp2, 5); if (nttmp2 == nt1) return -i-4; - - nttmp1 = prng_successor(nttmp1, 6); if (nttmp1 == nt2) return i+5; - nttmp2 = prng_successor(nttmp2, 6); if (nttmp2 == nt1) return -i-5; - - nttmp1 = prng_successor(nttmp1, 7); if (nttmp1 == nt2) return i+6; - nttmp2 = prng_successor(nttmp2, 7); if (nttmp2 == nt1) return -i-6; - - nttmp1 = prng_successor(nttmp1, 8); if (nttmp1 == nt2) return i+7; - nttmp2 = prng_successor(nttmp2, 8); if (nttmp2 == nt1) return -i-7; + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+1; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+1; + + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+2; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+2; + + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+3; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+3; + + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+4; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+4; + + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+5; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+5; + + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+6; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+6; + + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+7; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+7; + + nttmp1 = prng_successor_one(nttmp1); if (nttmp1 == nt2) return i+8; + nttmp2 = prng_successor_one(nttmp2); if (nttmp2 == nt1) return -i+8; +/* + if ( prng_successor(nttmp1, i) == nt2) return i; + if ( prng_successor(nttmp2, i) == nt1) return -i; + + if ( prng_successor(nttmp1, i+2) == nt2) return i+2; + if ( prng_successor(nttmp2, i+2) == nt1) return -(i+2); + + if ( prng_successor(nttmp1, i+3) == nt2) return i+3; + if ( prng_successor(nttmp2, i+3) == nt1) return -(i+3); + + if ( prng_successor(nttmp1, i+4) == nt2) return i+4; + if ( prng_successor(nttmp2, i+4) == nt1) return -(i+4); + + if ( prng_successor(nttmp1, i+5) == nt2) return i+5; + if ( prng_successor(nttmp2, i+5) == nt1) return -(i+5); + + if ( prng_successor(nttmp1, i+6) == nt2) return i+6; + if ( prng_successor(nttmp2, i+6) == nt1) return -(i+6); + + if ( prng_successor(nttmp1, i+7) == nt2) return i+7; + if ( prng_successor(nttmp2, i+7) == nt1) return -(i+7); + + if ( prng_successor(nttmp1, i+8) == nt2) return i+8; + if ( prng_successor(nttmp2, i+8) == nt1) return -(i+8); +*/ } return(-99999); // either nt1 or nt2 are invalid nonces @@ -2349,7 +2389,7 @@ void ReaderMifare(bool first_try, uint8_t block ) // if we missed the sync time already, advance to the next nonce repeat while(GetCountSspClk() > sync_time) { ++elapsed_prng_sequences; - sync_time = (sync_time & 0xfffffff8) + sync_cycles; + sync_time += sync_cycles; } // Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked) ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4c1fe1b64..ad8655db4 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -771,7 +771,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint32_t auth1_time, auth2_time; - static uint16_t delta_time; + static uint16_t delta_time = 0; LED_A_ON(); LED_C_OFF(); @@ -822,12 +822,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat rtr--; continue; }; + auth2_time = (delta_time) ? auth1_time + delta_time : 0; - if (delta_time) { - auth2_time = auth1_time + delta_time; - } else { - auth2_time = 0; - } if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) { if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error"); rtr--; @@ -836,7 +832,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 for (i = 101; i < 1200; i++) { - nttmp = prng_successor(nttmp, 1); + nttmp = prng_successor_one(nttmp); if (nttmp == nt2) break; } @@ -896,6 +892,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // nested authentication auth2_time = auth1_time + delta_time; + len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time); if (len != 4) { if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len); @@ -906,14 +903,18 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]); // Parity validity check - for (j = 0; j < 4; j++) { - par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01)); - } +// for (j = 0; j < 4; j++) { +// par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01)); +// } + par_array[0] = (oddparity8(receivedAnswer[0]) != ((par[0] >> (7-0)) & 0x01)); + par_array[1] = (oddparity8(receivedAnswer[1]) != ((par[0] >> (7-1)) & 0x01)); + par_array[2] = (oddparity8(receivedAnswer[2]) != ((par[0] >> (7-2)) & 0x01)); + par_array[3] = (oddparity8(receivedAnswer[3]) != ((par[0] >> (7-3)) & 0x01)); ncount = 0; nttest = prng_successor(nt1, dmin - 1); for (j = dmin; j < dmax + 1; j++) { - nttest = prng_successor(nttest, 1); + nttest = prng_successor_one(nttest); ks1 = nt2 ^ nttest; if (valid_nonce(nttest, nt2, ks1, par_array)){ @@ -942,8 +943,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // ----------------------------- crypto1 destroy crypto1_destroy(pcs); - byte_t buf[4 + 4 * 4]; - memcpy(buf, &cuid, 4); + byte_t buf[4 + 4 * 4] = {0}; + num_to_bytes(cuid, 4, buf); memcpy(buf+4, &target_nt[0], 4); memcpy(buf+8, &target_ks[0], 4); memcpy(buf+12, &target_nt[1], 4); @@ -986,9 +987,9 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) int OLD_MF_DBGLEVEL = MF_DBGLEVEL; MF_DBGLEVEL = MF_DBG_NONE; + LEDsoff(); LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); if (clearTrace) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d6cae59f0..3142fcd88 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -712,7 +712,6 @@ int CmdHF14AMfNested(const char *Cmd) // nested sectors iterations = 0; - PrintAndLog("enter nested..."); bool calibrate = true; for (i = 0; i < NESTED_SECTOR_RETRY; i++) { diff --git a/client/nonce2key/nonce2key.c b/client/nonce2key/nonce2key.c index 2d0590df3..95924e5e7 100644 --- a/client/nonce2key/nonce2key.c +++ b/client/nonce2key/nonce2key.c @@ -16,6 +16,7 @@ int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_t ks_info, uint64_t * key) { + struct Crypto1State *state; uint32_t i, pos, rr = 0, nr_diff; byte_t bt, ks3x[8], par[8][8]; @@ -39,17 +40,22 @@ int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_ for ( i = 0; i < 8; i++) { nr_diff = nr | i << 5; - printf("| %02x |%08x|", i << 5, nr_diff); - printf(" %01x | %01x |", ks3x[i], ks3x[i]^5); + printf("| %02x |%08x| %01x | %01x |", i << 5, nr_diff, ks3x[i], ks3x[i]^5); + for (pos = 0; pos < 7; pos++) printf("%01x,", par[i][pos]); printf("%01x|\n", par[i][7]); } printf("+----+--------+---+-----+---------------+\n"); + clock_t t1 = clock(); + state = lfsr_common_prefix(nr, rr, ks3x, par); lfsr_rollback_word(state, uid^nt, 0); crypto1_get_lfsr(state, key); crypto1_destroy(state); + + t1 = clock() - t1; + if ( t1 > 0 ) PrintAndLog("Time in nonce2key: %.0f ticks \n", (float)t1); return 0; } @@ -167,9 +173,9 @@ int tryMfk64(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){ pcs = &mpcs; uid = myuid;//(uint32_t)bytes_to_num(data + 0, 4); - nt = *(uint32_t*)(data+8); - nr_enc = *(uint32_t*)(data+12); - ar_enc = *(uint32_t*)(data+16); + nt = *(uint32_t*)(data+8); + nr_enc = *(uint32_t*)(data+12); + ar_enc = *(uint32_t*)(data+16); crypto1_word(pcs, nr_enc , 1); at_enc = prng_successor(nt, 96) ^ crypto1_word(pcs, 0, 0); @@ -195,4 +201,4 @@ int tryMfk64(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){ num_to_bytes(key, 6, outputkey); crypto1_destroy(revstate); return 0; -} \ No newline at end of file +} diff --git a/tools/mfkey/Makefile b/tools/mfkey/Makefile index aede38fd0..e1bb4d07d 100755 --- a/tools/mfkey/Makefile +++ b/tools/mfkey/Makefile @@ -5,7 +5,8 @@ LDFLAGS = OBJS = crapto1.o crypto1.o HEADERS = crapto1.h -EXES = mfkey64 mfkey64.exe mfkey32 mfkey32.exe mfkey32v2 mfkey32v2.exe +EXES = mfkey64 mfkey32 mfkey32v2 +WINEXE = mfkey64.exe mfkey32.exe mfkey32v2.exe LIBS = all: $(OBJS) $(EXES) $(LIBS) @@ -14,4 +15,5 @@ all: $(OBJS) $(EXES) $(LIBS) $(LD) $(CFLAGS) -o $@ $< $(OBJS) $(LDFLAGS) clean: - rm -f $(OBJS) $(EXES) $(LIBS) + rm -f $(OBJS) $(EXES) $(LIBS) $(WINEXE) + diff --git a/tools/nonce2key/Makefile b/tools/nonce2key/Makefile index 1800562d4..b84c9bbbe 100644 --- a/tools/nonce2key/Makefile +++ b/tools/nonce2key/Makefile @@ -5,7 +5,8 @@ LDFLAGS = OBJS = crypto1.o crapto1.o HEADERS = crapto1.h -EXES = nonce2key nonce2key.exe +EXES = nonce2key +WINEXES = nonce2key.exe all: $(OBJS) $(EXES) @@ -16,4 +17,4 @@ all: $(OBJS) $(EXES) $(LD) $(LDFLAGS) -o $@ $(OBJS) $< clean: - rm -f $(OBJS) $(EXES) + rm -f $(OBJS) $(EXES) $(WINEXES)