X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/60ca58872589f49c81fc49cb500c4930c032afe0..17ab9dcca02ae85e1f31b30eb74efec41a187917:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 425352b9..91a1a0f8 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1,4 +1,4 @@ - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // Merlok - June 2011, 2012 // Gerhard de Koning Gans - May 2008 // Hagen Fritsch - June 2010 @@ -759,7 +759,7 @@ static void Code4bitAnswerAsTag(uint8_t cmd) { // Stop when button is pressed // Or return TRUE when command is captured //----------------------------------------------------------------------------- -static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) { +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 @@ -1361,40 +1361,6 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) { BigBuf_free_keep_EM(); LED_A_OFF(); - /* - if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1) { - - for ( uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { - if (ar_nr_collected[i] == 2) { - Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i= 4){ Dbprintf("-[ Wake ups after halt [%d]", happened); Dbprintf("-[ Messages after halt [%d]", happened2); @@ -1567,7 +1533,7 @@ void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *p // Stop when button is pressed (return 1) or field was gone (return 2) // Or return 0 when command is captured //----------------------------------------------------------------------------- -static int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) { +int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) { *len = 0; uint32_t timer = 0, vtime = 0; @@ -1638,9 +1604,16 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNeeded) { // Modulate Manchester FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD); - // include correction bit if necessary - if (Uart.parityBits & 0x01) { - correctionNeeded = TRUE; + // Include correction bit if necessary + if (Uart.bitCount == 7) + { + // Short tags (7 bits) don't have parity, determine the correct value from MSB + correctionNeeded = Uart.output[0] & 0x40; + } + else + { + // The parity bits are left-aligned + correctionNeeded = Uart.parity[(Uart.len-1)/8] & (0x80 >> ((Uart.len-1) & 7)); } // 1236, so correction bit needed i = (correctionNeeded) ? 0 : 1; @@ -2791,34 +2764,37 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } } - /* - // Interactive mode flag, means we need to send ACK + crypto1_word(pcs, nr , 1); + uint32_t cardRr = ar ^ crypto1_word(pcs, 0, 0); - crypto1_word(pcs, ar , 1); - cardRr = nr ^ crypto1_word(pcs, 0, 0); - - test if auth OK + //test if auth OK if (cardRr != prng_successor(nonce, 64)){ - if (MF_DBGLEVEL >= 4) Dbprintf("AUTH FAILED for sector %d with key %c. cardRr=%08x, succ=%08x", - cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B', - cardRr, prng_successor(nonce, 64)); - 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 + if (MF_DBGLEVEL >= 3) { + Dbprintf("AUTH FAILED for sector %d with key %c. [nr=%08x cardRr=%08x] [nt=%08x succ=%08x]" + , cardAUTHSC + , (cardAUTHKEY == 0) ? 'A' : 'B' + , nr + , cardRr + , nonce // nt + , prng_successor(nonce, 64) + ); + } + // 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.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE); break; } - */ ans = prng_successor(nonce, 96) ^ crypto1_word(pcs, 0, 0); num_to_bytes(ans, 4, rAUTH_AT); EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); LED_C_ON(); - if (MF_DBGLEVEL >= 4) { + if (MF_DBGLEVEL >= 1) { Dbprintf("AUTH COMPLETED for sector %d with key %c. time=%d", cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B', @@ -2842,24 +2818,24 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * receivedCmd[0] == MIFARE_AUTH_KEYB) ) { authTimer = GetTickCount(); - cardAUTHSC = receivedCmd[1] / 4; // received block num - cardAUTHKEY = receivedCmd[0] - 0x60; // & 1 + cardAUTHSC = receivedCmd[1] / 4; // received block -> sector + cardAUTHKEY = receivedCmd[0] & 0x1; crypto1_destroy(pcs); + + // load key into crypto crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); - if (!encrypted_data) { + if (!encrypted_data) { // first authentication - crypto1_word(pcs, cuid ^ nonce, 0);// Update crypto state - num_to_bytes(nonce, 4, rAUTH_AT); // Send nonce - - if (MF_DBGLEVEL >= 4) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); - + // Update crypto state init (UID ^ NONCE) + crypto1_word(pcs, cuid ^ nonce, 0); + num_to_bytes(nonce, 4, rAUTH_AT); } else { // nested authentication ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); num_to_bytes(ans, 4, rAUTH_AT); - if (MF_DBGLEVEL >= 4) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); + if (MF_DBGLEVEL >= 3) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %c", receivedCmd[1], receivedCmd[1], cardAUTHKEY == 0 ? 'A' : 'B'); } EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT));