]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
nested authentication works ok (tested)
authorMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Thu, 26 May 2011 15:20:03 +0000 (15:20 +0000)
committerMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Thu, 26 May 2011 15:20:03 +0000 (15:20 +0000)
and code cleaning

armsrc/iso14443a.c
armsrc/mifareutil.c
armsrc/mifareutil.h
client/cmdhf14a.c

index bb280807b30efb3d264d110faf6c9fcae8165694..efe6bfc429b7f0fefcd292870cd61d8f847174b8 100644 (file)
@@ -1502,7 +1502,6 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
        uint8_t rats[]       = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
 
        uint8_t* resp = (((uint8_t *)BigBuf) + 3560);   // was 3560 - tied to other size changes
-       //uint8_t* uid  = resp + 7;
 
        uint8_t sak = 0x04; // cascade uid
        int cascade_level = 0;
@@ -1520,9 +1519,6 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
        if(resp_data)
                memcpy(resp_data->atqa, resp, 2);
        
-       //ReaderTransmit(sel_all,sizeof(sel_all)); --- avoid duplicate SELECT request
-       //if(!ReaderReceive(uid)) return 0;
-
        // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
        // which case we need to make a cascade 2 request and select - this is a long UID
        // While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
@@ -1778,17 +1774,17 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        ui64Key = bytes_to_num(datain, 6);
        
        // variables
-  byte_t isOK = 0;
-  byte_t dataoutbuf[16];
+       byte_t isOK = 0;
+       byte_t dataoutbuf[16];
        uint8_t uid[7];
        uint32_t cuid;
-  struct Crypto1State mpcs = {0, 0};
+       struct Crypto1State mpcs = {0, 0};
        struct Crypto1State *pcs;
        pcs = &mpcs;
 
        // clear trace
-  traceLen = 0;
-//  tracing = false;
+       traceLen = 0;
+//     tracing = false;
 
        iso14443a_setup();
 
@@ -1802,7 +1798,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        break;
                };
 
-               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, 0)) {
+               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
                        Dbprintf("Auth error");
                        break;
                };
@@ -1831,14 +1827,14 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        uid[1] = 0xff;
        uid[2] = 0xff;
        uid[3] = 0xff;
-  LogTrace(uid, 4, 0, 0, TRUE);
+       LogTrace(uid, 4, 0, 0, TRUE);
 
        UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
        memcpy(ack.d.asBytes, dataoutbuf, 16);
        
        LED_B_ON();
        UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-       LED_B_OFF();    
+       LED_B_OFF();
 
 
   // Thats it...
@@ -1861,17 +1857,17 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        ui64Key = bytes_to_num(datain, 6);
        
        // variables
-  byte_t isOK = 0;
-  byte_t dataoutbuf[16 * 4];
+       byte_t isOK = 0;
+       byte_t dataoutbuf[16 * 4];
        uint8_t uid[8];
        uint32_t cuid;
-  struct Crypto1State mpcs = {0, 0};
+       struct Crypto1State mpcs = {0, 0};
        struct Crypto1State *pcs;
        pcs = &mpcs;
 
        // clear trace
-  traceLen = 0;
-//  tracing = false;
+       traceLen = 0;
+//     tracing = false;
 
        iso14443a_setup();
 
@@ -1885,7 +1881,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        break;
                };
 
-               if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, 0)) {
+               if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {
                        Dbprintf("Auth error");
                        break;
                };
@@ -1926,7 +1922,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        uid[1] = 0xff;
        uid[2] = 0xff;
        uid[3] = 0xff;
-  LogTrace(uid, 4, 0, 0, TRUE);
+       LogTrace(uid, 4, 0, 0, TRUE);
 
        UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
        memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);
@@ -1940,7 +1936,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
        LED_B_OFF();    
 
-  // Thats it...
+       // Thats it...
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LEDsoff();
 //  tracing = TRUE;
