]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/hitag2.c
CHG: added the make command
[proxmark3-svn] / armsrc / hitag2.c
index 2d0645658c2dc2d2b68cf35f8f295308cf364925..12bea2e507e209cf80850af1bc830c2ddf48221a 100644 (file)
 // (c) 2012 Roel Verdult
 //-----------------------------------------------------------------------------
 
-#include "../include/proxmark3.h"
+#include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
-#include "../include/hitag2.h"
+#include "hitag2.h"
 #include "string.h"
 #include "BigBuf.h"
 
 static bool bQuiet;
-
 static bool bCrypto;
 static bool bAuthenticating;
 static bool bPwd;
 static bool bSuccessful;
 
-
-
 struct hitag2_tag {
        uint32_t uid;
        enum {
@@ -144,6 +141,16 @@ static u64 _hitag2_round (u64 *state)
        return _f20 (x);
 }
 
+// "MIKRON"             =  O  N  M  I  K  R
+// Key                  = 4F 4E 4D 49 4B 52             - Secret 48-bit key
+// Serial               = 49 43 57 69                   - Serial number of the tag, transmitted in clear
+// Random               = 65 6E 45 72                   - Random IV, transmitted in clear
+//~28~DC~80~31  = D7 23 7F CE                   - Authenticator value = inverted first 4 bytes of the keystream
+
+// The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
+// The inverse of the first 4 bytes is sent to the tag to authenticate.
+// The rest is encrypted by XORing it with the subsequent keystream.
+
 static u32 _hitag2_byte (u64 * x)
 {
        u32                                     i, c;
@@ -152,16 +159,13 @@ static u32 _hitag2_byte (u64 * x)
        return c;
 }
 
-static int hitag2_reset(void)
-{
+static int hitag2_reset(void) {
        tag.state = TAG_STATE_RESET;
        tag.crypto_active = 0;
        return 0;
 }
 
-static int hitag2_init(void)
-{
-//     memcpy(&tag, &resetdata, sizeof(tag));
+static int hitag2_init(void) {
        hitag2_reset();
        return 0;
 }
@@ -223,16 +227,16 @@ static int hitag2_cipher_transcrypt(uint64_t* cs, byte_t *data, unsigned int byt
 #define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */
 #define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */
 
-#define HITAG_T_TAG_ONE_HALF_PERIOD                    10
-#define HITAG_T_TAG_TWO_HALF_PERIOD                    25
-#define HITAG_T_TAG_THREE_HALF_PERIOD          41 
-#define HITAG_T_TAG_FOUR_HALF_PERIOD    57 
+#define HITAG_T_TAG_ONE_HALF_PERIOD            10
+#define HITAG_T_TAG_TWO_HALF_PERIOD            25
+#define HITAG_T_TAG_THREE_HALF_PERIOD  41 
+#define HITAG_T_TAG_FOUR_HALF_PERIOD   57 
 
-#define HITAG_T_TAG_HALF_PERIOD                                        16
-#define HITAG_T_TAG_FULL_PERIOD                                        32
+#define HITAG_T_TAG_HALF_PERIOD                        16
+#define HITAG_T_TAG_FULL_PERIOD                        32
 
-#define HITAG_T_TAG_CAPTURE_ONE_HALF           13
-#define HITAG_T_TAG_CAPTURE_TWO_HALF           25
+#define HITAG_T_TAG_CAPTURE_ONE_HALF   13
+#define HITAG_T_TAG_CAPTURE_TWO_HALF   25
 #define HITAG_T_TAG_CAPTURE_THREE_HALF 41 
 #define HITAG_T_TAG_CAPTURE_FOUR_HALF   57 
 
@@ -424,11 +428,10 @@ static void hitag_reader_send_bit(int bit) {
        if(bit == 0) {
                // Zero bit: |_-|
                while(AT91C_BASE_TC0->TC_CV < T0*22);
-               //              SpinDelayUs(16*8);
+
        } else {
                // One bit: |_--|
                while(AT91C_BASE_TC0->TC_CV < T0*28);
-               //              SpinDelayUs(22*8);
        }
        LED_A_OFF();
 }
@@ -475,26 +478,26 @@ static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t*
                                *txlen = 32;
                                memcpy(tx,password,4);
                                bPwd = true;
-        memcpy(tag.sectors[blocknr],rx,4);
-        blocknr++;
+                               memcpy(tag.sectors[blocknr],rx,4);
+                               blocknr++;
                        } else {
                                
-                       if(blocknr == 1){
-                               //store password in block1, the TAG answers with Block3, but we need the password in memory
-                               memcpy(tag.sectors[blocknr],tx,4);
-                       }else{
-                               memcpy(tag.sectors[blocknr],rx,4);
-                       }
-                       
-                       blocknr++;
-                       if (blocknr > 7) {
-                         DbpString("Read succesful!");
-        bSuccessful = true;
-                         return false;
-                       }
-                       *txlen = 10;
-                       tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
-                       tx[1] = ((blocknr^7) << 6);
+                               if(blocknr == 1){
+                                       //store password in block1, the TAG answers with Block3, but we need the password in memory
+                                       memcpy(tag.sectors[blocknr],tx,4);
+                               } else {
+                                       memcpy(tag.sectors[blocknr],rx,4);
+                               }
+                               
+                               blocknr++;
+                               if (blocknr > 7) {
+                                       DbpString("Read succesful!");
+                                       bSuccessful = true;
+                                       return false;
+                               }
+                               *txlen = 10;
+                               tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
+                               tx[1] = ((blocknr^7) << 6);
                        }
                } break;
                        
@@ -544,9 +547,9 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
           bCrypto = false;
         }
                        } else {
-        *txlen = 5;
-        memcpy(tx,"\xc0",nbytes(*txlen));
-      }
+                               *txlen = 5;
+                               memcpy(tx,"\xc0",nbytes(*txlen));
+                       }
                } break;
                        
       // Received UID, crypto tag answer
@@ -560,20 +563,20 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
         hitag2_cipher_transcrypt(&cipher_state,tx+4,4,0);
                                *txlen = 64;
                                bCrypto = true;
-        bAuthenticating = true;
+                               bAuthenticating = true;
                        } else {
         // Check if we received answer tag (at)
         if (bAuthenticating) {
-          bAuthenticating = false;
+                       bAuthenticating = false;
         } else {
-          // Store the received block
-          memcpy(tag.sectors[blocknr],rx,4);
-          blocknr++;
+                       // Store the received block
+                       memcpy(tag.sectors[blocknr],rx,4);
+                       blocknr++;
         }
         if (blocknr > 7) {
-          DbpString("Read succesful!");
-          bSuccessful = true;
-          return false;
+                       DbpString("Read succesful!");
+                       bSuccessful = true;
+                       return false;
         }
         *txlen = 10;
         tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
@@ -589,11 +592,11 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
        }
        
   
-  if(bCrypto) {
-    // We have to return now to avoid double encryption
-    if (!bAuthenticating) {
-      hitag2_cipher_transcrypt(&cipher_state,tx,*txlen/8,*txlen%8);
-    }
+       if(bCrypto) {
+               // We have to return now to avoid double encryption
+               if (!bAuthenticating) {
+                 hitag2_cipher_transcrypt(&cipher_state, tx, *txlen/8, *txlen%8);
+               }
        }
 
        return true;
@@ -625,8 +628,7 @@ static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size
                                bCrypto = true;
                        } else {
                                DbpString("Authentication succesful!");
-                               // We are done... for now
-                               return false;
+                               return true;
                        }
                } break;
                        
@@ -710,22 +712,24 @@ void SnoopHitag(uint32_t type) {
        byte_t rx[HITAG_FRAME_LEN];
        size_t rxlen=0;
        
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+       // Clean up trace and prepare it for storing frames
+       set_tracing(TRUE);
+       clear_trace();
+       
        auth_table_len = 0;
        auth_table_pos = 0;
+
        BigBuf_free();
     auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
        memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
-
-       // Clean up trace and prepare it for storing frames
-       set_tracing(TRUE);
-       clear_trace();
        
        DbpString("Starting Hitag2 snoop");
        LED_D_ON();
        
        // Set up eavesdropping mode, frequency divisor which will drive the FPGA
        // and analog mux selection.
-       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT  | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
        SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -763,7 +767,7 @@ void SnoopHitag(uint32_t type) {
        bSkip = true;
        tag_sof = 4;
        
-       while(!BUTTON_PRESS()) {
+       while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
                // Watchdog hit
                WDT_HIT();
                
@@ -905,7 +909,7 @@ void SnoopHitag(uint32_t type) {
     AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
     LED_A_OFF();
-       
+       set_tracing(TRUE);
 //     Dbprintf("frame received: %d",frame_count);
 //     Dbprintf("Authentication Attempts: %d",(auth_table_len/8));
 //     DbpString("All done");
@@ -922,6 +926,12 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
        bool bQuitTraceFull = false;
        bQuiet = false;
        
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+       // Clean up trace and prepare it for storing frames
+       set_tracing(TRUE);
+       clear_trace();
+
        auth_table_len = 0;
        auth_table_pos = 0;
     byte_t* auth_table;
@@ -929,10 +939,6 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
     auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
        memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
 
-       // Clean up trace and prepare it for storing frames
-       set_tracing(TRUE);
-       clear_trace();
-
        DbpString("Starting Hitag2 simulation");
        LED_D_ON();
        hitag2_init();
@@ -953,7 +959,6 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
        
        // Set up simulator mode, frequency divisor which will drive the FPGA
        // and analog mux selection.
-       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
        SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -989,7 +994,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
        // Enable and reset counter
        AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
        
-       while(!BUTTON_PRESS()) {
+       while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
                // Watchdog hit
                WDT_HIT();
                
@@ -1093,7 +1098,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        
        DbpString("Sim Stopped");
-       
+       set_tracing(TRUE);
 }
 
 void ReaderHitag(hitag_function htf, hitag_data* htd) {
@@ -1165,6 +1170,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
                        
                default: {
                        Dbprintf("Error, unknown function: %d",htf);
+                       set_tracing(FALSE);
                        return;
                } break;
        }
@@ -1214,26 +1220,27 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
        lastbit = 1;
        bStop = false;
 
-  // Tag specific configuration settings (sof, timings, etc.)
-  if (htf < 10){
-    // hitagS settings
-    reset_sof = 1;
-    t_wait = 200;
-    DbpString("Configured for hitagS reader");
-  } else if (htf < 20) {
-    // hitag1 settings
-    reset_sof = 1;
-    t_wait = 200;
-    DbpString("Configured for hitag1 reader");
-  } else if (htf < 30) {
-    // hitag2 settings
-    reset_sof = 4;
-    t_wait = HITAG_T_WAIT_2;
-    DbpString("Configured for hitag2 reader");
+       // Tag specific configuration settings (sof, timings, etc.)
+       if (htf < 10){
+               // hitagS settings
+               reset_sof = 1;
+               t_wait = 200;
+               DbpString("Configured for hitagS reader");
+       } else if (htf < 20) {
+               // hitag1 settings
+               reset_sof = 1;
+               t_wait = 200;
+               DbpString("Configured for hitag1 reader");
+       } else if (htf < 30) {
+               // hitag2 settings
+               reset_sof = 4;
+               t_wait = HITAG_T_WAIT_2;
+               DbpString("Configured for hitag2 reader");
        } else {
-    Dbprintf("Error, unknown hitag reader type: %d",htf);
-    return;
-  }
+               Dbprintf("Error, unknown hitag reader type: %d",htf);
+               set_tracing(FALSE);     
+               return;
+       }
                
        while(!bStop && !BUTTON_PRESS()) {
                // Watchdog hit
@@ -1271,6 +1278,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
                        } break;
                        default: {
                                Dbprintf("Error, unknown function: %d",htf);
+                               set_tracing(FALSE);
                                return;
                        } break;
                }
@@ -1378,7 +1386,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
        AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
        AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       Dbprintf("frame received: %d",frame_count);
-  DbpString("All done");
-  cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
-}
+       Dbprintf("DONE: frame received: %d",frame_count);
+       cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
+       set_tracing(FALSE);
+}
\ No newline at end of file
Impressum, Datenschutz