chg: reverting back to more or less offical pm3 version.

This commit is contained in:
iceman1001 2017-12-07 15:02:15 +01:00
parent e1a01dd2ff
commit 44280abf62
3 changed files with 42 additions and 51 deletions

View file

@ -2300,6 +2300,14 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
//-----------------------------------------------------------------------------
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
if ( first_try ) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
}
BigBuf_free(); BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
uint8_t mf_auth[] = { keytype, block, 0x00, 0x00 };
uint8_t mf_nr_ar[] = {0,0,0,0,0,0,0,0};
uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0};
@ -2309,9 +2317,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
uint8_t nt_diff = 0;
uint32_t nt = 0;
uint32_t previous_nt = 0;
uint32_t cuid = 0;
uint32_t nt = 0, previous_nt = 0, cuid = 0;
int32_t catch_up_cycles = 0;
int32_t last_catch_up = 0;
@ -2322,8 +2328,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
uint16_t unexpected_random = 0;
uint16_t sync_tries = 0;
bool received_nack;
bool have_uid = false;
bool received_nack;
uint8_t cascade_levels = 0;
// static variables here, is re-used in the next call
@ -2336,9 +2342,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
AppendCrc14443a(mf_auth, 2);
if (first_try) {
// create our reader nonce randomly
uint32_t nonce = prng_successor( GetCountSspClk() & 0xfffffff8 , 32);
num_to_bytes(nonce, 4, mf_nr_ar);
sync_time = GetCountSspClk() & 0xfffffff8;
sync_cycles = PRNG_SEQUENCE_LENGTH; // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
nt_attacked = 0;
mf_nr_ar3 = 0;
par_low = 0;
} else {
@ -2349,27 +2355,16 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
par[0] = par_low;
}
sync_cycles = PRNG_SEQUENCE_LENGTH; // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
nt_attacked = 0;
BigBuf_free(); BigBuf_Clear_ext(false);
clear_trace();
set_tracing(false);
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
sync_time = GetCountSspClk() & 0xfffffff8;
if (MF_DBGLEVEL >= 4) Dbprintf("Mifare::Sync %u", sync_time);
LED_C_ON();
uint16_t i;
for(i = 0; true; ++i) {
for (i = 0; true; ++i) {
received_nack = false;
WDT_HIT();
// Test if the action was cancelled
if(BUTTON_PRESS()) {
if (BUTTON_PRESS()) {
isOK = -1;
break;
}
@ -2403,14 +2398,14 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
// if we missed the sync time already, advance to the next nonce repeat
while ( GetCountSspClk() > sync_time) {
++elapsed_prng_sequences;
elapsed_prng_sequences++;
sync_time = (sync_time & 0xfffffff8 ) + 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);
// Receive the (4 Byte) "random" nonce from TAG
// Receive the (4 Byte) "random" TAG nonce
if (!ReaderReceive(receivedAnswer, receivedAnswerPar))
continue;
@ -2421,9 +2416,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
if (ReaderReceive(receivedAnswer, receivedAnswerPar))
received_nack = true;
}
// we didn't calibrate our clock yet,
// iceman: has to be calibrated every time.
if (first_try && previous_nt && !nt_attacked) {
@ -2557,7 +2552,6 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
* Thanks to @doegox for the feedback and new approaches.
*/
void DetectNACKbug() {
uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B};
uint8_t mf_nr_ar[] = {0,0,0,0,0,0,0,0};
uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0};
@ -2578,28 +2572,22 @@ void DetectNACKbug() {
// Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
uint32_t sync_cycles = PRNG_SEQUENCE_LENGTH;
// create our reader nonce randomly
uint32_t nonce = prng_successor( GetCountSspClk() & 0xfffffff8 , 32);
num_to_bytes(nonce, 4, mf_nr_ar);
BigBuf_free(); BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
sync_time = GetCountSspClk() & 0xfffffff8;
if (MF_DBGLEVEL >= 4) Dbprintf("Mifare::Sync %u", sync_time);
LED_C_ON();
uint16_t i;
for (i = 0; true; ++i) {
for (i = 1; true; ++i) {
received_nack = false;
// Cards always leaks a NACK, no matter the parity
if ((i==10) && (num_nacks == i)) {
if ((i==10) && (num_nacks == i-1)) {
isOK = 2;
break;
}
@ -2607,7 +2595,7 @@ void DetectNACKbug() {
WDT_HIT();
// Test if the action was cancelled
if(BUTTON_PRESS()) {
if (BUTTON_PRESS()) {
isOK = 99;
break;
}
@ -2640,7 +2628,7 @@ void DetectNACKbug() {
catch_up_cycles = 0;
// if we missed the sync time already, advance to the next nonce repeat
while( GetCountSspClk() > sync_time) {
while ( GetCountSspClk() > sync_time) {
++elapsed_prng_sequences;
sync_time = (sync_time & 0xfffffff8 ) + sync_cycles;
}
@ -2648,7 +2636,7 @@ void DetectNACKbug() {
// Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked)
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
// Receive the (4 Byte) "random" nonce from TAG
// Receive the (4 Byte) "random" TAG nonce
if (!ReaderReceive(receivedAnswer, receivedAnswerPar))
continue;
@ -2661,6 +2649,10 @@ void DetectNACKbug() {
if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
received_nack = true;
num_nacks++;
// ALWAYS leak Detection.
if ( i == num_nacks ) {
continue;
}
}
// we didn't calibrate our clock yet,
@ -2675,7 +2667,7 @@ void DetectNACKbug() {
} else {
if (nt_distance == -99999) { // invalid nonce received
unexpected_random++;
if (unexpected_random > MAX_UNEXPECTED_RANDOM) {
if (unexpected_random > MAX_UNEXPECTED_RANDOM ) {
// Card has an unpredictable PRNG. Give up
isOK = 98;
break;
@ -2683,7 +2675,7 @@ void DetectNACKbug() {
if (sync_cycles <= 0) {
sync_cycles += PRNG_SEQUENCE_LENGTH;
}
continue; // continue trying...
continue;
}
}

View file

@ -33,7 +33,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
while (ukbhit()) {
int gc = getchar(); (void)gc;
}
// wait cycle
while (true) {
printf(".");
@ -61,7 +61,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
printf("\n");
if (par_list == 0 && c.arg[0] == true) {
PrintAndLog("Parity is all zero. Most likely this card sends NACK on every failed authentication.");
PrintAndLog("Parity is all zero. Most likely this card sends NACK on every authentication.");
PrintAndLog("Attack will take a few seconds longer because we need two consecutive successful runs.");
}
c.arg[0] = false;

View file

@ -160,15 +160,15 @@ struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
int i;
// split the keystream into an odd and even part
for(i = 31; i >= 0; i -= 2)
for (i = 31; i >= 0; i -= 2)
oks = oks << 1 | BEBIT(ks2, i);
for(i = 30; i >= 0; i -= 2)
for (i = 30; i >= 0; i -= 2)
eks = eks << 1 | BEBIT(ks2, i);
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
even_head = even_tail = malloc(sizeof(uint32_t) << 21);
statelist = malloc(sizeof(struct Crypto1State) << 18);
if(!odd_tail-- || !even_tail-- || !statelist) {
if (!odd_tail-- || !even_tail-- || !statelist) {
free(statelist);
statelist = 0;
goto out;
@ -181,7 +181,7 @@ struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
for (uint32_t i = 0; i < 2; i++) {
for (uint32_t j = 0; j <= 0xff; j++) {
bucket[i][j].head = malloc(sizeof(uint32_t)<<14);
bucket[i][j].head = malloc(sizeof(uint32_t) << 14);
if (!bucket[i][j].head) {
goto out;
}
@ -436,7 +436,6 @@ static uint32_t fastfwd[2][8] = {
{ 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
{ 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
/** lfsr_prefix_ks
*
* Is an exported helper function from the common prefix attack
@ -523,15 +522,15 @@ struct Crypto1State* lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8]
even = lfsr_prefix_ks(ks, 0);
s = statelist = malloc((sizeof *statelist) << 24); // was << 20. Need more for no_par special attack. Enough???
if(!s || !odd || !even) {
if (!s || !odd || !even) {
free(statelist);
statelist = 0;
goto out;
goto out;
}
for(o = odd; *o + 1; ++o)
for(e = even; *e + 1; ++e)
for(top = 0; top < 64; ++top) {
for (o = odd; *o + 1; ++o)
for (e = even; *e + 1; ++e)
for (top = 0; top < 64; ++top) {
*o += 1 << 21;
*e += (!(top & 7) + 1) << 21;
s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par);