]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso14443a.c
CHG: moved a xor function into util.c
[proxmark3-svn] / armsrc / iso14443a.c
index 8e547147330f9de71de8a15fc9fc51a6adaa6421..200e31f25ee1a2991067948232bb8a11138d3648 100644 (file)
@@ -1007,7 +1007,7 @@ void SimulateIso14443aTag(int tagType, int flags, int uid_2nd, byte_t* data)
                response2a[0] = data[3];
                response2a[1] = data[4];
                response2a[2] = data[5];
-               response2a[3] = data[7];
+               response2a[3] = data[6]; //??
                response2a[4] = response2a[0] ^ response2a[1] ^ response2a[2] ^ response2a[3];
 
                // Configure the ATQA and SAK accordingly
@@ -1034,7 +1034,7 @@ void SimulateIso14443aTag(int tagType, int flags, int uid_2nd, byte_t* data)
        response3a[0] = sak & 0xFB;
        ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
 
-       uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce
+       uint8_t response5[] = { 0x01, 0x02, 0x03, 0x04 }; // Very random tag nonce
        uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS: 
        // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, 
        // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
@@ -2310,7 +2310,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        uint8_t cardWRBL = 0;
        uint8_t cardAUTHSC = 0;
        uint8_t cardAUTHKEY = 0xff;  // no authentication
-       uint32_t cardRr = 0;
+//     uint32_t cardRr = 0;
        uint32_t cuid = 0;
        //uint32_t rn_enc = 0;
        uint32_t ans = 0;
@@ -2328,7 +2328,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
        uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
        uint8_t rUIDBCC2[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; // !!!
-       uint8_t rSAK[] = {0x08, 0xb6, 0xdd};
+       //uint8_t rSAK[] = {0x08, 0xb6, 0xdd}; // Mifare Classic
+       uint8_t rSAK[] = {0x09, 0x3f, 0xcc };  // Mifare Mini 
        uint8_t rSAK1[] = {0x04, 0xda, 0x17};
 
        uint8_t rAUTH_NT[] = {0x01, 0x02, 0x03, 0x04};
@@ -2337,9 +2338,11 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        //Here, we collect UID,NT,AR,NR,UID2,NT2,AR2,NR2
        // This can be used in a reader-only attack.
        // (it can also be retrieved via 'hf 14a list', but hey...
-       uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0};
+       uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0,0,0};
        uint8_t ar_nr_collected = 0;
 
+       Dbprintf("FIRE");
+       
        // free eventually allocated BigBuf memory but keep Emulator Memory
        BigBuf_free_keep_EM();
 
@@ -2347,6 +2350,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        clear_trace();
        set_tracing(TRUE);
 
+       Dbprintf("ICE");
        // Authenticate response - nonce
        uint32_t nonce = bytes_to_num(rAUTH_NT, 4);
        
@@ -2376,6 +2380,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                }
        }
 
