]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge pull request #101 from marshmellow42/master
authorMartin Holst Swende <martin@swende.se>
Fri, 22 May 2015 19:55:34 +0000 (21:55 +0200)
committerMartin Holst Swende <martin@swende.se>
Fri, 22 May 2015 19:55:34 +0000 (21:55 +0200)
hf mfu updates + hf search + bug fixes

43 files changed:
armsrc/appmain.c
armsrc/apps.h
armsrc/des.c
armsrc/des.h
armsrc/iclass.c
armsrc/lfops.c
armsrc/mifarecmd.c
armsrc/mifareutil.c
armsrc/mifareutil.h
client/Makefile
client/cmddata.c
client/cmddata.h
client/cmdhf.c
client/cmdhf14a.c
client/cmdhf15.c
client/cmdhf15.h
client/cmdhficlass.c
client/cmdhficlass.h
client/cmdhfmf.c
client/cmdhfmfu.c
client/cmdhfmfu.h
client/cmdscript.c
client/default_keys.dic
client/lualibs/commands.lua
client/lualibs/default_toys.lua
client/lualibs/html_dumplib.lua
client/lualibs/md5.lua [new file with mode: 0644]
client/lualibs/mf_default_keys.lua
client/lualibs/precalc.lua [new file with mode: 0644]
client/lualibs/read14a.lua
client/lualibs/utils.lua
client/mifarehost.c
client/scripting.c
client/scripts/formatMifare.lua
client/scripts/tnp3clone.lua
client/scripts/tnp3dump.lua
client/scripts/tnp3sim.lua
client/util.c
client/util.h
common/crc64.c [new file with mode: 0644]
common/crc64.h [new file with mode: 0644]
common/protocols.h
include/usb_cmd.h

index 6e0b58b3da84fa7bc3e2463c47fd10bc285a9eb8..96644b9a09e039062130d5fae52c34952c3032d1 100644 (file)
@@ -738,7 +738,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
                        break;
 #endif
-            
+
 #ifdef WITH_ISO15693
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
                        AcquireRawAdcSamplesIso15693();
@@ -818,25 +818,22 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
                        
                case CMD_READER_MIFARE:
-            ReaderMifare(c->arg[0]);
+                       ReaderMifare(c->arg[0]);
                        break;
                case CMD_MIFARE_READBL:
                        MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFAREU_READBL:
-                       MifareUReadBlock(c->arg[0],c->d.asBytes);
-                       break;
-               case CMD_MIFAREUC_AUTH1:
-                       MifareUC_Auth1(c->arg[0],c->d.asBytes);
+                       MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
                        break;
-               case CMD_MIFAREUC_AUTH2:
-                       MifareUC_Auth2(c->arg[0],c->d.asBytes);
+               case CMD_MIFAREUC_AUTH:
+                       MifareUC_Auth(c->arg[0],c->d.asBytes);
                        break;
                case CMD_MIFAREU_READCARD:
-                       MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
+                       MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
-               case CMD_MIFAREUC_READCARD:
-                       MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
+               case CMD_MIFAREUC_SETPWD: 
+                       MifareUSetPwd(c->arg[0], c->d.asBytes);
                        break;
                case CMD_MIFARE_READSC:
                        MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
@@ -846,10 +843,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
                case CMD_MIFAREU_WRITEBL_COMPAT:
                        MifareUWriteBlock(c->arg[0], c->d.asBytes);
-                        break;
+                       break;
                case CMD_MIFAREU_WRITEBL:
-                        MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
-                        break;
+                       MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
+                       break;
                case CMD_MIFARE_NESTED:
                        MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
index 928a3075f44391c80e51f9ffc1f6d511225aa2ce..57fb55fd3d38c051c3f3a2b509cf672462173b42 100644 (file)
@@ -165,10 +165,9 @@ void EPA_PACE_Collect_Nonce(UsbCommand * c);
 void ReaderMifare(bool first_try);
 int32_t dist_nt(uint32_t nt1, uint32_t nt2);
 void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
-void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
-void MifareUC_Auth1(uint8_t arg0, uint8_t *datain);
-void MifareUC_Auth2(uint32_t arg0, uint8_t *datain);
-void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
+void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
+void MifareUC_Auth(uint8_t arg0, uint8_t *datain);
+void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain);
 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);
 void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
@@ -184,6 +183,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);  // Work with "magic Chinese" card
 void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 void MifareCIdent();  // is "magic chinese" card?
+void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
 
 //desfire
 void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);
index 0a27503e016d197e63d730a557b625cded147e63..a81df9c8d4234c7bd2bd5432b0a503f9a1c6ba36 100644 (file)
@@ -378,6 +378,60 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
        des_dec(out, out, (uint8_t*)key + 0);
 }
 
+void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
+
+       if( length % 8 ) return; 
+       
+       uint8_t i;
+       uint8_t* tin = (uint8_t*) in;
+       uint8_t* tout = (uint8_t*) out;
+       
+       while( length > 0 )
+       {
+               for ( i = 0; i < 8; i++ )
+                       tout[i] = (unsigned char)(tin[i] ^ iv[i]);
+
+               des_enc(tout,  tin, (uint8_t*)key + 0);
+               des_dec(tout, tout, (uint8_t*)key + 8);
+               des_enc(tout, tout, (uint8_t*)key + 0);
+               
+               memcpy(iv, tout, 8);
+
+               tin  += 8;
+               tout += 8;
+               length -= 8;
+       }
+}
+
+void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
+       
+       if( length % 8 ) return; 
+
+       uint8_t i;
+       unsigned char temp[8];
+       uint8_t* tin = (uint8_t*) in;
+       uint8_t* tout = (uint8_t*) out;
+       
+       while( length > 0 )
+       {
+               memcpy(temp, tin, 8);
+
+               des_dec(tout,  tin, (uint8_t*)key + 0);
+               des_enc(tout, tout, (uint8_t*)key + 8);
+               des_dec(tout, tout, (uint8_t*)key + 0);          
+
+               for (i = 0; i < 8; i++)
+                       tout[i] = (unsigned char)(tout[i] ^ iv[i]);
+
+               memcpy(iv, temp, 8);
+               
+               tin  += 8;
+               tout += 8;
+               length -= 8;
+       }
+}
+
+
 /******************************************************************************/
 
 
index 652886fd7a523d9aeab176057ac7003d8fd0ba2e..90f742464ba6d4ed41988c81f2cf33b8c4dc77ec 100644 (file)
@@ -97,6 +97,9 @@ void tdes_enc(void* out, const void* in, const void* key);
  */
  void tdes_dec(void* out, const void* in, const void* key);
 
+ void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]);
+ void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]);
+
 #endif /*DES_H_*/
 
 // Copied from des.h in desfire imp.
index 56bc29db5d760f4f631c51878635c486fe0d6de6..9139d3bd9f5a0734f4b2e651ca4b503e4b0a6485 100644 (file)
@@ -1677,7 +1677,7 @@ void ReaderIClass(uint8_t arg0) {
 
        uint8_t card_data[6 * 8]={0};
        memset(card_data, 0xFF, sizeof(card_data));
-    uint8_t last_csn[8]={0};
+       uint8_t last_csn[8]={0};
        
        //Read conf block CRC(0x01) => 0xfa 0x22
        uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22};
@@ -1685,16 +1685,18 @@ void ReaderIClass(uint8_t arg0) {
        uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64};
 
 
-    int read_status= 0;
+       int read_status= 0;
        uint8_t result_status = 0;
-    bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
-
+       bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
+       bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY;
        set_tracing(TRUE);
-    setupIclassReader();
+       setupIclassReader();
 
+       uint16_t tryCnt=0;
        while(!BUTTON_PRESS())
-    {
-
+       {
+               if (try_once && tryCnt > 5) break; 
+               tryCnt++;
                if(!tracing) {
                        DbpString("Trace full");
                        break;
@@ -1761,7 +1763,7 @@ void ReaderIClass(uint8_t arg0) {
 
                }
                LED_B_OFF();
-    }
+       }
     cmd_send(CMD_ACK,0,0,0,card_data, 0);
     LED_A_OFF();
 }
index e45b55fcb22767111a76ac54c99ea7470b3b51e2..c3fa8a0e630f2f743aaedd247b2d711c89610385 100644 (file)
@@ -651,7 +651,7 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
        int ledcontrol = 1;
        int n=0, i=0;
        uint8_t clk = (arg1 >> 8) & 0xFF;
-       uint8_t encoding = arg1 & 1;
+       uint8_t encoding = arg1 & 0xFF;
        uint8_t separator = arg2 & 1;
        uint8_t invert = (arg2 >> 8) & 1;
 
index a16cbf16612f9130e29f26ecce116c13669aacfa..0586a25db1b8882678ca3bd3080bcb37437d9293 100644 (file)
 \r
 #include "crc.h"\r
 \r
+// the block number for the ISO14443-4 PCB\r
+uint8_t pcb_blocknum = 0;\r
+// Deselect card by sending a s-block. the crc is precalced for speed\r
+static  uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};\r
+\r
+\r
 //-----------------------------------------------------------------------------\r
 // Select, Authenticate, Read a MIFARE tag. \r
 // read block\r
@@ -86,107 +92,90 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LEDsoff();\r
 }\r
 \r
+void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){\r
 \r
-void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){\r
-\r
-       byte_t isOK = 0;\r
-       byte_t dataoutbuf[16] = {0x00};\r
-       uint8_t uid[10] = {0x00};\r
-       uint32_t cuid;\r
+       bool turnOffField = (arg0 == 1);\r
 \r
-       LED_A_ON();\r
-       LED_B_OFF();\r
-       LED_C_OFF();\r
-    \r
+       LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
        clear_trace();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
 \r
-       if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Can't select card");\r
-               //OnError(0);\r
+       if(!iso14443a_select_card(NULL, NULL, NULL)) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
+               OnError(0);\r
                return;\r
        };\r
        \r
-       if(mifare_ultra_auth1(cuid, dataoutbuf)){\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)        \r
-                       Dbprintf("Authentication part1: Fail.");\r
-               //OnError(1);\r
+       if(!mifare_ultra_auth(keybytes)){\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed");\r
+               OnError(1);\r
                return;\r
        }\r
 \r
-       isOK = 1;\r
-       if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
-               DbpString("AUTH 1 FINISHED");\r
-    \r
-    cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11);\r
-       LEDsoff();\r
-}\r
-void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){\r
-\r
-       uint32_t cuid = arg0;\r
-       uint8_t key[16] = {0x00};\r
-       byte_t isOK = 0;\r
-       byte_t dataoutbuf[16] = {0x00};\r
-    \r
-       memcpy(key, datain, 16);\r
-    \r
-       LED_A_ON();\r
-       LED_B_OFF();\r
-       LED_C_OFF();\r
-       \r
-       if(mifare_ultra_auth2(cuid, key, dataoutbuf)){\r
-           if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
-                       Dbprintf("Authentication part2: Fail...");\r
-               //OnError(1);\r
-               return;                 \r
+       if (turnOffField) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               LEDsoff();\r
        }\r
-       \r
-       isOK = 1;\r
-       if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
-               DbpString("AUTH 2 FINISHED");\r
-    \r
-       cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-       LEDsoff();\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
 }\r
 \r
-void MifareUReadBlock(uint8_t arg0,uint8_t *datain)\r
+// Arg0 = BlockNo,\r
+// Arg1 = UsePwd bool\r
+// datain = PWD bytes,\r
+void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)\r
 {\r
        uint8_t blockNo = arg0;\r
        byte_t dataout[16] = {0x00};\r
-       uint8_t uid[10] = {0x00};\r
-       uint32_t cuid;\r
-    \r
+       bool useKey = (arg1 == 1); //UL_C\r
+       bool usePwd = (arg1 == 2); //UL_EV1/NTAG\r
+\r
+       LEDsoff();\r
        LED_A_ON();\r
-       LED_B_OFF();\r
-       LED_C_OFF();\r
-    \r
        clear_trace();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
-    \r
-       int len = iso14443a_select_card(uid, NULL, &cuid);\r
+\r
+       int len = iso14443a_select_card(NULL, NULL, NULL);\r
        if(!len) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Can't select card");\r
-               //OnError(1);\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);\r
+               OnError(1);\r
                return;\r
-               };\r
-        \r
-       len = mifare_ultra_readblock(cuid, blockNo, dataout);\r
-       if(len) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Read block error");\r
-               //OnError(2);\r
+       }\r
+\r
+       // UL-C authentication\r
+       if ( useKey ) {\r
+               uint8_t key[16] = {0x00};\r
+               memcpy(key, datain, sizeof(key) );\r
+\r
+               if ( !mifare_ultra_auth(key) ) {\r
+                       OnError(1);\r
+                       return;\r
+               }\r
+       }\r
+\r
+       // UL-EV1 / NTAG authentication\r
+       if ( usePwd ) {\r
+               uint8_t pwd[4] = {0x00};\r
+               memcpy(pwd, datain, 4);\r
+               uint8_t pack[4] = {0,0,0,0};\r
+               if (!mifare_ul_ev1_auth(pwd, pack)) {\r
+                       OnError(1);\r
+                       return;\r
+               }\r
+       }       \r
+\r
+       if( mifare_ultra_readblock(blockNo, dataout) ) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");\r
+               OnError(2);\r
                return;\r
-               };\r
-        \r
-       len = mifare_ultra_halt(cuid);\r
-       if(len) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Halt error");\r
-               //OnError(3);\r
+       }\r
+\r
+       if( mifare_ultra_halt() ) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
+               OnError(3);\r
                return;\r
-               };\r
-               \r
-    cmd_send(CMD_ACK,1,0,0,dataout,16);\r
+       }\r
+\r
+       cmd_send(CMD_ACK,1,0,0,dataout,16);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
@@ -259,73 +248,98 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LEDsoff();\r
 }\r
 \r
-void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)\r
+void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)\r
 {\r
-  // params\r
-        uint8_t sectorNo = arg0;\r
-       int Pages = arg1;\r
-       int count_Pages = 0;\r
-       byte_t dataout[176] = {0x00};;\r
-       uint8_t uid[10] = {0x00};\r
-       uint32_t cuid;\r
+       // free eventually allocated BigBuf memory\r
+       BigBuf_free();\r
+       // clear trace\r
+       clear_trace();\r
 \r
-       LED_A_ON();\r
-       LED_B_OFF();\r
-       LED_C_OFF();\r
+       // params\r
+       uint8_t blockNo = arg0;\r
+       uint16_t blocks = arg1;\r
+       bool useKey = (arg2 == 1); //UL_C\r
+       bool usePwd = (arg2 == 2); //UL_EV1/NTAG\r
+       uint32_t countblocks = 0;\r
+       uint8_t *dataout = BigBuf_malloc(CARD_MEMORY_SIZE);\r
+       if (dataout == NULL){\r
+               Dbprintf("out of memory");\r
+               OnError(1);\r
+               return;\r
+       }\r
 \r
-       if (MF_DBGLEVEL >= MF_DBG_ALL) \r
-               Dbprintf("Pages %d",Pages);\r
-       \r
-       clear_trace();\r
+       LEDsoff();\r
+       LED_A_ON();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
 \r
-       int len = iso14443a_select_card(uid, NULL, &cuid);\r
-       \r
+       int len = iso14443a_select_card(NULL, NULL, NULL);\r
        if (!len) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Can't select card");\r
-               //OnError(1);\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);\r
+               OnError(1);\r
                return;\r
        }\r
+\r
+       // UL-C authentication\r
+       if ( useKey ) {\r
+               uint8_t key[16] = {0x00};\r
+               memcpy(key, datain, sizeof(key) );\r
+\r
+               if ( !mifare_ultra_auth(key) ) {\r
+                       OnError(1);\r
+                       return;\r
+               }\r
+       }\r
+\r
+       // UL-EV1 / NTAG authentication\r
+       if (usePwd) {\r
+               uint8_t pwd[4] = {0x00};\r
+               memcpy(pwd, datain, sizeof(pwd));\r
+               uint8_t pack[4] = {0,0,0,0};\r
+\r
+               if (!mifare_ul_ev1_auth(pwd, pack)){\r
+                       OnError(1);\r
+                       return;                 \r
+               }\r
+       }\r
+\r
+       for (int i = 0; i < blocks; i++){\r
+               if ((i*4) + 4 > CARD_MEMORY_SIZE) {\r
+                       Dbprintf("Data exceeds buffer!!");\r
+                       break;\r
+               }\r
        \r
-       for (int i = 0; i < Pages; i++){\r
-       \r
-               len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);\r
-               \r
+               len = mifare_ultra_readblock(blockNo + i, dataout + 4 * i);\r
+\r
                if (len) {\r
-                       if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                               Dbprintf("Read block %d error",i);\r
-                       //OnError(2);\r
-                       return;\r
+                       if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block %d error",i);\r
+                       // if no blocks read - error out\r
+                       if (i==0){\r
+                               OnError(2);\r
+                               return;\r
+                       } else {\r
+                               //stop at last successful read block and return what we got\r
+                               break;\r
+                       }\r
                } else {\r
-                       count_Pages++;\r
+                       countblocks++;\r
                }\r
        }\r
-               \r
-       len = mifare_ultra_halt(cuid);\r
+\r
+       len = mifare_ultra_halt();\r
        if (len) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Halt error");\r
-               //OnError(3);\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
+               OnError(3);\r
                return;\r
        }\r
-       \r
-       if (MF_DBGLEVEL >= MF_DBG_ALL) {\r
-               Dbprintf("Pages read %d", count_Pages);\r
-       }\r
 \r
-       len = 16*4; //64 bytes\r
-       \r
-       // Read a UL-C\r
-       if (Pages == 44 && count_Pages > 16) \r
-               len = 176;\r
+       if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks);\r
 \r
-       cmd_send(CMD_ACK, 1, 0, 0, dataout, len);       \r
+       countblocks *= 4;\r
+       cmd_send(CMD_ACK, 1, countblocks, countblocks, 0, 0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
-\r
 //-----------------------------------------------------------------------------\r
 // Select, Authenticate, Write a MIFARE tag. \r
 // read block\r
@@ -400,94 +414,143 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
 void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)\r
 {\r
-        // params\r
-        uint8_t blockNo = arg0;\r
+       uint8_t blockNo = arg0;\r
        byte_t blockdata[16] = {0x00};\r
 \r
-        memcpy(blockdata, datain,16);\r
-        \r
-        // variables\r
-        byte_t isOK = 0;\r
+       memcpy(blockdata, datain, 16);\r
+\r
        uint8_t uid[10] = {0x00};\r
-        uint32_t cuid;\r
 \r
-               clear_trace();\r
-               iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+       LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
+\r
+       clear_trace();\r
+       iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+\r
+       if(!iso14443a_select_card(uid, NULL, NULL)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
+               OnError(0);\r
+               return;\r
+       };\r
+\r
+       if(mifare_ultra_writeblock(blockNo, blockdata)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");\r
+               OnError(0);\r
+               return; };\r
+\r
+       if(mifare_ultra_halt()) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+               OnError(0);\r
+               return;\r
+       };\r
+\r
+       if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
 \r
-        LED_A_ON();\r
-        LED_B_OFF();\r
-        LED_C_OFF();\r
-\r
-        while (true) {\r
-                if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
-                        break;\r
-                };\r
-\r
-                if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {\r
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");\r
-                        break;\r
-                };\r
-\r
-                if(mifare_ultra_halt(cuid)) {\r
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
-                        break;\r
-                };\r
-                \r
-                isOK = 1;\r
-                break;\r
-        }\r
-        \r
-        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
-\r
-               cmd_send(CMD_ACK,isOK,0,0,0,0);\r
-        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-        LEDsoff();\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
 }\r
 \r
 void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)\r
 {\r
-       // params\r
        uint8_t blockNo = arg0;\r
        byte_t blockdata[4] = {0x00};\r
-       \r
+\r
        memcpy(blockdata, datain,4);\r
+       \r
+       LEDsoff();\r
+       LED_A_ON();\r
+       clear_trace();\r
+       iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
 \r
-       // variables\r
-       byte_t isOK = 0;\r
-       uint8_t uid[10] = {0x00};\r
-       uint32_t cuid;\r
+       if(!iso14443a_select_card(NULL, NULL, NULL)) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+               OnError(0);\r
+               return;\r
+       };\r
+\r
+       if(mifare_ultra_special_writeblock(blockNo, blockdata)) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+               OnError(0);\r
+               return;\r
+       };\r
+\r
+       if(mifare_ultra_halt()) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+               OnError(0);\r
+               return;\r
+       };\r
+\r
+       if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
+\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+}\r
 \r
+void MifareUSetPwd(uint8_t arg0, uint8_t *datain){\r
+       \r
+       uint8_t pwd[16] = {0x00};\r
+       byte_t blockdata[4] = {0x00};\r
+       \r
+       memcpy(pwd, datain, 16);\r
+       \r
+       LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
        clear_trace();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
 \r
-       LED_A_ON();\r
-       LED_B_OFF();\r
-       LED_C_OFF();\r
+       if(!iso14443a_select_card(NULL, NULL, NULL)) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+               OnError(0);\r
+               return;\r
+       };\r
 \r
-       while (true) {\r
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
-                       break;\r
-               };\r
+       blockdata[0] = pwd[7];\r
+       blockdata[1] = pwd[6];\r
+       blockdata[2] = pwd[5];\r
+       blockdata[3] = pwd[4];\r
+       if(mifare_ultra_special_writeblock( 44, blockdata)) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+               OnError(44);\r
+               return;\r
+       };\r
 \r
-               if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {\r
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");\r
-                       break;\r
-               };\r
+       blockdata[0] = pwd[3];\r
+       blockdata[1] = pwd[2];\r
+       blockdata[2] = pwd[1];\r
+       blockdata[3] = pwd[0];\r
+       if(mifare_ultra_special_writeblock( 45, blockdata)) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+               OnError(45);\r
+               return;\r
+       };\r
 \r
-               if(mifare_ultra_halt(cuid)) {\r
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
-                       break;\r
-               };\r
+       blockdata[0] = pwd[15];\r
+       blockdata[1] = pwd[14];\r
+       blockdata[2] = pwd[13];\r
+       blockdata[3] = pwd[12];\r
+       if(mifare_ultra_special_writeblock( 46, blockdata)) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+               OnError(46);\r
+               return;\r
+       };\r
 \r
-               isOK = 1;\r
-               break;\r
-       }\r
+       blockdata[0] = pwd[11];\r
+       blockdata[1] = pwd[10];\r
+       blockdata[2] = pwd[9];\r
+       blockdata[3] = pwd[8];\r
+       if(mifare_ultra_special_writeblock( 47, blockdata)) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+               OnError(47);\r
+               return;\r
+       };      \r
 \r
-       if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
+       if(mifare_ultra_halt()) {\r
+               if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+               OnError(0);\r
+               return;\r
+       };\r
 \r
-       cmd_send(CMD_ACK,isOK,0,0,0,0);\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
@@ -1141,21 +1204,18 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
 \r
        int len = iso14443a_select_card(uid, NULL, &cuid);\r
        if(!len) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)        \r
-                       Dbprintf("Can't select card");\r
-               //OnError(1);\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
+               OnError(1);\r
                return;\r
        };\r
 \r
        if(mifare_desfire_des_auth1(cuid, dataout)){\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)        \r
-                       Dbprintf("Authentication part1: Fail.");\r
-               //OnError(4);\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part1: Fail.");\r
+               OnError(4);\r
                return;\r
        }\r
 \r
        if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");\r
-    \r
     cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));\r
 }\r
 \r
@@ -1184,3 +1244,18 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
+\r
+void OnSuccess(){\r
+       pcb_blocknum = 0;\r
+       ReaderTransmit(deselect_cmd, 3 , NULL);\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+}\r
+\r
+void OnError(uint8_t reason){\r
+       pcb_blocknum = 0;\r
+       ReaderTransmit(deselect_cmd, 3 , NULL);\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       cmd_send(CMD_ACK,0,reason,0,0,0);\r
+       LEDsoff();\r
+}\r
index f79c2ede2d78676ddc6aef7b373129e3198a23ca..2f84797b92e015384d8b2755410bd4c553431efd 100644 (file)
@@ -18,6 +18,7 @@
 #include "iso14443a.h"\r
 #include "crapto1.h"\r
 #include "mifareutil.h"\r
+#include "des.h"\r
 \r
 int MF_DBGLEVEL = MF_DBG_ALL;\r
 \r
@@ -67,24 +68,24 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
 // send commands\r
 int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)\r
 {\r
-       return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing);
-}
-
-int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
-{
-       uint8_t dcmd[8];
-    dcmd[0] = cmd;
-    dcmd[1] = data[0];
-       dcmd[2] = data[1];
-       dcmd[3] = data[2];
-       dcmd[4] = data[3];
-       dcmd[5] = data[4];
-       AppendCrc14443a(dcmd, 6);
-       ReaderTransmit(dcmd, sizeof(dcmd), NULL);
-       int len = ReaderReceive(answer, answer_parity);
-       if(!len) {
-                if (MF_DBGLEVEL >= 1)   Dbprintf("Authentication failed. Card timeout.");
-                return 2;
+       return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing);\r
+}\r
+\r
+int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)\r
+{\r
+       uint8_t dcmd[8];\r
+    dcmd[0] = cmd;\r
+    dcmd[1] = data[0];\r
+       dcmd[2] = data[1];\r
+       dcmd[3] = data[2];\r
+       dcmd[4] = data[3];\r
+       dcmd[5] = data[4];\r
+       AppendCrc14443a(dcmd, 6);\r
+       ReaderTransmit(dcmd, sizeof(dcmd), NULL);\r
+       int len = ReaderReceive(answer, answer_parity);\r
+       if(!len) {\r
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Authentication failed. Card timeout.");\r
+                return 2;\r
     }\r
        return len;\r
 }\r
