]> cvs.zerfleddert.de Git - proxmark3-svn/commitdiff
1. updated usb commands
authorMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Fri, 17 Jun 2011 18:39:54 +0000 (18:39 +0000)
committerMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Fri, 17 Jun 2011 18:39:54 +0000 (18:39 +0000)
2. added abilities to: clear, get, set, load from card, load from nested card emulator dump
3. tried to fix proxmark promt have seen everywhere (not so good)
4. reorganized arm code

15 files changed:
armsrc/Makefile
armsrc/appmain.c
armsrc/apps.h
armsrc/iso14443a.c
armsrc/iso14443a.h
armsrc/mifarecmd.c [new file with mode: 0644]
armsrc/mifarecmd.h [new file with mode: 0644]
armsrc/mifareutil.c
armsrc/mifareutil.h
client/cmdhfmf.c
client/cmdhfmf.h
client/mifarehost.c
client/mifarehost.h
client/proxmark3.c
include/usb_cmd.h

index 565de2fe9e225bbea6d4885180db567041f14032..b30de7577af1d77b8a78d99f9ec3fc8aa90f70cf 100644 (file)
@@ -16,7 +16,7 @@ APP_CFLAGS    = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b
 #SRC_LCD = fonts.c LCD.c
 SRC_LF = lfops.c hitag2.c
 SRC_ISO15693 = iso15693.c iso15693tools.c 
-SRC_ISO14443a = iso14443a.c mifareutil.c
+SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c
 SRC_ISO14443b = iso14443.c
 SRC_CRAPTO1 = crapto1.c crypto1.c
 
index 501f07a50a9420c4034a48447ce6eaec03e766c6..f2ae56d850e9ee15173004ca75656c506a968525 100644 (file)
@@ -713,6 +713,23 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_SIMULATE_MIFARE_CARD:
                        Mifare1ksim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
+               
+               // emulator
+               case CMD_MIFARE_SET_DBGMODE:
+                       MifareSetDbgLvl(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
+               case CMD_MIFARE_EML_MEMCLR:
+                       MifareEMemClr(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
+               case CMD_MIFARE_EML_MEMSET:
+                       MifareEMemSet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
+               case CMD_MIFARE_EML_MEMGET:
+                       MifareEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
+               case CMD_MIFARE_EML_CARDLOAD:
+                       MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
                        
 #endif
 
index 3b4611361db3a3c1021fc70c6ee742a83a30cd5d..c458595ee0e19449aaf2202f899fdab20f623a68 100644 (file)
@@ -107,6 +107,8 @@ void SnoopIso14443(void);
 void RAMFUNC SnoopIso14443a(void);
 void SimulateIso14443aTag(int tagType, int TagUid);    // ## simulate iso14443a tag
 void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
+
+// mifarecmd.h
 void ReaderMifare(uint32_t parameter);
 void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
 void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
@@ -114,6 +116,11 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 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);
+void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
+void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
+void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
+void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
+void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 
 /// iso15693.h
 void RecordRawAdcSamplesIso15693(void);
index ce8467bfe37ed1bf78d7136a03002a90360eb03f..74e269da11c92f60e62e82046c3e4ec16ca275fd 100644 (file)
@@ -65,6 +65,13 @@ void iso14a_set_trigger(int enable) {
        trigger = enable;
 }
 
+void iso14a_clear_tracelen(void) {
+       traceLen = 0;
+}
+void iso14a_set_tracing(int enable) {
+       tracing = enable;
+}
+
 //-----------------------------------------------------------------------------
 // Generate the parity value for a byte sequence
 //
@@ -836,7 +843,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, int len, uint32_t dwParity
 
        // Flush the buffer in FPGA!!
        for(i = 0; i < 5; i++) {
-               ToSend[++ToSendMax] = SEC_F;
+//             ToSend[++ToSendMax] = SEC_F;
        }
 
        // Convert from last byte pos to length
@@ -1989,582 +1996,6 @@ void ReaderMifare(uint32_t parameter)
        if (MF_DBGLEVEL >= 1)   DbpString("COMMAND mifare FINISHED");
 }
 