@@ -1953,25 +1949,25 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 //-----------------------------------------------------------------------------
 void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 {
-  // params
+       // params
        uint8_t blockNo = arg0;
        uint8_t keyType = arg1;
        uint64_t ui64Key = 0;
-  byte_t blockdata[16];
+       byte_t blockdata[16];
 
        ui64Key = bytes_to_num(datain, 6);
        memcpy(blockdata, datain + 10, 16);
        
        // variables
-  byte_t isOK = 0;
+       byte_t isOK = 0;
        uint8_t uid[8];
        uint32_t cuid;
-  struct Crypto1State mpcs = {0, 0};
+       struct Crypto1State mpcs = {0, 0};
        struct Crypto1State *pcs;
        pcs = &mpcs;
 
        // clear trace
-  traceLen = 0;
+       traceLen = 0;
 //  tracing = false;
 
        iso14443a_setup();
@@ -1986,7 +1982,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        break;
                };
 
-               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, 0)) {
+               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
                        Dbprintf("Auth error");
                        break;
                };
@@ -2015,7 +2011,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        uid[1] = 0xff;
        uid[2] = 0xff;
        uid[3] = 0xff;
-  LogTrace(uid, 4, 0, 0, TRUE);
+       LogTrace(uid, 4, 0, 0, TRUE);
 
        UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
        
@@ -2024,7 +2020,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_B_OFF();    
 
 
-  // Thats it...
+       // Thats it...
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LEDsoff();
 //  tracing = TRUE;
@@ -2037,7 +2033,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 //-----------------------------------------------------------------------------
 void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 {
-  // params
+       // params
        uint8_t blockNo = arg0;
        uint8_t keyType = arg1;
        uint64_t ui64Key = 0;
@@ -2045,16 +2041,16 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        ui64Key = bytes_to_num(datain, 6);
        
        // variables
-  byte_t isOK = 0;
+       byte_t isOK = 0;
        uint8_t uid[8];
        uint32_t cuid;
        uint8_t dataoutbuf[16];
-  struct Crypto1State mpcs = {0, 0};
+       struct Crypto1State mpcs = {0, 0};
        struct Crypto1State *pcs;
        pcs = &mpcs;
 
        // clear trace
-  traceLen = 0;
+       traceLen = 0;
 //  tracing = false;
 
        iso14443a_setup();
@@ -2069,13 +2065,13 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        break;
                };
                
-               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, 0)) {
+               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
                        Dbprintf("Auth error");
                        break;
                };
 
                // nested authenticate block = (blockNo + 1)