@@ -106,13 +107,34 @@ int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uin
     if(len==1) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)   Dbprintf("NAK - Authentication failed.");\r
                return 1;\r
-        }
-       return len;
-}
-
-int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
-{
-       uint8_t dcmd[4], ecmd[4];
+        }\r
+       return len;\r
+}\r
+\r
+int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)\r
+{\r
+    uint8_t dcmd[7];\r
+       int len; \r
+    dcmd[0] = cmd;\r
+    memcpy(dcmd+1,data,4);\r
+       AppendCrc14443a(dcmd, 5);\r
+       \r
+       ReaderTransmit(dcmd, sizeof(dcmd), timing);\r
+       len = ReaderReceive(answer, answer_parity);\r
+       if(!len) {\r
+        if (MF_DBGLEVEL >= MF_DBG_ERROR)   Dbprintf("Authentication failed. Card timeout.");\r
+        len = ReaderReceive(answer,answer_parity);\r
+    }\r
+    if(len==1) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR)   Dbprintf("NAK - Authentication failed.");\r
+               return 1;\r
+        }\r
+       return len;\r
+}\r
+\r
+int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)\r
+{\r
+       uint8_t dcmd[4], ecmd[4];\r
        uint16_t pos, res;\r
        uint8_t par[1];                 // 1 Byte parity is enough here\r
        dcmd[0] = cmd;\r
@@ -284,97 +306,149 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
        }\r
        \r
        memcpy(blockData, receivedAnswer, 16);\r
-       return 0;
-}
-
+       return 0;\r
+}\r
+\r
 // mifare ultralight commands\r
-int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){\r
+int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){\r
 \r
        uint16_t len;\r
-       uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
-       uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-       \r
-       len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);\r
-       if (len == 1) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
-               return 1;\r
+       uint8_t resp[4];\r
+       uint8_t respPar[1];\r
+       uint8_t key[4] = {0x00};\r
+       memcpy(key, keybytes, 4);\r
+\r
+       Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]);\r
+       len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL);\r
+       if (len != 4) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len);\r
+               return 0;\r
        }\r
-       if (len != 11)\r
-               return 1;\r
 \r
-       if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {\r
-               Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",\r
-                       receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],\r
-                       receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],\r
-                       receivedAnswer[10]);\r
-               }\r
-       memcpy(blockData, receivedAnswer, 11);\r
-       return 0;\r
+       if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
+               Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0],resp[1],resp[2],resp[3]);\r
+\r
+       memcpy(pack, resp, 4);\r
+       return 1;\r
 }\r
 \r
-int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){\r
+int mifare_ultra_auth(uint8_t *keybytes){\r
+\r
+       /// 3des2k\r
+\r
+       uint8_t random_a[8] = {1,1,1,1,1,1,1,1};\r
+       uint8_t random_b[8] = {0x00};\r
+       uint8_t enc_random_b[8] = {0x00};\r
+       uint8_t rnd_ab[16] = {0x00};\r
+       uint8_t IV[8] = {0x00};\r
+       uint8_t key[16] = {0x00};\r
+       memcpy(key, keybytes, 16);\r
 \r
        uint16_t len;\r
-       uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
-       uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+       uint8_t resp[19] = {0x00};\r
+       uint8_t respPar[3] = {0,0,0};\r
+\r
+       // REQUEST AUTHENTICATION\r
+       len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, resp, respPar ,NULL);\r
+       if (len != 11) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);\r
+               return 0;\r
+       }\r
+\r
+       // tag nonce.\r
+       memcpy(enc_random_b,resp+1,8);\r
+\r
+       // decrypt nonce.\r
+       tdes_2key_dec(random_b, enc_random_b, sizeof(random_b), key, IV );\r
+       rol(random_b,8);\r
+       memcpy(rnd_ab  ,random_a,8);\r
+       memcpy(rnd_ab+8,random_b,8);\r
+\r
+       if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {\r
+               Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x",\r
+                       enc_random_b[0],enc_random_b[1],enc_random_b[2],enc_random_b[3],enc_random_b[4],enc_random_b[5],enc_random_b[6],enc_random_b[7]);\r
+\r
+               Dbprintf("    B: %02x %02x %02x %02x %02x %02x %02x %02x",\r
+                       random_b[0],random_b[1],random_b[2],random_b[3],random_b[4],random_b[5],random_b[6],random_b[7]);\r
+\r
+               Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x",\r
+                               rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3],rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]);\r
+\r
+               Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x",\r
+                               rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11],rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15] );\r
+       }\r
+\r
+       // encrypt    out, in, length, key, iv\r
+       tdes_2key_enc(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b);\r
+\r
+       len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, rnd_ab, resp, respPar, NULL);\r
+       if (len != 11) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);\r
+               return 0;\r
+       }\r
+\r
+       uint8_t enc_resp[8] = { 0,0,0,0,0,0,0,0 };\r
+       uint8_t resp_random_a[8] = { 0,0,0,0,0,0,0,0 };\r
+       memcpy(enc_resp, resp+1, 8);\r
+\r
+       // decrypt    out, in, length, key, iv \r
+       tdes_2key_dec(resp_random_a, enc_resp, 8, key, enc_random_b);\r
+       if ( memcmp(resp_random_a, random_a, 8) != 0 ) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("failed authentication");\r
+               return 0;\r
+       }\r
+\r
+       if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {\r
+               Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", \r
+                               rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3],\r
+                               rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]);\r
+\r
+               Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x",\r
+                               rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11],\r
+                               rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15]);\r
+\r
+               Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x",\r
+                               random_a[0],random_a[1],random_a[2],random_a[3],\r
+                               random_a[4],random_a[5],random_a[6],random_a[7]);\r
+\r
+               Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x",\r
+                               resp_random_a[0],resp_random_a[1],resp_random_a[2],resp_random_a[3],\r
+                               resp_random_a[4],resp_random_a[5],resp_random_a[6],resp_random_a[7]);\r
+       }\r
+       return 1;\r
+}\r
+\r
+int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)\r
+{\r
+       uint16_t len;\r
+       uint8_t bt[2];\r
+       uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+       uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
        \r
-       len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);\r
+       len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
        if (len == 1) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
                return 1;\r
        }\r
-       if (len != 11)\r
-               return 1;       \r
-       \r
-       if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {\r
-               Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",\r
-                       receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],\r
-                       receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],\r
-                       receivedAnswer[10]);\r
+       if (len != 18) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);\r
+               return 2;\r
        }\r
-       memcpy(blockData, receivedAnswer, 11);\r
+    \r
+       memcpy(bt, receivedAnswer + 16, 2);\r
+       AppendCrc14443a(receivedAnswer, 16);\r
+       if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error.");\r
+               return 3;\r
+       }\r
+       \r
+       memcpy(blockData, receivedAnswer, 14);\r
        return 0;\r
 }\r
 \r
-int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
-{
-       uint16_t len;
-       uint8_t bt[2];
-       uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
-       uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-       
-       \r
-       // command MIFARE_CLASSIC_READBLOCK
-       len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
-       if (len == 1) {
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
-               return 1;
-       }
-       if (len != 18) {
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd Error: card timeout. len: %x", len);
-               return 2;
-       }
-    
-       memcpy(bt, receivedAnswer + 16, 2);
-       AppendCrc14443a(receivedAnswer, 16);
-       if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd CRC response error.");
-               return 3;
-       }
-       
-       memcpy(blockData, receivedAnswer, 14);
-       return 0;
-}
-
-
-int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) 
-{
-       // variables
+int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) \r
+{\r
+       // variables\r
        uint16_t len, i;        \r
        uint32_t pos;\r
        uint8_t par[3] = {0};           // enough for 18 Bytes to send\r
@@ -416,65 +490,65 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
                return 2;\r
        }\r
        \r
-       return 0;
-}
-
-int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) 
-{
-    uint16_t len;     
-    uint8_t par[3] = {0};  // enough for 18 parity bits
-       uint8_t d_block[18] = {0x00};
-       uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
-       uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-        
-    // command MIFARE_CLASSIC_WRITEBLOCK
-    len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
-
-    if ((len != 1) || (receivedAnswer[0] != 0x0A)) {   //  0x0a - ACK
+       return 0;\r
+}\r
+\r
+int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) \r
+{\r
+       uint16_t len;\r
+       uint8_t par[3] = {0};  // enough for 18 parity bits\r
+       uint8_t d_block[18] = {0x00};\r
+       uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+       uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
+\r
+       // command MIFARE_CLASSIC_WRITEBLOCK\r
+       len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+\r
+       if ((len != 1) || (receivedAnswer[0] != 0x0A)) {   //  0x0a - ACK\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);  
-        return 1;
-    }
-
-       memcpy(d_block, blockData, 16);
-    AppendCrc14443a(d_block, 16);
-
-       ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
-
-    len = ReaderReceive(receivedAnswer, receivedAnswerPar);    
-
-       if ((len != 1) || (receivedAnswer[0] != 0x0A)) {   //  0x0a - ACK
+                       Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);\r
+               return 1;\r
+       }\r
+\r
+       memcpy(d_block, blockData, 16);\r
+       AppendCrc14443a(d_block, 16);\r
+\r
+       ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);\r
+\r
+       len = ReaderReceive(receivedAnswer, receivedAnswerPar);\r
+\r
+       if ((len != 1) || (receivedAnswer[0] != 0x0A)) {   //  0x0a - ACK\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
-        return 2;
-    }        
-    return 0;
-} 
-
-int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
-{
-    uint16_t len;
-       uint8_t d_block[8] = {0x00};
+                       Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);\r
+               return 2;\r
+       }\r
+       return 0;\r
+}\r
+\r
+int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData)\r
+{\r
+       uint16_t len;\r
+       uint8_t d_block[8] = {0x00};\r
        uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
        uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-
-    // command MIFARE_CLASSIC_WRITEBLOCK
-       d_block[0]= blockNo;
-       memcpy(d_block+1,blockData,4);
-       AppendCrc14443a(d_block, 6);
-
-    len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
-
-    if (receivedAnswer[0] != 0x0A) {   //  0x0a - ACK
+\r
+       // command MIFARE_CLASSIC_WRITEBLOCK\r
+       d_block[0]= blockNo;\r
+       memcpy(d_block+1,blockData,4);\r
+       AppendCrc14443a(d_block, 6);\r
+\r
+       len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);\r
+\r
+       if (receivedAnswer[0] != 0x0A) {   //  0x0a - ACK\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
-        return 1;
-    }
-\r    return 0;
-}
-
-int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) 
-{
+                       Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) \r
+{\r
        uint16_t len;   \r
        uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
        uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
@@ -486,24 +560,24 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
                return 1;\r
        }\r
 \r
-       return 0;
-}
-
-int mifare_ultra_halt(uint32_t uid)
-{
-       uint16_t len;
+       return 0;\r
+}\r
+\r
+int mifare_ultra_halt()\r
+{\r
+       uint16_t len;\r
        uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
        uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-    
-       len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
-       if (len != 0) {
+    \r
+       len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
+       if (len != 0) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("halt error. response len: %x", len);
-               return 1;
-       }
-       return 0;
-}
-
+                       Dbprintf("halt error. response len: %x", len);\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
 \r
 // Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),\r
 // plus evtl. 8 sectors with 16 blocks each (4k cards)\r
@@ -525,9 +599,9 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
 }\r
 \r
 \r
-// work with emulator memory
-void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
-       uint8_t* emCARD = BigBuf_get_EM_addr();
+// work with emulator memory\r
+void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {\r
+       uint8_t* emCARD = BigBuf_get_EM_addr();\r
        memcpy(emCARD + blockNum * 16, data, blocksCount * 16);\r
 }\r
 \r
@@ -654,8 +728,8 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
        int len;\r
        // load key, keynumber\r
        uint8_t data[2]={0x0a, 0x00};\r
-       uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
-       uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+       uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+       uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
        \r
        len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL);\r
        if (len == 1) {\r
@@ -706,4 +780,4 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
                return 0;\r
        }\r
        return 1;\r
-}
+}\r
index 195afa534b45e639e5488163e9068be41385c99d..d4fcd818932e4cf66299edd53044e00f9432fb2f 100644 (file)
@@ -52,33 +52,34 @@ extern int MF_DBGLEVEL;
 \r
 #define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();\r
 \r
-//functions
-int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
-int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
+//functions\r
+int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);\r
+int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);\r
 \r
 int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);\r
-int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
-
+int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);\r
+int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);\r
+\r
 int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);\r
-int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
-int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); 
-int mifare_ultra_auth1(uint32_t cuid, uint8_t *blockData);\r
-int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData);\r
-int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
-int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
-int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
-int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
-int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); 
-int mifare_ultra_halt(uint32_t uid);
+int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);\r
+int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);\r
+int mifare_ul_ev1_auth(uint8_t *key, uint8_t *pack);\r
+int mifare_ultra_auth(uint8_t *key);\r
+int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData);\r
+int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);\r
+int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData);\r
+int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData);\r
+int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); \r
+int mifare_ultra_halt();\r
 \r
 // desfire\r
 int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);\r
 int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing);\r
 int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData);\r
 int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData);\r
-
-// crypto functions
-void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
+\r
+// crypto functions\r
+void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);\r
 void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);\r
 uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);\r
 \r
@@ -93,7 +94,7 @@ void emlGetMem(uint8_t *data, int blockNum, int blocksCount);
 void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount);\r
 uint64_t emlGetKey(int sectorNum, int keyType);\r
 int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum);\r
-int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);
-int emlCheckValBl(int blockNum);
-
-#endif
+int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);\r
+int emlCheckValBl(int blockNum);\r
+\r
+#endif\r
index 81af01499fa75425b4495d557f4666bd4fa05cad..7954d1ea2de3aa3cfc3f768974b4ea708f7fe881 100644 (file)
@@ -68,6 +68,7 @@ CMDSRCS =     nonce2key/crapto1.c\
                        mifarehost.c\
                        crc.c \
                        crc16.c \
+                       crc64.c \
                        iso14443crc.c \
                        iso15693tools.c \
                        data.c \
index 556ede06b5687f150187ec4162b41e2c0e107548..b9069bc19cb82b150b05de62345a188a56e5f6aa 100644 (file)
@@ -26,7 +26,7 @@
 
 uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
 uint8_t g_debugMode;
-int DemodBufferLen;
+size_t DemodBufferLen;
 static int CmdHelp(const char *Cmd);
 
 //set the demod buffer with given array of binary (one bit per byte)
@@ -1484,7 +1484,7 @@ int CmdIndalaDecode(const char *Cmd)
                return 0;
        }
        uint8_t invert=0;
-       ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert);
+       ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert);
        if (ans < 1) {
                if (g_debugMode==1)
                        PrintAndLog("Error2: %d",ans);
@@ -1892,7 +1892,7 @@ int getSamples(const char *Cmd, bool silent)
                PrintAndLog("Unpacking...");
                BitstreamOut bout = { got, bits_per_sample * n,  0};
                int j =0;
-               for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) {
+               for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
                        uint8_t sample = getByte(bits_per_sample, &bout);
                        GraphBuffer[j] = ((int) sample )- 128;
                }
index 57f0400123ed4e6d723eb7f1755348ba944e31df..c62307368d6ef3965a3d7dad3ae2842b9afc36d5 100644 (file)
@@ -70,7 +70,7 @@ int getSamples(const char *Cmd, bool silent);
 
 #define MAX_DEMOD_BUF_LEN (1024*128)
 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
-extern int DemodBufferLen;
+extern size_t DemodBufferLen;
 extern uint8_t g_debugMode;
 #define BIGBUF_SIZE 40000
 
index 22063bbbe566e22e139524ad98ba2cc817c9b641..16f7bb0f39f661c180723bd0c52bd1306407f8bd 100644 (file)
@@ -71,11 +71,57 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
        case MIFARE_CMD_DEC:                    snprintf(exp,size,"DEC(%d)",cmd[1]); break;
        case MIFARE_CMD_RESTORE:                snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
        case MIFARE_CMD_TRANSFER:               snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
-       case MIFARE_AUTH_KEYA:                  snprintf(exp,size,"AUTH-A(%d)",cmd[1]); break;
+       case MIFARE_AUTH_KEYA:{
+               if ( cmdsize > 3)
+                       snprintf(exp,size,"AUTH-A(%d)",cmd[1]); 
+               else
+                       //      case MIFARE_ULEV1_VERSION :  both 0x60.
+                       snprintf(exp,size,"EV1 VERSION");
+               break;
+       }
        case MIFARE_AUTH_KEYB:                  snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break;
        case MIFARE_MAGICWUPC1:                 snprintf(exp,size,"MAGIC WUPC1"); break;
        case MIFARE_MAGICWUPC2:                 snprintf(exp,size,"MAGIC WUPC2"); break;
        case MIFARE_MAGICWIPEC:                 snprintf(exp,size,"MAGIC WIPEC"); break;
+       case MIFARE_ULC_AUTH_1:         snprintf(exp,size,"AUTH "); break;
+       case MIFARE_ULC_AUTH_2:         snprintf(exp,size,"AUTH_ANSW"); break;
+       case MIFARE_ULEV1_AUTH:
+               if ( cmdsize == 7 )
+                       snprintf(exp,size,"PWD-AUTH KEY: 0x%02x%02x%02x%02x", cmd[1], cmd[2], cmd[3], cmd[4] );
+               else
+                       snprintf(exp,size,"PWD-AUTH");
+               break;
+       case MIFARE_ULEV1_FASTREAD:{
+               if ( cmdsize >=3 && cmd[2] <= 0xE6)
+                       snprintf(exp,size,"READ RANGE (%d-%d)",cmd[1],cmd[2]); 
+               else
+                       snprintf(exp,size,"?");
+               break;
+       }
+       case MIFARE_ULC_WRITE:{
+               if ( cmd[1] < 0x21 )
+                       snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); 
+               else
+                       snprintf(exp,size,"?");
+               break;
+       }
+       case MIFARE_ULEV1_READ_CNT:{
+               if ( cmd[1] < 5 )
+                       snprintf(exp,size,"READ CNT(%d)",cmd[1]);
+               else
+                       snprintf(exp,size,"?");
+               break;
+       }
+       case MIFARE_ULEV1_INCR_CNT:{
+               if ( cmd[1] < 5 )
+                       snprintf(exp,size,"INCR(%d)",cmd[1]);
+               else
+                       snprintf(exp,size,"?");
+               break;
+       }
+       case MIFARE_ULEV1_READSIG:              snprintf(exp,size,"READ_SIG"); break;
+       case MIFARE_ULEV1_CHECKTEAR:    snprintf(exp,size,"CHK_TEARING(%d)",cmd[1]); break;
+       case MIFARE_ULEV1_VCSL:         snprintf(exp,size,"VCSL"); break;
        default:                                                snprintf(exp,size,"?"); break;
        }
        return;
@@ -503,6 +549,32 @@ int CmdHFList(const char *Cmd)
        return 0;
 }
 
+int CmdHFSearch(const char *Cmd){
+       int ans = 0;
+       PrintAndLog("");
+       ans = CmdHF14AReader("s");
+       if (ans > 0) {
+               PrintAndLog("\nValid ISO14443A Tag Found - Quiting Search\n");
+               return ans;
+       } 
+       ans = HFiClassReader("", false, false);
+       if (ans) {
+               PrintAndLog("\nValid iClass Tag (or PicoPass Tag) Found - Quiting Search\n");
+               return ans;
+       }
+       ans = HF15Reader("", false);
+       if (ans) {
+               PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n");
+               return ans;
+       }
+
+
+       //14b has issues currently...
+       //ans = CmdHF14BRead(Cmd);
+       //if (ans > 0) return ans;
+
+       return 0;
+}
 
 static command_t CommandTable[] = 
 {
@@ -513,10 +585,11 @@ static command_t CommandTable[] =
   {"epa",         CmdHFEPA,         1, "{ German Identification Card... }"},
   {"legic",       CmdHFLegic,       0, "{ LEGIC RFIDs... }"},
   {"iclass",      CmdHFiClass,      1, "{ ICLASS RFIDs... }"},
-  {"mf",               CmdHFMF,                1, "{ MIFARE RFIDs... }"},
-  {"mfu",                      CmdHFMFUltra,           1, "{ MIFARE Ultralight RFIDs... }"},
+  {"mf",          CmdHFMF,          1, "{ MIFARE RFIDs... }"},
+  {"mfu",         CmdHFMFUltra,     1, "{ MIFARE Ultralight RFIDs... }"},
   {"tune",        CmdHFTune,        0, "Continuously measure HF antenna tuning"},
-  {"list",       CmdHFList,         1, "List protocol data in trace buffer"},
+  {"list",        CmdHFList,        1, "List protocol data in trace buffer"},
+  {"search",      CmdHFSearch,      1, "Search for known HF tags [preliminary]"},
        {NULL, NULL, 0, NULL}
 };
 
index d4285eeab5df128444ef2cc0ab59761cfb041507..9a761864b3fbc984ef21d839b0db886a69aeb647 100644 (file)
@@ -23,6 +23,7 @@
 #include "common.h"
 #include "cmdmain.h"
 #include "mifare.h"
+#include "cmdhfmfu.h"
 
 static int CmdHelp(const char *Cmd);
 static void waitCmd(uint8_t iLen);
@@ -143,7 +144,7 @@ int CmdHF14AReader(const char *Cmd)
        uint64_t select_status = resp.arg[0];           // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
        
        if(select_status == 0) {
-               PrintAndLog("iso14443a card select failed");
+               if (Cmd[0] != 's') PrintAndLog("iso14443a card select failed");
                // disconnect
                c.arg[0] = 0;
                c.arg[1] = 0;
@@ -169,6 +170,42 @@ int CmdHF14AReader(const char *Cmd)
 
        switch (card.sak) {
                case 0x00: 
+
+                       //***************************************test****************
+                       // disconnect
+                       c.arg[0] = 0;
+                       c.arg[1] = 0;
+                       c.arg[2] = 0;
+                       SendCommand(&c);
+                       
+                       uint32_t tagT = GetHF14AMfU_Type();
+                       ul_print_type(tagT, 0);
+
+                       //reconnect for further tests
+                       c.arg[0] = ISO14A_CONNECT | ISO14A_NO_DISCONNECT;
+                       c.arg[1] = 0;
+                       c.arg[2] = 0;
+
+                       SendCommand(&c);
+
+                       UsbCommand resp;
+                       WaitForResponse(CMD_ACK,&resp);
+                       
+                       memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
+
+                       select_status = resp.arg[0];            // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
+                       
+                       if(select_status == 0) {
+                               //PrintAndLog("iso14443a card select failed");
+                               // disconnect
+                               c.arg[0] = 0;
+                               c.arg[1] = 0;
+                               c.arg[2] = 0;
+                               SendCommand(&c);
+                               return 0;
+                       }
+
+                       /*  orig
                        // check if the tag answers to GETVERSION (0x60)
                        c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;
                        c.arg[1] = 1;
@@ -187,7 +224,7 @@ int CmdHF14AReader(const char *Cmd)
                                case 0x01:PrintAndLog("TYPE : NXP MIFARE Ultralight C");break;
                                case 0x00:PrintAndLog("TYPE : NXP MIFARE Ultralight");break;    
                        }
-
+                       */
                        break;
                case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break;
                case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break;
index c3ff7dd6d3976574b668ab5ec13fa5c0b398f8b3..8ddbea89bbab5cf8034ead823a6f6a2ea9c10f34 100644 (file)
@@ -374,6 +374,20 @@ int CmdHF15Record(const char *Cmd)
        return 0;
 }
 
+int HF15Reader(const char *Cmd, bool verbose)
+{
+       uint8_t uid[8];
+
+       if (!getUID(uid)) {
+               if (verbose) PrintAndLog("No Tag found.");
+               return 0;
+       }
+
+       PrintAndLog("Tag UID : %s",sprintUID(NULL,uid));
+       PrintAndLog("Tag Info: %s",getTagInfo(uid));
+       return 1;
+}
+
 int CmdHF15Reader(const char *Cmd)
 {
        UsbCommand c = {CMD_READER_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
@@ -469,7 +483,7 @@ int CmdHF15DumpMem(const char*Cmd) {
                                        // PrintAndLog("bn=%i",blocknum);
                                } else {
                                        PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); 
-                                       return 0;
+                                       return 1;
                                }
                        } // else PrintAndLog("crc");
                } // else PrintAndLog("r null");
@@ -481,7 +495,7 @@ int CmdHF15DumpMem(const char*Cmd) {
 //             PrintAndLog("CRC Failed");
 //     else 
 //             PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); 
-       return 0;
+       return 1;
 }
 
 
index 8d78e13f1c60fd30d63d27290bd135bc2d955257..c6264604670d1980b9f3d943d6088d32535fbeb6 100644 (file)
@@ -15,6 +15,7 @@ int CmdHF15(const char *Cmd);
 
 int CmdHF15Demod(const char *Cmd);
 int CmdHF15Read(const char *Cmd);
+int HF15Reader(const char *Cmd, bool verbose);
 int CmdHF15Reader(const char *Cmd);
 int CmdHF15Sim(const char *Cmd);
 int CmdHF15Record(const char *Cmd);
index b83371960d007958e6ae5c1a7d6f1d861693a9de..824aaa3674cc1bd5cf84d38174968d0e3fbd468e 100644 (file)
@@ -165,34 +165,47 @@ int CmdHFiClassSim(const char *Cmd)
        return 0;
 }
 