-//-----------------------------------------------------------------------------
-// Select, Authenticaate, Read an MIFARE tag. 
-// read block
-//-----------------------------------------------------------------------------
-void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
-{
-  // params
-       uint8_t blockNo = arg0;
-       uint8_t keyType = arg1;
-       uint64_t ui64Key = 0;
-       ui64Key = bytes_to_num(datain, 6);
-       
-       // variables
-       byte_t isOK = 0;
-       byte_t dataoutbuf[16];
-       uint8_t uid[8];
-       uint32_t cuid;
-       struct Crypto1State mpcs = {0, 0};
-       struct Crypto1State *pcs;
-       pcs = &mpcs;
-
-       // clear trace
-       traceLen = 0;
-//     tracing = false;
-
-       iso14443a_setup();
-
-       LED_A_ON();
-       LED_B_OFF();
-       LED_C_OFF();
-
-       while (true) {
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                       break;
-               };
-
-               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");
-                       break;
-               };
-               
-               if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block error");
-                       break;
-               };
-
-               if(mifare_classic_halt(pcs, cuid)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
-                       break;
-               };
-               
-               isOK = 1;
-               break;
-       }
-       
-       //  ----------------------------- crypto1 destroy
-       crypto1_destroy(pcs);
-       
-       if (MF_DBGLEVEL >= 2)   DbpString("READ BLOCK FINISHED");
-
-       // add trace trailer
-       memset(uid, 0x44, 4);
-       LogTrace(uid, 4, 0, 0, TRUE);
-
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
-       memcpy(ack.d.asBytes, dataoutbuf, 16);
-       
-       LED_B_ON();
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-       LED_B_OFF();
-
-
-  // Thats it...
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       LEDsoff();
-//  tracing = TRUE;
-
-}
-
-//-----------------------------------------------------------------------------
-// Select, Authenticaate, Read an MIFARE tag. 
-// read sector (data = 4 x 16 bytes = 64 bytes)
-//-----------------------------------------------------------------------------
-void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
-{
-  // params
-       uint8_t sectorNo = arg0;
-       uint8_t keyType = arg1;
-       uint64_t ui64Key = 0;
-       ui64Key = bytes_to_num(datain, 6);
-       
-       // variables
-       byte_t isOK = 0;
-       byte_t dataoutbuf[16 * 4];
-       uint8_t uid[8];
-       uint32_t cuid;
-       struct Crypto1State mpcs = {0, 0};
-       struct Crypto1State *pcs;
-       pcs = &mpcs;
-
-       // clear trace
-       traceLen = 0;
-//     tracing = false;
-
-       iso14443a_setup();
-
-       LED_A_ON();
-       LED_B_OFF();
-       LED_C_OFF();
-
-       while (true) {
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                       break;
-               };
-
-               if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");
-                       break;
-               };
-               
-               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf + 16 * 0)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 0 error");
-                       break;
-               };
-               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf + 16 * 1)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 1 error");
-                       break;
-               };
-               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf + 16 * 2)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 2 error");
-                       break;
-               };
-               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf + 16 * 3)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 3 error");
-                       break;
-               };
-               
-               if(mifare_classic_halt(pcs, cuid)) {
-               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
-                       break;
-               };
-
-               isOK = 1;
-               break;
-       }
-       
-       //  ----------------------------- crypto1 destroy
-       crypto1_destroy(pcs);
-       
-       if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");
-
-       // add trace trailer
-       memset(uid, 0x44, 4);
-       LogTrace(uid, 4, 0, 0, TRUE);
-
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
-       memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);
-       
-       LED_B_ON();
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-
-       SpinDelay(100);
-       
-       memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-       LED_B_OFF();    
-
-       // Thats it...
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       LEDsoff();
-//  tracing = TRUE;
-
-}
-
-//-----------------------------------------------------------------------------
-// Select, Authenticaate, Read an MIFARE tag. 
-// read block
-//-----------------------------------------------------------------------------
-void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
-{
-       // params
-       uint8_t blockNo = arg0;
-       uint8_t keyType = arg1;
-       uint64_t ui64Key = 0;
-       byte_t blockdata[16];
-
-       ui64Key = bytes_to_num(datain, 6);
-       memcpy(blockdata, datain + 10, 16);
-       
-       // variables
-       byte_t isOK = 0;
-       uint8_t uid[8];
-       uint32_t cuid;
-       struct Crypto1State mpcs = {0, 0};
-       struct Crypto1State *pcs;
-       pcs = &mpcs;
-
-       // clear trace
-       traceLen = 0;
-//  tracing = false;
-
-       iso14443a_setup();
-
-       LED_A_ON();
-       LED_B_OFF();
-       LED_C_OFF();
-
-       while (true) {
-                       if(!iso14443a_select_card(uid, NULL, &cuid)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                       break;
-               };
-
-               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");
-                       break;
-               };
-               
-               if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");
-                       break;
-               };
-
-               if(mifare_classic_halt(pcs, cuid)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
-                       break;
-               };
-               
-               isOK = 1;
-               break;
-       }
-       
-       //  ----------------------------- crypto1 destroy
-       crypto1_destroy(pcs);
-       
-       if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");
-
-       // add trace trailer
-       memset(uid, 0x44, 4);
-       LogTrace(uid, 4, 0, 0, TRUE);
-
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
-       
-       LED_B_ON();
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-       LED_B_OFF();    
-
-
-       // Thats it...
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       LEDsoff();
-//  tracing = TRUE;
-
-}
-
-// Return 1 if the nonce is invalid else return 0
-int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
-       return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
-       (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
-       (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// MIFARE nested authentication. 
-// 
-//-----------------------------------------------------------------------------
-void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
-{
-       // params
-       uint8_t blockNo = arg0;
-       uint8_t keyType = arg1;
-       uint8_t targetBlockNo = arg2 & 0xff;
-       uint8_t targetKeyType = (arg2 >> 8) & 0xff;
-       uint64_t ui64Key = 0;
-
-       ui64Key = bytes_to_num(datain, 6);
-       
-       // variables
-       int rtr, i, j, m, len;
-       int davg, dmin, dmax;
-       uint8_t uid[8];
-       uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;
-       uint8_t par_array[4];
-       nestedVector nvector[NES_MAX_INFO + 1][10];
-       int nvectorcount[NES_MAX_INFO + 1];
-       int ncount = 0;
-       UsbCommand ack = {CMD_ACK, {0, 0, 0}};
-       struct Crypto1State mpcs = {0, 0};
-       struct Crypto1State *pcs;
-       pcs = &mpcs;
-       uint8_t* receivedAnswer = mifare_get_bigbufptr();
-
-       //init
-       for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11;  //  11 - empty block;
-       
-       // clear trace
-       traceLen = 0;
-  tracing = false;
-       
-       iso14443a_setup();
-
-       LED_A_ON();
-       LED_B_ON();
-       LED_C_OFF();
-
-  FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-  SpinDelay(200);
-       
-       davg = dmax = 0;
-       dmin = 2000;
-
-       // test nonce distance
-       for (rtr = 0; rtr < 10; rtr++) {
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-    SpinDelay(100);
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
-
-    // Test if the action was cancelled
-    if(BUTTON_PRESS()) {
-      break;
-    }
-
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                       break;
-               };
-               
-               if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth1 error");
-                       break;
-               };
-
-               if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth2 error");
-                       break;
-               };
-               
-               nttmp = prng_successor(nt1, 500);
-               for (i = 501; i < 2000; i++) {
-                       nttmp = prng_successor(nttmp, 1);
-                       if (nttmp == nt2) break;
-               }
-               
-               if (i != 2000) {
-                       davg += i;
-                       if (dmin > i) dmin = i;
-                       if (dmax < i) dmax = i;
-                       if (MF_DBGLEVEL >= 4)   Dbprintf("r=%d nt1=%08x nt2=%08x distance=%d", rtr, nt1, nt2, i);
-               }
-       }
-       
-       if (rtr == 0)   return;
-
-       davg = davg / rtr;
-       if (MF_DBGLEVEL >= 3)   Dbprintf("distance: min=%d max=%d avg=%d", dmin, dmax, davg);
-
-       LED_B_OFF();
-
-//  -------------------------------------------------------------------------------------------------  
-       
-       LED_C_ON();
-
-       //  get crypted nonces for target sector
-       for (rtr = 0; rtr < NS_RETRIES_GETNONCE; rtr++) {
-       if (MF_DBGLEVEL >= 4)                   Dbprintf("------------------------------");
-
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-    SpinDelay(100);
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
-
-    // Test if the action was cancelled
-    if(BUTTON_PRESS()) {
-      break;
-    }
-
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                       break;
-               };
-               
-               if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth1 error");
-                       break;
-               };
-
-               // nested authentication
-               len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par);
-               if (len != 4) {
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth2 error len=%d", len);
-                       break;
-               };
-       
-               nt2 = bytes_to_num(receivedAnswer, 4);          
-               if (MF_DBGLEVEL >= 4)   Dbprintf("r=%d nt1=%08x nt2enc=%08x nt2par=%08x", rtr, nt1, nt2, par);
-               
-               // Parity validity check
-               for (i = 0; i < 4; i++) {
-                       par_array[i] = (oddparity(receivedAnswer[i]) != ((par & 0x08) >> 3));
-                       par = par << 1;
-               }
-               
-               ncount = 0;
-               for (m = dmin - NS_TOLERANCE; m < dmax + NS_TOLERANCE; m++) {
-                       nttest = prng_successor(nt1, m);
-                       ks1 = nt2 ^ nttest;
-
-                       if (valid_nonce(nttest, nt2, ks1, par_array) && (ncount < 11)){
-                               
-                               nvector[NES_MAX_INFO][ncount].nt = nttest;
-                               nvector[NES_MAX_INFO][ncount].ks1 = ks1;
-                               ncount++;
-                               nvectorcount[NES_MAX_INFO] = ncount;
-                               if (MF_DBGLEVEL >= 4)   Dbprintf("valid m=%d ks1=%08x nttest=%08x", m, ks1, nttest);
-                       }
-
-               }
-               
-               // select vector with length less than got
-               if (nvectorcount[NES_MAX_INFO] != 0) {
-                       m = NES_MAX_INFO;
-                       
-                       for (i = 0; i < NES_MAX_INFO; i++)
-                               if (nvectorcount[i] > 10) {
-                                       m = i;
-                                       break;
-                               }
-                               
-                       if (m == NES_MAX_INFO)
-                               for (i = 0; i < NES_MAX_INFO; i++)
-                                       if (nvectorcount[NES_MAX_INFO] < nvectorcount[i]) {
-                                               m = i;
-                                               break;
-                                       }
-                                       
-                       if (m != NES_MAX_INFO) {
-                               for (i = 0; i < nvectorcount[m]; i++) {
-                                       nvector[m][i] = nvector[NES_MAX_INFO][i];
-                               }
-                               nvectorcount[m] = nvectorcount[NES_MAX_INFO];
-                       }
-               }
-       }
-
-       LED_C_OFF();
-       
-       //  ----------------------------- crypto1 destroy
-       crypto1_destroy(pcs);
-       
-       // add trace trailer
-       memset(uid, 0x44, 4);
-       LogTrace(uid, 4, 0, 0, TRUE);
-
-       for (i = 0; i < NES_MAX_INFO; i++) {
-               if (nvectorcount[i] > 10) continue;
-               
-               for (j = 0; j < nvectorcount[i]; j += 5) {
-                       ncount = nvectorcount[i] - j;
-                       if (ncount > 5) ncount = 5; 
-
-                       ack.arg[0] = 0; // isEOF = 0
-                       ack.arg[1] = ncount;
-                       ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);
-                       memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));
-                       
-                       memcpy(ack.d.asBytes, &cuid, 4);
-                       for (m = 0; m < ncount; m++) {
-                               memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);
-                               memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);
-                       }
-       
-                       LED_B_ON();
-                       SpinDelay(100);
-                       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-                       LED_B_OFF();    
-               }
-       }
-
-       // finalize list
-       ack.arg[0] = 1; // isEOF = 1
-       ack.arg[1] = 0;
-       ack.arg[2] = 0;
-       memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));
-       
-       LED_B_ON();
-       SpinDelay(300);
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-       LED_B_OFF();    
-
-       if (MF_DBGLEVEL >= 4)   DbpString("NESTED FINISHED");
-
-       // Thats it...
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       LEDsoff();
-       
-  tracing = TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// MIFARE check keys. key count up to 8. 
-// 
-//-----------------------------------------------------------------------------
-void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
-{
-  // params
-       uint8_t blockNo = arg0;
-       uint8_t keyType = arg1;
-       uint8_t keyCount = arg2;
-       uint64_t ui64Key = 0;
-       
-       // variables
-       int i;
-       byte_t isOK = 0;
-       uint8_t uid[8];
-       uint32_t cuid;
-       struct Crypto1State mpcs = {0, 0};
-       struct Crypto1State *pcs;
-       pcs = &mpcs;
-       
-       // clear debug level
-       int OLD_MF_DBGLEVEL = MF_DBGLEVEL;      
-       MF_DBGLEVEL = MF_DBG_NONE;
-       
-       // clear trace
-       traceLen = 0;
-  tracing = TRUE;
-
-       iso14443a_setup();
-
-       LED_A_ON();
-       LED_B_OFF();
-       LED_C_OFF();
-
-       SpinDelay(300);
-       for (i = 0; i < keyCount; i++) {
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-    SpinDelay(100);
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
-
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {
-                       if (OLD_MF_DBGLEVEL >= 1)       Dbprintf("Can't select card");
-                       break;
-               };
-
-               ui64Key = bytes_to_num(datain + i * 6, 6);
-               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
-                       continue;
-               };
-               
-               isOK = 1;
-               break;
-       }
-       
-       //  ----------------------------- crypto1 destroy
-       crypto1_destroy(pcs);
-       
-       // add trace trailer
-       memset(uid, 0x44, 4);
-       LogTrace(uid, 4, 0, 0, TRUE);
-
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
-       if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);
-       
-       LED_B_ON();
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-       LED_B_OFF();
-
-  // Thats it...
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       LEDsoff();
-
-       // restore debug level
-       MF_DBGLEVEL = OLD_MF_DBGLEVEL;  
-}
 
 //-----------------------------------------------------------------------------
 // MIFARE 1K simulate. 
