+
+ // this part is from Piwi's faster nonce collecting part in Hardnested.
+ if (!have_uid) { // need a full select cycle to get the uid first
+ iso14a_card_select_t card_info;
+ if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {
+ if (MF_DBGLEVEL >= 4) Dbprintf("Mifare: Can't select card (ALL)");
+ break;
+ }
+ switch (card_info.uidlen) {
+ case 4 : cascade_levels = 1; break;
+ case 7 : cascade_levels = 2; break;
+ case 10: cascade_levels = 3; break;
+ default: break;
+ }
+ have_uid = TRUE;
+ } else { // no need for anticollision. We can directly select the card
+ if(!iso14443a_select_card(uid, NULL, &cuid, false, cascade_levels)) {
+ if (MF_DBGLEVEL >= 4) Dbprintf("Mifare: Can't select card (UID)");
+ continue;
+ }
+ }
+
+ // Sending timeslot of ISO14443a frame
+ sync_time = (sync_time & 0xfffffff8 ) + sync_cycles + catch_up_cycles;
+ catch_up_cycles = 0;
+
+ // 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;
+ }
+
+ // 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
+ if (!ReaderReceive(receivedAnswer, receivedAnswerPar))
+ continue;
+
+ previous_nt = nt;
+ nt = bytes_to_num(receivedAnswer, 4);
+
+ // Transmit reader nonce with fake par
+ ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
+
+ // we didn't calibrate our clock yet,
+ // iceman: has to be calibrated every time.
+ if (previous_nt && !nt_attacked) {
+
+ nt_distance = dist_nt(previous_nt, nt);
+
+ // if no distance between, then we are in sync.
+ if (nt_distance == 0) {
+ nt_attacked = nt;
+ } else {
+ if (nt_distance == -99999) { // invalid nonce received
+ ++unexpected_random;
+ if (unexpected_random > MAX_UNEXPECTED_RANDOM) {
+ isOK = -3; // Card has an unpredictable PRNG. Give up
+ break;
+ } else {
+ if (sync_cycles <= 0) sync_cycles += PRNG_SEQUENCE_LENGTH;
+ LED_B_OFF();
+ continue; // continue trying...
+ }
+ }
+
+ if (++sync_tries > MAX_SYNC_TRIES) {
+ isOK = -4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly
+ break;
+ }
+
+ sync_cycles = (sync_cycles - nt_distance)/elapsed_prng_sequences;
+
+ if (sync_cycles <= 0)
+ sync_cycles += PRNG_SEQUENCE_LENGTH;
+
+ if (MF_DBGLEVEL >= 4)
+ Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles);
+
+ LED_B_OFF();
+ continue;
+ }
+ }
+ LED_B_OFF();
+
+ if ( (nt != nt_attacked) && nt_attacked) { // we somehow lost sync. Try to catch up again...
+
+ catch_up_cycles = ABS(dist_nt(nt_attacked, nt));
+ if (catch_up_cycles == 99999) { // invalid nonce received. Don't resync on that one.
+ catch_up_cycles = 0;
+ continue;
+ }
+ // average?
+ catch_up_cycles /= elapsed_prng_sequences;
+
+ if (catch_up_cycles == last_catch_up) {
+ ++consecutive_resyncs;
+ } else {
+ last_catch_up = catch_up_cycles;
+ consecutive_resyncs = 0;
+ }
+
+ if (consecutive_resyncs < 3) {
+ if (MF_DBGLEVEL >= 4)
+ Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs);
+ } else {
+ sync_cycles += catch_up_cycles;
+
+ if (MF_DBGLEVEL >= 4)
+ Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles);
+
+ last_catch_up = 0;
+ catch_up_cycles = 0;
+ consecutive_resyncs = 0;
+ }
+ continue;
+ }
+
+ // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
+ if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
+ catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer
+
+ if (nt_diff == 0)
+ par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change
+
+ par_list[nt_diff] = SwapBits(par[0], 8);
+ ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // xor with NACK value to get keystream
+
+ // Test if the information is complete
+ if (nt_diff == 0x07) {
+ isOK = 1;
+ break;
+ }
+
+ nt_diff = (nt_diff + 1) & 0x07;
+ mf_nr_ar[3] = (mf_nr_ar[3] & 0x1F) | (nt_diff << 5);
+ par[0] = par_low;
+
+ } else {
+ // No NACK.
+ if (nt_diff == 0 && first_try) {
+ par[0]++;
+ if (par[0] == 0x00) { // tried all 256 possible parities without success. Card doesn't send NACK.
+ isOK = -2;
+ break;
+ }
+ } else {
+ // Why this?
+ par[0] = ((par[0] & 0x1F) + 1) | par_low;
+ }
+ }
+
+ // reset the resyncs since we got a complete transaction on right time.
+ consecutive_resyncs = 0;
+ } // end for loop
+
+ mf_nr_ar[3] &= 0x1F;
+
+ if (MF_DBGLEVEL >= 4) Dbprintf("Number of sent auth requestes: %u", i);
+
+ uint8_t buf[28] = {0x00};
+ memset(buf, 0x00, sizeof(buf));
+ num_to_bytes(cuid, 4, buf);
+ num_to_bytes(nt, 4, buf + 4);
+ memcpy(buf + 8, par_list, 8);
+ memcpy(buf + 16, ks_list, 8);
+ memcpy(buf + 24, mf_nr_ar, 4);
+
+ cmd_send(CMD_ACK, isOK, 0, 0, buf, sizeof(buf) );
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LEDsoff();
+ set_tracing(FALSE);
+}
+
+
+/**
+ *MIFARE 1K simulate.
+ *
+ *@param flags :
+ * FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK
+ * FLAG_4B_UID_IN_DATA - use 4-byte UID in the data-section
+ * FLAG_7B_UID_IN_DATA - use 7-byte UID in the data-section
+ * FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section
+ * FLAG_UID_IN_EMUL - use 4-byte UID from emulator memory
+ * FLAG_NR_AR_ATTACK - collect NR_AR responses for bruteforcing later
+ *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is inifite
+ */
+void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *datain) {
+ int cardSTATE = MFEMUL_NOFIELD;
+ int _UID_LEN = 0; // 4, 7, 10
+ int vHf = 0; // in mV
+ int res = 0;
+ uint32_t selTimer = 0;
+ uint32_t authTimer = 0;
+ uint16_t len = 0;
+ uint8_t cardWRBL = 0;
+ uint8_t cardAUTHSC = 0;
+ uint8_t cardAUTHKEY = 0xff; // no authentication
+ uint32_t cuid = 0;
+ uint32_t ans = 0;
+ uint32_t cardINTREG = 0;
+ uint8_t cardINTBLOCK = 0;
+ struct Crypto1State mpcs = {0, 0};
+ struct Crypto1State *pcs;
+ pcs = &mpcs;
+ uint32_t numReads = 0; // Counts numer of times reader read a block
+ uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
+ uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE] = {0x00};
+ uint8_t response[MAX_MIFARE_FRAME_SIZE] = {0x00};
+ uint8_t response_par[MAX_MIFARE_PARITY_SIZE] = {0x00};
+
+ uint8_t atqa[] = {0x04, 0x00}; // Mifare classic 1k
+ uint8_t sak_4[] = {0x0C, 0x00, 0x00}; // CL1 - 4b uid
+ uint8_t sak_7[] = {0x0C, 0x00, 0x00}; // CL2 - 7b uid
+ uint8_t sak_10[] = {0x0C, 0x00, 0x00}; // CL3 - 10b uid
+ // uint8_t sak[] = {0x09, 0x3f, 0xcc }; // Mifare Mini
+
+ uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
+ uint8_t rUIDBCC2[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
+ uint8_t rUIDBCC3[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
+
+ uint8_t rAUTH_NT[] = {0x01, 0x01, 0x01, 0x01}; // very random nonce
+ // uint8_t rAUTH_NT[] = {0x55, 0x41, 0x49, 0x92};// nonce from nested? why this?
+ uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00};
+
+ // Here, we collect CUID, NT, NR, AR, CUID2, NT2, NR2, AR2
+ // This can be used in a reader-only attack.
+ uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0,0};
+ uint8_t ar_nr_collected = 0;
+
+ // Authenticate response - nonce
+ uint32_t nonce = bytes_to_num(rAUTH_NT, 4);
+ ar_nr_responses[1] = nonce;
+
+ // -- Determine the UID
+ // Can be set from emulator memory or incoming data
+ // Length: 4,7,or 10 bytes
+ if ( (flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL)
+ emlGetMemBt(datain, 0, 10); // load 10bytes from EMUL to the datain pointer. to be used below.
+
+ if ( (flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) {
+ memcpy(rUIDBCC1, datain, 4);
+ _UID_LEN = 4;
+ } else if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) {
+ memcpy(&rUIDBCC1[1], datain, 3);
+ memcpy( rUIDBCC2, datain+3, 4);
+ _UID_LEN = 7;
+ } else if ( (flags & FLAG_10B_UID_IN_DATA) == FLAG_10B_UID_IN_DATA) {
+ memcpy(&rUIDBCC1[1], datain, 3);
+ memcpy(&rUIDBCC2[1], datain+3, 3);
+ memcpy( rUIDBCC3, datain+6, 4);
+ _UID_LEN = 10;
+ }
+
+ switch (_UID_LEN) {
+ case 4:
+ sak_4[0] &= 0xFB;
+ // save CUID
+ ar_nr_responses[0] = cuid = bytes_to_num(rUIDBCC1, 4);
+ // BCC
+ rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
+ if (MF_DBGLEVEL >= 2) {
+ Dbprintf("4B UID: %02x%02x%02x%02x",
+ rUIDBCC1[0],
+ rUIDBCC1[1],
+ rUIDBCC1[2],
+ rUIDBCC1[3]
+ );
+ }
+ break;
+ case 7:
+ atqa[0] |= 0x40;
+ sak_7[0] &= 0xFB;
+ // save CUID
+ ar_nr_responses[0] = cuid = bytes_to_num(rUIDBCC2, 4);
+ // CascadeTag, CT
+ rUIDBCC1[0] = 0x88;
+ // BCC
+ rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
+ rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
+ if (MF_DBGLEVEL >= 2) {
+ Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x",
+ rUIDBCC1[1],
+ rUIDBCC1[2],
+ rUIDBCC1[3],
+ rUIDBCC2[0],
+ rUIDBCC2[1],
+ rUIDBCC2[2],
+ rUIDBCC2[3]
+ );
+ }
+ break;
+ case 10:
+ atqa[0] |= 0x80;
+ sak_10[0] &= 0xFB;
+ // save CUID
+ ar_nr_responses[0] = cuid = bytes_to_num(rUIDBCC3, 4);
+ // CascadeTag, CT
+ rUIDBCC1[0] = 0x88;
+ rUIDBCC2[0] = 0x88;
+ // BCC
+ rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
+ rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
+ rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3];
+
+ if (MF_DBGLEVEL >= 2) {
+ Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ rUIDBCC1[1],
+ rUIDBCC1[2],
+ rUIDBCC1[3],
+ rUIDBCC2[1],
+ rUIDBCC2[2],
+ rUIDBCC2[3],
+ rUIDBCC3[0],
+ rUIDBCC3[1],
+ rUIDBCC3[2],
+ rUIDBCC3[3]
+ );
+ }
+ break;
+ default:
+ break;
+ }
+ // calc some crcs
+ ComputeCrc14443(CRC_14443_A, sak_4, 1, &sak_4[1], &sak_4[2]);
+ ComputeCrc14443(CRC_14443_A, sak_7, 1, &sak_7[1], &sak_7[2]);
+ ComputeCrc14443(CRC_14443_A, sak_10, 1, &sak_10[1], &sak_10[2]);
+
+ // We need to listen to the high-frequency, peak-detected path.
+ iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
+
+ // free eventually allocated BigBuf memory but keep Emulator Memory
+ BigBuf_free_keep_EM();
+ clear_trace();
+ set_tracing(TRUE);
+
+ bool finished = FALSE;
+ while (!BUTTON_PRESS() && !finished && !usb_poll_validate_length()) {
+ WDT_HIT();
+
+ // find reader field
+ if (cardSTATE == MFEMUL_NOFIELD) {
+ vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
+ if (vHf > MF_MINFIELDV) {
+ cardSTATE_TO_IDLE();
+ LED_A_ON();
+ }
+ }
+ if (cardSTATE == MFEMUL_NOFIELD) continue;
+
+ // Now, get data
+ res = EmGetCmd(receivedCmd, &len, receivedCmd_par);
+ if (res == 2) { //Field is off!
+ cardSTATE = MFEMUL_NOFIELD;
+ LEDsoff();
+ continue;
+ } else if (res == 1) {
+ break; // return value 1 means button press
+ }
+
+ // REQ or WUP request in ANY state and WUP in HALTED state
+ // this if-statement doesn't match the specification above. (iceman)
+ if (len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) {
+ selTimer = GetTickCount();
+ EmSendCmdEx(atqa, sizeof(atqa), (receivedCmd[0] == ISO14443A_CMD_WUPA));
+ cardSTATE = MFEMUL_SELECT1;
+ crypto1_destroy(pcs);
+ cardAUTHKEY = 0xff;
+ LEDsoff();
+ nonce++;
+ continue;
+ }
+
+ switch (cardSTATE) {
+ case MFEMUL_NOFIELD:
+ case MFEMUL_HALTED:
+ case MFEMUL_IDLE:{
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+ break;
+ }
+ case MFEMUL_SELECT1:{
+ if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && receivedCmd[1] == 0x20)) {
+ if (MF_DBGLEVEL >= 4) Dbprintf("SELECT ALL received");
+ EmSendCmd(rUIDBCC1, sizeof(rUIDBCC1));
+ break;
+ }
+ // select card
+ if (len == 9 &&
+ ( receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT &&
+ receivedCmd[1] == 0x70 &&
+ memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) {
+
+ // SAK 4b
+ EmSendCmd(sak_4, sizeof(sak_4));
+ switch(_UID_LEN){
+ case 4:
+ cardSTATE = MFEMUL_WORK;
+ LED_B_ON();
+ if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - selTimer);
+ continue;
+ case 7:
+ case 10:
+ cardSTATE = MFEMUL_SELECT2;
+ continue;
+ default:break;
+ }
+ } else {
+ cardSTATE_TO_IDLE();
+ }
+ break;
+ }
+ case MFEMUL_SELECT2:{
+ if (!len) {
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+ break;
+ }
+ if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && receivedCmd[1] == 0x20)) {
+ EmSendCmd(rUIDBCC2, sizeof(rUIDBCC2));
+ break;
+ }
+ if (len == 9 &&
+ (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 &&
+ receivedCmd[1] == 0x70 &&
+ memcmp(&receivedCmd[2], rUIDBCC2, 4) == 0) ) {
+
+ EmSendCmd(sak_7, sizeof(sak_7));
+ switch(_UID_LEN){
+ case 7:
+ cardSTATE = MFEMUL_WORK;
+ LED_B_ON();
+ if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer);
+ continue;
+ case 10:
+ cardSTATE = MFEMUL_SELECT3;
+ continue;
+ default:break;
+ }
+ }
+ cardSTATE_TO_IDLE();
+ break;
+ }
+ case MFEMUL_SELECT3:{
+ if (!len) {
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+ break;
+ }
+ if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && receivedCmd[1] == 0x20)) {
+ EmSendCmd(rUIDBCC3, sizeof(rUIDBCC3));
+ break;
+ }
+ if (len == 9 &&
+ (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 &&
+ receivedCmd[1] == 0x70 &&
+ memcmp(&receivedCmd[2], rUIDBCC3, 4) == 0) ) {
+
+ EmSendCmd(sak_10, sizeof(sak_10));
+ cardSTATE = MFEMUL_WORK;
+ LED_B_ON();
+ if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol3 time: %d", GetTickCount() - selTimer);
+ break;
+ }
+ cardSTATE_TO_IDLE();
+ break;
+ }
+ case MFEMUL_AUTH1:{
+ if( len != 8) {
+ cardSTATE_TO_IDLE();
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+ break;
+ }