- }
-
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LEDsoff();
-}
-
-#define TEST_LENGTH 100
-typedef struct mftest{
- uint8_t nt[8];
- uint8_t count;
-}mftest ;
-
-/**
- *@brief Tunes the mifare attack settings. This method checks the nonce entropy when
- *using a specified timeout.
- *Different cards behave differently, some cards require up to a second to power down (and thus reset
- *token generator), other cards are fine with 50 ms.
- *
- * @param time
- * @return the entropy. A value of 100 (%) means that every nonce was unique, while a value close to
- *zero indicates a low entropy: the given timeout is sufficient to power down the card.
- */
-int TuneMifare(int time)
-{
- // Mifare AUTH
- uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b };
- //uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
- uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); // was 3560 - tied to other size changes
-
- iso14443a_setup();
- int TIME1=time;
- int TIME2=2000;
- uint8_t uid[8];
- uint32_t cuid;
- byte_t nt[4];
- Dbprintf("Tuning... testing a delay of %d ms",time);
-
-
- mftest nt_values[TEST_LENGTH];
- int nt_size = 0;
- int i = 0;
- for(i = 0 ; i< 100 ; i++)
- {
- LED_C_OFF();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelay(TIME1);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
- LED_C_ON();
- SpinDelayUs(TIME2);
- if(!iso14443a_select_card(uid, NULL, &cuid)) continue;
-
- // Transmit MIFARE_CLASSIC_AUTH
- ReaderTransmit(mf_auth, sizeof(mf_auth));
-
- // Receive the (16 bit) "random" nonce
- if (!ReaderReceive(receivedAnswer)) continue;
- memcpy(nt, receivedAnswer, 4);
-
- //store it
- int already_stored = 0;
- for(int i = 0 ; i < nt_size && !already_stored; i++)
- {
- if( memcmp(nt, nt_values[i].nt, 4) == 0)
- {
- nt_values[i].count++;
- already_stored = 1;
- }
- }
- if(!already_stored)
- {
- mftest* ptr= &nt_values[nt_size++];
- //Clear it before use
- memset(ptr, 0, sizeof(mftest));
- memcpy(ptr->nt, nt, 4);
- ptr->count = 1;
- }
-
- if(BUTTON_PRESS())
- {
- Dbprintf("Tuning aborted prematurely");
- break;
- }
- }
- /*
- for(int i = 0 ; i < nt_size;i++){
- mftest x = nt_values[i];
- Dbprintf("%d,%d,%d,%d : %d",x.nt[0],x.nt[1],x.nt[2],x.nt[3],x.count);
- }
- */
- int result = nt_size *100 / i;
- Dbprintf(" ... results for %d ms : %d %",time, result);
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// Read an ISO 14443a tag. Send out commands and store answers.
-//
-//-----------------------------------------------------------------------------
-#define STATE_SIZE 100
-typedef struct AttackState{
- byte_t nt[4];
- //byte_t nt_attacked[4];
- byte_t par_list[8];
- byte_t ks_list[8];
- byte_t par;
- byte_t par_low;
- byte_t nt_diff;
- uint8_t mf_nr_ar[8];
-} AttackState;
-
-
-int continueAttack(AttackState* pState,uint8_t* receivedAnswer)
-{
-
- // Transmit reader nonce and reader answer
- ReaderTransmitPar(pState->mf_nr_ar, sizeof(pState->mf_nr_ar),pState->par);
-
- // Receive 4 bit answer
- int len = ReaderReceive(receivedAnswer);
- if (!len)
- {
- if (pState->nt_diff == 0)
- {
- pState->par++;
- } else {
- pState->par = (((pState->par >> 3) + 1) << 3) | pState->par_low;
- }
- return 2;
- }
- if(pState->nt_diff == 0)
- {
- pState->par_low = pState->par & 0x07;
- }
- //Dbprintf("answer received, parameter (%d), (memcmp(nt, nt_no)=%d",parameter,memcmp(nt, nt_noattack, 4));
- //if ( (parameter != 0) && (memcmp(nt, nt_noattack, 4) == 0) ) continue;
- //isNULL = 0;//|| !(nt_attacked[0] == 0) && (nt_attacked[1] == 0) && (nt_attacked[2] == 0) && (nt_attacked[3] == 0);
- //
- // if ( /*(isNULL != 0 ) && */(memcmp(nt, nt_attacked, 4) != 0) ) continue;
-
- //led_on = !led_on;
- //if(led_on) LED_B_ON(); else LED_B_OFF();
- pState->par_list[pState->nt_diff] = pState->par;
- pState->ks_list[pState->nt_diff] = receivedAnswer[0] ^ 0x05;
-
- // Test if the information is complete
- if (pState->nt_diff == 0x07) {
- return 0;
- }