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
#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
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
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);
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);
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
//
// 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
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.
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;
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};
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
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) {
// 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);
}
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:{
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);
#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);
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 */
--- /dev/null
+//-----------------------------------------------------------------------------\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
--- /dev/null
+//-----------------------------------------------------------------------------\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
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
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
//-----------------------------------------------------------------------------\r
\r
#include "cmdhfmf.h"\r
+#include "proxmark3.h"\r
\r
static int CmdHelp(const char *Cmd);\r
\r
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
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
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
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
}\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
\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
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
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
{"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
#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
*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
\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
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "proxusb.h"
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);
}
}
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;
// 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