From: marshmellow42 Date: Tue, 30 Jun 2015 02:30:18 +0000 (-0400) Subject: Merge remote-tracking branch 'upstream/master' X-Git-Tag: v2.3.0~33^2~10 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/463871be6e6e2a23c8a7391aac47fa1048d5ca11?hp=1c7d367e249f6ac133950b65d48d740c36859a65 Merge remote-tracking branch 'upstream/master' --- diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 703ade65..510f7bef 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -96,9 +96,6 @@ uint16_t BigBuf_max_traceLen(void) } void clear_trace() { - uint8_t *trace = BigBuf_get_addr(); - uint16_t max_traceLen = BigBuf_max_traceLen(); - memset(trace, 0x44, max_traceLen); traceLen = 0; } @@ -176,13 +173,10 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ } traceLen += num_paritybytes; - if(traceLen +4 < max_traceLen) - { //If it hadn't been cleared, for whatever reason.. - memset(trace+traceLen,0x44, 4); - } - return TRUE; } + + int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) { /** diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 4b173d6f..719164d1 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -710,22 +710,24 @@ void SnoopHitag(uint32_t type) { byte_t rx[HITAG_FRAME_LEN]; size_t rxlen=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + // Clean up trace and prepare it for storing frames + set_tracing(TRUE); + clear_trace(); + auth_table_len = 0; auth_table_pos = 0; + BigBuf_free(); auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH); memset(auth_table, 0x00, AUTH_TABLE_LENGTH); - // Clean up trace and prepare it for storing frames - set_tracing(TRUE); - clear_trace(); - DbpString("Starting Hitag2 snoop"); LED_D_ON(); // Set up eavesdropping mode, frequency divisor which will drive the FPGA // and analog mux selection. - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); @@ -922,6 +924,12 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) { bool bQuitTraceFull = false; bQuiet = false; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + // Clean up trace and prepare it for storing frames + set_tracing(TRUE); + clear_trace(); + auth_table_len = 0; auth_table_pos = 0; byte_t* auth_table; @@ -929,10 +937,6 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) { auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH); memset(auth_table, 0x00, AUTH_TABLE_LENGTH); - // Clean up trace and prepare it for storing frames - set_tracing(TRUE); - clear_trace(); - DbpString("Starting Hitag2 simulation"); LED_D_ON(); hitag2_init(); @@ -953,7 +957,6 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) { // Set up simulator mode, frequency divisor which will drive the FPGA // and analog mux selection. - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 9139d3bd..97c62bb6 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1125,7 +1125,6 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) int resp_cc_len; uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); - memset(receivedCmd, 0x44, MAX_FRAME_SIZE); int len; // Prepare card messages @@ -1336,7 +1335,6 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) } } - memset(receivedCmd, 0x44, MAX_FRAME_SIZE); } //Dbprintf("%x", cmdsRecvd); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index cf64da2f..5c7367a1 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -551,12 +551,8 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { LEDsoff(); - // We won't start recording the frames that we acquire until we trigger; - // a good trigger condition to get started is probably when we see a - // response from the tag. - // triggered == FALSE -- to wait first for card - bool triggered = !(param & 0x03); - + iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); + // Allocate memory from BigBuf for some buffers // free all previous allocations first BigBuf_free(); @@ -583,8 +579,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { bool TagIsActive = FALSE; bool ReaderIsActive = FALSE; - iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); - // Set up the demodulator for tag -> reader responses. DemodInit(receivedResponse, receivedResponsePar); @@ -594,6 +588,12 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // Setup and start DMA. FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); + // We won't start recording the frames that we acquire until we trigger; + // a good trigger condition to get started is probably when we see a + // response from the tag. + // triggered == FALSE -- to wait first for card + bool triggered = !(param & 0x03); + // And now we loop, receiving samples. for(uint32_t rsamples = 0; TRUE; ) { @@ -1026,6 +1026,9 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) .modulation_n = 0 }; + // We need to listen to the high-frequency, peak-detected path. + iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); + BigBuf_free_keep_EM(); // allocate buffers: @@ -1054,9 +1057,6 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) int happened2 = 0; int cmdsRecvd = 0; - // We need to listen to the high-frequency, peak-detected path. - iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - cmdsRecvd = 0; tag_response_info_t* p_response; @@ -1971,7 +1971,7 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) { nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i; nttmp2 = prng_successor(nttmp2, 1); - if (nttmp2 == nt1) return -i; + if (nttmp2 == nt1) return -i; } return(-99999); // either nt1 or nt2 are invalid nonces @@ -1994,6 +1994,10 @@ void ReaderMifare(bool first_try) uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + if (first_try) { + iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); + } + // free eventually allocated BigBuf memory. We want all for tracing. BigBuf_free(); @@ -2022,7 +2026,6 @@ void ReaderMifare(bool first_try) if (first_try) { mf_nr_ar3 = 0; - iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); sync_time = GetCountSspClk() & 0xfffffff8; sync_cycles = 65536; // theory: Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). nt_attacked = 0; @@ -2040,18 +2043,21 @@ void ReaderMifare(bool first_try) LED_B_OFF(); LED_C_OFF(); - + + #define DARKSIDE_MAX_TRIES 32 // number of tries to sync on PRNG cycle. Then give up. + uint16_t unsuccessfull_tries = 0; + for(uint16_t i = 0; TRUE; i++) { + LED_C_ON(); WDT_HIT(); // Test if the action was cancelled if(BUTTON_PRESS()) { + isOK = -1; break; } - LED_C_ON(); - if(!iso14443a_select_card(uid, NULL, &cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card"); continue; @@ -2086,8 +2092,14 @@ void ReaderMifare(bool first_try) nt_attacked = nt; } else { - if (nt_distance == -99999) { // invalid nonce received, try again - continue; + if (nt_distance == -99999) { // invalid nonce received + unsuccessfull_tries++; + if (!nt_attacked && unsuccessfull_tries > DARKSIDE_MAX_TRIES) { + isOK = -3; // Card has an unpredictable PRNG. Give up + break; + } else { + continue; // continue trying... + } } sync_cycles = (sync_cycles - nt_distance); if (MF_DBGLEVEL >= 3) Dbprintf("calibrating in cycle %d. nt_distance=%d, Sync_cycles: %d\n", i, nt_distance, sync_cycles); @@ -2149,6 +2161,10 @@ void ReaderMifare(bool first_try) 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 { par[0] = ((par[0] & 0x1F) + 1) | par_low; } @@ -2165,7 +2181,7 @@ void ReaderMifare(bool first_try) memcpy(buf + 16, ks_list, 8); memcpy(buf + 24, mf_nr_ar, 4); - cmd_send(CMD_ACK,isOK,0,0,buf,28); + cmd_send(CMD_ACK, isOK, 0, 0, buf, 28); // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -2226,13 +2242,6 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0}; uint8_t ar_nr_collected = 0; - // free eventually allocated BigBuf memory but keep Emulator Memory - BigBuf_free_keep_EM(); - - // clear trace - clear_trace(); - set_tracing(TRUE); - // Authenticate response - nonce uint32_t nonce = bytes_to_num(rAUTH_NT, 4); @@ -2274,10 +2283,6 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; } - // We need to listen to the high-frequency, peak-detected path. - iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - - if (MF_DBGLEVEL >= 1) { if (!_7BUID) { Dbprintf("4B UID: %02x%02x%02x%02x", @@ -2289,6 +2294,17 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } } + // 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 + clear_trace(); + set_tracing(TRUE); + + bool finished = FALSE; while (!BUTTON_PRESS() && !finished) { WDT_HIT(); @@ -2707,10 +2723,8 @@ void RAMFUNC SniffMifare(uint8_t param) { uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE]; - // As we receive stuff, we copy it from receivedCmd or receivedResponse - // into trace, along with its length and other annotations. - //uint8_t *trace = (uint8_t *)BigBuf; - + iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); + // free eventually allocated BigBuf memory BigBuf_free(); // allocate the DMA buffer, used to stream samples from the FPGA @@ -2722,8 +2736,6 @@ void RAMFUNC SniffMifare(uint8_t param) { bool ReaderIsActive = FALSE; bool TagIsActive = FALSE; - iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); - // Set up the demodulator for tag -> reader responses. DemodInit(receivedResponse, receivedResponsePar); diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 416c31f9..33c047d8 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -334,6 +334,8 @@ void SimulateIso14443bTag(void) 0x00, 0x21, 0x85, 0x5e, 0xd7 }; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + clear_trace(); set_tracing(TRUE); @@ -348,8 +350,6 @@ void SimulateIso14443bTag(void) uint16_t len; uint16_t cmdsRecvd = 0; - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // prepare the (only one) tag answer: CodeIso14443bAsTag(response1, sizeof(response1)); uint8_t *resp1Code = BigBuf_malloc(ToSendMax); @@ -908,9 +908,6 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) //----------------------------------------------------------------------------- void ReadSTMemoryIso14443b(uint32_t dwLast) { - clear_trace(); - set_tracing(TRUE); - uint8_t i = 0x00; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -929,6 +926,9 @@ void ReadSTMemoryIso14443b(uint32_t dwLast) FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); SpinDelay(200); + clear_trace(); + set_tracing(TRUE); + // First command: wake up the tag using the INITIATE command uint8_t cmd1[] = {0x06, 0x00, 0x97, 0x5b}; CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 94040a85..e7145c5c 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -877,12 +877,12 @@ int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv) LED_C_OFF(); LED_D_OFF(); + if (init) Iso15693InitReader(); + int answerLen=0; uint8_t *answer = BigBuf_get_addr() + 3660; if (recv != NULL) memset(answer, 0, 100); - if (init) Iso15693InitReader(); - if (!speed) { // low speed (1 out of 256) CodeIso15693AsReader256(send, sendlen); @@ -999,10 +999,6 @@ void ReaderIso15693(uint32_t parameter) LED_C_OFF(); LED_D_OFF(); - uint8_t *answer1 = BigBuf_get_addr() + 3660; - uint8_t *answer2 = BigBuf_get_addr() + 3760; - uint8_t *answer3 = BigBuf_get_addr() + 3860; - int answerLen1 = 0; int answerLen2 = 0; int answerLen3 = 0; @@ -1013,19 +1009,21 @@ void ReaderIso15693(uint32_t parameter) int elapsed = 0; uint8_t TagUID[8] = {0x00}; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + uint8_t *answer1 = BigBuf_get_addr() + 3660; + uint8_t *answer2 = BigBuf_get_addr() + 3760; + uint8_t *answer3 = BigBuf_get_addr() + 3860; // Blank arrays memset(answer1, 0x00, 300); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); // Setup SSC FpgaSetupSsc(); // Start from off (no field generated) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(200); // Give the tags time to energize FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); @@ -1111,24 +1109,22 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) LED_C_OFF(); LED_D_OFF(); - uint8_t *buf = BigBuf_get_addr() + 3660; - int answerLen1 = 0; int samples = 0; int tsamples = 0; int wait = 0; int elapsed = 0; - memset(buf, 0x00, 100); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + uint8_t *buf = BigBuf_get_addr() + 3660; + memset(buf, 0x00, 100); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); // Start from off (no field generated) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(200); LED_A_OFF(); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 939c9002..c2d85abb 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -44,10 +44,10 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) struct Crypto1State *pcs; pcs = &mpcs; - // clear trace - clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); @@ -95,9 +95,11 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ bool turnOffField = (arg0 == 1); LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - clear_trace(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + if(!iso14443a_select_card(NULL, NULL, NULL)) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); OnError(0); @@ -129,9 +131,10 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) LEDsoff(); LED_A_ON(); - clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + int len = iso14443a_select_card(NULL, NULL, NULL); if(!len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len); @@ -199,11 +202,10 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) struct Crypto1State *pcs; pcs = &mpcs; - // clear trace - clear_trace(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); @@ -252,6 +254,10 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // datain = KEY bytes void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) { + LEDsoff(); + LED_A_ON(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + // free eventually allocated BigBuf memory BigBuf_free(); clear_trace(); @@ -269,10 +275,6 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) return; } - LEDsoff(); - LED_A_ON(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - int len = iso14443a_select_card(NULL, NULL, NULL); if (!len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len); @@ -366,11 +368,10 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) struct Crypto1State *pcs; pcs = &mpcs; - // clear trace - clear_trace(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); @@ -472,9 +473,10 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) LEDsoff(); LED_A_ON(); - clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + if(!iso14443a_select_card(NULL, NULL, NULL)) { if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); OnError(0); @@ -530,9 +532,10 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){ memcpy(pwd, datain, 16); LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + if(!iso14443a_select_card(NULL, NULL, NULL)) { if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); OnError(0); @@ -632,19 +635,20 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat uint32_t auth1_time, auth2_time; static uint16_t delta_time; + LED_A_ON(); + LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + // free eventually allocated BigBuf memory BigBuf_free(); - // clear trace + clear_trace(); set_tracing(false); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - LED_A_ON(); - LED_C_OFF(); - - // statistics on nonce distance + int16_t isOK = 0; + #define NESTED_MAX_TRIES 12 + uint16_t unsuccessfull_tries = 0; if (calibrate) { // for first call only. Otherwise reuse previous calibration LED_B_ON(); WDT_HIT(); @@ -655,6 +659,12 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat for (rtr = 0; rtr < 17; rtr++) { + // Test if the action was cancelled + if(BUTTON_PRESS()) { + isOK = -2; + break; + } + // prepare next select. No need to power down the card. if(mifare_classic_halt(pcs, cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error"); @@ -702,14 +712,17 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing } if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i); + } else { + unsuccessfull_tries++; + if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable) + isOK = -3; + } } } - - if (rtr <= 1) return; davg = (davg + (rtr - 1)/2) / (rtr - 1); - if (MF_DBGLEVEL >= 3) Dbprintf("min=%d max=%d avg=%d, delta_time=%d", dmin, dmax, davg, delta_time); + if (MF_DBGLEVEL >= 3) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time); dmin = davg - 2; dmax = davg + 2; @@ -722,7 +735,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat LED_C_ON(); // get crypted nonces for target sector - for(i=0; i < 2; i++) { // look for exactly two different nonces + for(i=0; i < 2 && !isOK; i++) { // look for exactly two different nonces target_nt[i] = 0; while(target_nt[i] == 0) { // continue until we have an unambiguous nonce @@ -800,7 +813,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat memcpy(buf+16, &target_ks[1], 4); LED_B_ON(); - cmd_send(CMD_ACK, 0, 2, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf)); + cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf)); LED_B_OFF(); if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED"); @@ -835,15 +848,13 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) int OLD_MF_DBGLEVEL = MF_DBGLEVEL; MF_DBGLEVEL = MF_DBG_NONE; - // clear trace - clear_trace(); - set_tracing(TRUE); - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + clear_trace(); + set_tracing(TRUE); for (i = 0; i < keyCount; i++) { if(mifare_classic_halt(pcs, cuid)) { @@ -890,16 +901,23 @@ void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai //----------------------------------------------------------------------------- // Work with emulator memory // +// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not +// involved in dealing with emulator memory. But if it is called later, it might +// destroy the Emulator Memory. //----------------------------------------------------------------------------- + void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); emlClearMem(); } void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); emlSetMem(datain, arg0, arg1); // data, block num, blocks count } void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); byte_t buf[USB_CMD_DATA_SIZE]; emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4) @@ -926,15 +944,13 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai byte_t dataoutbuf2[16]; uint8_t uid[10]; - // clear trace - clear_trace(); - set_tracing(false); - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + clear_trace(); + set_tracing(false); bool isOK = true; @@ -1028,10 +1044,10 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_A_ON(); LED_B_OFF(); LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); clear_trace(); set_tracing(TRUE); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } while (true) { @@ -1146,10 +1162,10 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); set_tracing(TRUE); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } while (true) { @@ -1224,7 +1240,7 @@ void MifareCIdent(){ cmd_send(CMD_ACK,isOK,0,0,0,0); } - // +// // DESFIRE // @@ -1234,8 +1250,8 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){ uint8_t uid[10] = {0x00}; uint32_t cuid; - clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); int len = iso14443a_select_card(uid, NULL, &cuid); if(!len) { diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 5abda060..5ef5273a 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -17,7 +17,7 @@ int CmdHF14AMifare(const char *Cmd) uint32_t uid = 0; uint32_t nt = 0, nr = 0; uint64_t par_list = 0, ks_list = 0, r_key = 0; - uint8_t isOK = 0; + int16_t isOK = 0; uint8_t keyBlock[8] = {0}; UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}}; @@ -25,7 +25,7 @@ int CmdHF14AMifare(const char *Cmd) // message printf("-------------------------------------------------------------------------\n"); printf("Executing command. Expected execution time: 25sec on average :-)\n"); - printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n"); + printf("Press button on the proxmark3 device to abort both proxmark3 and client.\n"); printf("-------------------------------------------------------------------------\n"); @@ -47,15 +47,20 @@ start: } UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { - isOK = resp.arg[0] & 0xff; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { + isOK = resp.arg[0]; uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4); nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4); par_list = bytes_to_num(resp.d.asBytes + 8, 8); ks_list = bytes_to_num(resp.d.asBytes + 16, 8); nr = bytes_to_num(resp.d.asBytes + 24, 4); printf("\n\n"); - if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n"); + switch (isOK) { + case -1 : PrintAndLog("Button pressed. Aborted.\n"); break; + case -2 : PrintAndLog("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests).\n"); break; + case -3 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator is not predictable).\n"); break; + default: ; + } break; } } @@ -622,8 +627,14 @@ int CmdHF14AMfNested(const char *Cmd) if (cmdp == 'o') { PrintAndLog("--target block no:%3d, target key type:%c ", trgBlockNo, trgKeyType?'B':'A'); - if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true)) { - PrintAndLog("Nested error."); + int16_t isOK = mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true); + if (isOK) { + switch (isOK) { + case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break; + case -2 : PrintAndLog("Button pressed. Aborted.\n"); break; + case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break; + default : PrintAndLog("Unknown Error.\n"); + } return 2; } key64 = bytes_to_num(keyBlock, 6); @@ -696,11 +707,17 @@ int CmdHF14AMfNested(const char *Cmd) for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { if (e_sector[sectorNo].foundKey[trgKeyType]) continue; PrintAndLog("-----------------------------------------------"); - if(mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate)) { - PrintAndLog("Nested error.\n"); + int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate); + if(isOK) { + switch (isOK) { + case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break; + case -2 : PrintAndLog("Button pressed. Aborted.\n"); break; + case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break; + default : PrintAndLog("Unknown Error.\n"); + } free(e_sector); - return 2; } - else { + return 2; + } else { calibrate = false; } diff --git a/client/mifarehost.c b/client/mifarehost.c index 237979c1..95453ebf 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -69,7 +69,7 @@ void* nested_worker_thread(void *arg) int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) { - uint16_t i, len; + uint16_t i; uint32_t uid; UsbCommand resp; @@ -77,31 +77,29 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo struct Crypto1State *p1, *p2, *p3, *p4; // flush queue - WaitForResponseTimeout(CMD_ACK,NULL,100); + WaitForResponseTimeout(CMD_ACK, NULL, 100); UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}}; memcpy(c.d.asBytes, key, 6); SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - len = resp.arg[1]; - if (len == 2) { - memcpy(&uid, resp.d.asBytes, 4); - PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, (uint16_t)resp.arg[2] & 0xff, (uint16_t)resp.arg[2] >> 8); - - for (i = 0; i < 2; i++) { - statelists[i].blockNo = resp.arg[2] & 0xff; - statelists[i].keyType = (resp.arg[2] >> 8) & 0xff; - statelists[i].uid = uid; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + return -1; + } - memcpy(&statelists[i].nt, (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4); - memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4); - } - } - else { - PrintAndLog("Got 0 keys from proxmark."); - return 1; - } + if (resp.arg[0]) { + return resp.arg[0]; // error during nested + } + + memcpy(&uid, resp.d.asBytes, 4); + PrintAndLog("uid:%08x trgbl=%d trgkey=%x", uid, (uint16_t)resp.arg[2] & 0xff, (uint16_t)resp.arg[2] >> 8); + + for (i = 0; i < 2; i++) { + statelists[i].blockNo = resp.arg[2] & 0xff; + statelists[i].keyType = (resp.arg[2] >> 8) & 0xff; + statelists[i].uid = uid; + memcpy(&statelists[i].nt, (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4); + memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4); } // calc keys