X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/a8561e356bd39b45e7ba4ae66e9ed6233b66a356..98a67bc908980d93328a4436a1e5fd2a4ace16f7:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 0ca9873b..8686cea7 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -14,10 +14,12 @@ #include #include +#include + #include "proxmark3.h" #include "apps.h" #include "util.h" -#include "cmd.h" +#include "usb_cdc.h" #include "iso14443crc.h" #include "crapto1/crapto1.h" #include "mifareutil.h" @@ -192,7 +194,7 @@ void iso14a_set_trigger(bool enable) { void iso14a_set_timeout(uint32_t timeout) { // adjust timeout by FPGA delays and 2 additional ssp_frames to detect SOF iso14a_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) + 2; - if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443A Timeout set to %ld (%dms)", timeout, timeout / 106); + if (MF_DBGLEVEL >= 3) Dbprintf("ISO14443A Timeout set to %" PRIu32 " (%dms)", timeout, timeout / 106); } @@ -270,8 +272,7 @@ const bool Mod_Miller_LUT[] = { #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) -static void UartReset() -{ +static void UartReset() { Uart.state = STATE_UNSYNCD; Uart.bitCount = 0; Uart.len = 0; // number of decoded data bytes @@ -280,8 +281,7 @@ static void UartReset() Uart.parityBits = 0; // holds 8 parity bits } -static void UartInit(uint8_t *data, uint8_t *parity) -{ +static void UartInit(uint8_t *data, uint8_t *parity) { Uart.output = data; Uart.parity = parity; Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits @@ -291,8 +291,7 @@ static void UartInit(uint8_t *data, uint8_t *parity) } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time -static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) -{ +static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { Uart.fourBits = (Uart.fourBits << 8) | bit; @@ -447,8 +446,7 @@ const bool Mod_Manchester_LUT[] = { #define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)]) -static void DemodReset() -{ +static void DemodReset() { Demod.state = DEMOD_UNSYNCD; Demod.len = 0; // number of decoded data bytes Demod.parityLen = 0; @@ -461,16 +459,14 @@ static void DemodReset() Demod.endTime = 0; } -static void DemodInit(uint8_t *data, uint8_t *parity) -{ +static void DemodInit(uint8_t *data, uint8_t *parity) { Demod.output = data; Demod.parity = parity; DemodReset(); } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time -static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) -{ +static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) { Demod.twoBits = (Demod.twoBits << 8) | bit; @@ -729,8 +725,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { //----------------------------------------------------------------------------- // Prepare tag messages //----------------------------------------------------------------------------- -static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity) -{ +static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity) { ToSendReset(); // Correction bit, might be removed when not needed @@ -778,8 +773,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par } -static void Code4bitAnswerAsTag(uint8_t cmd) -{ +static void Code4bitAnswerAsTag(uint8_t cmd) { int i; ToSendReset(); @@ -853,8 +847,7 @@ static void EmLogTraceTag(uint8_t *tag_data, uint16_t tag_len, uint8_t *tag_Pari // Stop when button is pressed // Or return true when command is captured //----------------------------------------------------------------------------- -static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) -{ +static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) { // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen // only, since we are receiving, not transmitting). // Signal field is off with the appropriate LED @@ -951,8 +944,8 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info, uint8_ // Main loop of simulated tag: receive commands from reader, decide what // response to send, and send it. //----------------------------------------------------------------------------- -void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) -{ +void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, uint8_t* data) { + uint8_t sak; // The first response contains the ATQA (note: bytes are transmitted in reverse order). @@ -1231,8 +1224,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) // prepare a delayed transfer. This simply shifts ToSend[] by a number // of bits specified in the delay parameter. -static void PrepareDelayedTransfer(uint16_t delay) -{ +static void PrepareDelayedTransfer(uint16_t delay) { uint8_t bitmask = 0; uint8_t bits_to_shift = 0; uint8_t bits_shifted = 0; @@ -1261,8 +1253,7 @@ static void PrepareDelayedTransfer(uint16_t delay) // if == 0: transfer immediately and return time of transfer // if != 0: delay transfer until time specified //------------------------------------------------------------------------------------- -static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) -{ +static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) { LED_B_ON(); LED_D_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); @@ -1270,12 +1261,12 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing uint32_t ThisTransferTime = 0; if (timing) { - if(*timing == 0) { // Measure time + if (*timing == 0) { // Measure time *timing = (GetCountSspClk() + 8) & 0xfffffff8; } else { PrepareDelayedTransfer(*timing & 0x00000007); // Delay transfer (fine tuning - up to 7 MF clock ticks) } - if(MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) Dbprintf("TransmitFor14443a: Missed timing"); + if (MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) Dbprintf("TransmitFor14443a: Missed timing"); while (GetCountSspClk() < (*timing & 0xfffffff8)); // Delay transfer (multiple of 8 MF clock ticks) LastTimeProxToAirStart = *timing; } else { @@ -1284,12 +1275,9 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing LastTimeProxToAirStart = ThisTransferTime; } - // clear TXRDY - AT91C_BASE_SSC->SSC_THR = SEC_Y; - uint16_t c = 0; for (;;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c]; c++; if(c >= len) { @@ -1306,8 +1294,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing //----------------------------------------------------------------------------- // Prepare reader command (in bits, support short frames) to send to FPGA //----------------------------------------------------------------------------- -static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity) -{ +static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity) { int i, j; int last; uint8_t b; @@ -1390,8 +1377,7 @@ static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, cons // Stop when button is pressed (return 1) or field was gone (return 2) // Or return 0 when command is captured //----------------------------------------------------------------------------- -int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) -{ +int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) { uint32_t field_off_time = -1; uint32_t samples = 0; int ret = 0; @@ -1475,8 +1461,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) } -static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) -{ +static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) { LED_C_ON(); uint8_t b; @@ -1578,8 +1563,7 @@ int EmSendPrecompiledCmd(tag_response_info_t *response_info) { // If a response is captured return true // If it takes too long return false //----------------------------------------------------------------------------- -static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) -{ +static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c; // Set FPGA mode to "reader listen mode", no modulation (listen @@ -1598,9 +1582,9 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive for (;;) { WDT_HIT(); - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - if(ManchesterDecoding(b, offset, 0)) { + if (ManchesterDecoding(b, offset, 0)) { NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD); return true; } else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) { @@ -1611,13 +1595,13 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive } -void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) -{ +void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) { + CodeIso14443aBitsAsReaderPar(frame, bits, par); // Send command to tag TransmitFor14443a(ToSend, ToSendMax, timing); - if(trigger) + if (trigger) LED_A_ON(); // Log reader command in trace buffer @@ -1625,14 +1609,12 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t } -void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing) -{ - ReaderTransmitBitsPar(frame, len*8, par, timing); +void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing) { + ReaderTransmitBitsPar(frame, len*8, par, timing); } -static void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) -{ +static void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) { // Generate parity and redirect uint8_t par[MAX_PARITY_SIZE]; GetParity(frame, len/8, par); @@ -1640,8 +1622,7 @@ static void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) } -void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) -{ +void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) { // Generate parity and redirect uint8_t par[MAX_PARITY_SIZE]; GetParity(frame, len, par); @@ -1649,17 +1630,16 @@ void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) } -static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity) -{ +static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity) { if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return false; LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false); return Demod.len; } -int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) -{ +int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) { if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return false; + LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false); return Demod.len; } @@ -1696,7 +1676,7 @@ static void iso14a_set_ATS_times(uint8_t *ats) { static int GetATQA(uint8_t *resp, uint8_t *resp_par) { #define WUPA_RETRY_TIMEOUT 10 // 10ms - uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP + uint8_t wupa[] = {ISO14443A_CMD_WUPA}; // 0x26 - REQA 0x52 - WAKE-UP uint32_t save_iso14a_timeout = iso14a_get_timeout(); iso14a_set_timeout(1236/(16*8)+1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer. @@ -1723,13 +1703,13 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par) { // 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) // requests ATS unless no_rats is true -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, bool no_rats) { +int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) { 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[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller uint8_t resp_par[MAX_PARITY_SIZE]; - byte_t uid_resp[4]; + uint8_t uid_resp[4]; size_t uid_resp_len; uint8_t sak = 0x04; // cascade uid @@ -1737,7 +1717,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u int len; // init card struct - if(p_hi14a_card) { + if (p_hi14a_card) { p_hi14a_card->uidlen = 0; memset(p_hi14a_card->uid, 0, 10); p_hi14a_card->ats_len = 0; @@ -1747,7 +1727,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u return 0; } - if(p_hi14a_card) { + if (p_hi14a_card) { memcpy(p_hi14a_card->atqa, resp, 2); } @@ -2034,29 +2014,29 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u // Read an ISO 14443a tag. Send out commands and store answers. // //----------------------------------------------------------------------------- -void ReaderIso14443a(UsbCommand *c) -{ +void ReaderIso14443a(UsbCommand *c) { + iso14a_command_t param = c->arg[0]; uint8_t *cmd = c->d.asBytes; size_t len = c->arg[1] & 0xffff; size_t lenbits = c->arg[1] >> 16; uint32_t timeout = c->arg[2]; uint32_t arg0 = 0; - byte_t buf[USB_CMD_DATA_SIZE] = {0}; + uint8_t buf[USB_CMD_DATA_SIZE] = {0}; uint8_t par[MAX_PARITY_SIZE]; bool cantSELECT = false; set_tracing(true); - if(param & ISO14A_CLEAR_TRACE) { + if (param & ISO14A_CLEAR_TRACE) { clear_trace(); } - if(param & ISO14A_REQUEST_TRIGGER) { + if (param & ISO14A_REQUEST_TRIGGER) { iso14a_set_trigger(true); } - if(param & ISO14A_CONNECT) { + if (param & ISO14A_CONNECT) { LED_A_ON(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); if(!(param & ISO14A_NO_SELECT)) { @@ -2070,16 +2050,16 @@ void ReaderIso14443a(UsbCommand *c) } FpgaDisableTracing(); LED_B_ON(); - cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t)); + cmd_send(CMD_NACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t)); LED_B_OFF(); } } - if(param & ISO14A_SET_TIMEOUT) { + if (param & ISO14A_SET_TIMEOUT) { iso14a_set_timeout(timeout); } - if(param & ISO14A_APDU && !cantSELECT) { + if (param & ISO14A_APDU && !cantSELECT) { uint8_t res; arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res); FpgaDisableTracing(); @@ -2088,8 +2068,8 @@ void ReaderIso14443a(UsbCommand *c) LED_B_OFF(); } - if(param & ISO14A_RAW && !cantSELECT) { - if(param & ISO14A_APPEND_CRC) { + if (param & ISO14A_RAW && !cantSELECT) { + if (param & ISO14A_APPEND_CRC) { if(param & ISO14A_TOPAZMODE) { AppendCrc14443b(cmd,len); } else { @@ -2098,8 +2078,8 @@ void ReaderIso14443a(UsbCommand *c) len += 2; if (lenbits) lenbits += 16; } - if(lenbits>0) { // want to send a specific number of bits (e.g. short commands) - if(param & ISO14A_TOPAZMODE) { + if (lenbits > 0) { // want to send a specific number of bits (e.g. short commands) + if (param & ISO14A_TOPAZMODE) { int bits_to_send = lenbits; uint16_t i = 0; ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL); // first byte is always short (7bits) and no parity @@ -2113,7 +2093,7 @@ void ReaderIso14443a(UsbCommand *c) ReaderTransmitBitsPar(cmd, lenbits, par, NULL); // bytes are 8 bit with odd parity } } else { // want to send complete bytes only - if(param & ISO14A_TOPAZMODE) { + if (param & ISO14A_TOPAZMODE) { uint16_t i = 0; ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL); // first byte: 7 bits, no paritiy while (i < len) { @@ -2127,15 +2107,15 @@ void ReaderIso14443a(UsbCommand *c) FpgaDisableTracing(); LED_B_ON(); - cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf)); + cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); LED_B_OFF(); } - if(param & ISO14A_REQUEST_TRIGGER) { + if (param & ISO14A_REQUEST_TRIGGER) { iso14a_set_trigger(false); } - if(param & ISO14A_NO_DISCONNECT) { + if (param & ISO14A_NO_DISCONNECT) { return; }