-               if(mifare_classic_auth(pcs, (uint32_t)bytes_to_num(uid, 4), blockNo + 1, keyType, ui64Key, 1)) {
+               if(mifare_classic_auth(pcs, (uint32_t)bytes_to_num(uid, 4), blockNo + 1, keyType, ui64Key, AUTH_NESTED)) {
                        Dbprintf("Auth error");
                        break;
                };
@@ -2097,14 +2093,14 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        //  ----------------------------- crypto1 destroy
        crypto1_destroy(pcs);
        
-  DbpString("NESTED FINISHED");
+       DbpString("NESTED FINISHED");
 
        // add trace trailer
        uid[0] = 0xff;
        uid[1] = 0xff;
        uid[2] = 0xff;
        uid[3] = 0xff;
-  LogTrace(uid, 4, 0, 0, TRUE);
+       LogTrace(uid, 4, 0, 0, TRUE);
 
        UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
        memcpy(ack.d.asBytes, dataoutbuf, 16);
@@ -2113,7 +2109,7 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
        LED_B_OFF();    
 
-  // Thats it...
+       // Thats it...
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LEDsoff();
 //  tracing = TRUE;
index ede1cbc9de0bce383e8d3aeb0de34f5a0d05faa4..59dafedc57e5661c693d72f13b8799e7620642cf 100644 (file)
@@ -50,7 +50,7 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd,
 \r
        int len = ReaderReceive(answer);\r
 \r
-       if (crypted) {\r
+       if (crypted == CRYPT_ALL) {\r
                if (len == 1) {\r
                        res = 0;\r
                        for (pos = 0; pos < 4; pos++)\r
@@ -72,20 +72,20 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd,
 int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested) \r
 {\r
        // variables\r
-  int len;     \r
+       int len;        \r
        uint32_t pos;\r
        uint8_t tmp4[4];\r
-  byte_t par = 0;\r
-  byte_t ar[4];\r
+       byte_t par = 0;\r
+       byte_t ar[4];\r
        uint32_t nt, ntpp; // Supplied tag nonce\r
        \r
        uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
-  uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
 \r
-  // Transmit MIFARE_CLASSIC_AUTH\r
+       // Transmit MIFARE_CLASSIC_AUTH\r
        len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer);\r
 //     Dbprintf("rand nonce len: %x", len);  \r
-  if (len != 4) return 1;\r
+       if (len != 4) return 1;\r
        \r
        ar[0] = 0x55;\r
        ar[1] = 0x41;\r
@@ -94,50 +94,60 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo,
        \r
        // Save the tag nonce (nt)\r
        nt = bytes_to_num(receivedAnswer, 4);\r
-       Dbprintf("uid: %x nt: %x", uid, nt);  \r
 \r
        //  ----------------------------- crypto1 create\r
-  // Init cipher with key\r
+       if (isNested)\r
+               crypto1_destroy(pcs);\r
+\r
+       // Init cipher with key\r
        crypto1_create(pcs, ui64Key);\r
 \r
-  // Load (plain) uid^nt into the cipher\r
-       crypto1_word(pcs, nt ^ uid, 0);\r
+       if (isNested == AUTH_NESTED) {\r
+               // decrypt nt with help of new key \r
+               nt = crypto1_word(pcs, nt ^ uid, 1) ^ nt;\r
+       } else {\r
+               // Load (plain) uid^nt into the cipher\r
+               crypto1_word(pcs, nt ^ uid, 0);\r
+       }\r
+\r
+       // some statistic\r
+       Dbprintf("auth uid: %08x nt: %08x", uid, nt);  \r
 \r
        par = 0;\r
-  // Generate (encrypted) nr+parity by loading it into the cipher (Nr)\r
-  for (pos = 0; pos < 4; pos++)\r
-  {\r
-    mf_nr_ar[pos] = crypto1_byte(pcs, ar[pos], 0) ^ ar[pos];\r
+       // Generate (encrypted) nr+parity by loading it into the cipher (Nr)\r
+       for (pos = 0; pos < 4; pos++)\r
+       {\r
+               mf_nr_ar[pos] = crypto1_byte(pcs, ar[pos], 0) ^ ar[pos];\r
                par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(ar[pos])) & 0x01) * 0x80 );\r
-  }    \r
+       }       \r
                \r
-  // Skip 32 bits in pseudo random generator\r
-  nt = prng_successor(nt,32);\r
+       // Skip 32 bits in pseudo random generator\r
+       nt = prng_successor(nt,32);\r
 \r
        //  ar+parity\r
-  for (pos = 4; pos < 8; pos++)\r
-  {\r
+       for (pos = 4; pos < 8; pos++)\r
+       {\r
                nt = prng_successor(nt,8);\r
-    mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff);\r
+               mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff);\r
                par = (par >> 1)| ( ((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) * 0x80 );\r
-  }    \r
+       }       \r
                \r
-  // Transmit reader nonce and reader answer\r
-  ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par);\r
+       // Transmit reader nonce and reader answer\r
+       ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par);\r
 \r
-  // Receive 4 bit answer\r
+       // Receive 4 bit answer\r
        len = ReaderReceive(receivedAnswer);\r
-  if (!len)\r
-  {\r
-    Dbprintf("Authentication failed. Card timeout.");\r
+       if (!len)\r
+       {\r
+               Dbprintf("Authentication failed. Card timeout.");\r
                return 2;\r
-  }\r
+       }\r
        \r
-  memcpy(tmp4, receivedAnswer, 4);\r
+       memcpy(tmp4, receivedAnswer, 4);\r
        ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0,0);\r
        \r
        if (ntpp != bytes_to_num(tmp4, 4)) {\r
-    Dbprintf("Authentication failed. Error card response.");\r
+               Dbprintf("Authentication failed. Error card response.");\r
                return 3;\r
        }\r
 \r
