X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/471c5141672c1c386bae0b28d25041309b8118fe..117d9ec25c7cbc88555a6a990293ca95a544b915:/armsrc/iso14443a.c?ds=sidebyside diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b1d3690f..f43c59a1 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -22,9 +22,7 @@ #include "mifareutil.h" static uint32_t iso14a_timeout; -uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET; int rsamples = 0; -int traceLen = 0; int tracing = TRUE; uint8_t trigger = 0; // the block number for the ISO14443-4 PCB @@ -144,12 +142,12 @@ const uint8_t OddByteParity[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 }; - void iso14a_set_trigger(bool enable) { trigger = enable; } void iso14a_clear_trace() { + uint8_t *trace = BigBuf_get_addr(); memset(trace, 0x44, TRACE_SIZE); traceLen = 0; } @@ -205,6 +203,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ { if (!tracing) return FALSE; + uint8_t *trace = BigBuf_get_addr(); uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity uint16_t duration = timestamp_end - timestamp_start; @@ -310,6 +309,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) Uart.twoBits = (Uart.twoBits << 8) | bit; if (Uart.state == STATE_UNSYNCD) { // not yet synced + if (Uart.highCnt < 7) { // wait for a stable unmodulated signal if (Uart.twoBits == 0xffff) { Uart.highCnt++; @@ -395,7 +395,11 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) } else if (Uart.len & 0x0007) { // there are some parity bits to store Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them + } + if (Uart.len) { return TRUE; // we are finished with decoding the raw data sequence + } else { + UartReset(); // Nothing receiver - start over } } if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC @@ -469,7 +473,6 @@ void DemodReset() Demod.endTime = 0; } - void DemodInit(uint8_t *data, uint8_t *parity) { Demod.output = data; @@ -558,6 +561,8 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non } else if (Demod.len & 0x0007) { // there are some parity bits to store Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them + } + if (Demod.len) { return TRUE; // we are finished with decoding the raw data sequence } else { // nothing received. Start over DemodReset(); @@ -599,19 +604,19 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. // So 32 should be enough! - uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; - uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET; + uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; + uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET; // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; - uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; + uint8_t *receivedResponse = BigBuf_get_addr() + RECV_RESP_OFFSET; + uint8_t *receivedResponsePar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; // 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; // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET; + uint8_t *dmaBuf = BigBuf_get_addr() + DMA_BUFFER_OFFSET; uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@ -757,7 +762,6 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par // Send startbit ToSend[++ToSendMax] = SEC_D; - LastProxToAirDuration = 8 * ToSendMax - 4; for(uint16_t i = 0; i < len; i++) { @@ -881,7 +885,7 @@ int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par); bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity, uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity); -static uint8_t* free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); +static uint8_t* free_buffer_pointer; typedef struct { uint8_t* response; @@ -892,7 +896,7 @@ typedef struct { } tag_response_info_t; void reset_free_buffer() { - free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); + free_buffer_pointer = BigBuf_get_addr() + FREE_BUFFER_OFFSET; } bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) { @@ -932,7 +936,7 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { response_info->modulation = free_buffer_pointer; // Determine the maximum size we can use from our buffer - size_t max_buffer_size = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + FREE_BUFFER_SIZE) - free_buffer_pointer; + size_t max_buffer_size = BigBuf_get_addr() + FREE_BUFFER_OFFSET + FREE_BUFFER_SIZE - free_buffer_pointer; // Forward the prepare tag modulation function to the inner function if (prepare_tag_modulation(response_info,max_buffer_size)) { @@ -984,6 +988,12 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) response1[1] = 0x00; sak = 0x28; } break; + case 5: { // MIFARE TNP3XXX + // Says: I am a toy + response1[0] = 0x01; + response1[1] = 0x0f; + sak = 0x01; + } break; default: { Dbprintf("Error: unkown tagtype (%d)",tagType); return; @@ -991,10 +1001,11 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) } // The second response contains the (mandatory) first 24 bits of the UID - uint8_t response2[5]; + uint8_t response2[5] = {0x00}; // Check if the uid uses the (optional) part - uint8_t response2a[5]; + uint8_t response2a[5] = {0x00}; + if (uid_2nd) { response2[0] = 0x88; num_to_bytes(uid_1st,3,response2+1); @@ -1015,12 +1026,12 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3]; // Prepare the mandatory SAK (for 4 and 7 byte UID) - uint8_t response3[3]; + uint8_t response3[3] = {0x00}; response3[0] = sak; ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]); // Prepare the optional second SAK (for 7 byte UID), drop the cascade bit - uint8_t response3a[3]; + uint8_t response3a[3] = {0x00}; response3a[0] = sak & 0xFB; ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); @@ -1080,8 +1091,8 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); // buffers used on software Uart: - uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; - uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET; + uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; + uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET; cmdsRecvd = 0; tag_response_info_t* p_response; @@ -1117,7 +1128,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below p_response = NULL; } else if(receivedCmd[0] == 0x50) { // Received a HALT -// DbpString("Reader requested we HALT!:"); + if (tracing) { LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE); } @@ -1222,6 +1233,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) // do the tracing for the previous reader request and this tag answer: uint8_t par[MAX_PARITY_SIZE]; GetParity(p_response->response, p_response->response_n, par); + EmLogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, @@ -1302,13 +1314,6 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing // clear TXRDY AT91C_BASE_SSC->SSC_THR = SEC_Y; - // for(uint16_t c = 0; c < 10;) { // standard delay for each transfer (allow tag to be ready after last transmission) - // if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - // AT91C_BASE_SSC->SSC_THR = SEC_Y; - // c++; - // } - // } - uint16_t c = 0; for(;;) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { @@ -1321,7 +1326,6 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing } NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); - } @@ -1631,7 +1635,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start //----------------------------------------------------------------------------- static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { - uint16_t c; + uint32_t c; // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). @@ -1663,7 +1667,6 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) { - CodeIso14443aBitsAsReaderPar(frame, bits, par); // Send command to tag @@ -1724,8 +1727,8 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u 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 *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; - uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; + uint8_t *resp = BigBuf_get_addr() + RECV_RESP_OFFSET; + uint8_t *resp_par = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; byte_t uid_resp[4]; size_t uid_resp_len; @@ -1738,7 +1741,6 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u // Receive the ATQA if(!ReaderReceive(resp, resp_par)) return 0; - //Dbprintf("atqa: %02x %02x",resp[1],resp[0]); if(p_hi14a_card) { memcpy(p_hi14a_card->atqa, resp, 2); @@ -1771,7 +1773,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos); for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01; - uid_resp[uid_resp_bits & 0xf8] |= UIDbit << (uid_resp_bits % 8); + uid_resp[uid_resp_bits / 8] |= UIDbit << (uid_resp_bits % 8); } uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8); // next time select the card(s) with a 1 in the collision position uid_resp_bits++; @@ -1794,7 +1796,6 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u memcpy(uid_resp, resp, 4); } uid_resp_len = 4; - //Dbprintf("uid: %02x %02x %02x %02x",uid_resp[0],uid_resp[1],uid_resp[2],uid_resp[3]); // calculate crypto UID. Always use last 4 Bytes. if(cuid_ptr) { @@ -1812,15 +1813,10 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u if (!ReaderReceive(resp, resp_par)) return 0; sak = resp[0]; - // Test if more parts of the uid are comming + // Test if more parts of the uid are coming if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) { // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of: // http://www.nxp.com/documents/application_note/AN10927.pdf - // This was earlier: - //memcpy(uid_resp, uid_resp + 1, 3); - // But memcpy should not be used for overlapping arrays, - // and memmove appears to not be available in the arm build. - // Therefore: uid_resp[0] = uid_resp[1]; uid_resp[1] = uid_resp[2]; uid_resp[2] = uid_resp[3]; @@ -1843,9 +1839,8 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u p_hi14a_card->ats_len = 0; } - if( (sak & 0x20) == 0) { - return 2; // non iso14443a compliant tag - } + // non iso14443a compliant tag + if( (sak & 0x20) == 0) return 2; // Request for answer to select AppendCrc14443a(rats, 2); @@ -1853,6 +1848,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u if (!(len = ReaderReceive(resp, resp_par))) return 0; + if(p_hi14a_card) { memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats)); p_hi14a_card->ats_len = len; @@ -1860,7 +1856,6 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u // reset the PCB block number iso14_pcb_blocknum = 0; - return 1; } @@ -1951,7 +1946,7 @@ void ReaderIso14443a(UsbCommand *c) } if(param & ISO14A_SET_TIMEOUT) { - iso14a_timeout = c->arg[2]; + iso14a_set_timeout(c->arg[2]); } if(param & ISO14A_APDU) { @@ -2025,8 +2020,8 @@ void ReaderMifare(bool first_try) uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static uint8_t mf_nr_ar3; - uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); - uint8_t* receivedAnswerPar = (((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET); + uint8_t* receivedAnswer = BigBuf_get_addr() + RECV_RESP_OFFSET; + uint8_t* receivedAnswerPar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; iso14a_clear_trace(); iso14a_set_tracing(TRUE); @@ -2041,8 +2036,8 @@ void ReaderMifare(bool first_try) uint32_t nt = 0; uint32_t previous_nt = 0; static uint32_t nt_attacked = 0; - byte_t par_list[8] = {0,0,0,0,0,0,0,0}; - byte_t ks_list[8] = {0,0,0,0,0,0,0,0}; + byte_t par_list[8] = {0x00}; + byte_t ks_list[8] = {0x00}; static uint32_t sync_time; static uint32_t sync_cycles; @@ -2051,8 +2046,6 @@ void ReaderMifare(bool first_try) uint16_t consecutive_resyncs = 0; int isOK = 0; - - if (first_try) { mf_nr_ar3 = 0; iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); @@ -2729,18 +2722,18 @@ void RAMFUNC SniffMifare(uint8_t param) { // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. // So 32 should be enough! - uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); - uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET; + uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; + uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET; // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); - uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; + uint8_t *receivedResponse = BigBuf_get_addr() + RECV_RESP_OFFSET; + uint8_t *receivedResponsePar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; // 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; // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET; + uint8_t *dmaBuf = BigBuf_get_addr() + DMA_BUFFER_OFFSET; uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0;