X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/8f51ddb0bd8fb7536a07966433061f03d45f65e0..ab8b654efa9524b494014efd35ac426aaa42884b:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index ce8467bf..74e269da 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -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);