@@ -147,12 +157,12 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo,
 int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) \r
 {\r
        // variables\r
-  int len;     \r
+       int len;        \r
        uint8_t bt[2];\r
        \r
-  uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
        \r
-  // command MIFARE_CLASSIC_READBLOCK\r
+       // command MIFARE_CLASSIC_READBLOCK\r
        len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer);\r
        if (len == 1) {\r
                Dbprintf("Cmd Error: %02x", receivedAnswer[0]);  \r
@@ -164,7 +174,7 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
        }\r
 \r
        memcpy(bt, receivedAnswer + 16, 2);\r
-  AppendCrc14443a(receivedAnswer, 16);\r
+       AppendCrc14443a(receivedAnswer, 16);\r
        if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {\r
                Dbprintf("Cmd CRC response error.");  \r
                return 3;\r
@@ -177,15 +187,15 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
 int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) \r
 {\r
        // variables\r
-  int len, i;  \r
+       int len, i;     \r
        uint32_t pos;\r
-  uint32_t par = 0;\r
-  byte_t res;\r
+       uint32_t par = 0;\r
+       byte_t res;\r
        \r
        uint8_t d_block[18], d_block_enc[18];\r
-  uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
        \r
-  // command MIFARE_CLASSIC_WRITEBLOCK\r
+       // command MIFARE_CLASSIC_WRITEBLOCK\r
        len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer);\r
 \r
        if ((len != 1) || (receivedAnswer[0] != 0x0A)) {   //  0x0a - ACK\r
@@ -198,15 +208,15 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
        \r
        // crypto\r
        par = 0;\r
-  for (pos = 0; pos < 18; pos++)\r
-  {\r
-    d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos];\r
+       for (pos = 0; pos < 18; pos++)\r
+       {\r
+               d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos];\r
                par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) * 0x20000 );\r
-  }    \r
+       }       \r
 \r
-  ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par);\r
+       ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par);\r
 \r
-  // Receive the response\r
+       // Receive the response\r
        len = ReaderReceive(receivedAnswer);    \r
 \r
        res = 0;\r
@@ -224,13 +234,13 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
 int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) \r
 {\r
        // variables\r
-  int len;     \r
+       int len;        \r
        \r
        // Mifare HALT\r
-  uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
 \r
        len = mifare_sendcmd_short(pcs, 1, 0x50, 0x00, receivedAnswer);\r
-  if (len != 0) {\r
+       if (len != 0) {\r
                Dbprintf("halt error. response len: %x", len);  \r
                return 1;\r
        }\r
index ed2779fcd2f1f6995d3057b20ed94da20f281a0d..a75d0d326ba0f9c78fc96487e578c02feb08ce3d 100644 (file)
@@ -9,6 +9,12 @@
 // code for work with mifare cards.\r
 //-----------------------------------------------------------------------------\r
 \r
+#define CRYPT_NONE    0\r
+#define CRYPT_ALL     1\r
+#define CRYPT_REQUEST 2\r
+#define AUTH_FIRST    0\r
+#define AUTH_NESTED   2\r
+\r
 int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, \\r
                         uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested);\r
 int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); \r
index 922d1b7f923163737d21ae5cb3111fe53c6a9a71..25c46d1af0fefbb1c4c34bcc043e896587c17ee4 100644 (file)
@@ -387,6 +387,109 @@ int CmdHF14AMfRdSc(const char *Cmd)
   return 0;
 }
 
