]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
0. its alpha version!!!
authorMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Fri, 10 Jun 2011 13:35:10 +0000 (13:35 +0000)
committerMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Fri, 10 Jun 2011 13:35:10 +0000 (13:35 +0000)
1. commands changed from "hf 14a" to "hf mf"
2. some code cleaning and small bugfixes
3. alpha version hf mf sim
4. added internal function GetTickCount() for time measuring

14 files changed:
armsrc/appmain.c
armsrc/apps.h
armsrc/iso14443a.c
armsrc/mifareutil.c
armsrc/mifareutil.h
armsrc/util.c
armsrc/util.h
client/Makefile
client/cmdhf.c
client/cmdhf14a.c
client/cmdhfmf.c [new file with mode: 0644]
client/cmdhfmf.h [new file with mode: 0644]
client/util.c
include/usb_cmd.h

index 49718ee8801d26859d7fbce4eaf2c3636d47aa67..501f07a50a9420c4034a48447ce6eaec03e766c6 100644 (file)
@@ -171,7 +171,7 @@ static int ReadAdc(int ch)
        return d;
 }
 
-static int AvgAdc(int ch)
+int AvgAdc(int ch) // was static - merlok
 {
        int i;
        int a = 0;
@@ -930,6 +930,8 @@ void  __attribute__((noreturn)) AppMain(void)
        // Load the FPGA image, which we have stored in our flash.
        FpgaDownloadAndGo();
 
+       StartTickCount();
+       
 #ifdef WITH_LCD
 
        LCDInit();
index 322f2674d2409211a7b24de9725acad32057e8d8..3b4611361db3a3c1021fc70c6ee742a83a30cd5d 100644 (file)
@@ -33,6 +33,8 @@ void DbpString(char *str);
 void Dbprintf(const char *fmt, ...);
 void Dbhexdump(int len, uint8_t *d);
 
+int AvgAdc(int ch);
+
 void ToSendStuffBit(int b);
 void ToSendReset(void);
 void ListenReaderField(int limit);
index 9e1eea540c34e52ca23c5839794f0d6a0835794e..fb50cc825b00c7ad4b8165fe19b03936ebe5aef9 100644 (file)
@@ -932,6 +932,7 @@ static int GetIso14443aCommandFromReader(uint8_t *received, int *len, int maxLen
         }
     }
 }
+static int EmSendCmd14443aRaw(uint8_t *resp, int respLen, int correctionNeeded);
 
 //-----------------------------------------------------------------------------
 // Main loop of simulated tag: receive commands from reader, decide what
@@ -1180,8 +1181,13 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
                }
 
         if(respLen <= 0) continue;
+               //----------------------------
+               u = 0;
+               b = 0x00;
+               fdt_indicator = FALSE;
 
-        // Modulate Manchester
+               EmSendCmd14443aRaw(resp, respLen, receivedCmd[0] == 0x52);
+/*        // Modulate Manchester
                FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
         AT91C_BASE_SSC->SSC_THR = 0x00;
         FpgaSetupSsc();
@@ -1213,7 +1219,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
                            break;
                        }
         }
-
+*/
     }
 
        Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
@@ -1398,6 +1404,133 @@ void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity)
   ToSendMax++;
 }
 