@@ -2573,6 +2004,7 @@ 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 _7BUID = 0;
        int vHf = 0;    // in mV
        int nextCycleTimeout = 0;
        int res;
@@ -2594,12 +2026,13 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        uint8_t* receivedCmd = eml_get_bigbufptr_recbuf();
        uint8_t *response = eml_get_bigbufptr_sendbuf();
        
-       static uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k
+       static uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
 
        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 rSAK1[] = {0x04, 0xda, 0x17};
 
        static uint8_t rAUTH_NT[] = {0x1a, 0xac, 0xff, 0x4f};
        static uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00};
@@ -2608,11 +2041,24 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        traceLen = 0;
        tracing = true;
        
-       // emulator memory
-       emlClearMem();
-       emlGetMemBt(rUIDBCC1, 0, 4);
-       rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
-       
+       // get UID from emul memory
+       emlGetMemBt(receivedCmd, 7, 1);
+       _7BUID = !(receivedCmd[0] == 0x00);
+       if (!_7BUID) {                     // ---------- 4BUID
+               rATQA[0] = 0x04;
+
+               emlGetMemBt(rUIDBCC1, 0, 4);
+               rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
+       } else {                           // ---------- 7BUID
+               rATQA[0] = 0x44;
+
+               rUIDBCC1[0] = 0x88;
+               emlGetMemBt(&rUIDBCC1[1], 0, 3);
+               rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
+               emlGetMemBt(rUIDBCC2, 3, 4);
+               rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
+       }
+
 // --------------------------------------      test area
 
    // Authenticate response - nonce
@@ -2650,7 +2096,7 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
   FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
        SpinDelay(200);
 
-       Dbprintf("--> start");
+       Dbprintf("--> start. 7buid=%d", _7BUID);
        // calibrate mkseconds counter
        GetDeltaCountUS();
        while (true) {
@@ -2714,19 +2160,23 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                                // 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 && memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) {
-                                       EmSendCmd(rSAK, sizeof(rSAK));
+                                       if (!_7BUID) 
+                                               EmSendCmd(rSAK, sizeof(rSAK));
+                                       else
+                                               EmSendCmd(rSAK1, sizeof(rSAK1));
 
                                        cuid = bytes_to_num(rUIDBCC1, 4);
-                                       cardSTATE = MFEMUL_WORK;
+                                       if (!_7BUID) {
+                                               cardSTATE = MFEMUL_WORK;
+                                       } else {
+                                               cardSTATE = MFEMUL_SELECT2;
+                                               break;
+                                       }
                                        LED_B_ON();
                                        Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - selTimer);
                                }
@@ -2734,12 +2184,23 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                                break;
                        }
                        case MFEMUL_SELECT2:{
+                               if (len == 2 && (receivedCmd[0] == 0x95 && receivedCmd[1] == 0x20)) {
                                        EmSendCmd(rUIDBCC2, sizeof(rUIDBCC2));
+                                       break;
+                               }
 
-                               cuid = bytes_to_num(rUIDBCC2, 4);
-                               cardSTATE = MFEMUL_WORK;
-                               LED_B_ON();
-Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer);
+                               // select 2 card
+                               if (len == 9 && 
+                                               (receivedCmd[0] == 0x95 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC2, 4) == 0)) {
+                                       EmSendCmd(rSAK, sizeof(rSAK));
+
+                                       cuid = bytes_to_num(rUIDBCC2, 4);
+                                       cardSTATE = MFEMUL_WORK;
+                                       LED_B_ON();
+                                       Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer);
+                                       break;
+                               }
+                               // TODO: goto work state - i guess there is a command
                                break;
                        }
                        case MFEMUL_AUTH1:{
@@ -2775,6 +2236,7 @@ Dbprintf("AUTH COMPLETED. sec=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetT
                                if (len == 4 && (receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61)) {
 authTimer = GetTickCount();
 //                                     EmSendCmd(rAUTH_NT, sizeof(rAUTH_NT));
+//SpinDelayUs(190);
                                        EmSendCmd14443aRaw(resp1, resp1Len, 0);
 LogTrace(NULL, 0, GetDeltaCountUS(), 0, TRUE);
 //                                     crypto1_create(pcs, key64);
index 9ee20c8e36f7f615c78a302bb5b7a54dbeaea308..8d43a5b9eeff745c32892e105b9723cc676cff84 100644 (file)
@@ -27,7 +27,6 @@
 #define CARD_MEMORY        6000
 #define CARD_MEMORY_LEN    1024
 
-
 typedef struct nestedVector { uint32_t nt, ks1; } nestedVector;
 
 extern byte_t oddparity (const byte_t bt);
@@ -44,4 +43,8 @@ extern void iso14443a_setup();
 extern int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, uint32_t * cuid_ptr);
 extern void iso14a_set_trigger(int enable);
 
+extern void iso14a_clear_tracelen(void);
+extern void iso14a_set_tracing(int enable);
+extern int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
+
 #endif /* __ISO14443A_H */
diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
new file mode 100644 (file)
index 0000000..fca4f69
--- /dev/null
@@ -0,0 +1,716 @@
+//-----------------------------------------------------------------------------\r
+// Merlok - June 2011\r
+// Gerhard de Koning Gans - May 2008\r
+// Hagen Fritsch - June 2010\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
+// Routines to support ISO 14443 type A.\r
+//-----------------------------------------------------------------------------\r
+\r
+#include "mifarecmd.h"\r
+#include "apps.h"\r
+\r
+//-----------------------------------------------------------------------------\r
+// Select, Authenticaate, Read an MIFARE tag. \r
+// read block\r
+//-----------------------------------------------------------------------------\r
+void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
+{\r
+  // params\r
+       uint8_t blockNo = arg0;\r
+       uint8_t keyType = arg1;\r
+       uint64_t ui64Key = 0;\r
+       ui64Key = bytes_to_num(datain, 6);\r
+       \r
+       // variables\r
+       byte_t isOK = 0;\r
+       byte_t dataoutbuf[16];\r
+       uint8_t uid[8];\r
+       uint32_t cuid;\r
+       struct Crypto1State mpcs = {0, 0};\r
+       struct Crypto1State *pcs;\r
+       pcs = &mpcs;\r
+\r
+       // clear trace\r
+       iso14a_clear_tracelen();\r
+//     iso14a_set_tracing(false);\r
+\r
+       iso14443a_setup();\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_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");\r
+                       break;\r
+               };\r
+               \r
+               if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block error");\r
+                       break;\r
+               };\r
+\r
+               if(mifare_classic_halt(pcs, cuid)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                       break;\r
+               };\r
+               \r
+               isOK = 1;\r
+               break;\r
+       }\r
+       \r
+       //  ----------------------------- crypto1 destroy\r
+       crypto1_destroy(pcs);\r
+       \r
+       if (MF_DBGLEVEL >= 2)   DbpString("READ BLOCK FINISHED");\r
+\r
+       // add trace trailer\r
+       memset(uid, 0x44, 4);\r
+       LogTrace(uid, 4, 0, 0, TRUE);\r
+\r
+       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+       memcpy(ack.d.asBytes, dataoutbuf, 16);\r
+       \r
+       LED_B_ON();\r
+       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();\r
+\r
+\r
+  // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+//  iso14a_set_tracing(TRUE);\r
+\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// Select, Authenticaate, Read an MIFARE tag. \r
+// read sector (data = 4 x 16 bytes = 64 bytes)\r
+//-----------------------------------------------------------------------------\r
+void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
+{\r
+  // params\r
+       uint8_t sectorNo = arg0;\r
+       uint8_t keyType = arg1;\r
+       uint64_t ui64Key = 0;\r
+       ui64Key = bytes_to_num(datain, 6);\r
+       \r
+       // variables\r
+       byte_t isOK = 0;\r
+       byte_t dataoutbuf[16 * 4];\r
+       uint8_t uid[8];\r
+       uint32_t cuid;\r
+       struct Crypto1State mpcs = {0, 0};\r
+       struct Crypto1State *pcs;\r
+       pcs = &mpcs;\r
+\r
+       // clear trace\r
+       iso14a_clear_tracelen();\r
+//     iso14a_set_tracing(false);\r
+\r
+       iso14443a_setup();\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_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");\r
+                       break;\r
+               };\r
+               \r
+               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf + 16 * 0)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 0 error");\r
+                       break;\r
+               };\r
+               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf + 16 * 1)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 1 error");\r
+                       break;\r
+               };\r
+               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf + 16 * 2)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 2 error");\r
+                       break;\r
+               };\r
+               if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf + 16 * 3)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 3 error");\r
+                       break;\r
+               };\r
+               \r
+               if(mifare_classic_halt(pcs, cuid)) {\r
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                       break;\r
+               };\r
+\r
+               isOK = 1;\r
+               break;\r
+       }\r
+       \r
+       //  ----------------------------- crypto1 destroy\r
+       crypto1_destroy(pcs);\r
+       \r
+       if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
+\r
+       // add trace trailer\r
+       memset(uid, 0x44, 4);\r
+       LogTrace(uid, 4, 0, 0, TRUE);\r
+\r
+       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+       memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
+       \r
+       LED_B_ON();\r
+       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+\r
+       SpinDelay(100);\r
+       \r
+       memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
+       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();    \r
+\r
+       // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+//  iso14a_set_tracing(TRUE);\r
+\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// Select, Authenticaate, Read an MIFARE tag. \r
+// read block\r
+//-----------------------------------------------------------------------------\r
+void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
+{\r
+       // params\r
+       uint8_t blockNo = arg0;\r
+       uint8_t keyType = arg1;\r
+       uint64_t ui64Key = 0;\r
+       byte_t blockdata[16];\r
+\r
+       ui64Key = bytes_to_num(datain, 6);\r
+       memcpy(blockdata, datain + 10, 16);\r
+       \r
+       // variables\r
+       byte_t isOK = 0;\r
+       uint8_t uid[8];\r
+       uint32_t cuid;\r
+       struct Crypto1State mpcs = {0, 0};\r
+       struct Crypto1State *pcs;\r
+       pcs = &mpcs;\r
+\r
+       // clear trace\r
+       iso14a_clear_tracelen();\r
+//  iso14a_set_tracing(false);\r
+\r
+       iso14443a_setup();\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_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");\r
+                       break;\r
+               };\r
+               \r
+               if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");\r
+                       break;\r
+               };\r
+\r
+               if(mifare_classic_halt(pcs, cuid)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                       break;\r
+               };\r
+               \r
+               isOK = 1;\r
+               break;\r
+       }\r
+       \r
+       //  ----------------------------- crypto1 destroy\r
+       crypto1_destroy(pcs);\r
+       \r
+       if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
+\r
+       // add trace trailer\r
+       memset(uid, 0x44, 4);\r
+       LogTrace(uid, 4, 0, 0, TRUE);\r
+\r
+       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+       \r
+       LED_B_ON();\r
+       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();    \r
+\r
+\r
+       // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+//  iso14a_set_tracing(TRUE);\r
+\r
+}\r
+\r
+// Return 1 if the nonce is invalid else return 0\r
+int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {\r
+       return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \\r
+       (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \\r
+       (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// MIFARE nested authentication. \r
+// \r
+//-----------------------------------------------------------------------------\r
+void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)\r
+{\r
+       // params\r
+       uint8_t blockNo = arg0;\r
+       uint8_t keyType = arg1;\r
+       uint8_t targetBlockNo = arg2 & 0xff;\r
+       uint8_t targetKeyType = (arg2 >> 8) & 0xff;\r
+       uint64_t ui64Key = 0;\r
+\r
+       ui64Key = bytes_to_num(datain, 6);\r
+       \r
+       // variables\r
+       int rtr, i, j, m, len;\r
+       int davg, dmin, dmax;\r
+       uint8_t uid[8];\r
+       uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;\r
+       uint8_t par_array[4];\r
+       nestedVector nvector[NES_MAX_INFO + 1][10];\r
+       int nvectorcount[NES_MAX_INFO + 1];\r
+       int ncount = 0;\r
+       UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
+       struct Crypto1State mpcs = {0, 0};\r
+       struct Crypto1State *pcs;\r
+       pcs = &mpcs;\r
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+\r
+       //init\r
+       for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11;  //  11 - empty block;\r
+       \r
+       // clear trace\r
+       iso14a_clear_tracelen();\r
+  iso14a_set_tracing(false);\r
+       \r
+       iso14443a_setup();\r
+\r
+       LED_A_ON();\r
+       LED_B_ON();\r
+       LED_C_OFF();\r
+\r
+  FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+  SpinDelay(200);\r
+       \r
+       davg = dmax = 0;\r
+       dmin = 2000;\r
+\r
+       // test nonce distance\r
+       for (rtr = 0; rtr < 10; rtr++) {\r
+    FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+    SpinDelay(100);\r
+    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+\r
+    // Test if the action was cancelled\r
+    if(BUTTON_PRESS()) {\r
+      break;\r
+    }\r
+\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_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth1 error");\r
+                       break;\r
+               };\r
+\r
+               if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth2 error");\r
+                       break;\r
+               };\r
+               \r
+               nttmp = prng_successor(nt1, 500);\r
+               for (i = 501; i < 2000; i++) {\r
+                       nttmp = prng_successor(nttmp, 1);\r
+                       if (nttmp == nt2) break;\r
+               }\r
+               \r
+               if (i != 2000) {\r
+                       davg += i;\r
+                       if (dmin > i) dmin = i;\r
+                       if (dmax < i) dmax = i;\r
+                       if (MF_DBGLEVEL >= 4)   Dbprintf("r=%d nt1=%08x nt2=%08x distance=%d", rtr, nt1, nt2, i);\r
+               }\r
+       }\r
+       \r
+       if (rtr == 0)   return;\r
+\r
+       davg = davg / rtr;\r
+       if (MF_DBGLEVEL >= 3)   Dbprintf("distance: min=%d max=%d avg=%d", dmin, dmax, davg);\r
+\r
+       LED_B_OFF();\r
+\r
+//  -------------------------------------------------------------------------------------------------  \r
+       \r
+       LED_C_ON();\r
+\r
+       //  get crypted nonces for target sector\r
+       for (rtr = 0; rtr < NS_RETRIES_GETNONCE; rtr++) {\r
+       if (MF_DBGLEVEL >= 4)                   Dbprintf("------------------------------");\r
+\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+    SpinDelay(100);\r
+    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+\r
+    // Test if the action was cancelled\r
+    if(BUTTON_PRESS()) {\r
+      break;\r
+    }\r
+\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_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth1 error");\r
+                       break;\r
+               };\r
+\r
+               // nested authentication\r
+               len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par);\r
+               if (len != 4) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Auth2 error len=%d", len);\r
+                       break;\r
+               };\r
+       \r
+               nt2 = bytes_to_num(receivedAnswer, 4);          \r
+               if (MF_DBGLEVEL >= 4)   Dbprintf("r=%d nt1=%08x nt2enc=%08x nt2par=%08x", rtr, nt1, nt2, par);\r
+               \r
+               // Parity validity check\r
+               for (i = 0; i < 4; i++) {\r
+                       par_array[i] = (oddparity(receivedAnswer[i]) != ((par & 0x08) >> 3));\r
+                       par = par << 1;\r
+               }\r
+               \r
+               ncount = 0;\r
+               for (m = dmin - NS_TOLERANCE; m < dmax + NS_TOLERANCE; m++) {\r
+                       nttest = prng_successor(nt1, m);\r
+                       ks1 = nt2 ^ nttest;\r
+\r
+                       if (valid_nonce(nttest, nt2, ks1, par_array) && (ncount < 11)){\r
+                               \r
+                               nvector[NES_MAX_INFO][ncount].nt = nttest;\r
+                               nvector[NES_MAX_INFO][ncount].ks1 = ks1;\r
+                               ncount++;\r
+                               nvectorcount[NES_MAX_INFO] = ncount;\r
+                               if (MF_DBGLEVEL >= 4)   Dbprintf("valid m=%d ks1=%08x nttest=%08x", m, ks1, nttest);\r
+                       }\r
+\r
+               }\r
+               \r
+               // select vector with length less than got\r
+               if (nvectorcount[NES_MAX_INFO] != 0) {\r
+                       m = NES_MAX_INFO;\r
+                       \r
+                       for (i = 0; i < NES_MAX_INFO; i++)\r
+                               if (nvectorcount[i] > 10) {\r
+                                       m = i;\r
+                                       break;\r
+                               }\r
+                               \r
+                       if (m == NES_MAX_INFO)\r
+                               for (i = 0; i < NES_MAX_INFO; i++)\r
+                                       if (nvectorcount[NES_MAX_INFO] < nvectorcount[i]) {\r
+                                               m = i;\r
+                                               break;\r
+                                       }\r
+                                       \r
+                       if (m != NES_MAX_INFO) {\r
+                               for (i = 0; i < nvectorcount[m]; i++) {\r
+                                       nvector[m][i] = nvector[NES_MAX_INFO][i];\r
+                               }\r
+                               nvectorcount[m] = nvectorcount[NES_MAX_INFO];\r
+                       }\r
+               }\r
+       }\r
+\r
+       LED_C_OFF();\r
+       \r
+       //  ----------------------------- crypto1 destroy\r
+       crypto1_destroy(pcs);\r
+       \r
+       // add trace trailer\r
+       memset(uid, 0x44, 4);\r
+       LogTrace(uid, 4, 0, 0, TRUE);\r
+\r
+       for (i = 0; i < NES_MAX_INFO; i++) {\r
+               if (nvectorcount[i] > 10) continue;\r
+               \r
+               for (j = 0; j < nvectorcount[i]; j += 5) {\r
+                       ncount = nvectorcount[i] - j;\r
+                       if (ncount > 5) ncount = 5; \r
+\r
+                       ack.arg[0] = 0; // isEOF = 0\r
+                       ack.arg[1] = ncount;\r
+                       ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
+                       memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+                       \r
+                       memcpy(ack.d.asBytes, &cuid, 4);\r
+                       for (m = 0; m < ncount; m++) {\r
+                               memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
+                               memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
+                       }\r
+       \r
+                       LED_B_ON();\r
+                       SpinDelay(100);\r
+                       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+                       LED_B_OFF();    \r
+               }\r
+       }\r
+\r
+       // finalize list\r
+       ack.arg[0] = 1; // isEOF = 1\r
+       ack.arg[1] = 0;\r
+       ack.arg[2] = 0;\r
+       memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+       \r
+       LED_B_ON();\r
+       SpinDelay(300);\r
+       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();    \r
+\r
+       if (MF_DBGLEVEL >= 4)   DbpString("NESTED FINISHED");\r
+\r
+       // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+       \r
+  iso14a_set_tracing(TRUE);\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// MIFARE check keys. key count up to 8. \r
+// \r
+//-----------------------------------------------------------------------------\r
+void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
+{\r
+  // params\r
+       uint8_t blockNo = arg0;\r
+       uint8_t keyType = arg1;\r
+       uint8_t keyCount = arg2;\r
+       uint64_t ui64Key = 0;\r
+       \r
+       // variables\r
+       int i;\r
+       byte_t isOK = 0;\r
+       uint8_t uid[8];\r
+       uint32_t cuid;\r
+       struct Crypto1State mpcs = {0, 0};\r
+       struct Crypto1State *pcs;\r
+       pcs = &mpcs;\r
+       \r
+       // clear debug level\r
+       int OLD_MF_DBGLEVEL = MF_DBGLEVEL;      \r
+       MF_DBGLEVEL = MF_DBG_NONE;\r
+       \r
+       // clear trace\r
+       iso14a_clear_tracelen();\r
+  iso14a_set_tracing(TRUE);\r
+\r
+       iso14443a_setup();\r
+\r
+       LED_A_ON();\r
+       LED_B_OFF();\r
+       LED_C_OFF();\r
+\r
+       SpinDelay(300);\r
+       for (i = 0; i < keyCount; i++) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+    SpinDelay(100);\r
+    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+\r
+               if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+                       if (OLD_MF_DBGLEVEL >= 1)       Dbprintf("Can't select card");\r
+                       break;\r
+               };\r
+\r
+               ui64Key = bytes_to_num(datain + i * 6, 6);\r
+               if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
+                       continue;\r
+               };\r
+               \r
+               isOK = 1;\r
+               break;\r
+       }\r
+       \r
+       //  ----------------------------- crypto1 destroy\r
+       crypto1_destroy(pcs);\r
+       \r
+       // add trace trailer\r
+       memset(uid, 0x44, 4);\r
+       LogTrace(uid, 4, 0, 0, TRUE);\r
+\r
+       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+       if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
+       \r
+       LED_B_ON();\r
+       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();\r
+\r
+  // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+\r
+       // restore debug level\r
+       MF_DBGLEVEL = OLD_MF_DBGLEVEL;  \r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// MIFARE commands set debug level\r
+// \r
+//-----------------------------------------------------------------------------\r
+void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+       MF_DBGLEVEL = arg0;\r
+       Dbprintf("Debug level: %d", MF_DBGLEVEL);\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// Work with emulator memory\r
+// \r
+//-----------------------------------------------------------------------------\r
+void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+       emlClearMem();\r
+}\r
+\r
+void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+       emlSetMem(datain, arg0, arg1); // data, block num, blocks count\r
+}\r
+\r
+void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+       UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
+\r
+       emlGetMem(ack.d.asBytes, arg0, arg1); // data, block num, blocks count\r
+\r
+       LED_B_ON();\r
+       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// Load a card into the emulator memory\r
+// \r
+//-----------------------------------------------------------------------------\r
+void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+       int i;\r
+       uint8_t sectorNo = 0;\r
+       uint8_t keyType = arg1;\r
+       uint64_t ui64Key = 0;\r
+       uint32_t cuid;\r
+       struct Crypto1State mpcs = {0, 0};\r
+       struct Crypto1State *pcs;\r
+       pcs = &mpcs;\r
+\r
+       // variables\r
+       byte_t dataoutbuf[16];\r
+       uint8_t uid[8];\r
+\r
+       // clear trace\r
+       iso14a_clear_tracelen();\r
+       iso14a_set_tracing(false);\r
+       \r
+       iso14443a_setup();\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
+               for (i = 0; i < 16; i++) {\r
+                       sectorNo = i;\r
+                       ui64Key = emlGetKey(sectorNo, keyType);\r
+       \r
+                       if (!i){\r
+                               if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("Sector[%d]. Auth error", i);\r
+                                       break;\r
+                               }\r
+                       } else {\r
+                               if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_NESTED)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("Sector[%d]. Auth nested error", i);\r
+                                       break;\r
+                               }\r
+                       }\r
+               \r
+                       if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 0 error");\r
+                               break;\r
+                       };\r
+                       emlSetMem(dataoutbuf, sectorNo * 4 + 0, 1);\r
+                       \r
+                       if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 1 error");\r
+                               break;\r
+                       };\r
+                       emlSetMem(dataoutbuf, sectorNo * 4 + 1, 1);\r
+\r
+                       if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Read block 2 error");\r
+                               break;\r
+                       };\r
+                       emlSetMem(dataoutbuf, sectorNo * 4 + 2, 1);\r
+               }\r
+\r
+               if(mifare_classic_halt(pcs, cuid)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                       break;\r
+               };\r
+               \r
+               break;\r
+       }       \r
+\r
+       //  ----------------------------- crypto1 destroy\r
+       crypto1_destroy(pcs);\r
+       \r
+       if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");\r
+\r
+       // add trace trailer\r
+       memset(uid, 0x44, 4);\r
+       LogTrace(uid, 4, 0, 0, TRUE);\r
+       \r
+       Dbprintf("Loaded.");\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// MIFARE 1k emulator\r
+// \r
+//-----------------------------------------------------------------------------\r
+\r
diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h
new file mode 100644 (file)
index 0000000..3c00a34
--- /dev/null
@@ -0,0 +1,28 @@
+//-----------------------------------------------------------------------------\r
+// Merlok - June 2011\r
+// Gerhard de Koning Gans - May 2008\r
+// Hagen Fritsch - June 2010\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
+// Routines to support ISO 14443 type A.\r
+//-----------------------------------------------------------------------------\r
+\r
+#ifndef __MIFARECMD_H\r
+#define __MIFARECMD_H\r
+\r
+#include "proxmark3.h"\r
+#include "apps.h"\r
+#include "util.h"\r
+#include "string.h"\r
+\r
+#include "iso14443crc.h"\r
+#include "iso14443a.h"\r
+#include "crapto1.h"\r
+#include "mifareutil.h"\r
+#include "common.h"\r
+\r
+\r
+#endif
\ No newline at end of file
index 8970813567d2a5ede69d2a43e20a5418b2771aca..be36e9db2a0abd5f6c5d77b6fda4a500fbed26ba 100644 (file)
@@ -339,6 +339,14 @@ void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
        memcpy(data, emCARD + bytePtr, byteCount);\r
 }\r
 \r