+       Dbprintf("ICE2");
+       // save uid.
+       ar_nr_responses[0*5]   = bytes_to_num(rUIDBCC1+1, 3);
+       if ( _7BUID )
+               ar_nr_responses[0*5+1] = bytes_to_num(rUIDBCC2, 4);
+
        /*
         * Regardless of what method was used to set the UID, set fifth byte and modify
         * the ATQA for 4 or 7-byte UID
@@ -2403,6 +2413,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                }
        }
 
+       Dbprintf("ICE3");
        bool finished = FALSE;
        while (!BUTTON_PRESS() && !finished) {
                WDT_HIT();
@@ -2418,7 +2429,6 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                if(cardSTATE == MFEMUL_NOFIELD) continue;
 
                //Now, get data
-
                res = EmGetCmd(receivedCmd, &len, receivedCmd_par);
                if (res == 2) { //Field is off!
                        cardSTATE = MFEMUL_NOFIELD;
@@ -2493,10 +2503,11 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                if(ar_nr_collected < 2){
                                        if(ar_nr_responses[2] != ar)
                                        {// Avoid duplicates... probably not necessary, ar should vary. 
-                                               ar_nr_responses[ar_nr_collected*4] = cuid;
-                                               ar_nr_responses[ar_nr_collected*4+1] = nonce;
-                                               ar_nr_responses[ar_nr_collected*4+2] = ar;
-                                               ar_nr_responses[ar_nr_collected*4+3] = nr;
+                                               //ar_nr_responses[ar_nr_collected*5]   = 0;
+                                               //ar_nr_responses[ar_nr_collected*5+1] = 0;
+                                               ar_nr_responses[ar_nr_collected*5+2] = nonce;
+                                               ar_nr_responses[ar_nr_collected*5+3] = nr;
+                                               ar_nr_responses[ar_nr_collected*5+4] = ar;
                                                ar_nr_collected++;
                                        }                                               
                                        // Interactive mode flag, means we need to send ACK
@@ -2507,22 +2518,23 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                }
 
                                // --- crypto
-                               crypto1_word(pcs, ar , 1);
-                               cardRr = nr ^ crypto1_word(pcs, 0, 0);
-
-                               // test if auth OK
-                               if (cardRr != prng_successor(nonce, 64)){
-                                       if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED for sector %d with key %c. cardRr=%08x, succ=%08x",
-                                                       cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B',
-                                                       cardRr, prng_successor(nonce, 64));
+                               //crypto1_word(pcs, ar , 1);
+                               //cardRr = nr ^ crypto1_word(pcs, 0, 0);
+
+                               //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
-                                       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;
-                               }
+                                       //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);
 
@@ -2630,13 +2642,13 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                                || receivedCmd[0] == 0xB0) { // transfer
                                        if (receivedCmd[1] >= 16 * 4) {
                                                EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
-                                               if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
+                                               if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate (0x%02) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
                                                break;
                                        }
 
                                        if (receivedCmd[1] / 4 != cardAUTHSC) {
                                                EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
-                                               if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02) on block (0x%02x) not authenticated for (0x%02x), nacking",receivedCmd[0],receivedCmd[1],cardAUTHSC);
+                                               if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate (0x%02) on block (0x%02x) not authenticated for (0x%02x), nacking",receivedCmd[0],receivedCmd[1],cardAUTHSC);
                                                break;
                                        }
                                }
@@ -2668,7 +2680,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                if (receivedCmd[0] == 0xC0 || receivedCmd[0] == 0xC1 || receivedCmd[0] == 0xC2) {
                                        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");
+                                               if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate on block, but emlCheckValBl failed, nacking");
                                                EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
                                                break;
                                        }
@@ -2770,35 +2782,37 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        if(flags & FLAG_INTERACTIVE)// Interactive mode flag, means we need to send ACK
        {
                //May just aswell send the collected ar_nr in the response aswell
-               cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,1,0,&ar_nr_responses,ar_nr_collected*4*4);
+               uint8_t len = ar_nr_collected*5*4;
+               cmd_send(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, len, 0, &ar_nr_responses, len);
        }
 
        if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1 )
        {
                if(ar_nr_collected > 1 ) {
                        Dbprintf("Collected two pairs of AR/NR which can be used to extract keys from reader:");
-                       Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x %08x %08x",
-                                       ar_nr_responses[0], // UID
-                                       ar_nr_responses[1], // NT
-                                       ar_nr_responses[2], // AR1
-                                       ar_nr_responses[3], // NR1
-                                       ar_nr_responses[6], // AR2
-                                       ar_nr_responses[7]  // NR2
+                       Dbprintf("../tools/mfkey/mfkey32 %06x%08x %08x %08x %08x %08x %08x",
+                                       ar_nr_responses[0], // UID1
+                                       ar_nr_responses[1], // UID2
+                                       ar_nr_responses[2], // NT
+                                       ar_nr_responses[3], // AR1
+                                       ar_nr_responses[4], // NR1
+                                       ar_nr_responses[8], // AR2
+                                       ar_nr_responses[9]  // NR2
                                        );
                } else {
                        Dbprintf("Failed to obtain two AR/NR pairs!");
                        if(ar_nr_collected > 0 ) {
-                               Dbprintf("Only got these: UID=%08x, nonce=%08x, AR1=%08x, NR1=%08x",
-                                               ar_nr_responses[0], // UID
-                                               ar_nr_responses[1], // NT
-                                               ar_nr_responses[2], // AR1
-                                               ar_nr_responses[3]  // NR1
+                               Dbprintf("Only got these: UID=%07x%08x, nonce=%08x, AR1=%08x, NR1=%08x",
+                                               ar_nr_responses[0], // UID1
+                                               ar_nr_responses[1], // UID2
+                                               ar_nr_responses[2], // NT
+                                               ar_nr_responses[3], // AR1
+                                               ar_nr_responses[4]  // NR1
                                                );
                        }
                }
        }
-       if (MF_DBGLEVEL >= 1)   Dbprintf("Emulator stopped. Tracing: %d  trace length: %d ",    tracing, BigBuf_get_traceLen());
-       
+       if (MF_DBGLEVEL >= 1)   Dbprintf("Emulator stopped. Tracing: %d  trace length: %d ", tracing, BigBuf_get_traceLen());
 }
 
 
Impressum, Datenschutz