-int CmdHFiClassReader(const char *Cmd)
+int HFiClassReader(const char *Cmd, bool loop, bool verbose)
 {
+       bool tagFound = false;
        UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN|
                                        FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}};
+       if (!loop) c.arg[0] |= FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY;
        SendCommand(&c);
        UsbCommand resp;
        while(!ukbhit()){
-               if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
-                       uint8_t readStatus    = resp.arg[0] & 0xff;
-                       uint8_t * data  = resp.d.asBytes;
+               if (WaitForResponseTimeout(CMD_ACK,&resp, 4500)) {
+                       uint8_t readStatus = resp.arg[0] & 0xff;
+                       uint8_t *data = resp.d.asBytes;
 
-                       PrintAndLog("Readstatus:%02x", readStatus);
+                       if (verbose)
+                               PrintAndLog("Readstatus:%02x", readStatus);
                        if( readStatus == 0){
                                //Aborted
-                               PrintAndLog("Quitting...");
+                               if (verbose) PrintAndLog("Quitting...");
                                return 0;
                        }
-                       if( readStatus & FLAG_ICLASS_READER_CSN) PrintAndLog("CSN: %s",sprint_hex(data,8));
+                       if( readStatus & FLAG_ICLASS_READER_CSN){
+                               PrintAndLog("CSN: %s",sprint_hex(data,8));
+                               tagFound = true;
+                       }
                        if( readStatus & FLAG_ICLASS_READER_CC)  PrintAndLog("CC: %s",sprint_hex(data+16,8));
                        if( readStatus & FLAG_ICLASS_READER_CONF){
                                printIclassDumpInfo(data);
                        }
+                       if (tagFound && !loop) return 1;
                } else {
-                       PrintAndLog("Command execute timeout");
+                       if (verbose) PrintAndLog("Command execute timeout");
                }
+               if (!loop) break;
        }
-
        return 0;
+
+}
+
+int CmdHFiClassReader(const char *Cmd)
+{
+       return HFiClassReader(Cmd, true, true);
 }
 
 int CmdHFiClassReader_Replay(const char *Cmd)
index e4048eb170092b4f6cbfa5266830405ba70f406b..30c6a8a7b1907f2bedf6f121b79ffad46293c9a1 100644 (file)
@@ -17,6 +17,7 @@ int CmdHFiClass(const char *Cmd);
 int CmdHFiClassSnoop(const char *Cmd);
 int CmdHFiClassSim(const char *Cmd);
 int CmdHFiClassList(const char *Cmd);
+int HFiClassReader(const char *Cmd, bool loop, bool verbose);
 int CmdHFiClassReader(const char *Cmd);
 int CmdHFiClassReader_Replay(const char *Cmd);
 
index b96c9c1a78f8e180a9b831574e377998d005787f..aa3b66dc64b960f2bf855b62257f904b26196a4e 100644 (file)
@@ -547,7 +547,7 @@ int CmdHF14AMfNested(const char *Cmd)
        uint8_t trgKeyType = 0;\r
        uint8_t SectorsCnt = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
-       uint8_t keyBlock[13*6];\r
+       uint8_t keyBlock[14*6];\r
        uint64_t key64 = 0;\r
        bool transferToEml = false;\r
        \r
@@ -1202,7 +1202,7 @@ int CmdHF14AMfELoad(const char *Cmd)
        \r
        if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
 \r
-       fnameptr += len;\r
+       fnameptr += len-4;\r
 \r
        sprintf(fnameptr, ".eml"); \r
        \r
@@ -1311,7 +1311,7 @@ int CmdHF14AMfESave(const char *Cmd)
                for (j = 0; j < 7; j++, fnameptr += 2)\r
                        sprintf(fnameptr, "%02X", buf[j]); \r
        } else {\r
-               fnameptr += len;\r
+               fnameptr += len-4;\r
        }\r
 \r
        // add file extension\r
@@ -1575,7 +1575,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
                if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
 \r
                memcpy(filename, Cmd, len);\r
-               fnameptr += len;\r
+               fnameptr += len-4;\r
 \r
                sprintf(fnameptr, ".eml"); \r
        \r
@@ -1592,6 +1592,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
                        memset(buf, 0, sizeof(buf));\r
                        \r
                        if (fgets(buf, sizeof(buf), f) == NULL) {\r
+                               fclose(f);\r
                                PrintAndLog("File reading error.");\r
                                return 2;\r
                        }\r
@@ -1600,6 +1601,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
                                if(strlen(buf) && feof(f))\r
                                        break;\r
                                PrintAndLog("File content error. Block data must include 32 HEX symbols");\r
+                               fclose(f);\r
                                return 2;\r
                        }\r
                        for (i = 0; i < 32; i += 2)\r
index 8dfb9a3b1cceeb075f0facb06e37119a23a6c9e3..07c379bc0d63c5ffc77540384ea4246199b231a3 100644 (file)
 //-----------------------------------------------------------------------------
 // High frequency MIFARE ULTRALIGHT (C) commands
 //-----------------------------------------------------------------------------
-//#include <openssl/des.h>
 #include "loclass/des.h"
 #include "cmdhfmfu.h"
 #include "cmdhfmf.h"
 #include "cmdhf14a.h"
+#include "mifare.h"
+#include "util.h"
+#include "protocols.h"
+#include "data.h"
+
+#define MAX_UL_BLOCKS     0x0f
+#define MAX_ULC_BLOCKS    0x2b
+#define MAX_ULEV1a_BLOCKS 0x13
+#define MAX_ULEV1b_BLOCKS 0x28
+#define MAX_NTAG_203      0x29
+#define MAX_NTAG_210      0x13
+#define MAX_NTAG_212      0x28
+#define MAX_NTAG_213      0x2c
+#define MAX_NTAG_215      0x86
+#define MAX_NTAG_216      0xe6
+
+#define KEYS_3DES_COUNT 7
+uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = {
+               { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
+               { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
+               { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
+               { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
+               { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },// all ones
+               { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },// all FF
+               { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }     // 11 22 33
+};
+
+#define KEYS_PWD_COUNT 10
+uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = {
+       {0xFF,0xFF,0xFF,0xFF}, // PACK 0x00,0x00 -- factory default
+
+       {0x4A,0xF8,0x4B,0x19}, // PACK 0xE5,0xBE -- italian bus (sniffed)
+       {0x33,0x6B,0xA1,0x19}, // PACK 0x9c,0x2d -- italian bus (sniffed)
+       {0xFF,0x90,0x6C,0xB2}, // PACK 0x12,0x9e -- italian bus (sniffed)       
+       {0x46,0x1c,0xA3,0x19}, // PACK 0xE9,0x5A -- italian bus (sniffed)
+       {0x35,0x1C,0xD0,0x19}, // PACK 0x9A,0x5a -- italian bus (sniffed)
 
+       {0x05,0x22,0xE6,0xB4}, // PACK 0x80,0x80 -- Amiiboo (sniffed) pikachu-b UID:
+       {0x7E,0x22,0xE6,0xB4}, // PACK 0x80,0x80 -- AMiiboo (sniffed) 
+       {0x02,0xE1,0xEE,0x36}, // PACK 0x80,0x80 -- AMiiboo (sniffed) sonic UID:  04d257 7ae33e8027
+       {0x32,0x0C,0x16,0x17}, // PACK 0x80,0x80 -- AMiiboo (sniffed) 
+};
+
+#define MAX_UL_TYPES 16
+uint16_t UL_TYPES_ARRAY[MAX_UL_TYPES] = {UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, NTAG_203,
+           NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC};
 
-#define MAX_ULTRA_BLOCKS   0x0f
-#define MAX_ULTRAC_BLOCKS  0x2f
-//#define MAX_ULTRAC_BLOCKS  0x2c
+uint8_t UL_MEMORY_ARRAY[MAX_UL_TYPES] = {MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS,
+           MAX_ULEV1b_BLOCKS, MAX_NTAG_203, MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213,
+           MAX_NTAG_215, MAX_NTAG_216, MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS};
 
 
 static int CmdHelp(const char *Cmd);
 
-int CmdHF14AMfUInfo(const char *Cmd){
+char *getProductTypeStr( uint8_t id){
+
+       static char buf[20];
+       char *retStr = buf;
+
+       switch(id) {
+               case 3: sprintf(retStr, "%02X, Ultralight", id); break;
+               case 4: sprintf(retStr, "%02X, NTAG", id); break;
+               default: sprintf(retStr, "%02X, unknown", id); break;
+       }
+       return buf;
+}
 
-       uint8_t datatemp[7] = {0x00};
-       uint8_t isOK  = 0;
-       uint8_t *data = NULL;
+/*
+  The 7 MSBits (=n) code the storage size itself based on 2^n, 
+  the LSBit is set to '0' if the size is exactly 2^n
+  and set to '1' if the storage size is between 2^n and 2^(n+1). 
+*/
+char *getUlev1CardSizeStr( uint8_t fsize ){
+
+       static char buf[40];
+       char *retStr = buf;
+       memset(buf, 0, sizeof(buf));
+
+       uint16_t usize = 1 << ((fsize >>1) + 1);
+       uint16_t lsize = 1 << (fsize >>1);
+
+       // is  LSB set?
+       if (  fsize & 1 )
+               sprintf(retStr, "%02X, (%u <-> %u bytes)",fsize, usize, lsize);
+       else 
+               sprintf(retStr, "%02X, (%u bytes)", fsize, lsize);              
+       return buf;
+}
+
+static void ul_switch_on_field(void) {
+       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
+       SendCommand(&c);
+}
+
+void ul_switch_off_field(void) {
+       UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
+       SendCommand(&c);
+}
 
-       UsbCommand c = {CMD_MIFAREU_READCARD, {0, 4}};
+static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength ) {
+       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC, cmdlen, 0}};
+       memcpy(c.d.asBytes, cmd, cmdlen);
        SendCommand(&c);
        UsbCommand resp;
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
+       if (!resp.arg[0] && responseLength) return -1;
+
+       uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
+       memcpy(response, resp.d.asBytes, resplen);
+       return resplen;
+}
+/*
+static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength, bool append_crc ) {
+       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT , cmdlen, 0}};
+       if (append_crc)
+               c.arg[0] |= ISO14A_APPEND_CRC;
+
+       memcpy(c.d.asBytes, cmd, cmdlen);       
+       SendCommand(&c);
+       UsbCommand resp;
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
+       if (!resp.arg[0] && responseLength) return -1;
+
+       uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
+       memcpy(response, resp.d.asBytes, resplen);
+       return resplen;
+}
+*/
+static int ul_select( iso14a_card_select_t *card ){
 
-       if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
-               isOK  = resp.arg[0] & 0xff;
-               data  = resp.d.asBytes;
+       ul_switch_on_field();
+
+       UsbCommand resp;
+       bool ans = false;
+       ans = WaitForResponseTimeout(CMD_ACK, &resp, 1500);
+       if (!ans || resp.arg[0] < 1) {
+               PrintAndLog("iso14443a card select failed");
+               ul_switch_off_field();
+               return 0;
+       }
+
+       memcpy(card, resp.d.asBytes, sizeof(iso14a_card_select_t));
+       return 1;
+}
+
+// This read command will at least return 16bytes.
+static int ul_read( uint8_t page, uint8_t *response, uint16_t responseLength ){
+
+       uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, page};
+       int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
+       return len;
+}
+
+static int ul_comp_write( uint8_t page, uint8_t *data, uint8_t datalen ){
+
+       uint8_t cmd[18];
+       memset(cmd, 0x00, sizeof(cmd));
+       datalen = ( datalen > 16) ? 16 : datalen;
+
+       cmd[0] = ISO14443A_CMD_WRITEBLOCK;
+       cmd[1] = page;
+       memcpy(cmd+2, data, datalen);
+
+       uint8_t response[1] = {0xff};
+       ul_send_cmd_raw(cmd, 2+datalen, response, sizeof(response));
+       // ACK
+       if ( response[0] == 0x0a ) return 0;
+       // NACK
+       return -1;
+}
+
+static int ulc_requestAuthentication( uint8_t *nonce, uint16_t nonceLength ){
+
+       uint8_t cmd[] = {MIFARE_ULC_AUTH_1, 0x00};
+       int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
+       return len;
+}
+
+static int ulc_authentication( uint8_t *key, bool switch_off_field ){
+
+       UsbCommand c = {CMD_MIFAREUC_AUTH, {switch_off_field}};
+       memcpy(c.d.asBytes, key, 16);
+       SendCommand(&c);
+       UsbCommand resp;
+       if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return 0;
+       if ( resp.arg[0] == 1 ) return 1;
+
+       return 0;
+}
+
+static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack, uint16_t packLength ){
+
+       uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]};
+       int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack, packLength);
+       return len;
+}
 
-               if (!isOK) {
-                       PrintAndLog("Error reading from tag");
-                       return -1;
+static int ul_auth_select( iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authenticationkey, uint8_t *pack, uint8_t packSize){
+       if ( hasAuthKey && (tagtype & UL_C)) {
+               //will select card automatically and close connection on error
+               if (!ulc_authentication(authenticationkey, false)) {
+                       PrintAndLog("Error: Authentication Failed UL-C");
+                       return 0;
                }
        } else {
-               PrintAndLog("Command execute timed out");
-               return -1;
+               if ( !ul_select(card) ) return 0;
+
+               if (hasAuthKey) {
+                       if (ulev1_requestAuthentication(authenticationkey, pack, packSize) < 1) {
+                               ul_switch_off_field();
+                               PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
+                               return 0;
+                       }
+               }
        }
-       
-       PrintAndLog("");
-       PrintAndLog("-- Mifare Ultralight / Ultralight-C Tag Information ---------");
-       PrintAndLog("-------------------------------------------------------------");
+       return 1;
+}
 
-       // UID
-       memcpy( datatemp, data, 3);
-       memcpy( datatemp+3, data+4, 4);
+static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){
+
+       uint8_t cmd[] = {MIFARE_ULEV1_VERSION}; 
+       int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
+       return len;
+}
+
+// static int ulev1_fastRead( uint8_t startblock, uint8_t endblock, uint8_t *response ){
+       
+       // uint8_t cmd[] = {MIFARE_ULEV1_FASTREAD, startblock, endblock};
        