+uint64_t emlGetKey(int sectorNum, int keyType) {\r
+       uint8_t key[6];\r
+       uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
+       \r
+       memcpy(key, emCARD + 3 * 16 + sectorNum * 4 * 16 + keyType * 10, 6);\r
+       return bytes_to_num(key, 6);\r
+}\r
+\r
 void emlClearMem(void) {\r
        int i;\r
        \r
index 51ff25922f08751007dc8dcdeb996ebe6457d9b0..59e3cc5b52d35b05c4bd367ce640aea3e297bbf3 100644 (file)
@@ -82,5 +82,6 @@ void emlClearMem(void);
 void emlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
 void emlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
 void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount);\r
+uint64_t emlGetKey(int sectorNum, int keyType);\r
 \r
 #endif
\ No newline at end of file
index ee72dad5855d07314575809d917b86bfb9b1a808..d771c64544424d94a07d8a65eeb83f0fd3a4a48f 100644 (file)
@@ -9,6 +9,7 @@
 //-----------------------------------------------------------------------------\r
 \r
 #include "cmdhfmf.h"\r
+#include "proxmark3.h"\r
 \r
 static int CmdHelp(const char *Cmd);\r
 \r
@@ -268,17 +269,20 @@ int CmdHF14AMfNested(const char *Cmd)
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
        uint8_t keyBlock[16 * 6];\r
        uint64_t key64 = 0;\r