+//-----------------------------------------------------------------------------
+// Wait for commands from reader
+// Stop when button is pressed (return 1) or field was gone (return 2)
+// Or return 0 when command is captured
+//-----------------------------------------------------------------------------
+static int EmGetCmd(uint8_t *received, int *len, int maxLen)
+{
+       *len = 0;
+
+       uint32_t timer = 0, vtime = 0;
+       int analogCnt = 0;
+       int analogAVG = 0;
+
+       // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
+       // only, since we are receiving, not transmitting).
+       // Signal field is off with the appropriate LED
+       LED_D_OFF();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
+
+       // Set ADC to read field strength
+       AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
+       AT91C_BASE_ADC->ADC_MR =
+                               ADC_MODE_PRESCALE(32) |
+                               ADC_MODE_STARTUP_TIME(16) |
+                               ADC_MODE_SAMPLE_HOLD_TIME(8);
+       AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF);
+       // start ADC
+       AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
+       
+       // Now run a 'software UART' on the stream of incoming samples.
+       Uart.output = received;
+       Uart.byteCntMax = maxLen;
+       Uart.state = STATE_UNSYNCD;
+
+       for(;;) {
+               WDT_HIT();
+
+               if (BUTTON_PRESS()) return 1;
+
+               // test if the field exists
+               if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) {
+                       analogCnt++;
+                       analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF];
+                       AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
+                       if (analogCnt >= 32) {
+                               if ((33000 * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) {
+                                       vtime = GetTickCount();
+                                       if (!timer) timer = vtime;
+                                       // 50ms no field --> card to idle state
+                                       if (vtime - timer > 50) return 2;
+                               } else
+                                       if (timer) timer = 0;
+                               analogCnt = 0;
+                               analogAVG = 0;
+                       }
+               }
+               // transmit none
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                       AT91C_BASE_SSC->SSC_THR = 0x00;
+               }
+               // receive and test the miller decoding
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                       volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+                       if(MillerDecoding((b & 0xf0) >> 4)) {
+                               *len = Uart.byteCnt;
+                               return 0;
+                       }
+                       if(MillerDecoding(b & 0x0f)) {
+                               *len = Uart.byteCnt;
+                               return 0;
+                       }
+               }
+       }
+}
+
+static int EmSendCmd14443aRaw(uint8_t *resp, int respLen, int correctionNeeded)
+{
+       int i, u = 0;
+       uint8_t b = 0;
+
+       // Modulate Manchester
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
+       AT91C_BASE_SSC->SSC_THR = 0x00;
+       FpgaSetupSsc();
+       
+       // include correction bit
+       i = 1;
+       if((Uart.parityBits & 0x01) || correctionNeeded) {
+               // 1236, so correction bit needed
+               i = 0;
+       }
+       
+       // send cycle
+       for(;;) {
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                       volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+                       (void)b;
+               }
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                       if(i > respLen) {
+                               b = 0x00;
+                               u++;
+                       } else {
+                               b = resp[i];
+                               i++;
+                       }
+                       AT91C_BASE_SSC->SSC_THR = b;
+
+                       if(u > 4) break;
+               }
+               if(BUTTON_PRESS()) {
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int EmSendCmdEx(uint8_t *resp, int respLen, int correctionNeeded){
+  CodeIso14443aAsTag(resp, respLen);
+       return EmSendCmd14443aRaw(ToSend, ToSendMax, correctionNeeded);
+}
+
+static int EmSendCmd(uint8_t *resp, int respLen){
+       return EmSendCmdEx(resp, respLen, 0);
+}
+
 //-----------------------------------------------------------------------------
 // Wait a certain time for tag response
 //  If a response is captured return TRUE
@@ -2390,33 +2523,161 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 {
        int cardSTATE = MFEMUL_NOFIELD;
+       int vHf = 0;    // in mV
+       int res;
+       uint32_t timer = 0;
+       int len = 0;
+       uint8_t cardAUTHSC = 0;
+       uint8_t cardAUTHKEY = 0xff;  // no authentication
+       uint32_t cuid = 0;
+       struct Crypto1State mpcs = {0, 0};
+       struct Crypto1State *pcs;
+       pcs = &mpcs;
+       
+       uint64_t key64 = 0xffffffffffffULL;
+       
+       uint8_t* receivedCmd = mifare_get_bigbufptr();
+       
+       static uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k
+
+       static uint8_t rUIDBCC1[] = {0xde,  0xad,  0xbe,  0xaf,  0x62}; 
+       static uint8_t rUIDBCC2[] = {0xde,  0xad,  0xbe,  0xaf,  0x62}; // !!!
+               
+       static uint8_t rSAK[] = {0x08,  0xb6,  0xdd};
+
+       static uint8_t rAUTH_NT[] = {0x01, 0x02, 0x03, 0x04};
+       
+// --------------------------------------      test area
 
-       while (true) {
 
+// --------------------------------------      END test area
+
+       // We need to listen to the high-frequency, peak-detected path.
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+       FpgaSetupSsc();
+
+  FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
+       SpinDelay(200);
+
+Dbprintf("--> start");
+       while (true) {
+               WDT_HIT();
+//             timer = GetTickCount();
+//             Dbprintf("time: %d", GetTickCount() - timer);
+
+               // find reader field
+               // Vref = 3300mV, and an 10:1 voltage divider on the input
+               // can measure voltages up to 33000 mV
+               if (cardSTATE == MFEMUL_NOFIELD) {
+                       vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
+                       if (vHf > MF_MINFIELDV) {
+                               cardSTATE = MFEMUL_IDLE;
+                               LED_A_ON();
+                       }
+               } 
+
+               if (cardSTATE != MFEMUL_NOFIELD) {
+                       res = EmGetCmd(receivedCmd, &len, 100);
+                       if (res == 2) {
+                               cardSTATE = MFEMUL_NOFIELD;
+                               LEDsoff();
+                               continue;
+                       }
+                       if(res) break;
+               }
+               
                if(BUTTON_PRESS()) {
-      break;
-    }
+                       break;
+               }
        
+//             if (len) Dbprintf("len:%d cmd: %02x %02x %02x %02x", len, receivedCmd[0], receivedCmd[1], receivedCmd[2], receivedCmd[3]);
+               
                switch (cardSTATE) {
                        case MFEMUL_NOFIELD:{
                                break;
                        }
+                       case MFEMUL_HALTED:{
+                               // WUP request
+                               if (!(len == 1 && receivedCmd[0] == 0x52)) break;
+                       }
                        case MFEMUL_IDLE:{
+                               // REQ or WUP request
+                               if (len == 1 && (receivedCmd[0] == 0x26 || receivedCmd[0] == 0x52)) {
+timer = GetTickCount();
+                                       EmSendCmdEx(rATQA, sizeof(rATQA), (receivedCmd[0] == 0x52));
+                                       cardSTATE = MFEMUL_SELECT1;
+                                       
+                                       // init crypto block
+                                       crypto1_destroy(pcs);
+                                       cardAUTHKEY = 0xff;
+                               }
                                break;
                        }
                        case MFEMUL_SELECT1:{
+                               // select all
+                               if (len == 2 && (receivedCmd[0] == 0x93 && receivedCmd[1] == 0x20)) {
+                                       EmSendCmd(rUIDBCC1, sizeof(rUIDBCC1));
+
+                                       if (rUIDBCC1[0] == 0x88) {
+                                               cardSTATE = MFEMUL_SELECT2;
+                                       }
+                               }
+
+                               // select card
+                               if (len == 9 && (receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70)) {
+                                       EmSendCmd(rSAK, sizeof(rSAK));
+
+                                       cuid = bytes_to_num(rUIDBCC1, 4);
+                                       cardSTATE = MFEMUL_WORK;
+                                       LED_B_ON();
+Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - timer);
+                               }
+                               
                                break;
                        }
                        case MFEMUL_SELECT2:{
+                                       EmSendCmd(rUIDBCC2, sizeof(rUIDBCC2));
+
+                               cuid = bytes_to_num(rUIDBCC2, 4);
+                               cardSTATE = MFEMUL_WORK;
+                               LED_B_ON();
+Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - timer);
                                break;
                        }
                        case MFEMUL_AUTH1:{
+if (len) Dbprintf("au1 len:%d cmd: %02x %02x %02x %02x", len, receivedCmd[0], receivedCmd[1], receivedCmd[2], receivedCmd[3]);
+                               if (len == 8) {
+                               
+                               }
                                break;
                        }
                        case MFEMUL_AUTH2:{
+
+                               LED_C_ON();
+Dbprintf("AUTH COMPLETED. sec=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - timer);
                                break;
                        }
-                       case MFEMUL_HALTED:{
+                       case MFEMUL_WORK:{
+                               // auth
+                               if (len == 4 && (receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61)) {
+timer = GetTickCount();
+                                       crypto1_create(pcs, key64);
+//                                     if (cardAUTHKEY == 0xff) { // first auth
+                                       crypto1_word(pcs, cuid ^ bytes_to_num(rAUTH_NT, 4), 0); // uid ^ nonce
+//                                     } else { // nested auth
+//                                     }
+
+                                       EmSendCmd(rAUTH_NT, sizeof(rAUTH_NT));
+                                       cardAUTHSC = receivedCmd[1];
+                                       cardAUTHKEY = receivedCmd[0] - 0x60;
+                                       cardSTATE = MFEMUL_AUTH1;
+                               }
+                               
+                               // halt
+                               if (len == 4 && (receivedCmd[0] == 0x50 || receivedCmd[0] == 0x00)) {
+                                       cardSTATE = MFEMUL_HALTED;
+                                       LED_B_OFF();
+                               }
                                break;
                        }
                
@@ -2424,4 +2685,8 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        
        }
 
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       LEDsoff();
+
+       DbpString("Emulator stopped.");
 }
index 53e785f5b6f8e0570f20be590bd06ff04770f2fd..fc95de72666c0e75981106f179cf27fa148bbaa2 100644 (file)
@@ -266,3 +266,4 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
 \r
        return 0;\r
 }\r
+\r
index 9a909a355733879f447043d70a226a1d303110c7..4433fe65a952f3133dc571aff747b09f0495b6f7 100644 (file)
@@ -8,15 +8,20 @@
 //-----------------------------------------------------------------------------\r
 // code for work with mifare cards.\r
 //-----------------------------------------------------------------------------\r
+\r
 #ifndef __MIFAREUTIL_H\r
 #define __MIFAREUTIL_H\r
 \r
+// mifare authentication\r
 #define CRYPT_NONE    0\r
 #define CRYPT_ALL     1\r
 #define CRYPT_REQUEST 2\r
 #define AUTH_FIRST    0\r
 #define AUTH_NESTED   2\r
 \r
+// reader voltage field detector\r
+#define MF_MINFIELDV      4000\r
+\r
 // debug\r
 // 0 - no debug messages 1 - error messages 2 - all messages 4 - extended debug mode\r
 #define MF_DBG_NONE          0\r
@@ -33,14 +38,15 @@ extern int MF_DBGLEVEL;
 #define NS_RETRIES_GETNONCE 15\r
 #define NES_MAX_INFO         5\r
 \r
-//mifare emulate states\r
+//mifare emulator states\r
 #define MFEMUL_NOFIELD  0\r
 #define MFEMUL_IDLE     1\r
 #define MFEMUL_SELECT1  2\r
 #define MFEMUL_SELECT2  3\r
 #define MFEMUL_AUTH1    4\r
 #define MFEMUL_AUTH2    5\r
-#define MFEMUL_HALTED   6\r
+#define MFEMUL_WORK                    6\r
+#define MFEMUL_HALTED   7\r
 \r
 //functions\r
 uint8_t* mifare_get_bigbufptr(void);\r
index 5a8cfeec72ba0a063cee5ba87f12a6c4b1908431..9c6b3e8d76f919e957c468877c63df37a75b0f84 100644 (file)
@@ -235,3 +235,30 @@ void FormatVersionInformation(char *dst, int len, const char *prefix, void *vers
        strncat(dst, " ", len);
        strncat(dst, v->buildtime, len);
 }
+
+//  -------------------------------------------------------------------------
+//  timer lib
+//  -------------------------------------------------------------------------
+//  test procedure:
+//
+//     ti = GetTickCount();
+//     SpinDelay(1000);
+//     ti = GetTickCount() - ti;
+//     Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
+
+void StartTickCount()
+{
+//  must be 0x40, but on my cpu - included divider is optimal
+//  0x20 - 1 ms / bit 
+//  0x40 - 2 ms / bit
+
+       AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST + 0x003B;
+}
+
+/*
+* Get the current count.
+*/
+uint32_t RAMFUNC GetTickCount(){
+       return AT91C_BASE_RTTC->RTTC_RTVR * 2;
+}
+
index 34760ab1dedd4eb83e4df3c0ee60a26e44c3ad64..080dac6b5ebab17675dfe2ae4cb4de15fe5e46f0 100644 (file)
@@ -14,6 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define RAMFUNC __attribute((long_call, section(".ramfunc")))
+
 #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
 
 #define LED_RED 1
@@ -37,4 +39,7 @@ int BUTTON_CLICKED(int ms);
 int BUTTON_HELD(int ms);
 void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information);
 
+void StartTickCount();
+uint32_t RAMFUNC GetTickCount();
+
 #endif
index cf647c38aea0b31630e715fd8f33b10c0752906f..c76edf522e5b396e856a42f1ce80d6641ba3beac 100644 (file)
@@ -58,6 +58,7 @@ CMDSRCS = \
                        cmdhf15.c \
                        cmdhflegic.c \
                        cmdhficlass.c \