-       PrintAndLog("MANUFACTURER : %s", getTagInfo(datatemp[0]));
-       PrintAndLog("         UID : %s ", sprint_hex(datatemp, 7));
-       // BBC
+       // if ( !ul_send_cmd_raw(cmd, sizeof(cmd), response)){
+               // return -1;
+       // }
+       // return 0;
+// }
+
+static int ulev1_readCounter( uint8_t counter, uint8_t *response, uint16_t responseLength ){
+
+       uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter};
+       int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
+       return len;
+}
+
+static int ulev1_readTearing( uint8_t counter, uint8_t *response, uint16_t responseLength ){
+
+       uint8_t cmd[] = {MIFARE_ULEV1_CHECKTEAR, counter};
+       int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
+       return len;
+}
+
+static int ulev1_readSignature( uint8_t *response, uint16_t responseLength ){
+
+       uint8_t cmd[] = {MIFARE_ULEV1_READSIG, 0x00};
+       int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
+       return len;
+}
+
+static int ul_print_default( uint8_t *data){
+
+       uint8_t uid[7];
+       uid[0] = data[0];
+       uid[1] = data[1];
+       uid[2] = data[2];
+       uid[3] = data[4];
+       uid[4] = data[5];
+       uid[5] = data[6];
+       uid[6] = data[7];
+
+       PrintAndLog("       UID : %s ", sprint_hex(uid, 7));
+       PrintAndLog("    UID[0] : %02X, Manufacturer: %s",  uid[0], getTagInfo(uid[0]) );
+       if ( uid[0] == 0x05 ) {
+               uint8_t chip = (data[8] & 0xC7); // 11000111  mask, bit 3,4,5 RFU
+               switch (chip){
+                       case 0xc2: PrintAndLog("   IC type : SLE 66R04P"); break;
+                       case 0xc4: PrintAndLog("   IC type : SLE 66R16P"); break;
+                       case 0xc6: PrintAndLog("   IC type : SLE 66R32P"); break;
+               }
+       }
        // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 
        int crc0 = 0x88 ^ data[0] ^ data[1] ^data[2];
        if ( data[3] == crc0 )
-               PrintAndLog("        BCC0 : %02x - Ok", data[3]);
+               PrintAndLog("      BCC0 : %02X, Ok", data[3]);
        else
-               PrintAndLog("        BCC0 : %02x - crc should be %02x", data[3], crc0);
-               
+               PrintAndLog("      BCC0 : %02X, crc should be %02X", data[3], crc0);
+
        int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
        if ( data[8] == crc1 )
-               PrintAndLog("        BCC1 : %02x - Ok", data[8]);
+               PrintAndLog("      BCC1 : %02X, Ok", data[8]);
        else
-               PrintAndLog("        BCC1 : %02x - crc should be %02x", data[8], crc1 );
-       
-       PrintAndLog("    Internal : %s ", sprint_hex(data + 9, 1));
-       
-       memcpy(datatemp, data+10, 2);
-       PrintAndLog("        Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
-       PrintAndLog("  OneTimePad : %s ", sprint_hex(data + 3*4, 4));
-       PrintAndLog("");
+               PrintAndLog("      BCC1 : %02X, crc should be %02X", data[8], crc1 );
+
+       PrintAndLog("  Internal : %02X, %sdefault", data[9], (data[9]==0x48)?"":"not " );
+
+       PrintAndLog("      Lock : %s - %s",
+                               sprint_hex(data+10, 2),
+                               printBits(2, data+10)
+               );
+
+       PrintAndLog("OneTimePad : %s - %s\n",
+                               sprint_hex(data + 12, 4),
+                               printBits(4, data+12)
+               );
 
-       int len = CmdHF14AMfucAuth("K 0");
-//     PrintAndLog("CODE: %d",len);
-       
-       PrintAndLog("Seems to be a Ultralight %s", (len==0) ? "-C" :"");
        return 0;
 }
 
+static int ndef_print_CC(uint8_t *data) {
+       // no NDEF message
+       if(data[0] != 0xe1)
+               return -1;
+
+       PrintAndLog("--- NDEF Message");
+       PrintAndLog("Capability Container: %s", sprint_hex(data,4) );
+       PrintAndLog("  %02X : NDEF Magic Number", data[0]); 
+       PrintAndLog("  %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
+       PrintAndLog("  %02X : Physical Memory Size: %d bytes", data[2], (data[2] + 1) * 8);
+       if ( data[2] == 0x12 )
+               PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 144);
+       else if ( data[2] == 0x3e )
+               PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 496);
+       else if ( data[2] == 0x6d )
+               PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 872);
+
+       PrintAndLog("  %02X : %s / %s", data[3], 
+                               (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", 
+                               (data[3] & 0x0F)==0 ? "Write access granted without any security" : (data[3] & 0x0F)==0x0F ? "No write access granted at all" : "(RFU)");
+       return 0;
+}
+
+int ul_print_type(uint32_t tagtype, uint8_t spaces){
+       char spc[11] = "          ";
+       spc[10]=0x00;
+       char *spacer = spc + (10-spaces);
+
+       if ( tagtype & UL )     
+               PrintAndLog("%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
+       else if ( tagtype & UL_C)
+               PrintAndLog("%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
+       else if ( tagtype & UL_EV1_48)
+               PrintAndLog("%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer); 
+       else if ( tagtype & UL_EV1_128) 
+               PrintAndLog("%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer);
+       else if ( tagtype & NTAG )
+               PrintAndLog("%sTYPE : NTAG UNKNOWN", spacer);
+       else if ( tagtype & NTAG_203 )
+               PrintAndLog("%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer);
+       else if ( tagtype & NTAG_210 )
+               PrintAndLog("%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer);
+       else if ( tagtype & NTAG_212 )
+               PrintAndLog("%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer);
+       else if ( tagtype & NTAG_213 )
+               PrintAndLog("%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer);
+       else if ( tagtype & NTAG_215 )
+               PrintAndLog("%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer);
+       else if ( tagtype & NTAG_216 )
+               PrintAndLog("%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer);
+       else if ( tagtype & NTAG_I2C_1K )
+               PrintAndLog("%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD");
+       else if ( tagtype & NTAG_I2C_2K )       
+               PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD");
+       else if ( tagtype & MY_D )
+               PrintAndLog("%sTYPE : INFINEON my-d\x99", spacer);
+       else if ( tagtype & MY_D_NFC )
+               PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC", spacer);
+       else if ( tagtype & MY_D_MOVE )
+               PrintAndLog("%sTYPE : INFINEON my-d\x99 move", spacer);
+       else if ( tagtype & MY_D_MOVE_NFC )
+               PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC", spacer);
+       else
+               PrintAndLog("%sTYPE : Unknown %06x", spacer, tagtype);
+       return 0;
+}
+
+static int ulc_print_3deskey( uint8_t *data){
+       PrintAndLog("         deskey1 [44/0x2C] : %s [%.4s]", sprint_hex(data   ,4),data);
+       PrintAndLog("         deskey1 [45/0x2D] : %s [%.4s]", sprint_hex(data+4 ,4),data+4);
+       PrintAndLog("         deskey2 [46/0x2E] : %s [%.4s]", sprint_hex(data+8 ,4),data+8);
+       PrintAndLog("         deskey2 [47/0x2F] : %s [%.4s]", sprint_hex(data+12,4),data+12);
+       PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
+       return 0;
+}
+
+static int ulc_print_configuration( uint8_t *data){
+
+       PrintAndLog("--- UL-C Configuration");
+       PrintAndLog(" Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data, 4), printBits(2, data));
+       PrintAndLog("         Counter [41/0x29] : %s - %s", sprint_hex(data+4, 4), printBits(2, data+4));
+
+       bool validAuth = (data[8] >= 0x03 && data[8] <= 0x30);
+       if ( validAuth )
+               PrintAndLog("           Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data+8, 4), data[8],data[8] );
+       else{
+               if ( data[8] == 0){
+                       PrintAndLog("           Auth0 [42/0x2A] : %s default", sprint_hex(data+8, 4) );
+               } else {
+                       PrintAndLog("           Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data+8, 4) );
+               }
+       }
+       PrintAndLog("           Auth1 [43/0x2B] : %s %s",
+                       sprint_hex(data+12, 4),
+                       (data[12] & 1) ? "write access restricted": "read and write access restricted"
+                       );
+       return 0;
+}
+
+static int ulev1_print_configuration( uint8_t *data, uint8_t startPage){
+
+       PrintAndLog("\n--- Tag Configuration");
+
+       bool strg_mod_en = (data[0] & 2);
+       uint8_t authlim = (data[4] & 0x07);
+       bool cfglck = (data[4] & 0x40);
+       bool prot = (data[4] & 0x80);
+       uint8_t vctid = data[5];
+
+       PrintAndLog("  cfg0 [%u/0x%02X] : %s", startPage, startPage, sprint_hex(data, 4));
+       if ( data[3] < 0xff )
+               PrintAndLog("                    - page %d and above need authentication",data[3]);
+       else 
+               PrintAndLog("                    - pages don't need authentication");
+       PrintAndLog("                    - strong modulation mode %s", (strg_mod_en) ? "enabled":"disabled");
+       PrintAndLog("  cfg1 [%u/0x%02X] : %s", startPage + 1, startPage + 1,  sprint_hex(data+4, 4) );
+       if ( authlim == 0)
+               PrintAndLog("                    - Unlimited password attempts");
+       else
+               PrintAndLog("                    - Max number of password attempts is %d", authlim);
+       PrintAndLog("                    - user configuration %s", cfglck ? "permanently locked":"writeable");
+       PrintAndLog("                    - %s access is protected with password", prot ? "read and write":"write");
+       PrintAndLog("                    - %02X, Virtual Card Type Identifier is %s default", vctid, (vctid==0x05)? "":"not");
+       PrintAndLog("  PWD  [%u/0x%02X] : %s- (cannot be read)", startPage + 2, startPage + 2,  sprint_hex(data+8, 4));
+       PrintAndLog("  PACK [%u/0x%02X] : %s      - (cannot be read)", startPage + 3, startPage + 3,  sprint_hex(data+12, 2));
+       PrintAndLog("  RFU  [%u/0x%02X] :       %s- (cannot be read)", startPage + 3, startPage + 3,  sprint_hex(data+12, 2));
+       return 0;
+}
+
+static int ulev1_print_counters(){
+       PrintAndLog("--- Tag Counters");
+       uint8_t tear[1] = {0};
+       uint8_t counter[3] = {0,0,0};
+       uint16_t len = 0;
+       for ( uint8_t i = 0; i<3; ++i) {
+               ulev1_readTearing(i,tear,sizeof(tear));
+               len = ulev1_readCounter(i,counter, sizeof(counter) );
+               if (len == 3) {
+                       PrintAndLog("       [%0d] : %s", i, sprint_hex(counter,3));
+                       PrintAndLog("                    - %02X tearing %s", tear[0], ( tear[0]==0xBD)?"Ok":"failure");
+               }
+       }
+       return len;
+}
+
+static int ulev1_print_signature( uint8_t *data, uint8_t len){
+       PrintAndLog("\n--- Tag Signature");     
+       //PrintAndLog("IC signature public key name  : NXP NTAG21x 2013"); // don't know if there is other NXP public keys.. :(
+       PrintAndLog("IC signature public key value : 04494e1a386d3d3cfe3dc10e5de68a499b1c202db5b132393e89ed19fe5be8bc61");
+       PrintAndLog("    Elliptic curve parameters : secp128r1");
+       PrintAndLog("            Tag ECC Signature : %s", sprint_hex(data, len));
+       //to do:  verify if signature is valid
+       //PrintAndLog("IC signature status: %s valid", (iseccvalid() )?"":"not");
+       return 0;
+}
+
+static int ulev1_print_version(uint8_t *data){
+       PrintAndLog("\n--- Tag Version");
+       PrintAndLog("       Raw bytes : %s",sprint_hex(data, 8) );
+       PrintAndLog("       Vendor ID : %02X, %s", data[1], getTagInfo(data[1]));
+       PrintAndLog("    Product type : %s", getProductTypeStr(data[2]));
+       PrintAndLog(" Product subtype : %02X, %s", data[3], (data[3]==1) ?"17 pF":"50pF");
+       PrintAndLog("   Major version : %02X", data[4]);
+       PrintAndLog("   Minor version : %02X", data[5]);
+       PrintAndLog("            Size : %s", getUlev1CardSizeStr(data[6]));
+       PrintAndLog("   Protocol type : %02X", data[7]);
+       return 0;
+}
+
+/*
+static int ulc_magic_test(){
+       // Magic Ultralight test
+               // Magic UL-C, by observation,
+       // 1) it seems to have a static nonce response to 0x1A command.
+       // 2) the deskey bytes is not-zero:d out on as datasheet states.
+       // 3) UID - changeable, not only, but pages 0-1-2-3.
+       // 4) use the ul_magic_test !  magic tags answers specially!
+       int returnValue = UL_ERROR;
+       iso14a_card_select_t card;
+       uint8_t nonce1[11] = {0x00};
+       uint8_t nonce2[11] = {0x00};
+       int status = ul_select(&card);
+       if ( !status ){
+               return UL_ERROR;
+       }
+       status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
+       if ( status > 0 ) {
+               status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
+               returnValue =  ( !memcmp(nonce1, nonce2, 11) ) ? UL_C_MAGIC : UL_C;
+       } else {
+               returnValue = UL;
+       }       
+       ul_switch_off_field();
+       return returnValue;
+}
+*/
+static int ul_magic_test(){
+
+       // Magic Ultralight tests
+       // 1) take present UID, and try to write it back. OBSOLETE 
+       // 2) make a wrong length write to page0, and see if tag answers with ACK/NACK:
+       iso14a_card_select_t card;
+       if ( !ul_select(&card) ) 
+               return UL_ERROR;
+       int status = ul_comp_write(0, NULL, 0);
+       ul_switch_off_field();
+       if ( status == 0 ) 
+               return MAGIC;
+       return 0;
+}
+
+uint32_t GetHF14AMfU_Type(void){
+
+       TagTypeUL_t tagtype = UNKNOWN;
+       iso14a_card_select_t card;
+       uint8_t version[10] = {0x00};
+       int status = 0;
+       int len;
+
+       if (!ul_select(&card)) return UL_ERROR;
+
+       // Ultralight - ATQA / SAK 
+       if ( card.atqa[1] != 0x00 || card.atqa[0] != 0x44 || card.sak != 0x00 ) {
+               PrintAndLog("Tag is not Ultralight | NTAG | MY-D  [ATQA: %02X %02X SAK: %02X]\n", card.atqa[1], card.atqa[0], card.sak);
+               ul_switch_off_field();
+               return UL_ERROR;
+       }
+
+       if ( card.uid[0] != 0x05) {
+
+               len  = ulev1_getVersion(version, sizeof(version));
+               ul_switch_off_field();
+
+               switch (len) {
+                       case 0x0A: {
+
+                               if ( version[2] == 0x03 && version[6] == 0x0B )
+                                       tagtype = UL_EV1_48;
+                               else if ( version[2] == 0x03 && version[6] != 0x0B )
+                                       tagtype = UL_EV1_128;
+                               else if ( version[2] == 0x04 && version[3] == 0x01 && version[6] == 0x0B )
+                                       tagtype = NTAG_210;
+                               else if ( version[2] == 0x04 && version[3] == 0x01 && version[6] == 0x0E )
+                                       tagtype = NTAG_212;
+                               else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x0F )
+                                       tagtype = NTAG_213;
+                               else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x11 )
+                                       tagtype = NTAG_215;
+                               else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x13 )
+                                       tagtype = NTAG_216;
+                               else if ( version[2] == 0x04 && version[3] == 0x05 && version[6] == 0x13 )
+                                       tagtype = NTAG_I2C_1K;
+                               else if ( version[2] == 0x04 && version[3] == 0x05 && version[6] == 0x15 )
+                                       tagtype = NTAG_I2C_2K;
+                               else if ( version[2] == 0x04 )
+                                       tagtype = NTAG;
+
+                               break;
+                       }
+                       case 0x01: tagtype = UL_C; break;
+                       case 0x00: tagtype = UL; break;
+                       case -1  : tagtype = (UL | UL_C | NTAG_203); break;  // could be UL | UL_C magic tags
+                       default  : tagtype = UNKNOWN; break;
+               }
+               // UL vs UL-C vs ntag203 test
+               if (tagtype & (UL | UL_C | NTAG_203)) {
+                       if ( !ul_select(&card) ) return UL_ERROR;
+
+                       // do UL_C check first...
+                       uint8_t nonce[11] = {0x00};
+                       status = ulc_requestAuthentication(nonce, sizeof(nonce));
+                       ul_switch_off_field();
+                       if (status > 1) {
+                               tagtype = UL_C;
+                       } else { 
+                               // need to re-select after authentication error
+                               if ( !ul_select(&card) ) return UL_ERROR;
+
+                               uint8_t data[16] = {0x00};
+                               // read page 0x26-0x29 (last valid ntag203 page)
+                               status = ul_read(0x26, data, sizeof(data));
+                               if ( status <= 1 ) {
+                                       tagtype = UL;
+                               } else {
+                                       // read page 0x30 (should error if it is a ntag203)
+                                       status = ul_read(0x30, data, sizeof(data));
+                                       if ( status <= 1 ){
+                                               tagtype = NTAG_203;
+                                       } else {
+                                               tagtype = UNKNOWN;
+                                       }
+                               }
+                               ul_switch_off_field();
+                       }
+               }
+       } else {
+               // Infinition MY-D tests   Exam high nibble 
+               uint8_t nib = (card.uid[1] & 0xf0) >> 4;
+               switch ( nib ){
+                       case 1: tagtype =  MY_D; break;
+                       case 2: tagtype = (MY_D | MY_D_NFC); break; //notice: we can not currently distinguish between these two
+                       case 3: tagtype = (MY_D_MOVE | MY_D_MOVE_NFC); break; //notice: we can not currently distinguish between these two
+               }
+       }
+
+       tagtype |= ul_magic_test();
+       if (tagtype == (UNKNOWN | MAGIC)) tagtype = (UL_MAGIC);
+       return tagtype;
+}
+
+int CmdHF14AMfUInfo(const char *Cmd){
+
+       uint8_t authlim = 0xff;
+       uint8_t data[16] = {0x00};
+       iso14a_card_select_t card;
+       int status;
+       bool errors = false;
+       bool hasAuthKey = false;
+       bool locked = false;
+       bool swapEndian = false;
+       uint8_t cmdp = 0;
+       uint8_t dataLen = 0;
+       uint8_t authenticationkey[16] = {0x00};
+       uint8_t *authkeyptr = authenticationkey;
+       uint8_t *key;
+       uint8_t pack[4] = {0,0,0,0};
+       int len = 0;
+       char tempStr[50];
+
+       while(param_getchar(Cmd, cmdp) != 0x00)
+       {
+               switch(param_getchar(Cmd, cmdp))
+               {
+               case 'h':
+               case 'H':
+                       return usage_hf_mfu_info();
+               case 'k':
+               case 'K':
+                       dataLen = param_getstr(Cmd, cmdp+1, tempStr);
+                       if (dataLen == 32 || dataLen == 8) { //ul-c or ev1/ntag key length
+                               errors = param_gethex(tempStr, 0, authenticationkey, dataLen);
+                               dataLen /= 2; // handled as bytes from now on
+                       } else {
+                               PrintAndLog("\nERROR: Key is incorrect length\n");
+                               errors = true;
+                       }
+                       cmdp += 2;
+                       hasAuthKey = true;
+                       break;
+               case 'l':
+               case 'L':
+                       swapEndian = true;
+                       cmdp++;
+                       break;
+               default:
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                       errors = true;
+                       break;
+               }
+               if(errors) break;
+       }
+
+       //Validations
+       if(errors) return usage_hf_mfu_info();
+
+       TagTypeUL_t tagtype = GetHF14AMfU_Type();
+       if (tagtype == UL_ERROR) return -1;
+
+       PrintAndLog("\n--- Tag Information ---------");
+       PrintAndLog("-------------------------------------------------------------");
+       ul_print_type(tagtype, 6);
+
+       // Swap endianness 
+       if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4 );
+
+       if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
+
+       // read pages 0,1,2,3 (should read 4pages)
+       status = ul_read(0, data, sizeof(data));
+       if ( status == -1 ) {
+               ul_switch_off_field();
+               PrintAndLog("Error: tag didn't answer to READ");
+               return status;
+       } else if (status == 16) {
+               ul_print_default(data);
+               ndef_print_CC(data+12);
+       } else {
+               locked = true;
+       }
+
+       // UL_C Specific
+       if ((tagtype & UL_C)) {
+
+               // read pages 0x28, 0x29, 0x2A, 0x2B
+               uint8_t ulc_conf[16] = {0x00};
+               status = ul_read(0x28, ulc_conf, sizeof(ulc_conf));
+               if ( status == -1 ){
+                       PrintAndLog("Error: tag didn't answer to READ UL-C");
+                       ul_switch_off_field();
+                       return status;
+               } 
+               if (status == 16) ulc_print_configuration(ulc_conf);
+               else locked = true;
+
+               if ((tagtype & MAGIC)) {
+                       //just read key
+                       uint8_t ulc_deskey[16] = {0x00};
+                       status = ul_read(0x2C, ulc_deskey, sizeof(ulc_deskey));
+                       if ( status == -1 ) {
+                               ul_switch_off_field();
+                               PrintAndLog("Error: tag didn't answer to READ magic");
+                               return status;
+                       }
+                       if (status == 16) ulc_print_3deskey(ulc_deskey);
+
+               } else {
+                       ul_switch_off_field();
+                       // if we called info with key, just return 
+                       if ( hasAuthKey ) return 1;
+
+                       // also try to diversify default keys..  look into CmdHF14AMfuGenDiverseKeys
+                       PrintAndLog("Trying some default 3des keys");
+                       for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i ) {
+                               key = default_3des_keys[i];
+                               if (ulc_authentication(key, true)) {
+                                       PrintAndLog("Found default 3des key: ");
+                                       uint8_t keySwap[16];
+                                       memcpy(keySwap, SwapEndian64(key,16,8), 16);
+                                       ulc_print_3deskey(keySwap);
+                                       return 1;
+                               } 
+                       }
+                       return 1;
+               }
+       }
+
+       // do counters and signature first (don't neet auth) 
+
+       // ul counters are different than ntag counters
+       if ((tagtype & (UL_EV1_48 | UL_EV1_128))) {
+               if (ulev1_print_counters() != 3) {
+                       // failed - re-select
+                       if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
+               }
+       }
+
+       if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_213 | NTAG_215 | NTAG_216 | NTAG_I2C_1K | NTAG_I2C_2K     ))) {
+               uint8_t ulev1_signature[32] = {0x00};
+               status = ulev1_readSignature( ulev1_signature, sizeof(ulev1_signature));
+               if ( status == -1 ) {
+                       PrintAndLog("Error: tag didn't answer to READ SIGNATURE");
+                       ul_switch_off_field();
+                       return status;
+               }
+               if (status == 32) ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature));
+               else {
+                       // re-select
+                       if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
+               }
+       }
+
+       if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_210 | NTAG_212 | NTAG_213 | NTAG_215 | NTAG_216 | NTAG_I2C_1K | NTAG_I2C_2K))) {
+               uint8_t version[10] = {0x00};
+               status  = ulev1_getVersion(version, sizeof(version));
+               if ( status == -1 ) {
+                       PrintAndLog("Error: tag didn't answer to GETVERSION");
+                       ul_switch_off_field();
+                       return status;
+               } else if (status == 10) {
+                       ulev1_print_version(version);
+               } else {
+                       locked = true;
+                       if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
+               }
+
+               uint8_t startconfigblock = 0;
+               uint8_t ulev1_conf[16] = {0x00};
+               // config blocks always are last 4 pages
+               for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++)
+                       if (tagtype & UL_TYPES_ARRAY[idx])
+                               startconfigblock = UL_MEMORY_ARRAY[idx]-3;
+
+               if (startconfigblock){ // if we know where the config block is...
+                       status = ul_read(startconfigblock, ulev1_conf, sizeof(ulev1_conf));
+                       if ( status == -1 ) {
+                               PrintAndLog("Error: tag didn't answer to READ EV1");
+                               ul_switch_off_field();
+                               return status;
+                       } else if (status == 16) {
+                               // save AUTHENTICATION LIMITS for later:
+                               authlim = (ulev1_conf[4] & 0x07);
+                               ulev1_print_configuration(ulev1_conf, startconfigblock);
+                       }
+               }
+
+               // AUTHLIMIT, (number of failed authentications)
+               // 0 = limitless.
+               // 1-7 = limit. No automatic tries then.
+               // hasAuthKey,  if we was called with key, skip test.
+               if ( !authlim && !hasAuthKey ) {
+                       PrintAndLog("\n--- Known EV1/NTAG passwords.");
+                       len = 0;
+                       for (uint8_t i = 0; i < KEYS_PWD_COUNT; ++i ) {
+                               key = default_pwd_pack[i];
+                               len = ulev1_requestAuthentication(key, pack, sizeof(pack));
+                               if (len >= 1) {
+                                       PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
+                                       break;
+                               } else {
+                                       if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
+                               }
+                       }
+                       if (len < 1) PrintAndLog("password not known");
+               }
+       }
+
+       ul_switch_off_field();
+       if (locked) PrintAndLog("\nTag appears to be locked, try using the key to get more info");
+       PrintAndLog("");
+       return 1;
+}
+
 //
 //  Mifare Ultralight Write Single Block
 //