+       int transferToEml = 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(" all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)> [t]");\r
+               PrintAndLog(" one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)> [t]");\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("t - transfer keys into emulator memory");\r
                PrintAndLog(" ");\r
                PrintAndLog("      sample1: hf mf nested 1 0 A FFFFFFFFFFFF ");\r
+               PrintAndLog("      sample1: hf mf nested 1 0 A FFFFFFFFFFFF t ");\r
                PrintAndLog("      sample2: hf mf nested o 0 A FFFFFFFFFFFF 4 A");\r
                return 0;\r
        }       \r
@@ -296,7 +300,7 @@ int CmdHF14AMfNested(const char *Cmd)
                return 1;\r
        }\r
        \r
-       if (cmdp =='o' || cmdp == 'O') {\r
+       if (cmdp == 'o' || cmdp == 'O') {\r
                cmdp = 'o';\r
                trgBlockNo = param_get8(Cmd, 4);\r
                ctmp = param_getchar(Cmd, 5);\r
@@ -314,8 +318,13 @@ int CmdHF14AMfNested(const char *Cmd)
                        default:  SectorsCnt = 16;\r
                }\r
        }\r
+\r
+       ctmp = param_getchar(Cmd, 4);\r
+       if (ctmp == 't' || ctmp == 'T') transferToEml = 1;\r
+       ctmp = param_getchar(Cmd, 6);\r
+       transferToEml |= (ctmp == 't' || ctmp == 'T');\r
        \r
-       PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));\r
+       PrintAndLog("--block no:%02x key type:%02x key:%s etrans:%d", blockNo, keyType, sprint_hex(key, 6), transferToEml);\r
        if (cmdp == 'o')\r
                PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo, trgKeyType);\r
 \r
@@ -333,10 +342,22 @@ int CmdHF14AMfNested(const char *Cmd)
                res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);\r
                if (res)\r
                        res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);\r
-               if (!res)\r
+               if (!res) {\r
                        PrintAndLog("Found valid key:%012llx", key64);\r
-               else\r
+\r
+                       // transfer key to the emulator\r
+                       if (transferToEml) {\r
+                               mfEmlGetMem(keyBlock, (trgBlockNo / 4) * 4 + 3, 1);\r
+               \r
+                               if (!trgKeyType)\r
+                                       num_to_bytes(key64, 6, keyBlock);\r
+                               else\r
+                                       num_to_bytes(key64, 6, &keyBlock[10]);\r
+                               mfEmlSetMem(keyBlock, (trgBlockNo / 4) * 4 + 3, 1);             \r
+                       }\r
+               } else {\r
                        PrintAndLog("No valid key found");\r
+               }\r
        } else  // ------------------------------------  multiple sectors working\r
        {\r
                blDiff = blockNo % 4;\r
@@ -401,6 +422,18 @@ int CmdHF14AMfNested(const char *Cmd)
                }\r
                PrintAndLog("|---|----------------|---|----------------|---|");\r
                \r
+               // transfer them to the emulator\r
+               if (transferToEml) {\r
+                       for (i = 0; i < SectorsCnt; i++) {\r
+                               mfEmlGetMem(keyBlock, i * 4 + 3, 1);\r
+                               if (e_sector[i].foundKey[0])\r
+                                       num_to_bytes(e_sector[i].Key[1], 6, keyBlock);\r
+                               if (e_sector[i].foundKey[1])\r
+                                       num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]);\r
+                               mfEmlSetMem(keyBlock, i * 4 + 3, 1);\r
+                       }               \r
+               }\r
+               \r
                free(e_sector);\r
        }\r
 \r
@@ -488,7 +521,12 @@ int CmdHF14AMf1kSim(const char *Cmd)
 \r
 int CmdHF14AMfDbg(const char *Cmd)\r
 {\r
-       if (strlen(Cmd) < 1) {\r
+       int dbgMode = param_get32ex(Cmd, 0, 0, 10);\r
+       if (dbgMode > 4) {\r
+               PrintAndLog("Max debud mode parameter is 4 \n");\r
+       }\r
+\r
+       if (strlen(Cmd) < 1 || !param_getchar(Cmd, 0) || dbgMode > 4) {\r
                PrintAndLog("Usage:  hf mf dbg  <debug level>");\r
                PrintAndLog(" 0 - no debug messages");\r
                PrintAndLog(" 1 - error messages");\r
@@ -497,19 +535,83 @@ int CmdHF14AMfDbg(const char *Cmd)
                return 0;\r
        }       \r
 \r
-       PrintAndLog("No code here (");\r
+  UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};\r
+  SendCommand(&c);\r
+\r
   return 0;\r
 }\r
 \r
 int CmdHF14AMfEGet(const char *Cmd)\r
 {\r
-       PrintAndLog("No code here (");\r
+       uint8_t blockNo = 0;\r
+       uint8_t data[3 * 16];\r
+       int i;\r
+\r
+       if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
+               PrintAndLog("Usage:  hf mf eget <block number>");\r
+               PrintAndLog(" sample: hf mf eget 0 ");\r
+               return 0;\r
+       }       \r
+       \r
+       blockNo = param_get8(Cmd, 0);\r
+       if (blockNo >= 16 * 4) {\r
+               PrintAndLog("Block number must be in [0..63] as in MIFARE classic.");\r
+               return 1;\r
+       }\r
+\r
+       PrintAndLog(" ");\r
+       if (!mfEmlGetMem(data, blockNo, 3)) {\r
+               for (i = 0; i < 3; i++) {\r
+                       PrintAndLog("data[%d]:%s", blockNo + i, sprint_hex(data + i * 16, 16));\r
+               }\r
+       } else {\r
+               PrintAndLog("Command execute timeout");\r
+       }\r
+\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfEClear(const char *Cmd)\r
+{\r
+       if (param_getchar(Cmd, 0) == 'h') {\r
+               PrintAndLog("Usage:  hf mf eclr");\r
+               PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n");\r
+               return 0;\r
+       }       \r
+\r
+  UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};\r
+  SendCommand(&c);\r
   return 0;\r
 }\r
 \r
 int CmdHF14AMfESet(const char *Cmd)\r
 {\r
-       PrintAndLog("No code here (");\r
+       uint8_t memBlock[16];\r
+       uint8_t blockNo = 0;\r
+\r
+       memset(memBlock, 0x00, sizeof(memBlock));\r
+\r
+       if (strlen(Cmd) < 3 || param_getchar(Cmd, 0) == 'h') {\r
+               PrintAndLog("Usage:  hf mf eset <block number> <block data (32 hex symbols)>");\r
+               PrintAndLog(" sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f ");\r
+               return 0;\r
+       }       \r
+       \r
+       blockNo = param_get8(Cmd, 0);\r
+       if (blockNo >= 16 * 4) {\r
+               PrintAndLog("Block number must be in [0..63] as in MIFARE classic.");\r
+               return 1;\r
+       }\r
+       \r
+       if (param_gethex(Cmd, 1, memBlock, 32)) {\r
+               PrintAndLog("block data must include 32 HEX symbols");\r
+               return 1;\r
+       }\r
+       \r
+       //  1 - blocks count\r
+  UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}};\r
+       memcpy(c.d.asBytes, memBlock, 16);\r
+  SendCommand(&c);\r
   return 0;\r
 }\r
 \r
@@ -525,6 +627,51 @@ int CmdHF14AMfESave(const char *Cmd)
   return 0;\r
 }\r
 \r
+int CmdHF14AMfECFill(const char *Cmd) {\r
+       uint8_t keyType = 0;\r
+\r
+       if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
+               PrintAndLog("Usage:  hf mf efill <key A/B>");\r
+               PrintAndLog("sample:  hf mf efill A");\r
+               PrintAndLog("Card data blocks transfers to card emulator memory.");\r
+               PrintAndLog("Keys must be laid in the simulator memory. \n");\r
+               return 0;\r
+       }       \r
+\r
+       char ctmp = param_getchar(Cmd, 0);\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
+  UsbCommand c = {CMD_MIFARE_EML_CARDLOAD, {0, keyType, 0}};\r
+  SendCommand(&c);\r
+  return 0;\r
+}\r
+\r
+int CmdHF14AMfEKeyPrn(const char *Cmd) {\r
+       int i;\r
+       uint8_t data[16];\r
+       uint64_t keyA, keyB;\r
+       \r
+       PrintAndLog("|---|----------------|----------------|");\r
+       PrintAndLog("|sec|key A           |key B           |");\r
+       PrintAndLog("|---|----------------|----------------|");\r
+       for (i = 0; i < 16; i++) {\r
+               if (mfEmlGetMem(data, i * 4 + 3, 1)) {\r
+                       PrintAndLog("error get block %d", i * 4 + 3);\r
+                       break;\r
+               }\r
+               keyA = bytes_to_num(data, 6);\r
+               keyB = bytes_to_num(data + 10, 6);\r
+               PrintAndLog("|%03d|  %012llx  |  %012llx  |", i, keyA, keyB);\r
+       }\r
+       PrintAndLog("|---|----------------|----------------|");\r
+       \r
+       return 0;\r
+}\r
+\r
 static command_t CommandTable[] = \r
 {\r
   {"help",             CmdHelp,                                                1, "This help"},\r
@@ -536,10 +683,13 @@ static command_t CommandTable[] =
   {"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
+  {"eclr",     CmdHF14AMfEClear,               0, "Clear simulator memory block"},\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
+  {"ecfill",   CmdHF14AMfECFill,               0, "Fill simulator memory with help of keys from simulator"},\r
+  {"ekeyprn",  CmdHF14AMfEKeyPrn,      0, "Print keys from simulator memory"},\r
   {NULL, NULL, 0, NULL}\r
 };\r
 \r
index a4ca77600b5abe573a3f43325ec729bf549e4d32..d7ee5a4b050fc9f2f9618ae7997c3012f509e3ff 100644 (file)
@@ -15,6 +15,7 @@
 #include <stdlib.h>\r
 #include <string.h>\r
 #include <ctype.h>\r
+#include "proxmark3.h"\r
 #include "iso14443crc.h"\r
 #include "data.h"\r
 #include "proxusb.h"\r
index c6f2fe3fa248a7ebded551448addb14d975b2d74..f52fb602ec28da140d4c49a7f8c1ce256694ccd1 100644 (file)
@@ -195,3 +195,23 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
        *key = bytes_to_num(resp->d.asBytes, 6);\r
        return 0;\r
 }\r
+\r
+int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {\r
+  UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};\r
\r
+  SendCommand(&c);\r
+\r
+       UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+\r
+       if (resp == NULL) return 1;\r
+       memcpy(data, resp->d.asBytes, blocksCount * 16); \r
+       return 0;\r
+}\r
+\r
+int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {\r
+  UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};\r
+       memcpy(c.d.asBytes, data, blocksCount * 16); \r
+  SendCommand(&c);\r
+       return 0;\r
+}\r
+\r
index 728dc6cc9f6220d658552543058fb2d06df7b785..fe506f9b1228e5f31ad23b1d52c494a8f9dd14bc 100644 (file)
@@ -42,4 +42,6 @@ typedef struct {
 \r
 int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys);\r
 int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);\r
+int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
+int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
 \r
index 98b28c3cb981243f5256dfd1669b7c8d914f067c..fe3ba7c5f316094188c04f896d7134c77523112b 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
+#include <unistd.h>
 #include <readline/readline.h>
 #include <readline/history.h>
 #include "proxusb.h"
@@ -40,7 +41,11 @@ static void *usb_receiver(void *targ)
       for (int i = 0; i < strlen(PROXPROMPT); i++)
         putchar(0x08);
       UsbCommandReceived(&cmdbuf);
-      printf(PROXPROMPT);
+                       // there is a big bug )
+                       if (cmdbuf.cmd > 0x0100 && cmdbuf.cmd < 0x0110) { // debug commands
+                               rl_on_new_line_with_prompt();
+                               rl_forced_update_display();
+                       }
       fflush(NULL);
     }
   }
@@ -61,21 +66,28 @@ static void *main_loop(void *targ)
     pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
   }
 
-  while(1) {
-    cmd = readline(PROXPROMPT);
-    if (cmd) {
-      while(cmd[strlen(cmd) - 1] == ' ')
-        cmd[strlen(cmd) - 1] = 0x00;
-      if (cmd[0] != 0x00) {
-        CommandReceived(cmd);
-        add_history(cmd);
-      }
-      free(cmd);
-    } else {
-      printf("\n");
-      break;
-    }
-  }
+       read_history(".history");
+       while(1) {
+               cmd = readline(PROXPROMPT);
+               if (cmd) {
+                       while(cmd[strlen(cmd) - 1] == ' ')
+                       cmd[strlen(cmd) - 1] = 0x00;
+                       
+                       if (cmd[0] != 0x00) {
+                               if (strncmp(cmd, "quit", 4) == 0) {
+                                       write_history(".history");
+                                       break;
+                               }
+                               
+                               CommandReceived(cmd);
+                               add_history(cmd);
+                       }
+                       free(cmd);
+               } else {
+                       printf("\n");
+                       break;
+               }
+       }
 
   if (arg->usb_present == 1) {
     rarg.run = 0;
index 3e8066b04066cc01cbccb36979d9a816a80535bd..8b8133cc62fdcc795cb3a1f329058bcf2a8cbd1c 100644 (file)
@@ -103,18 +103,20 @@ typedef struct {
 
 // For mifare commands
 #define CMD_MIFARE_SET_DBGMODE                                 0x0600
-#define CMD_MIFARE_EML_MEMSET                                          0x0601
-#define CMD_MIFARE_EML_MEMGET                                          0x0602
+#define CMD_MIFARE_EML_MEMCLR                                          0x0601
+#define CMD_MIFARE_EML_MEMSET                                          0x0602
+#define CMD_MIFARE_EML_MEMGET                                          0x0603
+#define CMD_MIFARE_EML_CARDLOAD                                        0x0604
 
-#define CMD_SIMULATE_MIFARE_CARD                               0x0603
+#define CMD_SIMULATE_MIFARE_CARD                               0x0610
 
-#define CMD_READER_MIFARE                                                              0x0605
-#define CMD_MIFARE_NESTED                                                              0x0606
+#define CMD_READER_MIFARE                                                              0x0611
+#define CMD_MIFARE_NESTED                                                              0x0612
 
-#define CMD_MIFARE_READBL                                                              0x0610
-#define CMD_MIFARE_READSC                                                              0x0611
-#define CMD_MIFARE_WRITEBL                                                     0x0612
-#define CMD_MIFARE_CHKKEYS                                                     0x0613
+#define CMD_MIFARE_READBL                                                              0x0620
+#define CMD_MIFARE_READSC                                                              0x0621
+#define CMD_MIFARE_WRITEBL                                                     0x0622
+#define CMD_MIFARE_CHKKEYS                                                     0x0623
 
 #define CMD_UNKNOWN                                                                                    0xFFFF
 
Impressum, Datenschutz