+                       cmdhfmf.c \
                        cmdhw.c \
                        cmdlf.c \
                        cmdlfem4x.c \
index 15b9e9845aad34cd1eb9b2ce83e1718b8d2d46c3..87c819fb9cb502f1cccc8fcf23ebaefbcd1e8546 100644 (file)
@@ -19,6 +19,7 @@
 #include "cmdhf15.h"
 #include "cmdhflegic.h"
 #include "cmdhficlass.h"
+#include "cmdhfmf.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -37,6 +38,7 @@ static command_t CommandTable[] =
   {"15",          CmdHF15,          1, "{ ISO15693 RFIDs... }"},
   {"legic",       CmdHFLegic,       0, "{ LEGIC RFIDs... }"},
   {"iclass",      CmdHFiClass,      1, "{ ICLASS RFIDs... }"},
+  {"mf",               CmdHFMF,                      1, "{ MIFARE RFIDs... }"},
   {"tune",        CmdHFTune,        0, "Continuously measure HF antenna tuning"},
   {NULL, NULL, 0, NULL}
 };
index f2774a16a8ffcad5357d5e614c51f36c40611dca..2a8c1f8766294b095a19ff08e1f7eccaabd86201 100644 (file)
@@ -13,7 +13,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <ctype.h>
 #include "util.h"
 #include "iso14443crc.h"
 #include "data.h"
@@ -23,9 +22,6 @@
 #include "cmdhf14a.h"
 #include "common.h"
 #include "cmdmain.h"
-#include "nonce2key/nonce2key.h"
-#include "nonce2key/crapto1.h"
-#include "mifarehost.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -161,500 +157,13 @@ void iso14a_set_timeout(uint32_t timeout) {
        SendCommand(&c);
 }
 
