X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/1eb874ee3f7690cc92a720c0636fbe100e82b1e5..7d5ebac99397fe7661760259377a4f222fdb92cb:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index cf55e606..336250ed 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -22,10 +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 static uint8_t iso14_pcb_blocknum = 0; @@ -148,14 +145,7 @@ void iso14a_set_trigger(bool enable) { trigger = enable; } -void iso14a_clear_trace() { - memset(trace, 0x44, TRACE_SIZE); - traceLen = 0; -} -void iso14a_set_tracing(bool enable) { - tracing = enable; -} void iso14a_set_timeout(uint32_t timeout) { iso14a_timeout = timeout; @@ -199,61 +189,6 @@ void AppendCrc14443a(uint8_t* data, int len) ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); } -// The function LogTrace() is also used by the iClass implementation in iClass.c -bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) -{ - if (!tracing) return FALSE; - - uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity - uint16_t duration = timestamp_end - timestamp_start; - - // Return when trace is full - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= TRACE_SIZE) { - tracing = FALSE; // don't trace any more - return FALSE; - } - - // Traceformat: - // 32 bits timestamp (little endian) - // 16 bits duration (little endian) - // 16 bits data length (little endian, Highest Bit used as readerToTag flag) - // y Bytes data - // x Bytes parity (one byte per 8 bytes data) - - // timestamp (start) - trace[traceLen++] = ((timestamp_start >> 0) & 0xff); - trace[traceLen++] = ((timestamp_start >> 8) & 0xff); - trace[traceLen++] = ((timestamp_start >> 16) & 0xff); - trace[traceLen++] = ((timestamp_start >> 24) & 0xff); - - // duration - trace[traceLen++] = ((duration >> 0) & 0xff); - trace[traceLen++] = ((duration >> 8) & 0xff); - - // data length - trace[traceLen++] = ((iLen >> 0) & 0xff); - trace[traceLen++] = ((iLen >> 8) & 0xff); - - // readerToTag flag - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; - } - - // data bytes - if (btBytes != NULL && iLen != 0) { - memcpy(trace + traceLen, btBytes, iLen); - } - traceLen += iLen; - - // parity bytes - if (parity != NULL && iLen != 0) { - memcpy(trace + traceLen, parity, num_paritybytes); - } - traceLen += num_paritybytes; - - return TRUE; -} - //============================================================================= // ISO 14443 Type A - Miller decoder //============================================================================= @@ -591,9 +526,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // bit 1 - trigger from first reader 7-bit request LEDsoff(); - // init trace buffer - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); // 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 @@ -601,22 +533,25 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // triggered == FALSE -- to wait first for card bool triggered = !(param & 0x03); + // Allocate memory from BigBuf for some buffers + // free all previous allocations first + BigBuf_free(); + // 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_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); // 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; - - // 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; + uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedResponsePar = BigBuf_malloc(MAX_PARITY_SIZE); // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET; + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + + // init trace buffer + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@ -656,7 +591,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // test for length of buffer if(dataLen > maxDataLen) { maxDataLen = dataLen; - if(dataLen > 400) { + if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("blew circular buffer! dataLen=%d", dataLen); break; } @@ -885,7 +820,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; @@ -895,10 +830,6 @@ typedef struct { uint32_t ProxToAirDuration; } tag_response_info_t; -void reset_free_buffer() { - free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); -} - bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) { // Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes // This will need the following byte array for a modulation sequence @@ -910,7 +841,8 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe // ----------- + // 166 bytes, since every bit that needs to be send costs us a byte // - + + // Prepare the tag modulation bits from the message CodeIso14443aAsTag(response_info->response,response_info->response_n); @@ -931,15 +863,22 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe return true; } + +// "precompile" responses. There are 7 predefined responses with a total of 28 bytes data to transmit. +// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction) +// 28 * 8 data bits, 28 * 1 parity bits, 7 start bits, 7 stop bits, 7 correction bits +// -> need 273 bytes buffer +#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 273 + bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { // Retrieve and store the current buffer index 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 = ALLOCATED_TAG_MODULATION_BUFFER_SIZE; // Forward the prepare tag modulation function to the inner function - if (prepare_tag_modulation(response_info,max_buffer_size)) { + if (prepare_tag_modulation(response_info, max_buffer_size)) { // Update the free buffer offset free_buffer_pointer += ToSendMax; return true; @@ -954,10 +893,6 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { //----------------------------------------------------------------------------- void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) { - // Enable and clear the trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); - uint8_t sak; // The first response contains the ATQA (note: bytes are transmitted in reverse order). @@ -1001,10 +936,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); @@ -1025,12 +961,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]); @@ -1066,9 +1002,17 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) .modulation_n = 0 }; - // Reset the offset pointer of the free buffer - reset_free_buffer(); - + BigBuf_free_keep_EM(); + + // allocate buffers: + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); + free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); + + // clear trace + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + // Prepare the responses of the anticollision phase // there will be not enough time to do this at the moment the reader sends it REQA for (size_t i=0; iSSC_THR = SEC_F; // send cycle - for(; i <= respLen; ) { + for(; i < respLen; ) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = resp[i++]; FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -1726,8 +1667,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[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller + uint8_t resp_par[MAX_PARITY_SIZE]; byte_t uid_resp[4]; size_t uid_resp_len; @@ -1772,7 +1713,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++; @@ -2019,9 +1960,12 @@ 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[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + // free eventually allocated BigBuf memory. We want all for tracing. + BigBuf_free(); + iso14a_clear_trace(); iso14a_set_tracing(TRUE); @@ -2231,10 +2175,10 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * struct Crypto1State *pcs; pcs = &mpcs; uint32_t numReads = 0;//Counts numer of times reader read a block - uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf(); - uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE; - uint8_t* response = get_bigbufptr_recvrespbuf(); - uint8_t* response_par = response + MAX_FRAME_SIZE; + uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE]; + uint8_t response[MAX_MIFARE_FRAME_SIZE]; + uint8_t response_par[MAX_MIFARE_PARITY_SIZE]; uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; @@ -2251,6 +2195,8 @@ 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 iso14a_clear_trace(); iso14a_set_tracing(TRUE); @@ -2721,18 +2667,20 @@ 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[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE]; // 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[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; - // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET; + // free eventually allocated BigBuf memory + BigBuf_free(); + // allocate the DMA buffer, used to stream samples from the FPGA + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@ -2791,7 +2739,7 @@ void RAMFUNC SniffMifare(uint8_t param) { // test for length of buffer if(dataLen > maxDataLen) { // we are more behind than ever... maxDataLen = dataLen; - if(dataLen > 400) { + if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("blew circular buffer! dataLen=0x%x", dataLen); break; }