@@ -105,7 +861,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){
        
        blockNo = param_get8(Cmd, 0);
 
-       if (blockNo > MAX_ULTRA_BLOCKS){
+       if (blockNo > MAX_UL_BLOCKS){
                PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
                return 1;
        }
@@ -155,116 +911,223 @@ int CmdHF14AMfUWrBl(const char *Cmd){
 //  Mifare Ultralight Read Single Block
 //
 int CmdHF14AMfURdBl(const char *Cmd){
-  
-       uint8_t blockNo = -1;   
 
+       UsbCommand resp;
+       uint8_t blockNo = -1;   
        char cmdp = param_getchar(Cmd, 0);
        
        if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {    
                PrintAndLog("Usage:  hf mfu rdbl <block number>");
                PrintAndLog("        sample: hfu mfu rdbl 0");
                return 0;
-       }       
-               
+       }
+
        blockNo = param_get8(Cmd, 0);
 
-       if (blockNo > MAX_ULTRA_BLOCKS){
-          PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
-          return 1;
+       if (blockNo > MAX_UL_BLOCKS){
+               PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight");
+               return 1;
        }
-       
-       PrintAndLog("--block no:0x%02X (%d)", (int)blockNo, blockNo);
+
        UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
        SendCommand(&c);
 
-       UsbCommand resp;
+
        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
-               uint8_t isOK    = resp.arg[0] & 0xff;
-               uint8_t * data  = resp.d.asBytes;
-               
-               PrintAndLog("isOk: %02x", isOK);
-                       
-               if (isOK)
-                       PrintAndLog("Data: %s", sprint_hex(data, 4));
+               uint8_t isOK = resp.arg[0] & 0xff;
+               if (isOK) {
+                       uint8_t *data = resp.d.asBytes;
+                       PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
+               }
+               else {
+                       PrintAndLog("Failed reading block: (%02x)", isOK);
+               }
        } else {
-               PrintAndLog("Command execute timeout");
+               PrintAndLog("Command execute time-out");
        }
+
+       return 0;
+}
+
+int usage_hf_mfu_info(void) {
+       PrintAndLog("It gathers information about the tag and tries to detect what kind it is.");
+       PrintAndLog("Sometimes the tags are locked down, and you may need a key to be able to read the information");
+       PrintAndLog("The following tags can be identified:\n");
+       PrintAndLog("Ultralight, Ultralight-C, Ultralight EV1, NTAG 203, NTAG 210,");
+       PrintAndLog("NTAG 212, NTAG 213, NTAG 215, NTAG 216, NTAG I2C 1K & 2K");
+       PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n");
+       PrintAndLog("Usage:  hf mfu info k <key> l");
+       PrintAndLog("  Options : ");
+       PrintAndLog("  k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
+       PrintAndLog("  l       : (optional) swap entered key's endianness");
+       PrintAndLog("");
+       PrintAndLog("   sample : hf mfu info");
+       PrintAndLog("          : hf mfu info k 00112233445566778899AABBCCDDEEFF");
+       PrintAndLog("          : hf mfu info k AABBCCDDD");
+       return 0;
+}
+
+int usage_hf_mfu_dump(void) {
+       PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
+       PrintAndLog("NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
+       PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
+       PrintAndLog("It autodetects card type.\n");     
+       PrintAndLog("Usage:  hf mfu dump k <key> l n <filename w/o .bin>");
+       PrintAndLog("  Options : ");
+       PrintAndLog("  k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
+       PrintAndLog("  l       : (optional) swap entered key's endianness");
+       PrintAndLog("  n <FN > : filename w/o .bin to save the dump as");       
+       PrintAndLog("  p <Pg > : starting Page number to manually set a page to start the dump at");    
+       PrintAndLog("  q <qty> : number of Pages to manually set how many pages to dump");      
+
+       PrintAndLog("");
+       PrintAndLog("   sample : hf mfu dump");
+       PrintAndLog("          : hf mfu dump n myfile");
+       PrintAndLog("          : hf mfu dump k 00112233445566778899AABBCCDDEEFF");
+       PrintAndLog("          : hf mfu dump k AABBCCDDD\n");
        return 0;
 }
 
 //
-//  Mifare Ultralight / Ultralight-C;  Read and Dump Card Contents
-//
+//  Mifare Ultralight / Ultralight-C / Ultralight-EV1
+//  Read and Dump Card Contents,  using auto detection of tag size.
 int CmdHF14AMfUDump(const char *Cmd){
 
        FILE *fout;
        char filename[FILE_PATH_SIZE] = {0x00};
-       char * fnameptr = filename;
-       
+       char *fnameptr = filename;
        uint8_t *lockbytes_t = NULL;
        uint8_t lockbytes[2] = {0x00};
-       
        uint8_t *lockbytes_t2 = NULL;
        uint8_t lockbytes2[2] = {0x00};
-
        bool bit[16]  = {0x00};
        bool bit2[16] = {0x00};
-       
-       int i;
-       uint8_t BlockNo      = 0;
-       int Pages            = 16;
-
-       bool tmplockbit          = false;
-       uint8_t isOK         = 0;
-       uint8_t *data       = NULL;
+       uint8_t data[1024] = {0x00};
+       bool hasAuthKey = false;
+       int i = 0;
+       int Pages = 16;
+       bool tmplockbit = false;
+       uint8_t dataLen = 0;
+       uint8_t cmdp = 0;
+       uint8_t authenticationkey[16] = {0x00};
+       uint8_t *authKeyPtr = authenticationkey;
+       size_t fileNlen = 0;
+       bool errors = false;
+       bool swapEndian = false;
+       bool manualPages = false;
+       uint8_t startPage = 0;
+       char tempStr[50];
 
-       char cmdp = param_getchar(Cmd, 0);
-       
-       if (cmdp == 'h' || cmdp == 'H') {
-               PrintAndLog("Reads all pages from Mifare Ultralight or Ultralight-C tag.");
-               PrintAndLog("It saves binary dump into the file `filename.bin` or `cardUID.bin`");              
-               PrintAndLog("Usage:  hf mfu dump <c> <filename w/o .bin>");
-               PrintAndLog("     <c>  optional cardtype c == Ultralight-C, if not defaults to Ultralight");
-               PrintAndLog("     sample: hf mfu dump");
-               PrintAndLog("           : hf mfu dump myfile");
-               PrintAndLog("           : hf mfu dump c myfile");
-               return 0;
+       while(param_getchar(Cmd, cmdp) != 0x00)
+       {
+               switch(param_getchar(Cmd, cmdp))
+               {
+               case 'h':
+               case 'H':
+                       return usage_hf_mfu_dump();
+               case 'k':
+               case 'K':
+                       dataLen = param_getstr(Cmd, cmdp+1, tempStr);
+                       if (dataLen == 32 || dataLen == 8) { //ul-c or ev1/ntag key length
+                               errors = param_gethex(tempStr, 0, authenticationkey, dataLen);
+                               dataLen /= 2;
+                       } else {
+                               PrintAndLog("\nERROR: Key is incorrect length\n");
+                               errors = true;
+                       }
+                       cmdp += 2;
+                       hasAuthKey = true;
+                       break;
+               case 'l':
+               case 'L':
+                       swapEndian = true;
+                       cmdp++;
+                       break;
+               case 'n':
+               case 'N':
+                       fileNlen = param_getstr(Cmd, cmdp+1, filename);
+                       if (!fileNlen) errors = true; 
+                       if (fileNlen > FILE_PATH_SIZE-5) fileNlen = FILE_PATH_SIZE-5;
+                       cmdp += 2;
+                       break;
+               case 'p':
+               case 'P':
+                       startPage = param_get8(Cmd, cmdp+1);
+                       manualPages = true;
+                       cmdp += 2;
+                       break;
+               case 'q':
+               case 'Q':
+                       Pages = param_get8(Cmd, cmdp+1);
+                       cmdp += 2;
+                       manualPages = true;
+                       break;
+               default:
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                       errors = true;
+                       break;
+               }
+               if(errors) break;
        }
 
-       // UL or UL-C?
-       Pages = (cmdp == 'c' || cmdp == 'C') ? 44 : 16;
-       
-       PrintAndLog("Dumping Ultralight%s Card Data...", (Pages ==16)?"":"-C");
-               
-       UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}};
+       //Validations
+       if(errors) return usage_hf_mfu_dump();
+
+       if (swapEndian && hasAuthKey) 
+               authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
+
+       TagTypeUL_t tagtype = GetHF14AMfU_Type();
+       if (tagtype == UL_ERROR) return -1;
+
+       if (!manualPages)
+               for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++)
+                       if (tagtype & UL_TYPES_ARRAY[idx])
+                               Pages = UL_MEMORY_ARRAY[idx]+1;
+
+       ul_print_type(tagtype, 0);
+       PrintAndLog("Reading tag memory...");
+       UsbCommand c = {CMD_MIFAREU_READCARD, {startPage,Pages}};
+       if ( hasAuthKey ) {
+               if (tagtype & UL_C)
+                       c.arg[2] = 1; //UL_C auth
+               else
+                       c.arg[2] = 2; //UL_EV1/NTAG auth
+
+               memcpy(c.d.asBytes, authKeyPtr, dataLen);
+       }
        SendCommand(&c);
        UsbCommand resp;
+       if (!WaitForResponseTimeout(CMD_ACK, &resp,1500)) {
+               PrintAndLog("Command execute time-out");
+               return 1;
+       }
+       if (resp.arg[0] != 1) {
+               PrintAndLog("Failed reading block: (%02x)", i);
+               return 1;
+       }
 
-       if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
-               isOK  = resp.arg[0] & 0xff;
-               if (!isOK) {                
-                       PrintAndLog("Command error");
-                       return 0;
-               }
-               data  = resp.d.asBytes;
-       } else {
-               PrintAndLog("Command execute timeout");
-               return 0;
+       uint32_t bufferSize = resp.arg[1];
+       if (bufferSize > sizeof(data)) {
+               PrintAndLog("Data exceeded Buffer size!");
+               bufferSize = sizeof(data);
        }
-               
+       GetFromBigBuf(data, bufferSize, 0);
+       WaitForResponse(CMD_ACK,NULL);
+
+       Pages = bufferSize/4;
        // Load lock bytes.
        int j = 0;
-       
+
        lockbytes_t = data + 8;
        lockbytes[0] = lockbytes_t[2];
        lockbytes[1] = lockbytes_t[3];
        for(j = 0; j < 16; j++){
                bit[j] = lockbytes[j/8] & ( 1 <<(7-j%8));
-       }               
-       
+       }
+
        // Load bottom lockbytes if available
+       // TODO -- FIGURE OUT LOCK BYTES FOR TO EV1 and/or NTAG
        if ( Pages == 44 ) {
-               
                lockbytes_t2 = data + (40*4);
                lockbytes2[0] = lockbytes_t2[2];
                lockbytes2[1] = lockbytes_t2[3];
@@ -273,20 +1136,34 @@ int CmdHF14AMfUDump(const char *Cmd){
                }
        }
 
+       // add keys to block dump
+       if (hasAuthKey) {
+               if (!swapEndian){
+                       authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
+               } else {
+                       authKeyPtr = authenticationkey;
+               }
+
+               if (tagtype & UL_C){ //add 4 pages
+                       memcpy(data + Pages*4, authKeyPtr, dataLen);
+                       Pages += dataLen/4;  
+               } else { // 2nd page from end
+                       memcpy(data + (Pages*4) - 8, authenticationkey, dataLen);
+               }
+       }
+
        for (i = 0; i < Pages; ++i) {
-               
                if ( i < 3 ) {
                        PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
                        continue;
                }
-
                switch(i){
                        case 3: tmplockbit = bit[4]; break;
-                       case 4: tmplockbit = bit[3]; break;
-                       case 5: tmplockbit = bit[2]; break;
-                       case 6: tmplockbit = bit[1]; break;
-                       case 7: tmplockbit = bit[0]; break;
-                       case 8: tmplockbit = bit[15]; break;
+                       case 4: tmplockbit = bit[3]; break;
+                       case 5: tmplockbit = bit[2]; break;
+                       case 6: tmplockbit = bit[1]; break;
+                       case 7: tmplockbit = bit[0]; break;
+                       case 8: tmplockbit = bit[15]; break;
                        case 9: tmplockbit = bit[14]; break;
                        case 10: tmplockbit = bit[13]; break;
                        case 11: tmplockbit = bit[12]; break;
@@ -305,7 +1182,7 @@ int CmdHF14AMfUDump(const char *Cmd){
                        case 24:
                        case 25:
                        case 26:
-                       case 27: tmplockbit = bit2[4]; break;               
+                       case 27: tmplockbit = bit2[4]; break;
                        case 28:
                        case 29:
                        case 30:
@@ -324,32 +1201,21 @@ int CmdHF14AMfUDump(const char *Cmd){
                        case 43: tmplockbit = bit2[9]; break;  //auth1
                        default: break;
                }
-               PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),tmplockbit);
-       }  
-       
-       int len = 0;
-       if ( Pages == 16 )
-               len = param_getstr(Cmd,0,filename);
-       else
-               len = param_getstr(Cmd,1,filename);
-
-       if (len > FILE_PATH_SIZE-5) len = FILE_PATH_SIZE-5;
+               PrintAndLog("Block %02X:%s [%d] {%.4s}", i, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4);
+       }
 
        // user supplied filename?
-       if (len < 1) {
-       
+       if (fileNlen < 1) {
                // UID = data 0-1-2 4-5-6-7  (skips a beat)
                sprintf(fnameptr,"%02X%02X%02X%02X%02X%02X%02X.bin",
                        data[0],data[1], data[2], data[4],data[5],data[6], data[7]);
-
        } else {
-               sprintf(fnameptr + len," .bin");
+               sprintf(fnameptr + fileNlen,".bin");
        }
 
-
        if ((fout = fopen(filename,"wb")) == NULL) { 
                PrintAndLog("Could not create file name %s", filename);
-               return 1;       
+               return 1;
        }
        fwrite( data, 1, Pages*4, fout );
        fclose(fout);
@@ -358,15 +1224,6 @@ int CmdHF14AMfUDump(const char *Cmd){
        return 0;
 }
 
-// Needed to Authenticate to Ultralight C tags
-void rol (uint8_t *data, const size_t len){
-       uint8_t first = data[0];
-       for (size_t i = 0; i < len-1; i++) {
-               data[i] = data[i+1];
-       }
-       data[len-1] = first;
-}
-
 //-------------------------------------------------------------------------------
 // Ultralight C Methods
 //-------------------------------------------------------------------------------
@@ -376,130 +1233,44 @@ void rol (uint8_t *data, const size_t len){
 //
 int CmdHF14AMfucAuth(const char *Cmd){
 
-       uint8_t default_keys[5][16] = {
-               { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
-               { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
-               { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
-               { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
-               { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }     // all ones
-       };
+       uint8_t keyNo = 3;
+       bool errors = false;
 
        char cmdp = param_getchar(Cmd, 0);
-       
-       uint8_t keyNo = 0;
-       bool errors = false;
+
        //Change key to user defined one
        if (cmdp == 'k' || cmdp == 'K'){
                keyNo = param_get8(Cmd, 1);
-               if(keyNo >= 4) errors = true;
+               if(keyNo > KEYS_3DES_COUNT) 
+                       errors = true;
        }
 
-       if (cmdp == 'h' || cmdp == 'H') {
+       if (cmdp == 'h' || cmdp == 'H')
                errors = true;
-       }
-
+       
        if (errors) {
                PrintAndLog("Usage:  hf mfu cauth k <key number>");
                PrintAndLog("      0 (default): 3DES standard key");
-               PrintAndLog("      1 : all zeros key");
+               PrintAndLog("      1 : all 0x00 key");
                PrintAndLog("      2 : 0x00-0x0F key");
                PrintAndLog("      3 : nfc key");
-               PrintAndLog("      4 : all ones key");
-               PrintAndLog("        sample : hf mfu cauth k");
+               PrintAndLog("      4 : all 0x01 key");
+               PrintAndLog("      5 : all 0xff key");
+               PrintAndLog("      6 : 0x00-0xFF key");         
+               PrintAndLog("\n      sample : hf mfu cauth k");
                PrintAndLog("               : hf mfu cauth k 3");
                return 0;
        } 
 
-       uint8_t random_a[8]     = { 1,1,1,1,1,1,1,1 };
-       //uint8_t enc_random_a[8] = { 0 };
-       uint8_t random_b[8]     = { 0 };
-       uint8_t enc_random_b[8] = { 0 };
-       uint8_t random_a_and_b[16] = { 0 };
-       des3_context ctx        = { 0 };
-       uint8_t *key = default_keys[keyNo];
-       uint8_t blockNo = 0;
-       uint32_t cuid = 0;
-
-       //Auth1
-       UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
-       SendCommand(&c);
-       UsbCommand resp;
-       if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
-               uint8_t isOK  = resp.arg[0] & 0xff;
-               cuid  = resp.arg[1];
-               uint8_t * data= resp.d.asBytes;
-
-               if (isOK){
-                       PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
-                       memcpy(enc_random_b,data+1,8);
-               } else {
-                       PrintAndLog("Auth failed");
-                       return 2; // auth failed.
-               }               
-       } else {
-               PrintAndLog("Command execute timeout");
-               return 1;
-       }
-
-       uint8_t iv[8]           = { 0 };
-       // Do we need random ? Right now we use all ones, is that random enough ?
-//    DES_random_key(&RndA);
-
-       PrintAndLog("     RndA  :%s",sprint_hex(random_a, 8));
-       PrintAndLog("     e_RndB:%s",sprint_hex(enc_random_b, 8));
-
-       des3_set2key_dec(&ctx, key);
-
-       des3_crypt_cbc(&ctx      // des3_context *ctx
-               , DES_DECRYPT        // int mode
-               , sizeof(random_b)   // size_t length
-               , iv                 // unsigned char iv[8]
-               , enc_random_b       // const unsigned char *input
-               , random_b           // unsigned char *output
-               );
-
-       PrintAndLog("     RndB:%s",sprint_hex(random_b, 8));
-
-       rol(random_b,8);
-       memcpy(random_a_and_b  ,random_a,8);
-       memcpy(random_a_and_b+8,random_b,8);
-       
-       PrintAndLog("     RA+B:%s",sprint_hex(random_a_and_b, 16));
-
-       des3_set2key_enc(&ctx, key);
-
-       des3_crypt_cbc(&ctx          // des3_context *ctx
-               , DES_ENCRYPT            // int mode
-               , sizeof(random_a_and_b)   // size_t length
-               , enc_random_b           // unsigned char iv[8]
-               , random_a_and_b         // const unsigned char *input
-               , random_a_and_b         // unsigned char *output
-               );
-
-       PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
-
-       //Auth2
-       UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
-       memcpy(d.d.asBytes,random_a_and_b, 16);
-       SendCommand(&d);
-
-       UsbCommand respb;
-       if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
-               uint8_t  isOK  = respb.arg[0] & 0xff;
-               uint8_t * data2= respb.d.asBytes;
-
-               if (isOK){
-                       PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
-               } else {
-                       return 2;
-               }
+       uint8_t *key = default_3des_keys[keyNo];
+       if (ulc_authentication(key, true))
+               PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key, 16));
+       else
+               PrintAndLog("Authentication failed");
                
-       } else {
-               PrintAndLog("Command execute timeout");
-               return 1;
-       } 
        return 0;
 }
+
 /**
 A test function to validate that the polarssl-function works the same 
 was as the openssl-implementation. 
@@ -596,47 +1367,66 @@ int CmdTestDES(const char * cmd)
        return 0;       
 }
 **/
+
 //
 // Ultralight C Read Single Block
 //
 int CmdHF14AMfUCRdBl(const char *Cmd)
 {
+       UsbCommand resp;
+       bool hasPwd = FALSE;
        uint8_t blockNo = -1;
+       uint8_t key[16];
        char cmdp = param_getchar(Cmd, 0);
-       
+
        if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
-               PrintAndLog("Usage:  hf mfu crdbl  <block number>");
-               PrintAndLog("        sample: hf mfu crdbl 0");
+               PrintAndLog("Usage:  hf mfu crdbl  <block number> <key>");
+               PrintAndLog("");
+               PrintAndLog("sample: hf mfu crdbl 0");
+               PrintAndLog("        hf mfu crdbl 0 00112233445566778899AABBCCDDEEFF");
                return 0;
-       }       
-               
+       }
+
        blockNo = param_get8(Cmd, 0);
        if (blockNo < 0) {
                PrintAndLog("Wrong block number");
                return 1;
        }
-       
-       if (blockNo > MAX_ULTRAC_BLOCKS ){
-               PrintAndLog("Error: Maximum number of readable blocks is 47 for Ultralight-C Cards!");
+
+       if (blockNo > MAX_ULC_BLOCKS ){
+               PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C");
                return 1;
        } 
        
-       PrintAndLog("--block no: 0x%02X (%d)", (int)blockNo, blockNo);
+       // key
+       if ( strlen(Cmd) > 3){
+               if (param_gethex(Cmd, 1, key, 32)) {
+                       PrintAndLog("Key must include %d HEX symbols", 32);
+                       return 1;
+               } else {
+                       hasPwd = TRUE;
+               }       
+       }       
 
        //Read Block
-       UsbCommand e = {CMD_MIFAREU_READBL, {blockNo}};
-       SendCommand(&e);
-       UsbCommand resp_c;
-       if (WaitForResponseTimeout(CMD_ACK,&resp_c,1500)) {
-               uint8_t isOK = resp_c.arg[0] & 0xff;
-               uint8_t *data = resp_c.d.asBytes;
-               
-               PrintAndLog("isOk: %02x", isOK);
-               if (isOK)
-                       PrintAndLog("Data: %s", sprint_hex(data, 4));
-                       
+       UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
+       if ( hasPwd ) {
+               c.arg[1] = 1;
+               memcpy(c.d.asBytes,key,16);
+       }
+       SendCommand(&c);
+
+       if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+               uint8_t isOK = resp.arg[0] & 0xff;
+               if (isOK) {
+                       uint8_t *data = resp.d.asBytes;
+                       PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
+               }
+               else {
+                       PrintAndLog("Failed reading block: (%02x)", isOK);
+               }
        } else {
-               PrintAndLog("Command execute timeout");
+               PrintAndLog("Command execute time-out");
        }
        return 0;
 }
@@ -665,7 +1455,7 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
        }
        
        blockNo = param_get8(Cmd, 0);
-       if (blockNo > MAX_ULTRAC_BLOCKS ){
+       if (blockNo > MAX_ULC_BLOCKS ){
                PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C Cards!");
                return 1;
        }
@@ -674,14 +1464,15 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
                PrintAndLog("Block data must include 8 HEX symbols");
                return 1;
        }
-       
+
        if (strchr(Cmd,'w') != 0  || strchr(Cmd,'W') != 0 ) {
                chinese_card = TRUE; 
        }
-       
+
        if ( blockNo <= 3 ) {
                if (!chinese_card){
-                        PrintAndLog("Access Denied");  
+                       PrintAndLog("Access Denied");  
+                       return 1;
                } else {
                        PrintAndLog("--Special block no: 0x%02x", blockNo);
                        PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
@@ -693,8 +1484,9 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
                                PrintAndLog("isOk:%02x", isOK);
                        } else {
                                PrintAndLog("Command execute timeout");
-                       }  
-               }       
+                               return 1;
+                       }
+               }
        } else {
                        PrintAndLog("--Block no : 0x%02x", blockNo);
                        PrintAndLog("--Data: %s", sprint_hex(bldata, 4));               
@@ -706,26 +1498,251 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
                                PrintAndLog("isOk : %02x", isOK);
                        } else {
                                PrintAndLog("Command execute timeout");
+                               return 1;
                        }
        }
        return 0;
 }
 
