X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/6b23be6b7ecd1660922d53c8c1c0522f69389dc6..c3fc86d9af62ccf5a416ef6d732f350c028c5200:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index f9dfebd9..61c018bb 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -867,16 +867,16 @@ 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 #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack() - nonces_t ar_nr_resp[ATTACK_KEY_COUNT*2]; //*2 for 2 separate attack types (nml, moebius) + nonces_t ar_nr_resp[ATTACK_KEY_COUNT*2]; // for 2 separate attack types (nml, moebius) memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp)); - uint8_t ar_nr_collected[ATTACK_KEY_COUNT*2]; //*2 for 2nd attack type (moebius) + uint8_t ar_nr_collected[ATTACK_KEY_COUNT*2]; // for 2nd attack type (moebius) memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected)); uint8_t nonce1_count = 0; uint8_t nonce2_count = 0; uint8_t moebius_n_count = 0; bool gettingMoebius = false; - uint8_t mM = 0; //moebius_modifier for collection storage + uint8_t mM = 0; // moebius_modifier for collection storage switch (tagType) { @@ -918,8 +918,8 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { uint16_t start = 4 * (0+12); uint8_t emdata[8]; emlGetMemBt( emdata, start, sizeof(emdata)); - memcpy(data, emdata, 3); //uid bytes 0-2 - memcpy(data+3, emdata+4, 4); //uid bytes 3-7 + memcpy(data, emdata, 3); // uid bytes 0-2 + memcpy(data+3, emdata+4, 4); // uid bytes 3-7 flags |= FLAG_7B_UID_IN_DATA; } } break; @@ -984,10 +984,10 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { nonce = bytes_to_num(response5, 4); // Prepare GET_VERSION (different for UL EV-1 / NTAG) - //uint8_t response7_EV1[] = {0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x0b, 0x03, 0xfd, 0xf7}; //EV1 48bytes VERSION. - //uint8_t response7_NTAG[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x11, 0x03, 0x01, 0x9e}; //NTAG 215 + // uint8_t response7_EV1[] = {0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x0b, 0x03, 0xfd, 0xf7}; //EV1 48bytes VERSION. + // uint8_t response7_NTAG[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x11, 0x03, 0x01, 0x9e}; //NTAG 215 // Prepare CHK_TEARING - //uint8_t response9[] = {0xBD,0x90,0x3f}; + // uint8_t response9[] = {0xBD,0x90,0x3f}; #define TAG_RESPONSE_COUNT 10 tag_response_info_t responses[TAG_RESPONSE_COUNT] = { @@ -1001,8 +1001,8 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { { .response = response8, .response_n = sizeof(response8) } // EV1/NTAG PACK response }; - //{ .response = response7_NTAG, .response_n = sizeof(response7_NTAG)}, // EV1/NTAG GET_VERSION response - //{ .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response + // { .response = response7_NTAG, .response_n = sizeof(response7_NTAG)}, // EV1/NTAG GET_VERSION response + // { .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response // Allocate 512 bytes for the dynamic modulation, created when the reader queries for it @@ -1081,7 +1081,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { uint8_t block = receivedCmd[1]; // if Ultralight or NTAG (4 byte blocks) if ( tagType == 7 || tagType == 2 ) { - //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] uint16_t start = 4 * (block+12); uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; emlGetMemBt( emdata, start, 16); @@ -1094,14 +1094,14 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { emlGetMemBt( emdata, block, 16); AppendCrc14443a(emdata, 16); EmSendCmdEx(emdata, sizeof(emdata), false); - //EmSendCmdEx(data+(4*receivedCmd[1]),16,false); + // EmSendCmdEx(data+(4*receivedCmd[1]),16,false); // Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]); // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below p_response = NULL; } } else if(receivedCmd[0] == MIFARE_ULEV1_FASTREAD) { // Received a FAST READ (ranged read) uint8_t emdata[MAX_FRAME_SIZE]; - //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] int start = (receivedCmd[1]+12) * 4; int len = (receivedCmd[2] - receivedCmd[1] + 1) * 4; emlGetMemBt( emdata, start, len); @@ -1109,7 +1109,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { EmSendCmdEx(emdata, len+2, false); p_response = NULL; } else if(receivedCmd[0] == MIFARE_ULEV1_READSIG && tagType == 7) { // Received a READ SIGNATURE -- - //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] uint16_t start = 4 * 4; uint8_t emdata[34]; emlGetMemBt( emdata, start, 32); @@ -1136,7 +1136,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { EmSendCmdEx(ack,sizeof(ack),false); p_response = NULL; } else if(receivedCmd[0] == MIFARE_ULEV1_CHECKTEAR && tagType == 7) { // Received a CHECK_TEARING_EVENT -- - //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] uint8_t emdata[3]; uint8_t counter=0; if (receivedCmd[1]<3) counter = receivedCmd[1]; @@ -1237,7 +1237,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { } else if (receivedCmd[0] == MIFARE_ULC_AUTH_1 ) { // ULC authentication, or Desfire Authentication } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH) { // NTAG / EV-1 authentication if ( tagType == 7 ) { - uint16_t start = 13; //first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00] + uint16_t start = 13; // first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00] uint8_t emdata[4]; emlGetMemBt( emdata, start, 2); AppendCrc14443a(emdata, 2); @@ -1835,10 +1835,10 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) { // if anticollision is false, then the UID must be provided in uid_ptr[] // and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID) int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades) { - uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP - uint8_t sel_all[] = { 0x93,0x20 }; - uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 + uint8_t wupa[] = { ISO14443A_CMD_WUPA }; // 0x26 - ISO14443A_CMD_REQA 0x52 - ISO14443A_CMD_WUPA + uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x20 }; + uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t rats[] = { ISO14443A_CMD_RATS,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 uint8_t resp[MAX_FRAME_SIZE] = {0}; // theoretically. A usual RATS will be much smaller uint8_t resp_par[MAX_PARITY_SIZE] = {0}; byte_t uid_resp[4] = {0}; @@ -1987,31 +1987,31 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u } void iso14443a_setup(uint8_t fpga_minor_mode) { + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Set up the synchronous serial port FpgaSetupSsc(); // connect Demodulated Signal to ADC: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode); - LED_D_OFF(); // Signal field is on with the appropriate LED if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) LED_D_ON(); - // Prepare the demodulation functions - DemodReset(); - UartReset(); - - iso14a_set_timeout(10*106); // 10ms default + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode); - //NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; - NextTransferTime = DELAY_ARM2AIR_AS_READER << 1; + SpinDelay(20); // Start the timer StartCountSspClk(); + + // Prepare the demodulation functions + DemodReset(); + UartReset(); + NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; + iso14a_set_timeout(10*106); // 20ms default } int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) { @@ -2044,9 +2044,9 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) { return len; } + //----------------------------------------------------------------------------- // Read an ISO 14443a tag. Send out commands and store answers. -// //----------------------------------------------------------------------------- void ReaderIso14443a(UsbCommand *c) { iso14a_command_t param = c->arg[0]; @@ -2142,29 +2142,34 @@ 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 (i = 1; i < (32768/8); ++i) { + for (uint16_t i = 1; i < 32768/8; ++i) { nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i; nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -i; nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+1; nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+1); + nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+2; nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+2); + nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+3; nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+3); + nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+4; nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+4); + nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+5; nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+5); + nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+6; nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+6); + nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+7; - nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+7); - } + nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+7); + } // either nt1 or nt2 are invalid nonces return(-99999); } @@ -2175,8 +2180,10 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) { // Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime" // (article by Nicolas T. Courtois, 2009) //----------------------------------------------------------------------------- -void ReaderMifare(bool first_try, uint8_t block ) { - uint8_t mf_auth[] = { MIFARE_AUTH_KEYA, block, 0x00, 0x00 }; + +void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) { + + uint8_t mf_auth[] = { keytype, block, 0x00, 0x00 }; uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; uint8_t par_list[8] = {0,0,0,0,0,0,0,0}; @@ -2209,19 +2216,22 @@ void ReaderMifare(bool first_try, uint8_t block ) { #define PRNG_SEQUENCE_LENGTH (1 << 16) #define MAX_UNEXPECTED_RANDOM 4 // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up. #define MAX_SYNC_TRIES 32 - + + AppendCrc14443a(mf_auth, 2); + BigBuf_free(); BigBuf_Clear_ext(false); clear_trace(); set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); - AppendCrc14443a(mf_auth, 2); + 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; - if (first_try) { - sync_time = GetCountSspClk() & 0xfffffff8; - sync_cycles = PRNG_SEQUENCE_LENGTH + 1130; //65536; //0x10000 // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). - mf_nr_ar3 = 0; - nt_attacked = 0; + if (MF_DBGLEVEL >= 4) Dbprintf("Mifare::Sync %08x", sync_time); + + if (first_try) { + mf_nr_ar3 = 0; par_low = 0; } else { // we were unsuccessful on a previous call. @@ -2290,9 +2300,9 @@ void ReaderMifare(bool first_try, uint8_t block ) { // Transmit reader nonce with fake par ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); - WDT_HIT(); - LED_B_ON(); - if (first_try && previous_nt && !nt_attacked) { // we didn't calibrate our clock yet + // 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); @@ -2331,7 +2341,7 @@ void ReaderMifare(bool first_try, uint8_t block ) { } LED_B_OFF(); - if ((nt != nt_attacked) && nt_attacked) { // we somehow lost sync. Try to catch up again... + 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. @@ -2421,6 +2431,7 @@ void ReaderMifare(bool first_try, uint8_t block ) { set_tracing(FALSE); } + /** *MIFARE 1K simulate. * @@ -2451,7 +2462,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; - uint32_t numReads = 0; //Counts numer of times reader read a block + 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}; @@ -2461,14 +2472,14 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * 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 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_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 @@ -2480,7 +2491,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * uint32_t nonce = bytes_to_num(rAUTH_NT, 4); ar_nr_responses[1] = nonce; - //-- Determine the UID + // -- 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) @@ -2596,14 +2607,14 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } if (cardSTATE == MFEMUL_NOFIELD) continue; - //Now, get data + // 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 + break; // return value 1 means button press } // REQ or WUP request in ANY state and WUP in HALTED state @@ -2720,16 +2731,16 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * uint32_t nr = bytes_to_num(receivedCmd, 4); uint32_t ar = bytes_to_num(&receivedCmd[4], 4); - //Collect AR/NR - //if(ar_nr_collected < 2 && cardAUTHSC == 2){ + // Collect AR/NR + // if(ar_nr_collected < 2 && cardAUTHSC == 2){ if(ar_nr_collected < 2) { - //if(ar_nr_responses[2] != nr) { + // if(ar_nr_responses[2] != nr) { ar_nr_responses[ar_nr_collected*4] = cuid; ar_nr_responses[ar_nr_collected*4+1] = nonce; ar_nr_responses[ar_nr_collected*4+2] = nr; ar_nr_responses[ar_nr_collected*4+3] = ar; ar_nr_collected++; - //} + // } // Interactive mode flag, means we need to send ACK finished = ( ((flags & FLAG_INTERACTIVE) == FLAG_INTERACTIVE)&& ar_nr_collected == 2); @@ -2790,7 +2801,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * if (!encrypted_data) { // first authentication - crypto1_word(pcs, cuid ^ nonce, 0);//Update crypto state + crypto1_word(pcs, cuid ^ nonce, 0);// Update crypto state num_to_bytes(nonce, 4, rAUTH_AT); // Send nonce if (MF_DBGLEVEL >= 4) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); @@ -2970,7 +2981,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * // Interactive mode flag, means we need to send ACK if((flags & FLAG_INTERACTIVE) == FLAG_INTERACTIVE) { - //May just aswell send the collected ar_nr in the response aswell + // May just aswell send the collected ar_nr in the response aswell uint8_t len = ar_nr_collected * 4 * 4; cmd_send(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, len, 0, &ar_nr_responses, len); } @@ -2983,7 +2994,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * ar_nr_responses[1], // NT1 ar_nr_responses[2], // NR1 ar_nr_responses[3], // AR1 - //ar_nr_responses[4], // CUID2 + // ar_nr_responses[4], // CUID2 ar_nr_responses[5], // NT2 ar_nr_responses[6], // NR2 ar_nr_responses[7] // AR2