X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/7cc204bff881ce1d1833d8e93469f6bbba80c70e..b22f7a6bc68319533f9c83c24045d4bd79994f1f:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 099e1d68..6fe83c6e 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -10,13 +10,12 @@ // Routines to support ISO 14443 type A. //----------------------------------------------------------------------------- -#include "proxmark3.h" +#include "../include/proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "cmd.h" - -#include "iso14443crc.h" +#include "../common/cmd.h" +#include "../common/iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" @@ -190,8 +189,9 @@ void AppendCrc14443a(uint8_t* data, int len) } // The function LogTrace() is also used by the iClass implementation in iClass.c -bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool bReader) +bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool readerToTag) { + if (!tracing) return FALSE; // Return when trace is full if (traceLen + sizeof(timestamp) + sizeof(dwParity) + iLen >= TRACE_SIZE) { tracing = FALSE; // don't trace any more @@ -203,7 +203,8 @@ bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, trace[traceLen++] = ((timestamp >> 8) & 0xff); trace[traceLen++] = ((timestamp >> 16) & 0xff); trace[traceLen++] = ((timestamp >> 24) & 0xff); - if (!bReader) { + + if (!readerToTag) { trace[traceLen - 1] |= 0x80; } trace[traceLen++] = ((dwParity >> 0) & 0xff); @@ -505,6 +506,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { 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 @@ -1203,13 +1205,6 @@ static void TransmitFor14443a(const uint8_t *cmd, int 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)) { @@ -1221,8 +1216,7 @@ static void TransmitFor14443a(const uint8_t *cmd, int len, uint32_t *timing) } } - NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); - + NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); } @@ -1723,7 +1717,13 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u 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 - memcpy(uid_resp, uid_resp + 1, 3); + // 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. + // So this has been replaced with a for-loop: + for(int xx = 0; xx < 3; xx++) + uid_resp[xx] = uid_resp[xx+1]; uid_resp_len = 3; } @@ -1784,7 +1784,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { DemodReset(); UartReset(); NextTransferTime = 2*DELAY_ARM2AIR_AS_READER; - iso14a_set_timeout(1050); // 10ms default + iso14a_set_timeout(1050); // 10ms default 10*105 = } int iso14_apdu(uint8_t * cmd, size_t cmd_len, void * data) { @@ -1822,8 +1822,8 @@ void ReaderIso14443a(UsbCommand *c) { iso14a_command_t param = c->arg[0]; uint8_t *cmd = c->d.asBytes; - size_t len = c->arg[1]; - size_t lenbits = c->arg[2]; + size_t len = c->arg[1] & 0xFFFF; + size_t lenbits = c->arg[1] >> 16; uint32_t arg0 = 0; byte_t buf[USB_CMD_DATA_SIZE]; @@ -1847,7 +1847,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) { @@ -1859,8 +1859,10 @@ void ReaderIso14443a(UsbCommand *c) if(param & ISO14A_APPEND_CRC) { AppendCrc14443a(cmd,len); len += 2; + lenbits += 16; } if(lenbits>0) { + ReaderTransmitBitsPar(cmd,lenbits,GetParity(cmd,lenbits/8), NULL); } else { ReaderTransmit(cmd,len, NULL); @@ -1932,7 +1934,8 @@ void ReaderMifare(bool first_try) uint8_t uid[10]; uint32_t cuid; - uint32_t nt, previous_nt; + 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}; @@ -2272,7 +2275,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * // select card if (len == 9 && (receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) { - EmSendCmd(_7BUID?rSAK1:rSAK, sizeof(_7BUID?rSAK1:rSAK)); + EmSendCmd(_7BUID?rSAK1:rSAK, _7BUID?sizeof(rSAK1):sizeof(rSAK)); cuid = bytes_to_num(rUIDBCC1, 4); if (!_7BUID) { cardSTATE = MFEMUL_WORK; @@ -2318,6 +2321,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * // Shouldn't we respond anything here? // Right now, we don't nack or anything, which causes the // reader to do a WUPA after a while. /Martin + // -- which is the correct response. /piwi cardSTATE_TO_IDLE(); LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE); LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE); @@ -2331,7 +2335,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); LED_C_ON(); cardSTATE = MFEMUL_WORK; - if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED. sector=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - authTimer); + if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED for sector %d with key %c. time=%d", + cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B', + GetTickCount() - authTimer); break; } case MFEMUL_SELECT2:{ @@ -2389,12 +2395,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); if (!encrypted_data) { // first authentication - if (MF_DBGLEVEL >= 2) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); + if (MF_DBGLEVEL >= 4) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); crypto1_word(pcs, cuid ^ nonce, 0);//Update crypto state num_to_bytes(nonce, 4, rAUTH_AT); // Send nonce } else { // nested authentication - if (MF_DBGLEVEL >= 2) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); + if (MF_DBGLEVEL >= 4) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); num_to_bytes(ans, 4, rAUTH_AT); } @@ -2425,9 +2431,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * if(receivedCmd[0] == 0x30 // read block || receivedCmd[0] == 0xA0 // write block - || receivedCmd[0] == 0xC0 - || receivedCmd[0] == 0xC1 - || receivedCmd[0] == 0xC2 // inc dec restore + || receivedCmd[0] == 0xC0 // inc + || receivedCmd[0] == 0xC1 // dec + || receivedCmd[0] == 0xC2 // restore || receivedCmd[0] == 0xB0) { // transfer if (receivedCmd[1] >= 16 * 4) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); @@ -2443,7 +2449,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } // read block if (receivedCmd[0] == 0x30) { - if (MF_DBGLEVEL >= 2) { + if (MF_DBGLEVEL >= 4) { Dbprintf("Reader reading block %d (0x%02x)",receivedCmd[1],receivedCmd[1]); } emlGetMem(response, receivedCmd[1], 1); @@ -2459,7 +2465,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } // write block if (receivedCmd[0] == 0xA0) { - if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0xA0 write block %d (%02x)",receivedCmd[1],receivedCmd[1]); + if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0xA0 write block %d (%02x)",receivedCmd[1],receivedCmd[1]); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); cardSTATE = MFEMUL_WRITEBL2; cardWRBL = receivedCmd[1]; @@ -2467,7 +2473,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } // increment, decrement, restore if (receivedCmd[0] == 0xC0 || receivedCmd[0] == 0xC1 || receivedCmd[0] == 0xC2) { - if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]); + if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]); if (emlCheckValBl(receivedCmd[1])) { if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate on block, but emlCheckValBl failed, nacking"); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); @@ -2485,7 +2491,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } // transfer if (receivedCmd[0] == 0xB0) { - if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x transfer block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]); + if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0x%02x transfer block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]); if (emlSetValBl(cardINTREG, cardINTBLOCK, receivedCmd[1])) EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); else @@ -2620,7 +2626,8 @@ void RAMFUNC SniffMifare(uint8_t param) { // C(red) A(yellow) B(green) LEDsoff(); // init trace buffer - iso14a_clear_trace(); + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes.