From 9b82de75f4a74b2d7f149dc161f0d3a3fb1752fa Mon Sep 17 00:00:00 2001
From: Martin Holst Swende <martin@swende.se>
Date: Mon, 30 Jun 2014 00:20:40 +0200
Subject: [PATCH] more work towards iclass elite dumping.. not quite finished
 yet though :(

---
 armsrc/iclass.c              | 26 ++---------------
 client/cmdhficlass.c         | 56 +++++++++++++++++++++++++++++++-----
 client/loclass/elite_crack.h |  2 +-
 client/loclass/ikeys.c       |  4 +--
 4 files changed, 55 insertions(+), 33 deletions(-)

diff --git a/armsrc/iclass.c b/armsrc/iclass.c
index 9d31cd73..0ff24bfd 100644
--- a/armsrc/iclass.c
+++ b/armsrc/iclass.c
@@ -1502,7 +1502,6 @@ void ReaderIClass(uint8_t arg0) {
     uint8_t last_csn[8]={0};
 
     uint8_t* resp = (((uint8_t *)BigBuf) + 3560);	// was 3560 - tied to other size changes
-    FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
     int read_status= 0;
     bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
@@ -1594,29 +1593,10 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
 	} memory;
 	
 	uint8_t* resp = (((uint8_t *)BigBuf) + 3560);	// was 3560 - tied to other size changes
-    // Enable and clear the trace
-    iso14a_set_tracing(TRUE);
-    iso14a_clear_trace();
 
+    setupIclassReader();
 
 
-	// Setup SSC
-	FpgaSetupSsc();
-	// Start from off (no field generated)
-	// Signal field is off with the appropriate LED
-	LED_D_OFF();
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-	SpinDelay(200);
-
-	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-
-	// Now give it time to spin up.
-	// Signal field is on with the appropriate LED
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
-	SpinDelay(200);
-
-	LED_A_ON();
-
 	for(int i=0;i<1;i++) {
 	
 		if(traceLen > TRACE_SIZE) {
@@ -1654,8 +1634,8 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
 				Dbprintf("Authenticate");
 				//for now replay captured auth (as cc not updated)
 				memcpy(check+5,MAC,4);
-				Dbprintf("     AA: %02x %02x %02x %02x",
-					check[5], check[6], check[7],check[8]);
+                //Dbprintf("     AA: %02x %02x %02x %02x",
+                //	check[5], check[6], check[7],check[8]);
 				ReaderTransmitIClass(check, sizeof(check));
 				if(ReaderReceiveIClass(resp) == 4) {
 				   Dbprintf("     AR: %02x %02x %02x %02x",
diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c
index a7ef53c1..0650eef9 100644
--- a/client/cmdhficlass.c
+++ b/client/cmdhficlass.c
@@ -461,11 +461,20 @@ int CmdHFiClassReader_Dump(const char *Cmd)
   uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
   //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
   uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-
+  uint8_t keytable[128] = {0};
+  int elite = 0;
+  uint8_t *used_key;
+  int i;
   if (strlen(Cmd)<1) 
   {
-    PrintAndLog("Usage:  hf iclass dump <Key>");
+    PrintAndLog("Usage:  hf iclass dump <Key> [e]");
+    PrintAndLog("        Key    - A 16 byte master key");
+    PrintAndLog("        e      - If 'e' is specified, the key is interpreted as the 16 byte");
+    PrintAndLog("                 Custom Key (KCus), which can be obtained via reader-attack");
+    PrintAndLog("                 See 'hf iclass sim 2'. This key should be on iclass-format");
     PrintAndLog("        sample: hf iclass dump 0011223344556677");
+
+
     return 0;
   }
 
@@ -474,7 +483,18 @@ int CmdHFiClassReader_Dump(const char *Cmd)
     PrintAndLog("KEY must include 16 HEX symbols");
     return 1;
   }
-    
+
+  if (param_getchar(Cmd, 1) == 'e')
+  {
+    PrintAndLog("Elite switch on");
+    elite = 1;
+
+    //calc h2
+    hash2(KEY, keytable);
+
+  }
+
+
   UsbCommand c = {CMD_READER_ICLASS, {0}};
   c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE;
 
@@ -495,12 +515,34 @@ int CmdHFiClassReader_Dump(const char *Cmd)
         {
             PrintAndLog("CSN: %s",sprint_hex(CSN,8));
         }
-        if(isOK >= 1)
+        if(isOK > 1)
         {
-            //PrintAndLog("CC: %s",sprint_hex(CCNR,8));
-            diversifyKey(CSN,KEY, div_key);
+            if(elite)
+            {
+                uint8_t key_sel[8] = {0};
+                uint8_t key_sel_p[8] = { 0 };
+                //Get the key index (hash1)
+                uint8_t key_index[8] = {0};
+
+                hash1(CSN, key_index);
+                printvar("hash1", key_index,8);
+                for(i = 0; i < 8 ; i++)
+                    key_sel[i] = keytable[key_index[i]] & 0xFF;
+                printvar("k_sel", key_sel,8);
+                //Permute from iclass format to standard format
+                permutekey_rev(key_sel,key_sel_p);
+                used_key = key_sel_p;
+            }else{
+                used_key = KEY;
+
+            }
+            printvar("CC:",CCNR,8);
+            printvar("Used key",used_key,8);
+            diversifyKey(CSN,used_key, div_key);
+            printvar("Div key", div_key, 8);
             doMAC(CCNR,12,div_key, MAC);
-            PrintAndLog("MAC:  %s",sprint_hex(MAC,sizeof(MAC)));
+            printvar("MAC", MAC, 4);
+
             UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
             memcpy(d.d.asBytes, MAC, 4);
             SendCommand(&d);
diff --git a/client/loclass/elite_crack.h b/client/loclass/elite_crack.h
index c1fa3f1c..21004e59 100644
--- a/client/loclass/elite_crack.h
+++ b/client/loclass/elite_crack.h
@@ -68,7 +68,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]);
  * @param k output
  */
 void hash1(uint8_t csn[] , uint8_t k[]);
-
+void hash2(uint8_t *key64, uint8_t *outp_keytable);
 /**
  * From dismantling iclass-paper:
  *	Assume that an adversary somehow learns the first 16 bytes of hash2(K_cus ), i.e., y [0] and z [0] .
diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c
index 2bedad8d..cd2b72ee 100644
--- a/client/loclass/ikeys.c
+++ b/client/loclass/ikeys.c
@@ -390,8 +390,8 @@ void diversifyKey(uint8_t csn[8], uint8_t key[8], uint8_t div_key[8])
 	des_crypt_ecb(&ctx_enc,csn, crypted_csn);
 
 	//Calculate HASH0(DES))
-        uint64_t crypt_csn = x_bytes_to_num(crypted_csn, 8);
-	uint64_t crypted_csn_swapped = swapZvalues(crypt_csn);
+    uint64_t crypt_csn = x_bytes_to_num(crypted_csn, 8);
+    //uint64_t crypted_csn_swapped = swapZvalues(crypt_csn);
 
 	hash0(crypt_csn,div_key);
 }
-- 
2.39.5