+int CmdHF14AMfNested(const char *Cmd)
+{
+       int i, temp;
+       uint8_t sectorNo = 0;
+       uint8_t keyType = 0;
+       uint8_t key[6] = {0, 0, 0, 0, 0, 0};
+       
+       const char *cmdp        = Cmd;
+
+
+       if (strlen(Cmd)<3) {
+               PrintAndLog("Usage:  hf 14a nested    <sector number> <key A/B> <key (12 hex symbols)>");
+               PrintAndLog("           sample: hf 14a nested 0 A FFFFFFFFFFFF ");
+               return 0;
+       }       
+       
+  // skip spaces
+       while (*cmdp==' ' || *cmdp=='\t') cmdp++;
+       sectorNo = strtol(cmdp, NULL, 0) & 0xff;
+       
+       // next value
+       while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
+       while (*cmdp==' ' || *cmdp=='\t') cmdp++;
+       if (*cmdp != 'A' && *cmdp != 'a')  {
+               keyType = 1;
+       }
+
+       // next value
+       while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
+       while (*cmdp==' ' || *cmdp=='\t') cmdp++;
+
+       if (strlen(cmdp) != 12) {
+               PrintAndLog("Length of key must be 12 hex symbols");
+               return 0;
+       }
+       
+       for(i = 0; i < 6; i++) {
+               sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
+               key[i] = temp & 0xff;
+               cmdp++;
+               cmdp++;
+       }       
+       PrintAndLog(" sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));
+       
+  UsbCommand c = {CMD_MIFARE_NESTED, {sectorNo, keyType, 0}};
+       memcpy(c.d.asBytes, key, 6);
+  SendCommand(&c);
+       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
+       PrintAndLog(" ");
+
+       if (resp != NULL) {
+               uint8_t                isOK  = resp->arg[0] & 0xff;
+               uint8_t              * data  = resp->d.asBytes;
+
+               PrintAndLog("isOk:%02x", isOK);
+               for (i = 0; i < 2; i++) {
+                       PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
+               }
+       } else {
+               PrintAndLog("Command execute timeout");
+       }
+
+  return 0;
+}
+
+int CmdHF14AMf1kSim(const char *Cmd)
+{
+       int i, temp;
+       uint8_t uid[4] = {0, 0, 0, 0};
+       
+       const char *cmdp        = Cmd;
+
+
+       if (strlen(Cmd)<3) {
+               PrintAndLog("Usage:  hf 14a mfsim  <uid (8 hex symbols)>");
+               PrintAndLog("           sample: hf 14a mfsim 0a0a0a0a ");
+               return 0;
+       }       
+       
+  // skip spaces
+       while (*cmdp==' ' || *cmdp=='\t') cmdp++;
+
+       if (strlen(cmdp) != 8) {
+               PrintAndLog("Length of UID must be 8 hex symbols");
+               return 0;
+       }
+       
+       for(i = 0; i < 4; i++) {
+               sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
+               uid[i] = temp & 0xff;
+               cmdp++;
+               cmdp++;
+       }       
+       PrintAndLog(" uid:%s ", sprint_hex(uid, 4));
+       
+  UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}};
+       memcpy(c.d.asBytes, uid, 6);
+  SendCommand(&c);
+
+  return 0;
+}
+
+
 int CmdHF14AReader(const char *Cmd)
 {
        UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
@@ -439,15 +542,17 @@ int CmdHF14ASnoop(const char *Cmd)
 
 static command_t CommandTable[] = 
 {
-  {"help",    CmdHelp,        1, "This help"},
-  {"list",    CmdHF14AList,   0, "List ISO 14443a history"},
-  {"mifare",  CmdHF14AMifare, 0, "Read out sector 0 parity error messages"},
-  {"mfrdbl",  CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
-  {"mfrdsc",  CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
-  {"mfwrbl",  CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},
-  {"reader",  CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
-  {"sim",     CmdHF14ASim,    0, "<UID> -- Fake ISO 14443a tag"},
-  {"snoop",   CmdHF14ASnoop,  0, "Eavesdrop ISO 14443 Type A"},
+  {"help",   CmdHelp,          1, "This help"},
+  {"list",   CmdHF14AList,     0, "List ISO 14443a history"},
+  {"mifare", CmdHF14AMifare,   0, "Read out sector 0 parity error messages"},
+  {"mfrdbl", CmdHF14AMfRdBl,   0, "Read MIFARE classic block"},
+  {"mfrdsc", CmdHF14AMfRdSc,   0, "Read MIFARE classic sector"},
+  {"mfwrbl", CmdHF14AMfWrBl,   0, "Write MIFARE classic block"},
+  {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
+  {"mfsim",  CmdHF14AMf1kSim,  0, "Simulate MIFARE 1k card - NOT WORKING!!!"},
+  {"reader", CmdHF14AReader,   0, "Act like an ISO14443 Type A reader"},
+  {"sim",    CmdHF14ASim,      0, "<UID> -- Fake ISO 14443a tag"},
+  {"snoop",  CmdHF14ASnoop,    0, "Eavesdrop ISO 14443 Type A"},
   {NULL, NULL, 0, NULL}
 };
 
Impressum, Datenschutz