-int CmdHF14AMifare(const char *Cmd)
-{
-       uint32_t uid = 0;
-       uint32_t nt = 0;
-       uint64_t par_list = 0, ks_list = 0, r_key = 0;
-       uint8_t isOK = 0;
-       uint8_t keyBlock[6] = {0,0,0,0,0,0};
-       
-       if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, keyBlock, 8)) {
-               PrintAndLog("Nt must include 8 HEX symbols");
-               return 1;
-       }
-       
-       UsbCommand c = {CMD_READER_MIFARE, {(uint32_t)bytes_to_num(keyBlock, 4), 0, 0}};
-       SendCommand(&c);
-       
-       //flush queue
-       while (ukbhit())        getchar();
-
-       // message
-       printf("-------------------------------------------------------------------------\n");
-       printf("Executing command. It may take up to 30 min.\n");
-       printf("Press the key on proxmark3 device to abort proxmark3.\n");
-       printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
-       printf("-------------------------------------------------------------------------\n");
-       
-       // wait cycle
-       while (true) {
-               printf(".");
-               if (ukbhit()) {
-                       getchar();
-                       printf("\naborted via keyboard!\n");
-                       break;
-               }
-               
-               UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
-               if (resp != NULL) {
-                       isOK  = resp->arg[0] & 0xff;
-       
-                       uid = (uint32_t)bytes_to_num(resp->d.asBytes +  0, 4);
-                       nt =  (uint32_t)bytes_to_num(resp->d.asBytes +  4, 4);
-                       par_list = bytes_to_num(resp->d.asBytes +  8, 8);
-                       ks_list = bytes_to_num(resp->d.asBytes +  16, 8);
-       
-                       printf("\n\n");
-                       PrintAndLog("isOk:%02x", isOK);
-                       if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");
-                       break;
-               }
-       }       
-       printf("\n");
-       
-       // error
-       if (isOK != 1) return 1;
-       
-       // execute original function from util nonce2key
-       if (nonce2key(uid, nt, par_list, ks_list, &r_key)) return 2;
-       printf("------------------------------------------------------------------\n");
-       PrintAndLog("Key found:%012llx \n", r_key);
-
-       num_to_bytes(r_key, 6, keyBlock);
-       isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
-       if (!isOK) 
-               PrintAndLog("Found valid key:%012llx", r_key);
-       else
-               PrintAndLog("Found invalid key. (");    
-       
-       
-       return 0;
-}
-
-int CmdHF14AMfWrBl(const char *Cmd)
-{
-       uint8_t blockNo = 0;
-       uint8_t keyType = 0;
-       uint8_t key[6] = {0, 0, 0, 0, 0, 0};
-       uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-       
-       char cmdp       = 0x00;
-
-       if (strlen(Cmd)<3) {
-               PrintAndLog("Usage:  hf 14 mfwrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
-               PrintAndLog("        sample: hf 14a mfwrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
-               return 0;
-       }       
-
-       blockNo = param_get8(Cmd, 0);
-       cmdp = param_getchar(Cmd, 1);
-       if (cmdp == 0x00) {
-               PrintAndLog("Key type must be A or B");
-               return 1;
-       }
-       if (cmdp != 'A' && cmdp != 'a') keyType = 1;
-       if (param_gethex(Cmd, 2, key, 12)) {
-               PrintAndLog("Key must include 12 HEX symbols");
-               return 1;
-       }
-       if (param_gethex(Cmd, 3, bldata, 32)) {
-               PrintAndLog("Block data must include 32 HEX symbols");
-               return 1;
-       }
-       PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6));
-       PrintAndLog("--data: %s", sprint_hex(bldata, 16));
-       
-  UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
-       memcpy(c.d.asBytes, key, 6);
-       memcpy(c.d.asBytes + 10, bldata, 16);
-  SendCommand(&c);
-       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
-
-       if (resp != NULL) {
-               uint8_t                isOK  = resp->arg[0] & 0xff;
-
-               PrintAndLog("isOk:%02x", isOK);
-       } else {
-               PrintAndLog("Command execute timeout");
-       }
-
-       return 0;
-}
-
-int CmdHF14AMfRdBl(const char *Cmd)
-{
-       uint8_t blockNo = 0;
-       uint8_t keyType = 0;
-       uint8_t key[6] = {0, 0, 0, 0, 0, 0};
-       
-       char cmdp       = 0x00;
-
-
-       if (strlen(Cmd)<3) {
-               PrintAndLog("Usage:  hf 14 mfrdbl    <block number> <key A/B> <key (12 hex symbols)>");
-               PrintAndLog("        sample: hf 14a mfrdbl 0 A FFFFFFFFFFFF ");
-               return 0;
-       }       
-       
-       blockNo = param_get8(Cmd, 0);
-       cmdp = param_getchar(Cmd, 1);
-       if (cmdp == 0x00) {
-               PrintAndLog("Key type must be A or B");
-               return 1;
-       }
-       if (cmdp != 'A' && cmdp != 'a') keyType = 1;
-       if (param_gethex(Cmd, 2, key, 12)) {
-               PrintAndLog("Key must include 12 HEX symbols");
-               return 1;
-       }
-       PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
-       
-  UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
-       memcpy(c.d.asBytes, key, 6);
-  SendCommand(&c);
-       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
-
-       if (resp != NULL) {
-               uint8_t                isOK  = resp->arg[0] & 0xff;
-               uint8_t              * data  = resp->d.asBytes;
-
-               if (isOK)
-                       PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
-               else
-                       PrintAndLog("isOk:%02x", isOK);
-       } else {
-               PrintAndLog("Command execute timeout");
-       }
-
-  return 0;
-}
-
-int CmdHF14AMfRdSc(const char *Cmd)
-{
-       int i;
-       uint8_t sectorNo = 0;
-       uint8_t keyType = 0;
-       uint8_t key[6] = {0, 0, 0, 0, 0, 0};
-       
-       uint8_t isOK  = 0;
-       uint8_t * data  = NULL;
-
-       char cmdp       = 0x00;
-
-       if (strlen(Cmd)<3) {
-               PrintAndLog("Usage:  hf 14 mfrdsc    <sector number> <key A/B> <key (12 hex symbols)>");
-               PrintAndLog("        sample: hf 14a mfrdsc 0 A FFFFFFFFFFFF ");
-               return 0;
-       }       
-       
-       sectorNo = param_get8(Cmd, 0);
-       if (sectorNo > 63) {
-               PrintAndLog("Sector number must be less than 64");
-               return 1;
-       }
-       cmdp = param_getchar(Cmd, 1);
-       if (cmdp == 0x00) {
-               PrintAndLog("Key type must be A or B");
-               return 1;
-       }
-       if (cmdp != 'A' && cmdp != 'a') keyType = 1;
-       if (param_gethex(Cmd, 2, key, 12)) {
-               PrintAndLog("Key must include 12 HEX symbols");
-               return 1;
-       }
-       PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));
-       
-  UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
-       memcpy(c.d.asBytes, key, 6);
-  SendCommand(&c);
-       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
-       PrintAndLog(" ");
-
-       if (resp != NULL) {
-               isOK  = resp->arg[0] & 0xff;
-               data  = resp->d.asBytes;
-
-               PrintAndLog("isOk:%02x", isOK);
-               if (isOK) 
-                       for (i = 0; i < 2; i++) {
-                               PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
-                       }
-       } else {
-               PrintAndLog("Command1 execute timeout");
-       }
-
-               // response2
-       resp = WaitForResponseTimeout(CMD_ACK, 500);
-       PrintAndLog(" ");
-
-       if (resp != NULL) {
-               isOK  = resp->arg[0] & 0xff;
-               data  = resp->d.asBytes;
-
-               if (isOK) 
-                       for (i = 0; i < 2; i++) {
-                               PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
-               }
-       } else {
-               PrintAndLog("Command2 execute timeout");
-       }
-       
-  return 0;
-}
-
-int CmdHF14AMfNested(const char *Cmd)
-{
-       int i, j, res, iterations;
-       sector  *       e_sector = NULL;
-       uint8_t blockNo = 0;
-       uint8_t keyType = 0;
-       uint8_t trgBlockNo = 0;
-       uint8_t trgKeyType = 0;
-       uint8_t blDiff = 0;
-       int  SectorsCnt = 0;
-       uint8_t key[6] = {0, 0, 0, 0, 0, 0};
-       uint8_t keyBlock[16 * 6];
-       uint64_t key64 = 0;
-       
-       char cmdp, ctmp;
-
-       if (strlen(Cmd)<3) {
-               PrintAndLog("Usage:");
-               PrintAndLog(" all sectors:  hf 14a nested  <card memory> <block number> <key A/B> <key (12 hex symbols)>");
-               PrintAndLog(" one sector:   hf 14a nested  o <block number> <key A/B> <key (12 hex symbols)>");
-               PrintAndLog("               <target block number> <target key A/B>");
-               PrintAndLog("card memory - 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
-               PrintAndLog(" ");
-               PrintAndLog("      sample1: hf 14a nested 1 0 A FFFFFFFFFFFF ");
-               PrintAndLog("      sample2: hf 14a nested o 0 A FFFFFFFFFFFF 4 A");
-               return 0;
-       }       
-       
-       cmdp = param_getchar(Cmd, 0);
-       blockNo = param_get8(Cmd, 1);
-       ctmp = param_getchar(Cmd, 2);
-       if (ctmp == 0x00) {
-               PrintAndLog("Key type must be A or B");
-               return 1;
-       }
-       if (ctmp != 'A' && ctmp != 'a') keyType = 1;
-       if (param_gethex(Cmd, 3, key, 12)) {
-               PrintAndLog("Key must include 12 HEX symbols");
-               return 1;
-       }
-       
-       if (cmdp =='o' || cmdp == 'O') {
-               cmdp = 'o';
-               trgBlockNo = param_get8(Cmd, 4);
-               ctmp = param_getchar(Cmd, 5);
-               if (ctmp == 0x00) {
-                       PrintAndLog("Target key type must be A or B");
-                       return 1;
-               }
-               if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;
-       } else {
-               switch (cmdp) {
-                       case '1': SectorsCnt = 16; break;
-                       case '2': SectorsCnt = 32; break;
-                       case '4': SectorsCnt = 64; break;
-                       default:  SectorsCnt = 16;
-               }
-       }
-       
-       PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
-       if (cmdp == 'o')
-               PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo, trgKeyType);
-
-       if (cmdp == 'o') {
-               if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) {
-                       PrintAndLog("Nested error.");
-                       return 2;
-               }
-
-               for (i = 0; i < 16; i++) {
-                       PrintAndLog("cnt=%d key= %s", i, sprint_hex(keyBlock + i * 6, 6));
-               }
-       
-               // test keys
-               res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
-               if (res)
-                       res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
-               if (!res)
-                       PrintAndLog("Found valid key:%012llx", key64);
-               else
-                       PrintAndLog("No valid key found");
-       } else  // ------------------------------------  multiple sectors working
-       {
-               blDiff = blockNo % 4;
-               PrintAndLog("Block shift=%d", blDiff);
-               e_sector = calloc(SectorsCnt, sizeof(sector));
-               if (e_sector == NULL) return 1;
-               
-               //test current key 4 sectors
-               memcpy(keyBlock, key, 6);
-               num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 1 * 6));
-               num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 2 * 6));
-               num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 3 * 6));
-               num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 4 * 6));
-               num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));
-
-               PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);
-               for (i = 0; i < SectorsCnt; i++) {
-                       for (j = 0; j < 2; j++) {
-                               if (e_sector[i].foundKey[j]) continue;
-                               
-                               res = mfCheckKeys(i * 4 + blDiff, j, 6, keyBlock, &key64);
-                               
-                               if (!res) {
-                                       e_sector[i].Key[j] = key64;
-                                       e_sector[i].foundKey[j] = 1;
-                               }
-                       }
-               } 
-               
-               
-               // nested sectors
-               iterations = 0;
-               PrintAndLog("nested...");
-               for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
-                       for (trgBlockNo = blDiff; trgBlockNo < SectorsCnt * 4; trgBlockNo = trgBlockNo + 4) 
-                               for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { 
-                                       if (e_sector[trgBlockNo / 4].foundKey[trgKeyType]) continue;
-                                       if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) continue;
-                                       
-                                       iterations++;
-                                       
-                                       //try keys from nested
-                                       res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
-                                       if (res)
-                                               res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
-                                       if (!res) {
-                                               PrintAndLog("Found valid key:%012llx", key64);  
-                                               e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;
-                                               e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;
-                                       }
-                               }
-               }
-
-               PrintAndLog("Iterations count: %d", iterations);
-               //print them
-               PrintAndLog("|---|----------------|---|----------------|---|");
-               PrintAndLog("|blk|key A           |res|key B           |res|");
-               PrintAndLog("|---|----------------|---|----------------|---|");
-               for (i = 0; i < SectorsCnt; i++) {
-                       PrintAndLog("|%03d|  %012llx  | %d |  %012llx  | %d |", i, 
-                               e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);
-               }
-               PrintAndLog("|---|----------------|---|----------------|---|");
-               
-               free(e_sector);
-       }
-
-       return 0;
-}
-
-int CmdHF14AMfChk(const char *Cmd)
-{
-       int i, res;
-       int     keycnt = 0;
-       char ctmp       = 0x00;
-       uint8_t blockNo = 0;
-       uint8_t keyType = 0;
-       uint8_t keyBlock[8 * 6];
-       uint64_t key64 = 0;
-
-       memset(keyBlock, 0x00, sizeof(keyBlock));
-
-       if (strlen(Cmd)<3) {
-               PrintAndLog("Usage:  hf 14a chk <block number> <key A/B> [<key (12 hex symbols)>]");
-               PrintAndLog("      sample: hf 14a chk 0 A FFFFFFFFFFFF a0a1a2a3a4a5 b01b2b3b4b5 ");
-               return 0;
-       }       
-       
-       blockNo = param_get8(Cmd, 0);
-       ctmp = param_getchar(Cmd, 1);
-       if (ctmp == 0x00) {
-               PrintAndLog("Key type must be A or B");
-               return 1;
-       }
-       if (ctmp != 'A' && ctmp != 'a') keyType = 1;
-       
-       for (i = 0; i < 6; i++) {
-               if (!isxdigit(param_getchar(Cmd, 2 + i))) break;
-
-               if (param_gethex(Cmd, 2 + i, keyBlock + 6 * i, 12)) {
-                       PrintAndLog("Key[%d] must include 12 HEX symbols", i);
-                       return 1;
-               }
-               keycnt = i + 1;
-       }
-       
-       if (keycnt == 0) {
-               PrintAndLog("There is must be at least one key");
-               return 1;
-       }
-
-       PrintAndLog("--block no:%02x key type:%02x key count:%d ", blockNo, keyType, keycnt);
-       
-       res = mfCheckKeys(blockNo, keyType, keycnt, keyBlock, &key64);
-       if (res !=1) {
-               if (!res)
-                       PrintAndLog("isOk:%02x valid key:%012llx", 1, key64);
-               else
-                       PrintAndLog("isOk:%02x", 0);
-       } else {
-               PrintAndLog("Command execute timeout");
-       }
-
-  return 0;
-}
-
-int CmdHF14AMf1kSim(const char *Cmd)
-{
-       int i, temp;
-       uint8_t uid[4] = {0, 0, 0, 0};
-       
-       const char *cmdp        = Cmd;
-
-
-       if (strlen(Cmd)<3) {
-               PrintAndLog("Usage:  hf 14a mfsim  <uid (8 hex symbols)>");
-               PrintAndLog("           sample: hf 14a mfsim 0a0a0a0a ");
-               return 0;
-       }       
-       
-  // skip spaces
-       while (*cmdp==' ' || *cmdp=='\t') cmdp++;
-
-       if (strlen(cmdp) != 8) {
-               PrintAndLog("Length of UID must be 8 hex symbols");
-               return 0;
-       }
-       
-       for(i = 0; i < 4; i++) {
-               sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
-               uid[i] = temp & 0xff;
-               cmdp++;
-               cmdp++;
-       }       
-       PrintAndLog(" uid:%s ", sprint_hex(uid, 4));
-       
-  UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}};
-       memcpy(c.d.asBytes, uid, 6);
-  SendCommand(&c);
-
-  return 0;
-}
-
-
 int CmdHF14AReader(const char *Cmd)
 {
        UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
        SendCommand(&c);
        UsbCommand * resp = WaitForResponse(CMD_ACK);
        uint8_t              * uid  = resp->d.asBytes;
-       iso14a_card_select_t * card = uid + 12;
+       iso14a_card_select_t * card = (iso14a_card_select_t *)(uid + 12);
 
        if(resp->arg[0] == 0) {
                PrintAndLog("iso14443a card select failed");
@@ -664,6 +173,18 @@ int CmdHF14AReader(const char *Cmd)
        PrintAndLog("ATQA : %02x %02x", card->atqa[0], card->atqa[1]);
        PrintAndLog(" UID : %s", sprint_hex(uid, 12));
        PrintAndLog(" SAK : %02x [%d]", card->sak, resp->arg[0]);
+       switch (card->sak) {
+               case  0: PrintAndLog(" SAK : MIFARE ultralight?"); break;
+               case  8: PrintAndLog(" SAK : MIFARE CLASSIC 1K"); break;
+               case  9: PrintAndLog(" SAK : MIFARE MINI"); break;
+               case 18: PrintAndLog(" SAK : MIFARE CLASSIC 4K"); break;
+               case 20: PrintAndLog(" SAK : MIFARE DESFIRE or JCOP 31/41"); break;
+               case 28: PrintAndLog(" SAK : JCOP31 or JCOP41 v2.3.1"); break;
+               case 38: PrintAndLog(" SAK : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break;
+               case 88: PrintAndLog(" SAK : Infineon MIFARE CLASSIC 1K"); break;
+               case 98: PrintAndLog(" SAK : Gemplus MPCOS"); break;
+               default: ;
+       }
        if(resp->arg[0] == 1)
                PrintAndLog(" ATS : %s", sprint_hex(card->ats, card->ats_len));
        else
@@ -702,13 +223,6 @@ static command_t CommandTable[] =
 {
   {"help",   CmdHelp,          1, "This help"},
   {"list",   CmdHF14AList,     0, "List ISO 14443a history"},
-  {"mifare", CmdHF14AMifare,   0, "Read out sector 0 parity error messages. param - <used card nonce>"},
-  {"mfrdbl", CmdHF14AMfRdBl,   0, "Read MIFARE classic block"},
-  {"mfrdsc", CmdHF14AMfRdSc,   0, "Read MIFARE classic sector"},
-  {"mfwrbl", CmdHF14AMfWrBl,   0, "Write MIFARE classic block"},
-  {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
-  {"chk",    CmdHF14AMfChk,    0, "Test block up to 8 keys"},
-  {"mfsim",  CmdHF14AMf1kSim,  0, "Simulate MIFARE 1k card - NOT WORKING!!!"},
   {"reader", CmdHF14AReader,   0, "Act like an ISO14443 Type A reader"},
   {"sim",    CmdHF14ASim,      0, "<UID> -- Fake ISO 14443a tag"},
   {"snoop",  CmdHF14ASnoop,    0, "Eavesdrop ISO 14443 Type A"},
diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c
new file mode 100644 (file)
index 0000000..ee72dad
--- /dev/null
@@ -0,0 +1,559 @@
+//-----------------------------------------------------------------------------\r
+// Copyright (C) 2011 Merlok\r
+//\r
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,\r
+// at your option, any later version. See the LICENSE.txt file for the text of\r
+// the license.\r
+//-----------------------------------------------------------------------------\r
+// High frequency MIFARE commands\r
+//-----------------------------------------------------------------------------\r
+\r
+#include "cmdhfmf.h"\r
+\r
+static int CmdHelp(const char *Cmd);\r
+\r
+\r
+int CmdHF14AMifare(const char *Cmd)\r
+{\r
+       uint32_t uid = 0;\r
+       uint32_t nt = 0;\r
+       uint64_t par_list = 0, ks_list = 0, r_key = 0;\r
+       uint8_t isOK = 0;\r
+       uint8_t keyBlock[6] = {0,0,0,0,0,0};\r
+       \r
+       if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, keyBlock, 8)) {\r
+               PrintAndLog("Nt must include 8 HEX symbols");\r
+               return 1;\r
+       }\r
+       \r
+       UsbCommand c = {CMD_READER_MIFARE, {(uint32_t)bytes_to_num(keyBlock, 4), 0, 0}};\r
+       SendCommand(&c);\r
+       \r
+       //flush queue\r
+       while (ukbhit())        getchar();\r
+\r
+       // message\r
+       printf("-------------------------------------------------------------------------\n");\r
+       printf("Executing command. It may take up to 30 min.\n");\r
+       printf("Press the key on proxmark3 device to abort proxmark3.\n");\r
+       printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");\r
+       printf("-------------------------------------------------------------------------\n");\r
+       \r
+       // wait cycle\r
+       while (true) {\r
+               printf(".");\r
+               if (ukbhit()) {\r
+                       getchar();\r
+                       printf("\naborted via keyboard!\n");\r
+                       break;\r
+               }\r
+               \r
+               UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);\r
+               if (resp != NULL) {\r
+                       isOK  = resp->arg[0] & 0xff;\r
+       \r
+                       uid = (uint32_t)bytes_to_num(resp->d.asBytes +  0, 4);\r
+                       nt =  (uint32_t)bytes_to_num(resp->d.asBytes +  4, 4);\r
+                       par_list = bytes_to_num(resp->d.asBytes +  8, 8);\r
+                       ks_list = bytes_to_num(resp->d.asBytes +  16, 8);\r
+       \r
+                       printf("\n\n");\r
+                       PrintAndLog("isOk:%02x", isOK);\r
+                       if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");\r
+                       break;\r
+               }\r
+       }       \r
+       printf("\n");\r
+       \r
+       // error\r
+       if (isOK != 1) return 1;\r
+       \r
+       // execute original function from util nonce2key\r
+       if (nonce2key(uid, nt, par_list, ks_list, &r_key)) return 2;\r
+       printf("------------------------------------------------------------------\n");\r
+       PrintAndLog("Key found:%012llx \n", r_key);\r
+\r
+       num_to_bytes(r_key, 6, keyBlock);\r
+       isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);\r
+       if (!isOK) \r
+               PrintAndLog("Found valid key:%012llx", r_key);\r
+       else\r
+               PrintAndLog("Found invalid key. ( Nt=%08x", nt);        \r
+       \r
+       \r
+       return 0;\r
+}\r
+\r
+int CmdHF14AMfWrBl(const char *Cmd)\r
+{\r
+       uint8_t blockNo = 0;\r
+       uint8_t keyType = 0;\r
+       uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
+       uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\r
+       \r
+       char cmdp       = 0x00;\r
+\r
+       if (strlen(Cmd)<3) {\r
+               PrintAndLog("Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");\r
+               PrintAndLog("        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");\r
+               return 0;\r
+       }       \r
+\r
+       blockNo = param_get8(Cmd, 0);\r
+       cmdp = param_getchar(Cmd, 1);\r
+       if (cmdp == 0x00) {\r
+               PrintAndLog("Key type must be A or B");\r
+               return 1;\r
+       }\r
+       if (cmdp != 'A' && cmdp != 'a') keyType = 1;\r
+       if (param_gethex(Cmd, 2, key, 12)) {\r
+               PrintAndLog("Key must include 12 HEX symbols");\r
+               return 1;\r
+       }\r
+       if (param_gethex(Cmd, 3, bldata, 32)) {\r
+               PrintAndLog("Block data must include 32 HEX symbols");\r
+               return 1;\r
+       }\r
+       PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6));\r
+       PrintAndLog("--data: %s", sprint_hex(bldata, 16));\r
+       \r
+  UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
+       memcpy(c.d.asBytes, key, 6);\r
+       memcpy(c.d.asBytes + 10, bldata, 16);\r
+  SendCommand(&c);\r
+       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+\r
+       if (resp != NULL) {\r
+               uint8_t                isOK  = resp->arg[0] & 0xff;\r
+\r
+               PrintAndLog("isOk:%02x", isOK);\r
+       } else {\r
+               PrintAndLog("Command execute timeout");\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+int CmdHF14AMfRdBl(const char *Cmd)\r
+{\r
+       uint8_t blockNo = 0;\r
+       uint8_t keyType = 0;\r
+       uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
+       \r
+       char cmdp       = 0x00;\r
+\r
+\r
+       if (strlen(Cmd)<3) {\r
+               PrintAndLog("Usage:  hf mf rdbl    <block number> <key A/B> <key (12 hex symbols)>");\r
+               PrintAndLog("        sample: hf mf rdbl 0 A FFFFFFFFFFFF ");\r
+               return 0;\r
+       }       \r
+       \r
+       blockNo = param_get8(Cmd, 0);\r
+       cmdp = param_getchar(Cmd, 1);\r
+       if (cmdp == 0x00) {\r
+               PrintAndLog("Key type must be A or B");\r
+               return 1;\r
+       }\r
+       if (cmdp != 'A' && cmdp != 'a') keyType = 1;\r
+       if (param_gethex(Cmd, 2, key, 12)) {\r
+               PrintAndLog("Key must include 12 HEX symbols");\r
+               return 1;\r
+       }\r
+       PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));\r
+       \r
+  UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
+       memcpy(c.d.asBytes, key, 6);\r
+  SendCommand(&c);\r
+       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+\r
+       if (resp != NULL) {\r
+               uint8_t                isOK  = resp->arg[0] & 0xff;\r
+               uint8_t              * data  = resp->d.asBytes;\r
+\r
+               if (isOK)\r
+                       PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));\r
+               else\r
+                       PrintAndLog("isOk:%02x", isOK);\r
+       } else {\r
+               PrintAndLog("Command execute timeout");\r
+       }\r
+\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfRdSc(const char *Cmd)\r
+{\r
+       int i;\r
+       uint8_t sectorNo = 0;\r
+       uint8_t keyType = 0;\r
+       uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
+       \r
+       uint8_t isOK  = 0;\r
+       uint8_t * data  = NULL;\r
+\r
+       char cmdp       = 0x00;\r
+\r
+       if (strlen(Cmd)<3) {\r
+               PrintAndLog("Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>");\r
+               PrintAndLog("        sample: hf mf rdsc 0 A FFFFFFFFFFFF ");\r
+               return 0;\r
+       }       \r
+       \r
+       sectorNo = param_get8(Cmd, 0);\r
+       if (sectorNo > 63) {\r
+               PrintAndLog("Sector number must be less than 64");\r
+               return 1;\r
+       }\r
+       cmdp = param_getchar(Cmd, 1);\r
+       if (cmdp == 0x00) {\r
+               PrintAndLog("Key type must be A or B");\r
+               return 1;\r
+       }\r
+       if (cmdp != 'A' && cmdp != 'a') keyType = 1;\r
+       if (param_gethex(Cmd, 2, key, 12)) {\r
+               PrintAndLog("Key must include 12 HEX symbols");\r
+               return 1;\r
+       }\r
+       PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));\r
+       \r
+  UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};\r
+       memcpy(c.d.asBytes, key, 6);\r
+  SendCommand(&c);\r
+       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+       PrintAndLog(" ");\r
+\r
+       if (resp != NULL) {\r
+               isOK  = resp->arg[0] & 0xff;\r
+               data  = resp->d.asBytes;\r
+\r
+               PrintAndLog("isOk:%02x", isOK);\r
+               if (isOK) \r
+                       for (i = 0; i < 2; i++) {\r
+                               PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));\r
+                       }\r
+       } else {\r
+               PrintAndLog("Command1 execute timeout");\r
+       }\r
+\r
+               // response2\r
+       resp = WaitForResponseTimeout(CMD_ACK, 500);\r
+       PrintAndLog(" ");\r
+\r
+       if (resp != NULL) {\r
+               isOK  = resp->arg[0] & 0xff;\r
+               data  = resp->d.asBytes;\r
+\r
+               if (isOK) \r
+                       for (i = 0; i < 2; i++) {\r
+                               PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));\r
+               }\r
+       } else {\r
+               PrintAndLog("Command2 execute timeout");\r
+       }\r
+       \r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfNested(const char *Cmd)\r
+{\r
+       int i, j, res, iterations;\r
+       sector  *       e_sector = NULL;\r
+       uint8_t blockNo = 0;\r
+       uint8_t keyType = 0;\r
+       uint8_t trgBlockNo = 0;\r
+       uint8_t trgKeyType = 0;\r
+       uint8_t blDiff = 0;\r
+       int  SectorsCnt = 0;\r
+       uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
+       uint8_t keyBlock[16 * 6];\r
+       uint64_t key64 = 0;\r
+       \r
+       char cmdp, ctmp;\r
+\r
+       if (strlen(Cmd)<3) {\r
+               PrintAndLog("Usage:");\r
+               PrintAndLog(" all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)>");\r
+               PrintAndLog(" one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)>");\r
+               PrintAndLog("               <target block number> <target key A/B>");\r
+               PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");\r
+               PrintAndLog(" ");\r
+               PrintAndLog("      sample1: hf mf nested 1 0 A FFFFFFFFFFFF ");\r
+               PrintAndLog("      sample2: hf mf nested o 0 A FFFFFFFFFFFF 4 A");\r
+               return 0;\r
+       }       \r
+       \r
+       cmdp = param_getchar(Cmd, 0);\r
+       blockNo = param_get8(Cmd, 1);\r
+       ctmp = param_getchar(Cmd, 2);\r
+       if (ctmp == 0x00) {\r
+               PrintAndLog("Key type must be A or B");\r
+               return 1;\r
+       }\r
+       if (ctmp != 'A' && ctmp != 'a') keyType = 1;\r
+       if (param_gethex(Cmd, 3, key, 12)) {\r
+               PrintAndLog("Key must include 12 HEX symbols");\r
+               return 1;\r
+       }\r
+       \r
+       if (cmdp =='o' || cmdp == 'O') {\r
+               cmdp = 'o';\r
+               trgBlockNo = param_get8(Cmd, 4);\r
+               ctmp = param_getchar(Cmd, 5);\r
+               if (ctmp == 0x00) {\r
+                       PrintAndLog("Target key type must be A or B");\r
+                       return 1;\r
+               }\r
+               if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;\r
+       } else {\r
+               switch (cmdp) {\r
+                       case '0': SectorsCnt = 05; break;\r
+                       case '1': SectorsCnt = 16; break;\r
+                       case '2': SectorsCnt = 32; break;\r
+                       case '4': SectorsCnt = 64; break;\r
+                       default:  SectorsCnt = 16;\r
+               }\r
+       }\r
+       \r
+       PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));\r
+       if (cmdp == 'o')\r
+               PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo, trgKeyType);\r
+\r
+       if (cmdp == 'o') {\r
+               if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) {\r
+                       PrintAndLog("Nested error.");\r
+                       return 2;\r
+               }\r
+\r
+               for (i = 0; i < 16; i++) {\r
+                       PrintAndLog("cnt=%d key= %s", i, sprint_hex(keyBlock + i * 6, 6));\r
+               }\r
+       \r
+               // test keys\r
+               res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);\r
+               if (res)\r
+                       res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);\r
+               if (!res)\r
+                       PrintAndLog("Found valid key:%012llx", key64);\r
+               else\r
+                       PrintAndLog("No valid key found");\r
+       } else  // ------------------------------------  multiple sectors working\r
+       {\r
+               blDiff = blockNo % 4;\r
+               PrintAndLog("Block shift=%d", blDiff);\r
+               e_sector = calloc(SectorsCnt, sizeof(sector));\r
+               if (e_sector == NULL) return 1;\r
+               \r
+               //test current key 4 sectors\r
+               memcpy(keyBlock, key, 6);\r
+               num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 1 * 6));\r
+               num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 2 * 6));\r
+               num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 3 * 6));\r
+               num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 4 * 6));\r
+               num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));\r
+\r
+               PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);\r
+               for (i = 0; i < SectorsCnt; i++) {\r
+                       for (j = 0; j < 2; j++) {\r
+                               if (e_sector[i].foundKey[j]) continue;\r
+                               \r
+                               res = mfCheckKeys(i * 4 + blDiff, j, 6, keyBlock, &key64);\r
+                               \r
+                               if (!res) {\r
+                                       e_sector[i].Key[j] = key64;\r
+                                       e_sector[i].foundKey[j] = 1;\r
+                               }\r
+                       }\r
+               } \r
+               \r
+               \r
+               // nested sectors\r
+               iterations = 0;\r
+               PrintAndLog("nested...");\r
+               for (i = 0; i < NESTED_SECTOR_RETRY; i++) {\r
+                       for (trgBlockNo = blDiff; trgBlockNo < SectorsCnt * 4; trgBlockNo = trgBlockNo + 4) \r
+                               for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { \r
+                                       if (e_sector[trgBlockNo / 4].foundKey[trgKeyType]) continue;\r
+                                       if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) continue;\r
+                                       \r
+                                       iterations++;\r
+                                       \r
+                                       //try keys from nested\r
+                                       res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);\r
+                                       if (res)\r
+                                               res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);\r
+                                       if (!res) {\r
+                                               PrintAndLog("Found valid key:%012llx", key64);  \r
+                                               e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;\r
+                                               e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;\r
+                                       }\r
+                               }\r
+               }\r
+\r
+               PrintAndLog("Iterations count: %d", iterations);\r
+               //print them\r
+               PrintAndLog("|---|----------------|---|----------------|---|");\r
+               PrintAndLog("|sec|key A           |res|key B           |res|");\r
+               PrintAndLog("|---|----------------|---|----------------|---|");\r
+               for (i = 0; i < SectorsCnt; i++) {\r
+                       PrintAndLog("|%03d|  %012llx  | %d |  %012llx  | %d |", i, \r
+                               e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);\r
+               }\r
+               PrintAndLog("|---|----------------|---|----------------|---|");\r
+               \r
+               free(e_sector);\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+int CmdHF14AMfChk(const char *Cmd)\r
+{\r
+       int i, res;\r
+       int     keycnt = 0;\r
+       char ctmp       = 0x00;\r
+       uint8_t blockNo = 0;\r
+       uint8_t keyType = 0;\r
+       uint8_t keyBlock[8 * 6];\r
+       uint64_t key64 = 0;\r
+\r
+       memset(keyBlock, 0x00, sizeof(keyBlock));\r
+\r
+       if (strlen(Cmd)<3) {\r
+               PrintAndLog("Usage:  hf mf chk <block number> <key A/B> [<key (12 hex symbols)>]");\r
+               PrintAndLog("      sample: hf mf chk 0 A FFFFFFFFFFFF a0a1a2a3a4a5 b01b2b3b4b5 ");\r
+               return 0;\r
+       }       \r
+       \r
+       blockNo = param_get8(Cmd, 0);\r
+       ctmp = param_getchar(Cmd, 1);\r
+       if (ctmp == 0x00) {\r
+               PrintAndLog("Key type must be A or B");\r
+               return 1;\r
+       }\r
+       if (ctmp != 'A' && ctmp != 'a') keyType = 1;\r
+       \r
+       for (i = 0; i < 6; i++) {\r
+               if (!isxdigit(param_getchar(Cmd, 2 + i))) break;\r
+\r
+               if (param_gethex(Cmd, 2 + i, keyBlock + 6 * i, 12)) {\r
+                       PrintAndLog("Key[%d] must include 12 HEX symbols", i);\r
+                       return 1;\r
+               }\r
+               keycnt = i + 1;\r
+       }\r
+       \r
+       if (keycnt == 0) {\r
+               PrintAndLog("There is must be at least one key");\r
+               return 1;\r
+       }\r
+\r
+       PrintAndLog("--block no:%02x key type:%02x key count:%d ", blockNo, keyType, keycnt);\r
+       \r
+       res = mfCheckKeys(blockNo, keyType, keycnt, keyBlock, &key64);\r
+       if (res !=1) {\r
+               if (!res)\r
+                       PrintAndLog("isOk:%02x valid key:%012llx", 1, key64);\r
+               else\r
+                       PrintAndLog("isOk:%02x", 0);\r
+       } else {\r
+               PrintAndLog("Command execute timeout");\r
+       }\r
+\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMf1kSim(const char *Cmd)\r
+{\r
+       uint8_t uid[4] = {0, 0, 0, 0};\r
+       \r
+       if (param_getchar(Cmd, 0) == 'h') {\r
+               PrintAndLog("Usage:  hf mf sim  <uid (8 hex symbols)>");\r
+               PrintAndLog("           sample: hf mf sim 0a0a0a0a ");\r
+               return 0;\r
+       }       \r
+       \r
+       if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {\r
+               PrintAndLog("UID must include 8 HEX symbols");\r
+               return 1;\r
+       }\r
+       PrintAndLog(" uid:%s ", sprint_hex(uid, 4));\r
+       \r
+  UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}};\r
+       memcpy(c.d.asBytes, uid, 4);\r
+  SendCommand(&c);\r
+\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfDbg(const char *Cmd)\r
+{\r
+       if (strlen(Cmd) < 1) {\r
+               PrintAndLog("Usage:  hf mf dbg  <debug level>");\r
+               PrintAndLog(" 0 - no debug messages");\r
+               PrintAndLog(" 1 - error messages");\r
+               PrintAndLog(" 2 - all messages");\r
+               PrintAndLog(" 4 - extended debug mode");\r
+               return 0;\r
+       }       \r
+\r
+       PrintAndLog("No code here (");\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfEGet(const char *Cmd)\r
+{\r
+       PrintAndLog("No code here (");\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfESet(const char *Cmd)\r
+{\r
+       PrintAndLog("No code here (");\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfELoad(const char *Cmd)\r
+{\r
+       PrintAndLog("No code here (");\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfESave(const char *Cmd)\r
+{\r
+       PrintAndLog("No code here (");\r
+  return 0;\r
+}\r
+\r
+static command_t CommandTable[] = \r
+{\r
+  {"help",             CmdHelp,                                                1, "This help"},\r
+  {"dbg",                      CmdHF14AMfDbg,                  0, "Set default debug mode"},\r
+  {"rdbl",             CmdHF14AMfRdBl,                 0, "Read MIFARE classic block"},\r
+  {"rdsc",             CmdHF14AMfRdSc,                 0, "Read MIFARE classic sector"},\r
+  {"wrbl",             CmdHF14AMfWrBl,                 0, "Write MIFARE classic block"},\r
+  {"chk",                      CmdHF14AMfChk,                  0, "Test block up to 8 keys"},\r
+  {"mifare",   CmdHF14AMifare,                 0, "Read parity error messages. param - <used card nonce>"},\r
+  {"nested",   CmdHF14AMfNested,               0, "Test nested authentication"},\r
+  {"sim",                      CmdHF14AMf1kSim,                0, "Simulate MIFARE 1k card"},\r
+  {"eget",             CmdHF14AMfEGet,                 0, "Set simulator memory block"},\r
+  {"eset",             CmdHF14AMfESet,                 0, "Get simulator memory block"},\r
+  {"eload",            CmdHF14AMfELoad,                0, "Load from file emul dump"},\r
+  {"esave",            CmdHF14AMfESave,                0, "Save to file emul dump"},\r
+  {NULL, NULL, 0, NULL}\r
+};\r
+\r
+int CmdHFMF(const char *Cmd)\r
+{\r
+       // flush\r
+       while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;\r
+\r
+  CmdsParse(CommandTable, Cmd);\r
+  return 0;\r
+}\r
+\r
+int CmdHelp(const char *Cmd)\r
+{\r
+  CmdsHelp(CommandTable);\r
+  return 0;\r
+}\r
diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h
new file mode 100644 (file)
index 0000000..a4ca776
--- /dev/null
@@ -0,0 +1,29 @@
+//-----------------------------------------------------------------------------\r
+// Copyright (C) 2011 Merlok\r
+//\r
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,\r
+// at your option, any later version. See the LICENSE.txt file for the text of\r
+// the license.\r
+//-----------------------------------------------------------------------------\r
+// High frequency MIFARE commands\r
+//-----------------------------------------------------------------------------\r
+\r
+#ifndef CMDHFMF_H__\r
+#define CMDHFMF_H__\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include "iso14443crc.h"\r
+#include "data.h"\r
+#include "proxusb.h"\r
+#include "ui.h"\r
+#include "cmdparser.h"\r
+#include "common.h"\r
+#include "util.h"\r
+#include "mifarehost.h"\r
+\r
+int CmdHFMF(const char *Cmd);\r
+\r
+#endif\r
index 6825d721d4622d9f383f79a6ac6ebe21984c2fea..c7764f7092df5c0d6358e23bd409397603298e71 100644 (file)
@@ -89,6 +89,10 @@ uint64_t bytes_to_num(uint8_t* src, size_t len)
        return num;
 }
 
+//  -------------------------------------------------------------------------
+//  string parameters lib
+//  -------------------------------------------------------------------------
+
 //  -------------------------------------------------------------------------
 //  line     - param line
 //  bg, en   - symbol numbers in param line of beginning an ending parameter
index f4793cfc8ca2382f023fc3a3b44a0f51681de1e7..3e8066b04066cc01cbccb36979d9a816a80535bd 100644 (file)
@@ -33,13 +33,13 @@ typedef struct {
 } PACKED UsbCommand;
 
 // For the bootloader
-#define CMD_DEVICE_INFO                                        0x0000
-#define CMD_SETUP_WRITE                                        0x0001
-#define CMD_FINISH_WRITE                               0x0003
-#define CMD_HARDWARE_RESET                     0x0004
-#define CMD_START_FLASH                                        0x0005
-#define CMD_NACK                                                               0x00fe
-#define CMD_ACK                                                                        0x00ff
+#define CMD_DEVICE_INFO                                                                0x0000
+#define CMD_SETUP_WRITE                                                                0x0001
+#define CMD_FINISH_WRITE                                                       0x0003
+#define CMD_HARDWARE_RESET                                             0x0004
+#define CMD_START_FLASH                                                                0x0005
+#define CMD_NACK                                                                                       0x00fe
+#define CMD_ACK                                                                                                0x00ff
 
 // For general mucking around
 #define CMD_DEBUG_PRINT_STRING                         0x0100
@@ -52,32 +52,32 @@ typedef struct {
 #define CMD_VERSION                                                                            0x0107
 
 // For low-frequency tags
-#define CMD_READ_TI_TYPE                                                                               0x0202
-#define CMD_WRITE_TI_TYPE                                                                              0x0203
-#define CMD_DOWNLOADED_RAW_BITS_TI_TYPE                        0x0204
-#define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K               0x0205
-#define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K      0x0206
-#define CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K              0x0207
-#define CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K            0x0208
-#define CMD_DOWNLOADED_SIM_SAMPLES_125K                        0x0209
-#define CMD_SIMULATE_TAG_125K                          0x020A
-#define CMD_HID_DEMOD_FSK                              0x020B
-#define CMD_HID_SIM_TAG                                        0x020C
-#define CMD_SET_LF_DIVISOR                             0x020D
-#define CMD_LF_SIMULATE_BIDIR                          0x020E
-#define CMD_SET_ADC_MUX                                        0x020F
+#define CMD_READ_TI_TYPE                                                                                                               0x0202
+#define CMD_WRITE_TI_TYPE                                                                                                              0x0203
+#define CMD_DOWNLOADED_RAW_BITS_TI_TYPE                                                        0x0204
+#define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K                                               0x0205
+#define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K              0x0206
+#define CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K                                              0x0207
+#define CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K                                    0x0208
+#define CMD_DOWNLOADED_SIM_SAMPLES_125K                                                        0x0209
+#define CMD_SIMULATE_TAG_125K                                                                                          0x020A
+#define CMD_HID_DEMOD_FSK                                                              0x020B
+#define CMD_HID_SIM_TAG                                                                        0x020C
+#define CMD_SET_LF_DIVISOR                                                     0x020D
+#define CMD_LF_SIMULATE_BIDIR                                          0x020E
+#define CMD_SET_ADC_MUX                                                                        0x020F
 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
 
 // For the 13.56 MHz tags
 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693          0x0300
 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443          0x0301
-#define CMD_READ_SRI512_TAG                                                    0x0303
-#define CMD_READ_SRIX4K_TAG                                                    0x0304
-#define CMD_READER_ISO_15693                                           0x0310
-#define CMD_SIMTAG_ISO_15693                                           0x0311
+#define CMD_READ_SRI512_TAG                                                                                    0x0303
+#define CMD_READ_SRIX4K_TAG                                                                                    0x0304
+#define CMD_READER_ISO_15693                                                                           0x0310
+#define CMD_SIMTAG_ISO_15693                                                                           0x0311
 #define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693           0x0312
-#define CMD_ISO_15693_COMMAND                                          0x0313
-#define CMD_ISO_15693_COMMAND_DONE                     0x0314
+#define CMD_ISO_15693_COMMAND                                                                          0x0313
+#define CMD_ISO_15693_COMMAND_DONE                                                     0x0314
 #define CMD_ISO_15693_FIND_AFI                                 0x0315
 #define CMD_ISO_15693_DEBUG                                                    0x0316
 #define CMD_SIMULATE_TAG_HF_LISTEN                     0x0380
@@ -86,28 +86,37 @@ typedef struct {
 #define CMD_SNOOP_ISO_14443a                                           0x0383
 #define CMD_SIMULATE_TAG_ISO_14443a                    0x0384
 #define CMD_READER_ISO_14443a                                          0x0385
-#define CMD_SIMULATE_MIFARE_CARD                               0x0386
 #define CMD_SIMULATE_TAG_LEGIC_RF                              0x0387
 #define CMD_READER_LEGIC_RF                                                    0x0388
 #define CMD_WRITER_LEGIC_RF                                                    0x0399
-#define CMD_READER_MIFARE                                                              0x0389
-#define CMD_MIFARE_NESTED                                                              0x0390
-#define CMD_MIFARE_READBL                                                              0x0391
-#define CMD_MIFARE_READSC                                                              0x0393
-#define CMD_MIFARE_WRITEBL                                                     0x0394
-#define CMD_MIFARE_CHKKEYS                                                     0x0395
+
 #define CMD_SNOOP_ICLASS                                                               0x0392
 
 // For measurements of the antenna tuning
-#define CMD_MEASURE_ANTENNA_TUNING                             0x0400
-#define CMD_MEASURE_ANTENNA_TUNING_HF                  0x0401
-#define CMD_MEASURED_ANTENNA_TUNING                            0x0410
-#define CMD_LISTEN_READER_FIELD                                                0x0420
+#define CMD_MEASURE_ANTENNA_TUNING                     0x0400
+#define CMD_MEASURE_ANTENNA_TUNING_HF          0x0401
+#define CMD_MEASURED_ANTENNA_TUNING                    0x0410
+#define CMD_LISTEN_READER_FIELD                                        0x0420
 
 // For direct FPGA control
-#define CMD_FPGA_MAJOR_MODE_OFF                                                0x0500
+#define CMD_FPGA_MAJOR_MODE_OFF                                        0x0500
+
+// For mifare commands
+#define CMD_MIFARE_SET_DBGMODE                                 0x0600
+#define CMD_MIFARE_EML_MEMSET                                          0x0601
+#define CMD_MIFARE_EML_MEMGET                                          0x0602
+
+#define CMD_SIMULATE_MIFARE_CARD                               0x0603
+
+#define CMD_READER_MIFARE                                                              0x0605
+#define CMD_MIFARE_NESTED                                                              0x0606
+
+#define CMD_MIFARE_READBL                                                              0x0610
+#define CMD_MIFARE_READSC                                                              0x0611
+#define CMD_MIFARE_WRITEBL                                                     0x0612
+#define CMD_MIFARE_CHKKEYS                                                     0x0613
 
-#define CMD_UNKNOWN                                                                                            0xFFFF
+#define CMD_UNKNOWN                                                                                    0xFFFF
 
 // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
 /* Whether a bootloader that understands the common_area is present */
Impressum, Datenschutz