+// 
+// Mifare Ultralight C - Set password
+//
+int CmdHF14AMfucSetPwd(const char *Cmd){
+
+       uint8_t pwd[16] = {0x00};
+       
+       char cmdp = param_getchar(Cmd, 0);
+       
+       if (strlen(Cmd) == 0  || cmdp == 'h' || cmdp == 'H') {  
+               PrintAndLog("Usage:  hf mfu setpwd <password (32 hex symbols)>");
+               PrintAndLog("       [password] - (32 hex symbols)");
+               PrintAndLog("");
+               PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f");
+               PrintAndLog("");
+               return 0;
+       }
+       
+       if (param_gethex(Cmd, 0, pwd, 32)) {
+               PrintAndLog("Password must include 32 HEX symbols");
+               return 1;
+       }
+       
+       UsbCommand c = {CMD_MIFAREUC_SETPWD};   
+       memcpy( c.d.asBytes, pwd, 16);
+       SendCommand(&c);
+
+       UsbCommand resp;
+       
+       if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+               if ( (resp.arg[0] & 0xff) == 1)
+                       PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
+               else{
+                       PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
+                       return 1;
+               }
+       }
+       else {
+               PrintAndLog("command execution time out");
+               return 1;
+       }
+       
+       return 0;
+}
+
+//
+// Magic UL / UL-C tags  - Set UID
+//
+int CmdHF14AMfucSetUid(const char *Cmd){
+
+       UsbCommand c;
+       UsbCommand resp;
+       uint8_t uid[7] = {0x00};
+       char cmdp = param_getchar(Cmd, 0);
+       
+       if (strlen(Cmd) == 0  || cmdp == 'h' || cmdp == 'H') {  
+               PrintAndLog("Usage:  hf mfu setuid <uid (14 hex symbols)>");
+               PrintAndLog("       [uid] - (14 hex symbols)");
+               PrintAndLog("\nThis only works for Magic Ultralight tags.");
+               PrintAndLog("");
+               PrintAndLog("sample: hf mfu setuid 11223344556677");
+               PrintAndLog("");
+               return 0;
+       }
+       
+       if (param_gethex(Cmd, 0, uid, 14)) {
+               PrintAndLog("UID must include 14 HEX symbols");
+               return 1;
+       }
+
+       // read block2. 
+       c.cmd = CMD_MIFAREU_READBL;
+       c.arg[0] = 2;
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+               PrintAndLog("Command execute timeout");
+               return 2;
+       }
+       
+       // save old block2.
+       uint8_t oldblock2[4] = {0x00};
+       memcpy(resp.d.asBytes, oldblock2, 4);
+       
+       // block 0.
+       c.cmd = CMD_MIFAREU_WRITEBL;
+       c.arg[0] = 0;
+       c.d.asBytes[0] = uid[0];
+       c.d.asBytes[1] = uid[1];
+       c.d.asBytes[2] = uid[2];
+       c.d.asBytes[3] =  0x88 ^ uid[0] ^ uid[1] ^ uid[2];
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+               PrintAndLog("Command execute timeout");
+               return 3;
+       }
+       
+       // block 1.
+       c.arg[0] = 1;
+       c.d.asBytes[0] = uid[3];
+       c.d.asBytes[1] = uid[4];
+       c.d.asBytes[2] = uid[5];
+       c.d.asBytes[3] = uid[6];
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+               PrintAndLog("Command execute timeout");
+               return 4;
+       }
+
+       // block 2.
+       c.arg[0] = 2;
+       c.d.asBytes[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
+       c.d.asBytes[1] = oldblock2[1];
+       c.d.asBytes[2] = oldblock2[2];
+       c.d.asBytes[3] = oldblock2[3];
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+               PrintAndLog("Command execute timeout");
+               return 5;
+       }
+       
+       return 0;
+}
+
+int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
+       
+       uint8_t iv[8] = { 0x00 };
+       uint8_t block = 0x07;
+       
+       // UL-EV1
+       //04 57 b6 e2 05 3f 80 UID
+       //4a f8 4b 19   PWD
+       uint8_t uid[] = { 0xF4,0xEA, 0x54, 0x8E };
+       uint8_t mifarekeyA[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
+       uint8_t mifarekeyB[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
+       uint8_t dkeyA[8] = { 0x00 };
+       uint8_t dkeyB[8] = { 0x00 };
+       
+       uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
+       
+       uint8_t mix[8] = { 0x00 };
+       uint8_t divkey[8] = { 0x00 };
+       
+       memcpy(mix, mifarekeyA, 4);
+       
+       mix[4] = mifarekeyA[4] ^ uid[0];
+       mix[5] = mifarekeyA[5] ^ uid[1];
+       mix[6] = block ^ uid[2];
+       mix[7] = uid[3];
+       
+       des3_context ctx = { 0x00 };
+       des3_set2key_enc(&ctx, masterkey);
+
+       des3_crypt_cbc(&ctx  // des3_context
+               , DES_ENCRYPT    // int mode
+               , sizeof(mix)    // length
+               , iv             // iv[8]
+               , mix            // input
+               , divkey         // output
+               );
+
+       PrintAndLog("3DES version");
+       PrintAndLog("Masterkey    :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
+       PrintAndLog("UID          :\t %s", sprint_hex(uid, sizeof(uid)));
+       PrintAndLog("Sector       :\t %0d", block);
+       PrintAndLog("Mifare key   :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
+       PrintAndLog("Message      :\t %s", sprint_hex(mix, sizeof(mix)));
+       PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
+               
+       PrintAndLog("\n DES version");
+       
+       for (int i=0; i < sizeof(mifarekeyA); ++i){
+               dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
+               dkeyA[6] |=  ((mifarekeyA[i] >> 7) & 1) << (i+1);
+       }
+       
+       for (int i=0; i < sizeof(mifarekeyB); ++i){
+               dkeyB[1] |=  ((mifarekeyB[i] >> 7) & 1) << (i+1);
+               dkeyB[2+i] = (mifarekeyB[i] << 1) & 0xff;
+       }
+       
+       uint8_t zeros[8] = {0x00};
+       uint8_t newpwd[8] = {0x00};
+       uint8_t dmkey[24] = {0x00};
+       memcpy(dmkey, dkeyA, 8);
+       memcpy(dmkey+8, dkeyB, 8);
+       memcpy(dmkey+16, dkeyA, 8);
+       memset(iv, 0x00, 8);
+       
+       des3_set3key_enc(&ctx, dmkey);
+
+       des3_crypt_cbc(&ctx  // des3_context
+               , DES_ENCRYPT    // int mode
+               , sizeof(newpwd) // length
+               , iv             // iv[8]
+               , zeros         // input
+               , newpwd         // output
+               );
+       
+       PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
+       PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
+       PrintAndLog("Mifare ABA   :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
+       PrintAndLog("Mifare Pwd   :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
+       
+       return 0;
+}
+
+// static uint8_t * diversify_key(uint8_t * key){
+       
+ // for(int i=0; i<16; i++){
+   // if(i<=6) key[i]^=cuid[i];
+   // if(i>6) key[i]^=cuid[i%7];
+ // }
+ // return key;
+// }
+
+// static void GenerateUIDe( uint8_t *uid, uint8_t len){
+       // for (int i=0; i<len; ++i){
+                       
+       // }
+       // return;
+// }
+
 //------------------------------------
 // Menu Stuff
 //------------------------------------
 static command_t CommandTable[] =
 {
-       {"help",        CmdHelp,                        1,"This help"},
-       {"dbg",         CmdHF14AMfDbg,          0,"Set default debug mode"},
-       {"info",        CmdHF14AMfUInfo,        0,"Taginfo"},
-       {"dump",        CmdHF14AMfUDump,        0,"Dump MIFARE Ultralight / Ultralight-C tag to binary file"},
-       {"rdbl",        CmdHF14AMfURdBl,        0,"Read block - MIFARE Ultralight"},
-       {"wrbl",        CmdHF14AMfUWrBl,        0,"Write block - MIFARE Ultralight"},    
-       {"crdbl",       CmdHF14AMfUCRdBl,       0,"Read block - MIFARE Ultralight C"},
-       {"cwrbl",       CmdHF14AMfUCWrBl,       0,"Write MIFARE Ultralight C block"},   
-       {"cauth",       CmdHF14AMfucAuth,       0,"try a Ultralight C Authentication"},
-       //{"testdes", CmdTestDES ,        1, "Test DES"},
+       {"help",        CmdHelp,                        1, "This help"},
+       {"dbg",         CmdHF14AMfDbg,          0, "Set default debug mode"},
+       {"info",        CmdHF14AMfUInfo,        0, "Tag information"},
+       {"dump",        CmdHF14AMfUDump,        0, "Dump Ultralight / Ultralight-C tag to binary file"},
+       {"rdbl",        CmdHF14AMfURdBl,        0, "Read block  - Ultralight"},
+       {"wrbl",        CmdHF14AMfUWrBl,        0, "Write block - Ultralight"},    
+       {"crdbl",       CmdHF14AMfUCRdBl,       0, "Read block        - Ultralight C"},
+       {"cwrbl",       CmdHF14AMfUCWrBl,       0, "Write block       - Ultralight C"},
+       {"cauth",       CmdHF14AMfucAuth,       0, "Authentication    - Ultralight C"},
+       {"setpwd",      CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"},
+       {"setuid",      CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"},
+       {"gen",         CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
        {NULL, NULL, 0, NULL}
 };
 
@@ -738,4 +1755,4 @@ int CmdHFMFUltra(const char *Cmd){
 int CmdHelp(const char *Cmd){
        CmdsHelp(CommandTable);
        return 0;
-}
\ No newline at end of file
+}
index c4bc03415c7bb8a8a7467a055d58495d32d614f8..83f2840316c06d111597a80ce09a632fe1b7a21c 100644 (file)
@@ -1,6 +1,9 @@
 #include "cmdhfmf.h"
 #include "cmdhf14a.h"
 
+#ifndef CMDHFMFU_H__
+#define CMDHFMFU_H__
+
 //standard ultralight
 int CmdHF14AMfUWrBl(const char *Cmd);
 int CmdHF14AMfURdBl(const char *Cmd);
@@ -12,8 +15,40 @@ int CmdHF14AMfucAuth(const char *Cmd);
 
 //general stuff
 int CmdHF14AMfUDump(const char *Cmd);
-void rol (uint8_t *data, const size_t len);
+int CmdHF14AMfUInfo(const char *Cmd);
+uint32_t GetHF14AMfU_Type(void);
+
+int ul_print_type(uint32_t tagtype, uint8_t spacer);
+void ul_switch_off_field(void);
 
+int usage_hf_mfu_dump(void);
+int usage_hf_mfu_info(void);
 
 int CmdHFMFUltra(const char *Cmd);
-int CmdHF14AMfUInfo(const char *Cmd);
+
+typedef enum TAGTYPE_UL {
+       UNKNOWN       = 0x000000,
+       UL            = 0x000001,
+       UL_C          = 0x000002,
+       UL_EV1_48     = 0x000004,
+       UL_EV1_128    = 0x000008,
+       NTAG          = 0x000010,
+       NTAG_203      = 0x000020,
+       NTAG_210      = 0x000040,
+       NTAG_212      = 0x000080,
+       NTAG_213      = 0x000100,
+       NTAG_215      = 0x000200,
+       NTAG_216      = 0x000400,
+       MY_D          = 0x000800,
+       MY_D_NFC      = 0x001000,
+       MY_D_MOVE     = 0x002000,
+       MY_D_MOVE_NFC = 0x004000,
+       NTAG_I2C_1K   = 0x008000,
+       NTAG_I2C_2K   = 0x010000,
+       MAGIC         = 0x020000,
+       UL_MAGIC      = UL | MAGIC,
+       UL_C_MAGIC    = UL_C | MAGIC,
+       UL_ERROR      = 0xFFFFFF,
+} TagTypeUL_t;
+
+#endif
index 928a216d7334bc72cf52f4b457f12ecbb111683c..730f4e96ab26dd78e3392015af2ad5ef6d82a8af 100644 (file)
@@ -83,7 +83,7 @@ int CmdList(const char *Cmd)
     {
         while ((ep = readdir (dp)) != NULL)
         {
-            if(ep->d_name != NULL && str_ends_with(ep->d_name, ".lua"))
+            if(str_ends_with(ep->d_name, ".lua"))
                 PrintAndLog("%-16s %s", ep->d_name, "A script file");
         }
         (void) closedir (dp);
index 5c2773008fe347ce2de85207a1659a01c1a3f69a..520317bf312952d02115512a24f43c5129c1d060 100644 (file)
@@ -11,7 +11,7 @@ d3f7d3f7d3f7,
 587ee5f9350f,
 a0478cc39091,
 533cb6c723f6,
-8fd0a4f256e9
+8fd0a4f256e9,
 # more Keys from mf_default_keys.lua
 000000000001,
 000000000002,
@@ -42,6 +42,7 @@ a0478cc39091,
 47524f555041,--RKFJOJOGROUPKeyA
 47524f555042,--RKFJOJOGROUPKeyB
 4AF9D7ADEBE4,--DirectoryandeventlogKeyA
+4b0b20107ccb,--TNP3xxx
 505249564141,--RKFJOJOPRIVAKeyA
 505249564142,--RKFJOJOPRIVAKeyB
 505249565441,
@@ -49,14 +50,19 @@ a0478cc39091,
 54726176656c,--VästtrafikenKeyA
 555555555555,
 55f5a5dd38c9,
+569369c5a0e5,--kiev
 5c598c9c58b5,--RKFSLKeyB
+632193be1c3c,--kiev
+644672bd4afe,--kiev
 666666666666,
 722bfcc5375f,--RKFRejskortDanmarkKeyA
 776974687573,--VästtrafikenKeyB
 777777777777,
 888888888888,
+8fe644038790,--kiev
 999999999999,
 99c636334433,
+9de89e070277,--kiev
 a00000000000,
 a053a292a4af,
 a64598a77478,--RKFSLKeyA
@@ -65,6 +71,7 @@ aaaaaaaaaaaa,
 abcdef123456,--Keyfromladyada.net
 b00000000000,
 b127c6f41436,
+b5ff67cba951,--kiev
 bbbbbbbbbbbb,
 bd493a3962b6,
 c934fe34d934,
@@ -73,7 +80,15 @@ dddddddddddd,
 e4d2770a89be,--RKFSLKeyB
 ee0042f88840,--VästtrafikenKeyB
 eeeeeeeeeeee,
+eff603e1efe9,--kiev
+f14ee7cae863,--kiev
 f1a97341a9fc,
 f1d83f964314,--RKFRejskortDanmarkKeyB
 fc00018778f7,--VästtrafikenKeyA
 fc0001877bf7,--RKFÖstgötaTrafikenKeyA
+44ab09010845,-- hotel system
+85fed980ea5a,-- hotel system
+314B49474956,--VIGIK1KeyA
+564c505f4d41,--VIGIK1KeyB
+f4a9ef2afc6d,--BCARD KeyB
+a9f953def0a3,--
\ No newline at end of file
index b0257ef0eb0d27f125b9b0a52b5b2fc994a6fbd9..678c745ec65cc2afd8b0583ed99ec3d74489c80f 100644 (file)
@@ -135,11 +135,9 @@ local _commands = {
        CMD_MIFARE_SNIFFER =                                                 0x0630,
 
        --//ultralightC
-       CMD_MIFAREUC_AUTH1 =                                                                     0x0724,
-       CMD_MIFAREUC_AUTH2 =                                                                     0x0725,
-       CMD_MIFAREUC_READCARD =                                                                      0x0726,
-       CMD_MIFAREUC_SETPWD =                                                                                            0x0727,
-       CMD_MIFAREU_SETUID =                                                                         0x0728,
+       CMD_MIFAREUC_AUTH =                                                  0x0724,
+       CMD_MIFAREUC_SETPWD =                                                0x0727,
+       CMD_MIFAREU_SETUID =                                                 0x0728,
 
        --// mifare desfire
        CMD_MIFARE_DESFIRE_READBL =                                          0x0728,
index f34d510d61aa9d2cc23a6682de34eb004c7c2b0d..cb603ec0c6d41812edc80fe0e918dcbe695860dc 100644 (file)
@@ -24,6 +24,7 @@ local _names = {
 {"13", "0d00", "0030", "water", "regular", "Wham Shell"},
 {"14", "0e00", "0030", "water", "regular", "Gill Grunt"},
 --{"14", "0e00", "0030", "water", "regular", "Elite Gill Grunt"},
+--{"14", "0e00", "0030", "water", "regular", "Tidal Wave Gill Grunt"},
 {"15", "0f00", "0030", "water", "regular", "Slam Bam"},
 --{"15", "0f00", "0030", "water", "regular", "Surfer Slam Bam"},
 {"16", "1000", "0030", "magic", "regular", "Spyro"},
@@ -43,7 +44,8 @@ local _names = {
 {"25", "1900", "0030", "life", "regular", "Zook"},
 {"26", "1a00", "0030", "life", "regular", "Stealth Elf"},
 --{"26", "1a00", "0030", "life", "regular", "Elite Stealth Elf"},
---{"26", "1a00", "0030", "life", "regular", "Dark Stealth Elf"},
+--{"26", "1a00", "0528", "life", "regular", "Dark Stealth Elf"},
+{"26", "1a00", "0528", "life", "swapforce", "Ninja Stealth Elf"},
 {"27", "1b00", "0030", "life", "regular", "Stump Smash"},
 {"27", "1b00", "0118", "life", "regular", "Stump Smash"},
 --{"27", "1b00", "0030", "life", "regular", "Autumn Stump Smash"},
@@ -59,6 +61,7 @@ local _names = {
 --{"32", "2000", "0030", "undead", "regular", "Skeletal Cynder"},
 
 {"100", "6400", "0030", "air", "giant", "Jet Vac"},
+--{"100", "6400", "0030", "air", "giant", "Full blast Jet Vac"},
 {"101", "6500", "0030", "air", "giant", "Swarm"},
 {"102", "6600", "0030", "earth", "giant", "Crusher"},
 {"103", "6700", "0030", "earth", "giant", "Flashwing"},
@@ -73,12 +76,14 @@ local _names = {
 --{"108", "6c00", "0030", "magic", "giant", "Hoppity Pop Fizz"},
 {"108", "6c00", "023c", "magic", "giant", "Love Potion Pop Fizz"},
 --{"108", "6c00", "0030", "magic", "giant", "Punch Pop Fizz"},
+--{"108", "6c00", "0030", "magic", "giant", "Fizzy Frenzy Pop Fizz"},
 {"109", "6d00", "0030", "magic", "giant", "Nin Jini"},
 {"110", "6e00", "0030", "tech", "giant", "Bouncer"},
 {"111", "6f00", "0030", "tech", "giant", "Sprocket"},
 {"112", "7000", "0030", "life", "giant", "Tree Rex"},
 --{"112", "7000", "0030", "life", "giant", "Gnarly Tree Rex"},
-{"113", "7100", "0030", "life", "giant", "Shroomboom"}, --lightcore
+{"113", "7100", "0030", "life", "giant", "Shroomboom"},
+--{"113", "7100", "0030", "life", "giant", "Sure shot Shroomboom"},
 {"114", "7200", "0030", "undead", "giant", "Eye Broawl"},
 {"115", "7300", "0030", "undead", "giant", "Fright Rider"},
 
@@ -268,27 +273,35 @@ local _names = {
 {"485", "e501", "0030", "dark", "regular", "Blackout"},
 --{"485", "e501", "0234", "dark", "regular", "Special Blackout"},
 
+-- MINI's
 {"502", "f601", "0030", "earth", "mini", "Bop"},
-{"503", "f701", "0030", "magic", "mini", "Spry"},
-{"504", "f801", "0030", "undead", "mini", "Hijinx"},
 {"505", "f901", "0030", "earth", "mini", "Terrabite"},
+
 {"506", "fa01", "0030", "air", "mini", "Breeze"},
-{"507", "fb01", "0030", "fire", "mini", "Weeruptor"},
---{"507", "fb01", "0030", "fire", "mini", "Eggsellent Weeruptor"},
 {"508", "fc01", "0030", "air", "mini", "Pet Vac"},
 --{"508", "fc01", "0030", "air", "mini", "Power Punch Pet Vac"},
+
+{"507", "fb01", "0030", "fire", "mini", "Weeruptor"},
+--{"507", "fb01", "0030", "fire", "mini", "Eggsellent Weeruptor"},
 {"509", "fd01", "0030", "fire", "mini", "Small Fry"},
+
 {"510", "fe01", "0030", "tech", "mini", "Drobit"},
-{"514", "0202", "0030", "water", "mini", "Gill Runt"},
 {"519", "0702", "0030", "tech", "mini", "Trigger Snappy"},
+
 {"526", "0e02", "0030", "life", "mini", "Whisper Elf"},
 {"540", "1c02", "0030", "life", "mini", "Barkley"},
 --{"540", "1c02", "0030", "life", "mini", "Gnarly Barkley"},
+
 {"541", "1d02", "0030", "water", "mini", "Thumpling"},
+{"514", "0202", "0030", "water", "mini", "Gill Runt"},
+
 {"542", "1e02", "0030", "magic", "mini", "mini Jini"},
+{"503", "f701", "0030", "magic", "mini", "Spry"},
+
+{"504", "f801", "0030", "undead", "mini", "Hijinx"},
 {"543", "1f02", "0030", "undead", "mini", "Eye Small"},
 
-{"3000", "b80b", "0030", "air", "SWAPFORCE", "Scratch"},
+{"3000", "b80b", "0030", "air", "mini", "Scratch", "SWAPFORCE"},
 {"3001", "b90b", "0030", "air", "SWAPFORCE", "Pop Thorn"},
 --{"3001", "b90b", "0030", "air", "SWAPFORCE", "Buttered Pop Thorn"},
 {"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Slobber Tooth"},
@@ -315,6 +328,29 @@ local _names = {
 {"3013", "c50b", "0030", "undead", "SWAPFORCE", "Grim Creeper"},
 {"3014", "c60b", "0030", "water", "SWAPFORCE", "Rip Tide"},
 {"3015", "c70b", "0030", "water", "SWAPFORCE", "Punk Shock"},
+
+--{"", "", "0030", "water", "SWAPFORCE", "Hoot Loop"},
+--{"", "", "0030", "water", "SWAPFORCE", "Trap Shadow"},
+--{"", "", "0030", "water", "SWAPFORCE", "Wash Buckler"},
+--{"", "", "0030", "water", "SWAPFORCE", "Freeze Blade"},
+--{"", "", "0030", "fire", "SWAPFORCE", "Magna Charge"},
+--{"", "", "0030", "fire", "SWAPFORCE", "Spy Rise"},
+
+--{"", "", "0030", "fire", "SWAPFORCE", "Doom Stone"},
+--{"", "", "0030", "fire", "SWAPFORCE", "Rubble Rouser"},
+
+--{"", "", "0030", "fire", "SWAPFORCE", "Blast Zone"}
+--{"", "", "0030", "fire", "SWAPFORCE", "Fire Kraken"},
+
+--{"", "", "0030", "fire", "SWAPFORCE", "Rattle Shake"},
+--{"", "", "0030", "fire", "SWAPFORCE", "Night Shift"},
+
+--{"", "", "0030", "life", "SWAPFORCE", "Stink Bomb"},
+--{"", "", "0030", "life", "SWAPFORCE", "Grilla Drilla"},
+
+--{"", "", "0030", "air", "SWAPFORCE", "Free Ranger"},
+--{"", "", "0030", "air", "SWAPFORCE", "Boom Jet"},
+
 }
 
 local function find( main, sub)
@@ -327,7 +363,15 @@ local function find( main, sub)
        end
        return nil
 end
+local function list()
+       print ("Type\tSub\tElement\tGame            Name")
+       print (string.rep('=', 54))
+    for k, v in pairs(_names) do
+               print(("%s\t%s\t%s\t%-9s\t%s"):format(v[2],v[3],v[4], v[5], v[6] ))
+       end 
+end
 
 return {
        Find = find,
+       List = list,
 }
index 3a28d5ae6f988cf5b30c0ffb40094342bca797e6..566128f7dde5324f5db084fc8d008517cb958365 100644 (file)
@@ -192,7 +192,7 @@ end
 return {
        convert_bin_to_html = convert_bin_to_html,
        convert_eml_to_html = convert_eml_to_html,
-    convert_eml_to_bin = convert_eml_to_bin,   
-    SaveAsBinary = save_BIN,
+       convert_eml_to_bin = convert_eml_to_bin,
+       SaveAsBinary = save_BIN,
        SaveAsText = save_TEXT,
 }
diff --git a/client/lualibs/md5.lua b/client/lualibs/md5.lua
new file mode 100644 (file)
index 0000000..2390f95
--- /dev/null
@@ -0,0 +1,384 @@
+local md5 = {
+  _VERSION     = "md5.lua 0.5.0",
+  _DESCRIPTION = "MD5 computation in Lua (5.1)",
+  _URL         = "https://github.com/kikito/md5.lua",
+  _LICENSE     = [[
+    MIT LICENSE
+
+    Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the
+    "Software"), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  ]]
+}
+
+-- bit lib implementions
+
+local floor, abs, max = math.floor, math.abs, math.max
+local char, byte, format, rep, sub =
+  string.char, string.byte, string.format, string.rep, string.sub
+
+local function check_int(n)
+  -- checking not float
+  if(n - floor(n) > 0) then
+    error("trying to use bitwise operation on non-integer!")
+  end
+end
+
+local function tbl2number(tbl)
+  local n = #tbl
+
+  local rslt = 0
+  local power = 1
+  for i = 1, n do
+    rslt = rslt + tbl[i]*power
+    power = power*2
+  end
+
+  return rslt
+end
+
+local function expand(tbl_m, tbl_n)
+  local big = {}
+  local small = {}
+  if(#tbl_m > #tbl_n) then
+    big = tbl_m
+    small = tbl_n
+  else
+    big = tbl_n
+    small = tbl_m
+  end
+  -- expand small
+  for i = #small + 1, #big do
+    small[i] = 0
+  end
+
+end
+
+local to_bits -- needs to be declared before bit_not
+
+local function bit_not(n)
+  local tbl = to_bits(n)
+  local size = max(#tbl, 32)
+  for i = 1, size do
+    if(tbl[i] == 1) then
+      tbl[i] = 0
+    else
+      tbl[i] = 1
+    end
+  end
+  return tbl2number(tbl)
+end
+
+-- defined as local above
+to_bits = function (n)
+  check_int(n)
+  if(n < 0) then
+    -- negative
+    return to_bits(bit_not(abs(n)) + 1)
+  end
+  -- to bits table
+  local tbl = {}
+  local cnt = 1
+  while (n > 0) do
+    local last = math.fmod(n,2)
+    if(last == 1) then
+      tbl[cnt] = 1
+    else
+      tbl[cnt] = 0
+    end
+    n = (n-last)/2
+    cnt = cnt + 1
+  end
+
+  return tbl
+end
+
+local function bit_or(m, n)
+  local tbl_m = to_bits(m)
+  local tbl_n = to_bits(n)
+  expand(tbl_m, tbl_n)
+
+  local tbl = {}
+  local rslt = max(#tbl_m, #tbl_n)
+  for i = 1, rslt do
+    if(tbl_m[i]== 0 and tbl_n[i] == 0) then
+      tbl[i] = 0
+    else
+      tbl[i] = 1
+    end
+  end
+
+  return tbl2number(tbl)
+end
+
+local function bit_and(m, n)
+  local tbl_m = to_bits(m)
+  local tbl_n = to_bits(n)
+  expand(tbl_m, tbl_n)
+
+  local tbl = {}
+  local rslt = max(#tbl_m, #tbl_n)
+  for i = 1, rslt do
+    if(tbl_m[i]== 0 or tbl_n[i] == 0) then
+      tbl[i] = 0
+    else
+      tbl[i] = 1
+    end
+  end
+
+  return tbl2number(tbl)
+end
+
+local function bit_xor(m, n)
+  local tbl_m = to_bits(m)
+  local tbl_n = to_bits(n)
+  expand(tbl_m, tbl_n)
+
+  local tbl = {}
+  local rslt = max(#tbl_m, #tbl_n)
+  for i = 1, rslt do
+    if(tbl_m[i] ~= tbl_n[i]) then
+      tbl[i] = 1
+    else
+      tbl[i] = 0
+    end
+  end
+
+  return tbl2number(tbl)
+end
+
+local function bit_rshift(n, bits)
+  check_int(n)
+
+  local high_bit = 0
+  if(n < 0) then
+    -- negative
+    n = bit_not(abs(n)) + 1
+    high_bit = 2147483648 -- 0x80000000
+  end
+
+  for i=1, bits do
+    n = n/2
+    n = bit_or(floor(n), high_bit)
+  end
+  return floor(n)
+end
+
+local function bit_lshift(n, bits)
+  check_int(n)
+
+  if(n < 0) then
+    -- negative
+    n = bit_not(abs(n)) + 1
+  end
+
+  for i=1, bits do
+    n = n*2
+  end
+  return bit_and(n, 4294967295) -- 0xFFFFFFFF
+end
+
+-- convert little-endian 32-bit int to a 4-char string
+local function lei2str(i)
+  local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
+  return f(0)..f(8)..f(16)..f(24)
+end
+
+-- convert raw string to big-endian int
+local function str2bei(s)
+  local v=0
+  for i=1, #s do
+    v = v * 256 + byte(s, i)
+  end
+  return v
+end
+
+-- convert raw string to little-endian int
+local function str2lei(s)
+  local v=0
+  for i = #s,1,-1 do
+    v = v*256 + byte(s, i)
+  end
+  return v
+end
+
+-- cut up a string in little-endian ints of given size
+local function cut_le_str(s,...)
+  local o, r = 1, {}
+  local args = {...}
+  for i=1, #args do
+    table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
+    o = o + args[i]
+  end
+  return r
+end
+
+local swap = function (w) return str2bei(lei2str(w)) end
+
+local function hex2binaryaux(hexval)
+  return char(tonumber(hexval, 16))
+end
+
+local function hex2binary(hex)
+  local result, _ = hex:gsub('..', hex2binaryaux)
+  return result
+end
+
+-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
+-- 10/02/2001 jcw@equi4.com
+
+local FF     = 0xffffffff
+local CONSTS = {
+  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+  0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
+  0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
+}
+
+local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
+local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
+local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
+local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
+local z=function (f,a,b,c,d,x,s,ac)
+  a=bit_and(a+f(b,c,d)+x+ac,FF)
+  -- be *very* careful that left shift does not cause rounding!
+  return bit_or(bit_lshift(bit_and(a,bit_rshift(FF,s)),s),bit_rshift(a,32-s))+b
+end
+
+local function transform(A,B,C,D,X)
+  local a,b,c,d=A,B,C,D
+  local t=CONSTS
+
+  a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
+  d=z(f,d,a,b,c,X[ 1],12,t[ 2])
+  c=z(f,c,d,a,b,X[ 2],17,t[ 3])
+  b=z(f,b,c,d,a,X[ 3],22,t[ 4])
+  a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
+  d=z(f,d,a,b,c,X[ 5],12,t[ 6])
+  c=z(f,c,d,a,b,X[ 6],17,t[ 7])
+  b=z(f,b,c,d,a,X[ 7],22,t[ 8])
+  a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
+  d=z(f,d,a,b,c,X[ 9],12,t[10])
+  c=z(f,c,d,a,b,X[10],17,t[11])
+  b=z(f,b,c,d,a,X[11],22,t[12])
+  a=z(f,a,b,c,d,X[12], 7,t[13])
+  d=z(f,d,a,b,c,X[13],12,t[14])
+  c=z(f,c,d,a,b,X[14],17,t[15])
+  b=z(f,b,c,d,a,X[15],22,t[16])
+
+  a=z(g,a,b,c,d,X[ 1], 5,t[17])
+  d=z(g,d,a,b,c,X[ 6], 9,t[18])
+  c=z(g,c,d,a,b,X[11],14,t[19])
+  b=z(g,b,c,d,a,X[ 0],20,t[20])
+  a=z(g,a,b,c,d,X[ 5], 5,t[21])
+  d=z(g,d,a,b,c,X[10], 9,t[22])
+  c=z(g,c,d,a,b,X[15],14,t[23])
+  b=z(g,b,c,d,a,X[ 4],20,t[24])
+  a=z(g,a,b,c,d,X[ 9], 5,t[25])
+  d=z(g,d,a,b,c,X[14], 9,t[26])
+  c=z(g,c,d,a,b,X[ 3],14,t[27])
+  b=z(g,b,c,d,a,X[ 8],20,t[28])
+  a=z(g,a,b,c,d,X[13], 5,t[29])
+  d=z(g,d,a,b,c,X[ 2], 9,t[30])
+  c=z(g,c,d,a,b,X[ 7],14,t[31])
+  b=z(g,b,c,d,a,X[12],20,t[32])
+
+  a=z(h,a,b,c,d,X[ 5], 4,t[33])
+  d=z(h,d,a,b,c,X[ 8],11,t[34])
+  c=z(h,c,d,a,b,X[11],16,t[35])
+  b=z(h,b,c,d,a,X[14],23,t[36])
+  a=z(h,a,b,c,d,X[ 1], 4,t[37])
+  d=z(h,d,a,b,c,X[ 4],11,t[38])
+  c=z(h,c,d,a,b,X[ 7],16,t[39])
+  b=z(h,b,c,d,a,X[10],23,t[40])
+  a=z(h,a,b,c,d,X[13], 4,t[41])
+  d=z(h,d,a,b,c,X[ 0],11,t[42])
+  c=z(h,c,d,a,b,X[ 3],16,t[43])
+  b=z(h,b,c,d,a,X[ 6],23,t[44])
+  a=z(h,a,b,c,d,X[ 9], 4,t[45])
+  d=z(h,d,a,b,c,X[12],11,t[46])
+  c=z(h,c,d,a,b,X[15],16,t[47])
+  b=z(h,b,c,d,a,X[ 2],23,t[48])
+
+  a=z(i,a,b,c,d,X[ 0], 6,t[49])
+  d=z(i,d,a,b,c,X[ 7],10,t[50])
+  c=z(i,c,d,a,b,X[14],15,t[51])
+  b=z(i,b,c,d,a,X[ 5],21,t[52])
+  a=z(i,a,b,c,d,X[12], 6,t[53])
+  d=z(i,d,a,b,c,X[ 3],10,t[54])
+  c=z(i,c,d,a,b,X[10],15,t[55])
+  b=z(i,b,c,d,a,X[ 1],21,t[56])
+  a=z(i,a,b,c,d,X[ 8], 6,t[57])
+  d=z(i,d,a,b,c,X[15],10,t[58])
+  c=z(i,c,d,a,b,X[ 6],15,t[59])
+  b=z(i,b,c,d,a,X[13],21,t[60])
+  a=z(i,a,b,c,d,X[ 4], 6,t[61])
+  d=z(i,d,a,b,c,X[11],10,t[62])
+  c=z(i,c,d,a,b,X[ 2],15,t[63])
+  b=z(i,b,c,d,a,X[ 9],21,t[64])
+
+  return A+a,B+b,C+c,D+d
+end
+
+----------------------------------------------------------------
+
+function md5.sumhexa(s)
+  local msgLen = #s
+  local padLen = 56 - msgLen % 64
+
+  if msgLen % 64 > 56 then padLen = padLen + 64 end
+
+  if padLen == 0 then padLen = 64 end
+
+  s = s .. char(128) .. rep(char(0),padLen-1) .. lei2str(8*msgLen) .. lei2str(0)
+
+  assert(#s % 64 == 0)
+
+  local t = CONSTS
+  local a,b,c,d = t[65],t[66],t[67],t[68]
+
+  for i=1,#s,64 do
+    local X = cut_le_str(sub(s,i,i+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
+    assert(#X == 16)
+    X[0] = table.remove(X,1) -- zero based!
+    a,b,c,d = transform(a,b,c,d,X)
+  end
+
+  return format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d))
+end
+
+function md5.sum(s)
+  return hex2binary(md5.sumhexa(s))
+end
+
+return md5
index 757112c671f0169fc26ea53f76326bd0db073f77..804d4a842f1de78587a2cc3406af3b3947698d62 100644 (file)
@@ -2,6 +2,7 @@
     
 local _keys = {
 
+
     --[[
 
     These keys are from the pm3 c-codebase. 
@@ -157,9 +158,30 @@ local _keys = {
        '9de89e070277',
        'eff603e1efe9',
        '644672bd4afe',
-
        'b5ff67cba951',
-  }
+       
+       --[[
+    hotel system cards,
+       http://www.proxmark.org/forum/viewtopic.php?id=2430
+    --]]       
+         '44ab09010845',
+      '85fed980ea5a',
+         
+        --[[
+        VIGIK1
+        --]]
+        '314B49474956',
+        '564c505f4d41',
+        
+        --[[
+        BCARD keyB
+        --]]
+        'f4a9ef2afc6d',
+        
+        --[[    
+        --]]
+        'a9f953def0a3',
+}
 
 ---
 --    The keys above have just been pasted in, for completeness sake. They contain duplicates. 
diff --git a/client/lualibs/precalc.lua b/client/lualibs/precalc.lua
new file mode 100644 (file)
index 0000000..ce58998
--- /dev/null
@@ -0,0 +1,94 @@
+--[[
+       This is an experimental lib. 
+--]]
+local utils = require('utils')
+
+-- LOOKUP Tables
+local perm = {}
+perm [1]= { 0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5, 0xF, 0xE, 0xC, 0xD, 0x8, 0x9, 0xB, 0xA }
+perm [2]= { 0x1, 0x0, 0x2, 0x3, 0x6, 0x7, 0x5, 0x4, 0xE, 0xF, 0xD, 0xC, 0x9, 0x8, 0xA, 0xB }
+perm [3]= { 0x2, 0x3, 0x1, 0x0, 0x5, 0x4, 0x6, 0x7, 0xD, 0xC, 0xE, 0xF, 0xA, 0xB, 0x9, 0x8 }
+perm [4]= { 0x3, 0x2, 0x0, 0x1, 0x4, 0x5, 0x7, 0x6, 0xC, 0xD, 0xF, 0xE, 0xB, 0xA, 0x8, 0x9 }
+perm [5]= { 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1, 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE }
+perm [6]= { 0x5, 0x4, 0x6, 0x7, 0x2, 0x3, 0x1, 0x0, 0xA, 0xB, 0x9, 0x8, 0xD, 0xC, 0xE, 0xF }
+perm [7]= { 0x6, 0x7, 0x5, 0x4, 0x1, 0x0, 0x2, 0x3, 0x9, 0x8, 0xA, 0xB, 0xE, 0xF, 0xD, 0xC }
+perm [8]= { 0x7, 0x6, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0x8, 0x9, 0xB, 0xA, 0xF, 0xE, 0xC, 0xD }
+perm [9]= { 0x8, 0x9, 0xB, 0xA, 0xF, 0xE, 0xC, 0xD, 0x7, 0x6, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2 }
+perm [10]= { 0x9, 0x8, 0xA, 0xB, 0xE, 0xF, 0xD, 0xC, 0x6, 0x7, 0x5, 0x4, 0x1, 0x0, 0x2, 0x3 }
+perm [11]= { 0xA, 0xB, 0x9, 0x8, 0xD, 0xC, 0xE, 0xF, 0x5, 0x4, 0x6, 0x7, 0x2, 0x3, 0x1, 0x0 }
+perm [12]= { 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE, 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1 }
+perm [13]= { 0xC, 0xD, 0xF, 0xE, 0xB, 0xA, 0x8, 0x9, 0x3, 0x2, 0x0, 0x1, 0x4, 0x5, 0x7, 0x6 }
+perm [14]= { 0xD, 0xC, 0xE, 0xF, 0xA, 0xB, 0x9, 0x8, 0x2, 0x3, 0x1, 0x0, 0x5, 0x4, 0x6, 0x7 }
+perm [15]= { 0xE, 0xF, 0xD, 0xC, 0x9, 0x8, 0xA, 0xB, 0x1, 0x0, 0x2, 0x3, 0x6, 0x7, 0x5, 0x4 }
+perm [16]= { 0xF, 0xE, 0xC, 0xD, 0x8, 0x9, 0xB, 0xA, 0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5 }
+
+local shifts = {}
+shifts[1]= { 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1, 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE }
+shifts[2]= { 0x4, 0xB, 0xB, 0x4, 0xB, 0x4, 0x4, 0xB, 0xA, 0x5, 0x5, 0xA, 0x5, 0xA, 0xA, 0x5 }
+shifts[3]= { 0xB, 0x6, 0x0, 0xD, 0xD, 0x0, 0x6, 0xB, 0x6, 0xB, 0xD, 0x0, 0x0, 0xD, 0xB, 0x6 }
+shifts[4]= { 0xE, 0x5, 0x9, 0x2, 0x0, 0xB, 0x7, 0xC, 0x3, 0x8, 0x4, 0xF, 0xD, 0x6, 0xA, 0x1 }
+shifts[5]= { 0x4, 0xE, 0x1, 0xB, 0xF, 0x5, 0xA, 0x0, 0x3, 0x9, 0x6, 0xC, 0x8, 0x2, 0xD, 0x7 }
+shifts[6]= { 0xA, 0x4, 0x7, 0x9, 0x0, 0xE, 0xD, 0x3, 0xE, 0x0, 0x3, 0xD, 0x4, 0xA, 0x9, 0x7 }
+shifts[7]= { 0xE, 0x6, 0xE, 0x6, 0xF, 0x7, 0xF, 0x7, 0xD, 0x5, 0xD, 0x5, 0xC, 0x4, 0xC, 0x4 }
+shifts[8]= { 0x7, 0x1, 0xB, 0xD, 0xE, 0x8, 0x2, 0x4, 0x4, 0x2, 0x8, 0xE, 0xD, 0xB, 0x1, 0x7 }
+shifts[9]= { 0xD, 0xB, 0x0, 0x6, 0x6, 0x0, 0xB, 0xD, 0xA, 0xC, 0x7, 0x1, 0x1, 0x7, 0xC, 0xA }
+shifts[10]= { 0xe, 0x1, 0x1, 0xe, 0x1, 0xe, 0xe, 0x1, 0x1, 0xe, 0xe, 0x1, 0xe, 0x1, 0x1, 0xe }
+
+local function ApplyPermutationAndShifts( pos, value, nibble)
+       local shiftbytes = shifts[pos]
+       local shiftElem = shiftbytes[nibble+1] --one indexed
+       local shiftOne = shiftbytes[1]
+       local rs = bit32.bxor(value, bit32.bxor(shiftOne, shiftElem))
+       return rs
+end
+
+local function GetOne( uid, block )
+
+       if uid == nil then return nil, 'empty uid string' end
+       if #uid == 0 then return nil, 'empty uid string' end
+       if #uid ~= 8 then return nil, 'uid wrong length. Should be 4 hex bytes' end
+       if type(block) ~= 'number' then return nil, 'block is not number' end
+       if  block > 16 or block < 0 then return nil, 'block is out-of-range' end
+       
+       local s = ('%s%02X'):format(uid,block)
+       local nibble1 = tonumber(s:sub(1,1),16) + 1
+
+       local permuted = ''
+       for i = 1, #s do                
+               local el_row = shifts[i]
+               local el_value = el_row[nibble1] 
+               j = 1
+               while j <= i do
+                       if  i-j > 0 then 
+                               local nibble = tonumber(s:sub(j+1,j+1),16) 
+                               el_value = ApplyPermutationAndShifts(i-j, el_value, nibble)
+                       end
+                       j = j+1
+               end 
+               permuted =('%s%X'):format(permuted,el_value)
+       end     
+
+       permuted = 'C2'..permuted
+       local crc64numStr = utils.Crc64(permuted)
+       local keybytes = utils.ConvertAsciiToBytes(crc64numStr, true)
+       local key = utils.ConvertBytesToHex(keybytes) 
+       return key:sub(1,12)
+end
+
+local PreCalc = 
+{
+       GetAll = function(id)
+               if id == nil then return nil, 'empty string' end
+               if #id == 0 then return nil, 'empty string' end
+               if #id ~= 8 then return nil, 'wrong length. Should be 4 hex bytes' end
+               
+               local list = '4b0b20107ccb'
+               for i = 1,15 do
+                       local key, err  = GetOne(id,i)
+                       if not key then return oops(err) end
+                       list = list..key
+               end
+               return list
+       end,
+}
+return PreCalc
\ No newline at end of file
index 10e7c2d4a929b05ba29c9e32e841f569e9d0a8c6..943a1722426d10fa8c951ebba6df0b57b458d7a2 100644 (file)
@@ -20,7 +20,9 @@ local ISO14A_COMMAND = {
        ISO14A_RAW = 8,
        ISO14A_REQUEST_TRIGGER = 0x10,
        ISO14A_APPEND_CRC = 0x20,
-       ISO14A_SET_TIMEOUT = 0x40
+       ISO14A_SET_TIMEOUT = 0x40,
+       ISO14A_NO_SELECT = 0x80,
+       ISO14A_TOPAZMODE = 0x100
 }
 
 local ISO14443a_TYPES = {}             
index c5baa406955d067012d525e9b57c8bf9cc525a42..a968fde2a90c3b2218b6e67aa005bdeec7486db6 100644 (file)
@@ -71,8 +71,8 @@ local Utils =
                return outResults\r
        end,\r
        \r
-       ------------ CRC-16 ccitt checksums\r
        \r
+       ------------ CRC-16 ccitt checksums\r
        -- Takes a hex string and calculates a crc16\r
        Crc16 = function(s)\r
                if s == nil then return nil end\r
@@ -85,7 +85,22 @@ local Utils =
                end\r
                return nil\r
        end,\r
-\r
+       \r
+       ------------ CRC-64 ecma checksums\r
+       -- Takes a hex string and calculates a crc64 ecma\r
+       Crc64 = function(s)\r
+               if s == nil then return nil end\r
+               if #s == 0 then return nil end\r
+               if  type(s) == 'string' then\r
+                       local utils = require('utils')\r
+                       local asc = utils.ConvertHexToAscii(s)\r
+                       local hash = core.crc64(asc)\r
+                       return hash\r
+               end\r
+               return nil\r
+       end,\r
+       \r
+       \r
        -- input parameter is a string\r
        -- Swaps the endianess and returns a number,  \r
        -- IE:  'cd7a' -> '7acd'  -> 0x7acd\r
@@ -135,7 +150,7 @@ local Utils =
                while IN>0 do\r
                        I=I+1\r
                        IN , D = math.floor(IN/B), math.modf(IN,B)+1\r
-                       OUT=string.sub(K,D,D)..OUT\r
+                       OUT = string.sub(K,D,D)..OUT\r
                end\r
                return OUT\r
        end,\r
@@ -147,7 +162,7 @@ local Utils =
                end\r
                local s={}\r
                for i = 1, #(bytes) do\r
-                       s[i] =   string.format("%02X",bytes[i]) \r
+                       s[i] = string.format("%02X",bytes[i]) \r
                end\r
                return table.concat(s)\r
        end,    \r
@@ -171,16 +186,28 @@ local Utils =
                end\r
                return t\r
        end,\r
-       ConvertAsciiToBytes = function(s)\r
-               local t={}\r
+       ConvertAsciiToBytes = function(s, reverse)\r
+               local t = {}\r
                if s == nil then return t end\r
                if #s == 0 then return t end\r
                \r
                for k in s:gmatch"(.)" do\r
                        table.insert(t, string.byte(k))\r
                end\r
-               return t\r
+               \r
+               if not reverse then\r
+                       return t\r
+               end\r
+       \r
+               local rev = {}\r
+               if reverse then\r
+                       for i = #t, 1,-1 do\r
+                               table.insert(rev, t[i] )\r
+                       end\r
+               end\r
+               return rev\r
        end,\r
+       \r
        ConvertHexToAscii = function(s)\r
                local t={}\r
                if s == nil then return t end\r
@@ -191,6 +218,30 @@ local Utils =
                return  table.concat(t) \r
        end,\r
        \r
+       Chars2num = function(s)\r
+        return (s:byte(1)*16777216)+(s:byte(2)*65536)+(s:byte(3)*256)+(s:byte(4))\r
+       end,\r
+       \r
+       -- use length of string to determine 8,16,32,64 bits\r
+       bytes_to_int = function(str,endian,signed) \r
+               local t={str:byte(1,-1)}\r
+               if endian=="big" then --reverse bytes\r
+                       local tt={}\r
+                       for k=1,#t do\r
+                               tt[#t-k+1]=t[k]\r
+                       end\r
+                       t=tt\r
+               end\r
+               local n=0\r
+               for k=1,#t do\r
+                       n=n+t[k]*2^((k-1)*8)\r
+               end\r
+               if signed then\r
+                       n = (n > 2^(#t*8-1) -1) and (n - 2^(#t*8)) or n -- if last bit set, negative.\r
+               end\r
+               return n\r
+       end,\r
+       \r
        -- function convertStringToBytes(str)\r
        -- local bytes = {}\r
        -- local strLength = string.len(str)\r
index 35499b83677e18129e2278221ed865edbc52f32a..237979c1bfaaefc13ca0940093c2a47d5b954f40 100644 (file)
@@ -354,10 +354,7 @@ int loadTraceCard(uint8_t *tuid) {
        FillFileNameByUID(traceFileName, tuid, ".eml", 7);\r
 \r
        f = fopen(traceFileName, "r");\r
-       if (!f) {\r
-               fclose(f);\r
-               return 1;\r
-       }\r
+       if (!f) return 1;\r
        \r
        blockNum = 0;\r
                \r
@@ -394,10 +391,7 @@ int saveTraceCard(void) {
        if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;\r
        \r
        f = fopen(traceFileName, "w+");\r
-       if ( !f ) {\r
-               fclose(f);\r
-               return 1;\r
-       }\r
+       if ( !f ) return 1;\r
        \r
        for (int i = 0; i < 64; i++) {  // blocks\r
                for (int j = 0; j < 16; j++)  // bytes\r
index d7f51c234ea0b5751ca2e82f28fe8e77ec771246..152fd9d44335236ffe3def9237d3bb38eccb68b3 100644 (file)
@@ -19,6 +19,7 @@
 #include "nonce2key/nonce2key.h"
 #include "../common/iso15693tools.h"
 #include "../common/crc16.h"
+#include "../common/crc64.h"
 #include "aes.h"
 /**
  * The following params expected:
  */
 static int l_SendCommand(lua_State *L){
 
-    /*
-     *
-     The SendCommand (native) expects the following structure:
-
-     typedef struct {
-      uint64_t cmd; //8 bytes
-      uint64_t arg[3]; // 8*3 bytes = 24 bytes
-      union {
-        uint8_t  asBytes[USB_CMD_DATA_SIZE]; // 1 byte * 512 = 512 bytes (OR)
-        uint32_t asDwords[USB_CMD_DATA_SIZE/4]; // 4 byte * 128 = 512 bytes
-      } d;
-    } PACKED UsbCommand;
-
-    ==> A 544 byte buffer will do.
-    **/
-    //Pop cmd
-    size_t size;
-    const char *data = luaL_checklstring(L, 1, &size);
-    if(size != sizeof(UsbCommand))
-    {
-        printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand));
-        lua_pushstring(L,"Wrong data size");
-        return 1;
-    }
+       /*
+        *
+        The SendCommand (native) expects the following structure:
+
+        typedef struct {
+         uint64_t cmd; //8 bytes
+         uint64_t arg[3]; // 8*3 bytes = 24 bytes
+         union {
+               uint8_t  asBytes[USB_CMD_DATA_SIZE]; // 1 byte * 512 = 512 bytes (OR)
+               uint32_t asDwords[USB_CMD_DATA_SIZE/4]; // 4 byte * 128 = 512 bytes
+         } d;
+       } PACKED UsbCommand;
+
+       ==> A 544 byte buffer will do.
+       **/
+       //Pop cmd
+       size_t size;
+       const char *data = luaL_checklstring(L, 1, &size);
+       if(size != sizeof(UsbCommand))
+       {
+               printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand));
+               lua_pushstring(L,"Wrong data size");
+               return 1;
+       }
 
 //    UsbCommand c = (*data);
-    SendCommand((UsbCommand* )data);
-    return 0; // no return values
+       SendCommand((UsbCommand* )data);
+       return 0; // no return values
 }
 /**
  * @brief The following params expected:
@@ -67,105 +68,105 @@ static int l_SendCommand(lua_State *L){
  */
 static int l_WaitForResponseTimeout(lua_State *L){
 
-    uint32_t cmd = 0;
-    size_t ms_timeout = -1;
-
-    //Check number of arguments
-    int n = lua_gettop(L);
-    if(n == 0)
-    {
-        //signal error by returning Nil, errorstring
-        lua_pushnil(L);
-        lua_pushstring(L,"You need to supply at least command to wait for");
-        return 2; // two return values
-    }
-    if(n >= 1)
-    {
-        //pop cmd
-        cmd = luaL_checkunsigned(L,1);
-    }
-    if(n >= 2)
-    {
-        //Did the user send a timeout ?
-        //Check if the current top of stack is an integer
-        ms_timeout = luaL_checkunsigned(L,2);
-        //printf("Timeout set to %dms\n" , (int) ms_timeout);
-    }
-
-    UsbCommand response;
-
-    if(WaitForResponseTimeout(cmd, &response, ms_timeout))
-    {
-        //Push it as a string
-         lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand));
-
-        return 1;// return 1 to signal one return value
-    }else{
-        //Push a Nil instead
-        lua_pushnil(L);
-        return 1;// one return value
-    }
+       uint32_t cmd = 0;
+       size_t ms_timeout = -1;
+
+       //Check number of arguments
+       int n = lua_gettop(L);
+       if(n == 0)
+       {
+               //signal error by returning Nil, errorstring
+               lua_pushnil(L);
+               lua_pushstring(L,"You need to supply at least command to wait for");
+               return 2; // two return values
+       }
+       if(n >= 1)
+       {
+               //pop cmd
+               cmd = luaL_checkunsigned(L,1);
+       }
+       if(n >= 2)
+       {
+               //Did the user send a timeout ?
+               //Check if the current top of stack is an integer
+               ms_timeout = luaL_checkunsigned(L,2);
+               //printf("Timeout set to %dms\n" , (int) ms_timeout);
+       }
+
+       UsbCommand response;
+
+       if(WaitForResponseTimeout(cmd, &response, ms_timeout))
+       {
+               //Push it as a string
+               lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand));
+
+               return 1;// return 1 to signal one return value
+       }else{
+               //Push a Nil instead
+               lua_pushnil(L);
+               return 1;// one return value
+       }
 }
 
 static int returnToLuaWithError(lua_State *L, const char* fmt, ...)
 {
-    char buffer[200];
-    va_list args;
-    va_start(args,fmt);
-    vsnprintf(buffer, sizeof(buffer), fmt,args);
-    va_end(args);
-
-    lua_pushnil(L);
-    lua_pushstring(L,buffer);
-    return 2;
+       char buffer[200];
+       va_list args;
+       va_start(args,fmt);
+       vsnprintf(buffer, sizeof(buffer), fmt,args);
+       va_end(args);
+
+       lua_pushnil(L);
+       lua_pushstring(L,buffer);
+       return 2;
 }
 
 static int l_nonce2key(lua_State *L){
 
-    size_t size;
-    const char *p_uid = luaL_checklstring(L, 1, &size);
-    if(size != 4)  return returnToLuaWithError(L,"Wrong size of uid, got %d bytes, expected 4", (int) size);
+       size_t size;
+       const char *p_uid = luaL_checklstring(L, 1, &size);
+       if(size != 4)  return returnToLuaWithError(L,"Wrong size of uid, got %d bytes, expected 4", (int) size);
+
+       const char *p_nt = luaL_checklstring(L, 2, &size);
+       if(size != 4)  return returnToLuaWithError(L,"Wrong size of nt, got %d bytes, expected 4", (int) size);
 
-    const char *p_nt = luaL_checklstring(L, 2, &size);
-    if(size != 4)  return returnToLuaWithError(L,"Wrong size of nt, got %d bytes, expected 4", (int) size);
+       const char *p_nr = luaL_checklstring(L, 3, &size);
+       if(size != 4)  return returnToLuaWithError(L,"Wrong size of nr, got %d bytes, expected 4", (int) size);
 
-    const char *p_nr = luaL_checklstring(L, 3, &size);
-    if(size != 4)  return returnToLuaWithError(L,"Wrong size of nr, got %d bytes, expected 4", (int) size);
+       const char *p_par_info = luaL_checklstring(L, 4, &size);
+       if(size != 8)  return returnToLuaWithError(L,"Wrong size of par_info, got %d bytes, expected 8", (int) size);
 
-    const char *p_par_info = luaL_checklstring(L, 4, &size);
-    if(size != 8)  return returnToLuaWithError(L,"Wrong size of par_info, got %d bytes, expected 8", (int) size);
+       const char *p_pks_info = luaL_checklstring(L, 5, &size);
+       if(size != 8)  return returnToLuaWithError(L,"Wrong size of ks_info, got %d bytes, expected 8", (int) size);
 
-    const char *p_pks_info = luaL_checklstring(L, 5, &size);
-    if(size != 8)  return returnToLuaWithError(L,"Wrong size of ks_info, got %d bytes, expected 8", (int) size);
 
+       uint32_t uid = bytes_to_num(( uint8_t *)p_uid,4);
+       uint32_t nt = bytes_to_num(( uint8_t *)p_nt,4);
 
-    uint32_t uid = bytes_to_num(( uint8_t *)p_uid,4);
-    uint32_t nt = bytes_to_num(( uint8_t *)p_nt,4);
+       uint32_t nr = bytes_to_num(( uint8_t*)p_nr,4);
+       uint64_t par_info = bytes_to_num(( uint8_t *)p_par_info,8);
+       uint64_t ks_info = bytes_to_num(( uint8_t *)p_pks_info,8);
 
-    uint32_t nr = bytes_to_num(( uint8_t*)p_nr,4);
-    uint64_t par_info = bytes_to_num(( uint8_t *)p_par_info,8);
-    uint64_t ks_info = bytes_to_num(( uint8_t *)p_pks_info,8);
+       uint64_t key = 0;
 
-    uint64_t key = 0;
+       int retval = nonce2key(uid,nt, nr, par_info,ks_info, &key);
 
-    int retval = nonce2key(uid,nt, nr, par_info,ks_info, &key);
+       //Push the retval on the stack
+       lua_pushinteger(L,retval);
 
-    //Push the retval on the stack
-    lua_pushinteger(L,retval);
-  
-    //Push the key onto the stack
-    uint8_t dest_key[8];
-    num_to_bytes(key,sizeof(dest_key),dest_key);
+       //Push the key onto the stack
+       uint8_t dest_key[8];
+       num_to_bytes(key,sizeof(dest_key),dest_key);
 
-    //printf("Pushing to lua stack: %012"llx"\n",key);
-    lua_pushlstring(L,(const char *) dest_key,sizeof(dest_key));
+       //printf("Pushing to lua stack: %012"llx"\n",key);
+       lua_pushlstring(L,(const char *) dest_key,sizeof(dest_key));
 
-    return 2; //Two return values
+       return 2; //Two return values
 }
 //static int l_PrintAndLog(lua_State *L){ return CmdHF14AMfDump(luaL_checkstring(L, 1));}
 static int l_clearCommandBuffer(lua_State *L){
-    clearCommandBuffer();
-    return 0;
+       clearCommandBuffer();
+       return 0;
 }
 /**
  * @brief l_foobar is a dummy function to test lua-integration with
@@ -174,23 +175,23 @@ static int l_clearCommandBuffer(lua_State *L){
  */
 static int l_foobar(lua_State *L)
 {
-    //Check number of arguments
-    int n = lua_gettop(L);
-    printf("foobar called with %d arguments" , n);
-    lua_settop(L, 0);
-    printf("Arguments discarded, stack now contains %d elements", lua_gettop(L));
-  
-    // todo: this is not used, where was it intended for?
-    // UsbCommand response =  {CMD_MIFARE_READBL, {1337, 1338, 1339}};
-  
-    printf("Now returning a uint64_t as a string");
-    uint64_t x = 0xDEADBEEF;
-    uint8_t destination[8];
-    num_to_bytes(x,sizeof(x),destination);
-    lua_pushlstring(L,(const char *)&x,sizeof(x));
-    lua_pushlstring(L,(const char *)destination,sizeof(destination));
-
-    return 2;
+       //Check number of arguments
+       int n = lua_gettop(L);
+       printf("foobar called with %d arguments" , n);
+       lua_settop(L, 0);
+       printf("Arguments discarded, stack now contains %d elements", lua_gettop(L));
+
+       // todo: this is not used, where was it intended for?
+       // UsbCommand response =  {CMD_MIFARE_READBL, {1337, 1338, 1339}};
+
+       printf("Now returning a uint64_t as a string");
+       uint64_t x = 0xDEADBEEF;
+       uint8_t destination[8];
+       num_to_bytes(x,sizeof(x),destination);
+       lua_pushlstring(L,(const char *)&x,sizeof(x));
+       lua_pushlstring(L,(const char *)destination,sizeof(destination));
+
+       return 2;
 }
 
 
@@ -201,8 +202,8 @@ static int l_foobar(lua_State *L)
  */
 static int l_ukbhit(lua_State *L)
 {
-    lua_pushboolean(L,ukbhit() ? true : false);
-    return 1;
+       lua_pushboolean(L,ukbhit() ? true : false);
+       return 1;
 }
 /**
  * @brief Calls the command line parser to deal with the command. This enables
@@ -212,58 +213,78 @@ static int l_ukbhit(lua_State *L)
  */
 static int l_CmdConsole(lua_State *L)
 {
-    CommandReceived((char *)luaL_checkstring(L, 1));
-    return 0;
+       CommandReceived((char *)luaL_checkstring(L, 1));
+       return 0;
 }
 
 static int l_iso15693_crc(lua_State *L)
 {
-    //    uint16_t Iso15693Crc(uint8_t *v, int n);
-    size_t size;
-    const char *v = luaL_checklstring(L, 1, &size);
-    uint16_t retval = Iso15693Crc((uint8_t *) v, size);
-    lua_pushinteger(L, (int) retval);
-    return 1;
+       //    uint16_t Iso15693Crc(uint8_t *v, int n);
+       size_t size;
+       const char *v = luaL_checklstring(L, 1, &size);
+       uint16_t retval = Iso15693Crc((uint8_t *) v, size);
+       lua_pushinteger(L, (int) retval);
+       return 1;
 }
 
 /*
  Simple AES 128 cbc hook up to OpenSSL.
  params:  key, input
 */
-static int l_aes(lua_State *L)
+static int l_aes128decrypt(lua_State *L)
 {
        //Check number of arguments
        int i;
-    size_t size;
-    const char *p_key = luaL_checklstring(L, 1, &size);
-    if(size != 32)  return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
+       size_t size;
+       const char *p_key = luaL_checklstring(L, 1, &size);
+       if(size != 32)  return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
+
+       const char *p_encTxt = luaL_checklstring(L, 2, &size);
 
-    const char *p_encTxt = luaL_checklstring(L, 2, &size);
-    
        unsigned char indata[16] = {0x00};
        unsigned char outdata[16] = {0x00};
-    unsigned char aes_key[16] = {0x00};
+       unsigned char aes_key[16] = {0x00};
        unsigned char iv[16] = {0x00};
-       
-       // convert key to bytearray
+
+       // convert key to bytearray and convert input to bytearray
        for (i = 0; i < 32; i += 2) {
                sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]);
+               sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
        }
+
+       aes_context ctx;
+       aes_init(&ctx);
+       aes_setkey_dec(&ctx, aes_key, 128);
+       aes_crypt_cbc(&ctx,AES_DECRYPT,sizeof(indata), iv, indata,outdata );
+       //Push decrypted array as a string
+       lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
+       return 1;// return 1 to signal one return value
+}
+static int l_aes128encrypt(lua_State *L)
+{
+       //Check number of arguments
+       int i;
+       size_t size;
+       const char *p_key = luaL_checklstring(L, 1, &size);
+       if(size != 32)  return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
+
+       const char *p_txt = luaL_checklstring(L, 2, &size);
+
+       unsigned char indata[16] = {0x00};
+       unsigned char outdata[16] = {0x00};
+       unsigned char aes_key[16] = {0x00};
+       unsigned char iv[16] = {0x00};
        
-       // convert input to bytearray
        for (i = 0; i < 32; i += 2) {
+               sscanf(&p_txt[i], "%02x", (unsigned int *)&indata[i / 2]);
                sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
        }
-       
-       //AES_KEY key;
-    //AES_set_decrypt_key(aes_key, 128, &key);
-    //AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
 
-    aes_context ctx;
-    aes_init(&ctx);
-    aes_setkey_dec(&ctx, aes_key, 128);
-       aes_crypt_cbc(&ctx,AES_DECRYPT,sizeof(indata), iv, indata,outdata );
-    //Push decrypted array as a string
+       aes_context ctx;
+       aes_init(&ctx);
+       aes_setkey_enc(&ctx, aes_key, 128);
+       aes_crypt_cbc(&ctx, AES_ENCRYPT, sizeof(indata), iv, indata, outdata );
+       //Push encrypted array as a string
        lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
        return 1;// return 1 to signal one return value
 }
@@ -272,10 +293,32 @@ static int l_crc16(lua_State *L)
 {
        size_t size;
        const char *p_str = luaL_checklstring(L, 1, &size);
-               
+
        uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size);
-    lua_pushinteger(L, (int) retval);
-    return 1;
+       lua_pushinteger(L, (int) retval);
+       return 1;
+}
+
+static int l_crc64(lua_State *L)
+{
+       size_t size;
+       uint64_t crc = 0; 
+       unsigned char outdata[8] = {0x00};
+
+       const char *p_str = luaL_checklstring(L, 1, &size);
+
+       crc64( (uint8_t*) p_str, size, &crc);
+
+       outdata[0] = (uint8_t)(crc >> 56) & 0xff;
+       outdata[1] = (uint8_t)(crc >> 48) & 0xff;
+       outdata[2] = (uint8_t)(crc >> 40) & 0xff;
+       outdata[3] = (uint8_t)(crc >> 32) & 0xff;
+       outdata[4] = (uint8_t)(crc >> 24) & 0xff;
+       outdata[5] = (uint8_t)(crc >> 16) & 0xff;
+       outdata[6] = (uint8_t)(crc >> 8) & 0xff;
+       outdata[7] = crc & 0xff;
+       lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
+       return 1;
 }
 
 /**
@@ -288,57 +331,60 @@ static int l_crc16(lua_State *L)
  */
 int setLuaPath( lua_State* L, const char* path )
 {
-    lua_getglobal( L, "package" );
-    lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1)
-    const char* cur_path = lua_tostring( L, -1 ); // grab path string from top of stack
-    int requiredLength = strlen(cur_path)+ strlen(path)+10; //A few bytes too many, whatever we can afford it
-    char * buf = malloc(requiredLength);
-    snprintf(buf, requiredLength, "%s;%s", cur_path, path);
-    lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5
-    lua_pushstring( L, buf ); // push the new one
-    lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack
-    lua_pop( L, 1 ); // get rid of package table from top of stack
-    return 0; // all done!
+       lua_getglobal( L, "package" );
+       lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1)
+       const char* cur_path = lua_tostring( L, -1 ); // grab path string from top of stack
+       int requiredLength = strlen(cur_path)+ strlen(path)+10; //A few bytes too many, whatever we can afford it
+       char * buf = malloc(requiredLength);
+       snprintf(buf, requiredLength, "%s;%s", cur_path, path);
+       lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5
+       lua_pushstring( L, buf ); // push the new one
+       lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack
+       lua_pop( L, 1 ); // get rid of package table from top of stack
+       free(buf);
+       return 0; // all done!
 }
 
 
 int set_pm3_libraries(lua_State *L)
 {
 
-    static const luaL_Reg libs[] = {
-        {"SendCommand",                 l_SendCommand},
-        {"WaitForResponseTimeout",      l_WaitForResponseTimeout},
-        {"nonce2key",                   l_nonce2key},
-        //{"PrintAndLog",                 l_PrintAndLog},
-        {"foobar",                      l_foobar},
-        {"ukbhit",                      l_ukbhit},
-        {"clearCommandBuffer",          l_clearCommandBuffer},
-        {"console",                      l_CmdConsole},
-        {"iso15693_crc",                 l_iso15693_crc},
-               {"aes",                         l_aes},
+       static const luaL_Reg libs[] = {
+               {"SendCommand",                 l_SendCommand},
+               {"WaitForResponseTimeout",      l_WaitForResponseTimeout},
+               {"nonce2key",                   l_nonce2key},
+               //{"PrintAndLog",                 l_PrintAndLog},
+               {"foobar",                      l_foobar},
+               {"ukbhit",                      l_ukbhit},
+               {"clearCommandBuffer",          l_clearCommandBuffer},
+               {"console",                     l_CmdConsole},
+               {"iso15693_crc",                l_iso15693_crc},
+               {"aes128_decrypt",              l_aes128decrypt},
+               {"aes128_encrypt",              l_aes128encrypt},
                {"crc16",                       l_crc16},
-        {NULL, NULL}
-    };
-
-    lua_pushglobaltable(L);
-    // Core library is in this table. Contains '
-    //this is 'pm3' table
-    lua_newtable(L);
-
-    //Put the function into the hash table.
-    for (int i = 0; libs[i].name; i++) {
-        lua_pushcfunction(L, libs[i].func);
-        lua_setfield(L, -2, libs[i].name);//set the name, pop stack
-    }
-    //Name of 'core'
-    lua_setfield(L, -2, "core");
-
-    //-- remove the global environment table from the stack
-    lua_pop(L, 1);
-
-    //-- Last but not least, add to the LUA_PATH (package.path in lua)
-    // so we can load libraries from the ./lualib/ - directory
-    setLuaPath(L,"./lualibs/?.lua");
-
-    return 1;
+               {"crc64",                       l_crc64},
+               {NULL, NULL}
+       };
+
+       lua_pushglobaltable(L);
+       // Core library is in this table. Contains '
+       //this is 'pm3' table
+       lua_newtable(L);
+
+       //Put the function into the hash table.
+       for (int i = 0; libs[i].name; i++) {
+               lua_pushcfunction(L, libs[i].func);
+               lua_setfield(L, -2, libs[i].name);//set the name, pop stack
+       }
+       //Name of 'core'
+       lua_setfield(L, -2, "core");
+
+       //-- remove the global environment table from the stack
+       lua_pop(L, 1);
+
+       //-- Last but not least, add to the LUA_PATH (package.path in lua)
+       // so we can load libraries from the ./lualib/ - directory
+       setLuaPath(L,"./lualibs/?.lua");
+
+       return 1;
 }
index 0d735e98f72a7ce4d3c099fbfe916894cdca92a9..66a61fba9005f29555ae38904470e223bfa5dafb 100644 (file)
@@ -80,14 +80,14 @@ function GetCardInfo()
 \r
        core.clearCommandBuffer()\r
        \r
-       if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k\r
+       if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k\r
                -- IFARE Classic 4K offers 4096 bytes split into forty sectors, \r
                -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. \r
                numSectors = 40\r
-       elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k\r
+       elseif 0x08 == result.sak then  -- NXP MIFARE CLASSIC 1k | Plus 2k\r
                -- 1K offers 1024 bytes of data storage, split into 16 sector\r
                numSectors = 16\r
-       elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k\r
+       elseif 0x09 == result.sak then  -- NXP MIFARE Mini 0.3k\r
                -- MIFARE Classic mini offers 320 bytes split into five sectors.\r
                numSectors = 5\r
        elseif  0x10 == result.sak then -- NXP MIFARE Plus 2k\r
index 6c4a148c2e25b57cee40aa5444c4a325cfc60164..e87c338ea07e36d559d71d1d6a8ae9e392075c65 100644 (file)
@@ -13,6 +13,7 @@ local band = bit32.band
 example =[[
        script run tnp3clone
        script run tnp3clone -h
+       script run tnp3clone -l
        script run tnp3clone -t aa00 -s 0030
 
 ]]
@@ -23,7 +24,8 @@ This script will try making a barebone clone of a tnp3 tag on to a magic generat
 
 Arguments:
        -h             : this help
-       -t <data>      : toytype id, 4hex symbols.
+       -l             : list all known toy tokens
+       -t <data>      : toytype id, 4hex symbols
        -s <data>      : subtype id, 4hex symbols               
        
        For fun,  try the following subtype id: 
@@ -32,7 +34,7 @@ Arguments:
        0138 - Series 2
        0234 - Special
        023c - Special
-       
+       0020 - Swapforce
 ]]
 
 
@@ -74,7 +76,7 @@ local function readmagicblock( blocknum )
        -- Read block 0
        local CSETBLOCK_SINGLE_OPERATION = 0x1F
        cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum}
-       err = core.SendCommand(cmd:getBytes())
+       err = core.SendCommand(cmd:getBytes())
        if err then return nil, err end
        local block0, err = waitCmd()
        if err then return nil, err end
@@ -98,12 +100,13 @@ local function main(args)
        local DEBUG = true
        
        -- Arguments for the script
-       for o, a in getopt.getopt(args, 'ht:s:') do
+       for o, a in getopt.getopt(args, 'ht:s:l') do
                if o == "h" then return help() end              
                if o == "t" then toytype = a end
                if o == "s" then subtype = a end
+               if o == "l" then return toys.List() end
        end
-       
+
        if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end   
        if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end   
 
@@ -139,8 +142,9 @@ local function main(args)
        -- wipe card.
        local cmd  = (csetuid..'%s 0004 08 w'):format(result.uid)       
        core.console(cmd) 
+
+       local b1 = toytype..string.rep('00',10)..subtype
        
-       local b1 = toytype..'00000000000000000000'..subtype
        local calc = utils.Crc16(b0..b1)
        local calcEndian = bor(rsh(calc,8), lsh(band(calc, 0xff), 8))
        
index cd547e8adf2225987a5a1a2abbbd36acf78d7b6a..211d146fd1c4da89d200ea05d568cb1a3f0a1fa6 100644 (file)
@@ -205,18 +205,19 @@ local function main(args)
                
                        if blockNo < 8 then
                                -- Block 0-7 not encrypted
-                               blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                               blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata)
                        else
                                -- blocks with zero not encrypted.
                                if string.find(blockdata, '^0+$') then
-                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata)
                                else
                                        local baseStr = utils.ConvertHexToAscii(tmpHash:format(blockNo))
                                        local key = md5.sumhexa(baseStr)
                                        local aestest = core.aes128_decrypt(key, blockdata)
-                                       local hex = utils.ConvertAsciiToBytes(aestest)                                  
+                                       local hex = utils.ConvertAsciiToBytes(aestest)
                                        hex = utils.ConvertBytesToHex(hex)
-                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,hex)                                 
+                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,hex)
+                                       io.write(blockNo..',')
                                end             
                        end
                else
@@ -273,5 +274,7 @@ local function main(args)
        print( ('                  UID : 0x%s'):format(uid) )
        print( ('               CARDID : 0x%s'):format(cardid ) )
        print( string.rep('--',20) )
+       
+       core.clearCommandBuffer()
 end
 main(args)
\ No newline at end of file
index af3d2d4cfeb5a060bd4df6a36e0771b43948c4bf..4e10eb75382ac8b4e05f54b2648fb2eb58dd409f 100644 (file)
@@ -23,10 +23,22 @@ Arguments:
        -h             : this help
        -m             : Maxed out items (experimental)
        -i             : filename for the datadump to read (bin)
-]]
+
+       ]]
 
 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
-local DEBUG = true -- the debug flag
+local DEBUG = false -- the debug flag
+local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+
+local band = bit32.band
+local bor = bit32.bor
+local lshift = bit32.lshift
+local rshift = bit32.rshift
+local byte = string.byte
+local char = string.char
+local sub = string.sub
+local format = string.format
+
 
 
 local band = bit32.band
@@ -197,8 +209,6 @@ local function ValidateCheckSums(blocks)
        io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
 end
 
-local function LoadEmulator(blocks)
-       local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
        local cmd
        local blockdata
        for _,b in pairs(blocks) do 
@@ -207,10 +217,10 @@ local function LoadEmulator(blocks)
                
                if  _%4 ~= 3 then
                        if (_ >= 8 and _<=21)  or  (_ >= 36 and _<=49) then
-                               local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT)      
+                               local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , RANDOM)    
                                local baseStr = utils.ConvertHexToAscii(base)
                                local key = md5.sumhexa(baseStr)
-                               local enc = core.aes(key, blockdata)
+                               local enc = core.aes128_encrypt(key, blockdata)
                                local hex = utils.ConvertAsciiToBytes(enc)
                                hex = utils.ConvertBytesToHex(hex)
                        
@@ -346,21 +356,6 @@ local function main(args)
        local cmdSetDbgOff = "hf mf dbg 0"
        core.console( cmdSetDbgOff) 
        
-       -- if not loadFromDump then
-               -- -- Look for tag present on reader,
-               -- result, err = lib14a.read1443a(false)
-               -- if not result then return oops(err)  end
-
-               -- core.clearCommandBuffer()
-       
-               -- if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
-                       -- return oops('This is not a TNP3xxx tag. aborting.')
-               -- end  
-
-               -- -- Show tag info
-               -- print((' Found tag : %s'):format(result.name))
-       -- end
-       
        -- Load dump.bin file
        print( (' Load data from %s'):format(inputTemplate))
        hex, err = utils.ReadDumpFile(inputTemplate)
@@ -374,7 +369,7 @@ local function main(args)
        end
 
        if DEBUG then
-               print('Validating checksums in the loaded datadump')
+               print(' Validating checksums')
                ValidateCheckSums(blocks)
        end
        
@@ -393,7 +388,7 @@ local function main(args)
        local item = toys.Find( toytype, subtype)
        if item then
                local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4])
-               print(' ITEM TYPE :'..itemStr )
+               print(' ITEM TYPE : '..itemStr )
        else
                print( (' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype) )
        end     
@@ -407,12 +402,19 @@ local function main(args)
        print( string.rep('--',20) )
 
 
-       -- lets do something.
-       -- 
+       -- Experience should be:        
        local experience = blocks[8]:sub(1,6)
-       print(('Experience  : %d'):format(utils.SwapEndianness(experience,24)))
+       print(('Experience  : %d'):format(utils.SwapEndianness(experience,16)))
+       
        local money = blocks[8]:sub(7,10)
        print(('Money       : %d'):format(utils.SwapEndianness(money,16)))
+
+       -- 
+       
+       -- Sequence number
+       local seqnum = blocks[8]:sub(18,19)
+       print(('Sequence number : %d'):format( tonumber(seqnum,16)))
+       
        local fairy = blocks[9]:sub(1,8)
        --FD0F = Left, FF0F = Right
        local path = 'not choosen'
@@ -425,6 +427,12 @@ local function main(args)
        
        local hat = blocks[9]:sub(8,11)
        print(('Hat         : %d'):format(utils.SwapEndianness(hat,16)))
+
+       local level = blocks[13]:sub(27,28)
+       print(('LEVEL : %d'):format( tonumber(level,16)))
+       --hälsa: 667 029b  
+       --local health = blocks[]:sub();
+       --print(('Health : %d'):format( tonumber(health,16))
        
        --0x0D    0x29    0x0A    0x02    16-bit hero points value. Maximum 100.
        local heropoints = blocks[13]:sub(20,23)
@@ -434,6 +442,11 @@ local function main(args)
        local challenges = blocks[16]:sub(25,32)
        print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32)))
        
+       -- Character Name
+       local name1 = blocks[10]:sub(1,32)
+       local name2 = blocks[12]:sub(1,32)
+       print('Custom name : '..utils.ConvertHexToAscii(name1..name2))
+       
        if maxed then
                print('Lets try to max out some values')
                -- max out money, experience
index 709e2014911205631f689f1970f19594573d1930..cea9f7d734a81150d1f5536118364552dcbfa807 100644 (file)
@@ -112,6 +112,7 @@ char * sprint_hex(const uint8_t * data, const size_t len) {
        
        int maxLen = ( len > 1024/3) ? 1024/3 : len;
        static char buf[1024];
+       memset(buf, 0x00, 1024);
        char * tmp = buf;
        size_t i;
 
@@ -123,8 +124,9 @@ char * sprint_hex(const uint8_t * data, const size_t len) {
 
 char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks) {
        
-       int maxLen = ( len > 1024) ? 1024 : len;
+       int maxLen = ( len > 1020) ? 1020 : len;
        static char buf[1024];
+       memset(buf, 0x00, 1024);
        char *tmp = buf;
 
        for (size_t i=0; i < maxLen; ++i){
@@ -158,6 +160,22 @@ uint64_t bytes_to_num(uint8_t* src, size_t len)
        return num;
 }
 
+// aa,bb,cc,dd,ee,ff,gg,hh, ii,jj,kk,ll,mm,nn,oo,pp
+// to
+// hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii
+// up to 64 bytes or 512 bits
+uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){
+       static uint8_t buf[64];
+       memset(buf, 0x00, 64);
+       uint8_t *tmp = buf;
+       for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
+               for (size_t i = 0; i < blockSize; i++){
+                       tmp[i+(blockSize*block)] = src[(blockSize-1-i)+(blockSize*block)];
+               }
+       }
+       return tmp;
+}
+
 //assumes little endian
 char * printBits(size_t const size, void const * const ptr)
 {
index a6d0f49f206db2483dd656b8f431689917e0c2c7..f58f64cb47200defd20fb82aa084bebd5dccf18e 100644 (file)
@@ -44,6 +44,7 @@ char * sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t bre
 void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
 uint64_t bytes_to_num(uint8_t* src, size_t len);
 char * printBits(size_t const size, void const * const ptr);
+uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
 
 char param_getchar(const char *line, int paramnum);
 uint8_t param_get8(const char *line, int paramnum);
diff --git a/common/crc64.c b/common/crc64.c
new file mode 100644 (file)
index 0000000..709c64d
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdint.h>
+#include <stddef.h>
+#include "crc64.h"
+
+#define CRC64_ISO_PRESET 0xFFFFFFFFFFFFFFFF
+#define CRC64_ECMA_PRESET 0x0000000000000000
+
+const uint64_t crc64_table[] = {
+                0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
+         0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
+         0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B,
+         0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4,
+         0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A,
+         0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285,
+         0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4,
+         0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B,
+         0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8, 0x0B6BD3C3DBFD506B,
+         0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
+         0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5,
+         0x172F5B3033043EBF, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A,
+         0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584,
+         0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B,
+         0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A,
+         0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5,
+         0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A,
+         0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, 0x16D7A787B7FAA0D6, 0x5427466C1E109645,
+         0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324,
+         0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB,
+         0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75,
+         0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA,
+         0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB,
+         0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87, 0xA07CF2199274CA14,
+         0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144,
+         0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B,
+         0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA,
+         0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425,
+         0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB,
+         0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874,
+         0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15,
+         0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA,
+         0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, 0x731B26172EE619EB, 0x31EBC7FC870C2F78,
+         0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7,
+         0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6,
+         0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19,
+         0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97,
+         0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648,
+         0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA, 0xC5B073890B687329,
+         0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6,
+         0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6,
+         0x73B3727A52B393CC, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879,
+         0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18,
+         0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7,
+         0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149,
+         0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96,
+         0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7,
+         0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, 0x020905D88D03A2BB, 0x40F9E43324E99428,
+         0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57,
+         0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288,
+         0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9,
+         0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36,
+         0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8,
+         0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4, 0xC4E0DB53F3C36767,
+         0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206,
+         0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9,
+         0xE085162AB69D5E3C, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589,
+         0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956,
+         0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37,
+         0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8,
+         0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066,
+         0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9,
+         0x14DEA25F3AF9026D, 0x562E43B4931334FE, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8,
+         0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507
+};
+
+void crc64 (const uint8_t *data, const size_t len, uint64_t *crc) {
+
+       for (size_t i = 0; i < len; i++)
+       {
+               //uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
+               uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
+               *crc = crc64_table[tableIndex] ^ (*crc << 8);
+       }
+}
+
+//suint8_t x =         (c & 0xFF00000000000000 ) >> 56;
\ No newline at end of file
diff --git a/common/crc64.h b/common/crc64.h
new file mode 100644 (file)
index 0000000..e28fba1
--- /dev/null
@@ -0,0 +1,14 @@
+//-----------------------------------------------------------------------------
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// CRC64 ECMA
+//-----------------------------------------------------------------------------
+
+#ifndef __CRC64_H
+#define __CRC64_H
+
+void crc64 (const uint8_t *data, const size_t len, uint64_t *crc) ;
+
+#endif
index 01b738c2b6076ec1fed19d7d47dd2b2033683442..580342728b866ee7f76d3f09537580da1c43c72d 100644 (file)
@@ -123,9 +123,21 @@ NXP/Philips CUSTOM COMMANDS
 #define MIFARE_CMD_RESTORE      0xC2
 #define MIFARE_CMD_TRANSFER     0xB0
 
-#define MIFARE_ULC_WRITE        0xA0
+#define MIFARE_ULC_WRITE        0xA2
+//#define MIFARE_ULC__COMP_WRITE  0xA0
 #define MIFARE_ULC_AUTH_1       0x1A
-#define MIFARE_ULC_AUTH_2        0xAF
+#define MIFARE_ULC_AUTH_2       0xAF
+
+#define MIFARE_ULEV1_AUTH       0x1B
+#define MIFARE_ULEV1_VERSION    0x60
+#define MIFARE_ULEV1_FASTREAD   0x3A
+//#define MIFARE_ULEV1_WRITE      0xA2
+//#define MIFARE_ULEV1_COMP_WRITE 0xA0
+#define MIFARE_ULEV1_READ_CNT   0x39
+#define MIFARE_ULEV1_INCR_CNT   0xA5
+#define MIFARE_ULEV1_READSIG    0x3C
+#define MIFARE_ULEV1_CHECKTEAR  0x3E
+#define MIFARE_ULEV1_VCSL       0x4B
 
 /**
 06 00 = INITIATE
index 62c3d949d2427e934be53fa143c8ad01b45a38de..357395d43f3103eb01a66144648dbd2e97d001e9 100644 (file)
@@ -132,8 +132,8 @@ typedef struct{
 #define CMD_SNOOP_ICLASS                                                  0x0392
 #define CMD_SIMULATE_TAG_ICLASS                                           0x0393
 #define CMD_READER_ICLASS                                                 0x0394
-#define CMD_READER_ICLASS_REPLAY                                                                                 0x0395
-#define CMD_ICLASS_ISO14443A_WRITE                                                                               0x0397
+#define CMD_READER_ICLASS_REPLAY                                          0x0395
+#define CMD_ICLASS_ISO14443A_WRITE                                        0x0397
 #define CMD_ICLASS_EML_MEMSET                                             0x0398
 
 // For measurements of the antenna tuning
@@ -163,20 +163,21 @@ typedef struct{
 #define CMD_MIFARE_NESTED                                                 0x0612
 
 #define CMD_MIFARE_READBL                                                 0x0620
-#define CMD_MIFAREU_READBL                                               0x0720
+#define CMD_MIFAREU_READBL                                                0x0720
 #define CMD_MIFARE_READSC                                                 0x0621
-#define CMD_MIFAREU_READCARD                                             0x0721
+#define CMD_MIFAREU_READCARD                                              0x0721
 #define CMD_MIFARE_WRITEBL                                                0x0622
-#define CMD_MIFAREU_WRITEBL                                                                      0x0722
-#define CMD_MIFAREU_WRITEBL_COMPAT                                                           0x0723
+#define CMD_MIFAREU_WRITEBL                                               0x0722
+#define CMD_MIFAREU_WRITEBL_COMPAT                                        0x0723
 
 #define CMD_MIFARE_CHKKEYS                                                0x0623
 
 #define CMD_MIFARE_SNIFFER                                                0x0630
 //ultralightC
-#define CMD_MIFAREUC_AUTH1                                                                       0x0724
-#define CMD_MIFAREUC_AUTH2                                                                       0x0725
-#define CMD_MIFAREUC_READCARD                                                                0x0726
+#define CMD_MIFAREUC_AUTH                                                 0x0724
+//0x0725 and 0x0726 no longer used 
+#define CMD_MIFAREUC_SETPWD                                               0x0727
+
 
 // mifare desfire
 #define CMD_MIFARE_DESFIRE_READBL                                         0x0728
@@ -199,10 +200,11 @@ typedef struct{
 
 //Iclass reader flags
 #define FLAG_ICLASS_READER_ONLY_ONCE    0x01
-#define FLAG_ICLASS_READER_CC       0x02
-#define FLAG_ICLASS_READER_CSN         0x04
-#define FLAG_ICLASS_READER_CONF                0x08
-#define FLAG_ICLASS_READER_AA          0x10
+#define FLAG_ICLASS_READER_CC           0x02
+#define FLAG_ICLASS_READER_CSN          0x04
+#define FLAG_ICLASS_READER_CONF         0x08
+#define FLAG_ICLASS_READER_AA           0x10
+#define FLAG_ICLASS_READER_ONE_TRY      0x20
 
 
 
Impressum, Datenschutz