X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/8f51ddb0bd8fb7536a07966433061f03d45f65e0..912a3e94e48952b6a117b4ec9c9623c0ceea1270:/armsrc/iso14443a.c?ds=sidebyside diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index ce8467bf..13a00aba 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -20,11 +20,12 @@ #include "crapto1.h" #include "mifareutil.h" -static uint8_t *trace = (uint8_t *) BigBuf; -static int traceLen = 0; -static int rsamples = 0; -static int tracing = TRUE; static uint32_t iso14a_timeout; +uint8_t *trace = (uint8_t *) BigBuf; +int traceLen = 0; +int rsamples = 0; +int tracing = TRUE; +uint8_t trigger = 0; // CARD TO READER - manchester // Sequence D: 11110000 modulation with subcarrier during first half @@ -41,7 +42,7 @@ static uint32_t iso14a_timeout; #define SEC_Y 0x00 #define SEC_Z 0xc0 -static const uint8_t OddByteParity[256] = { +const uint8_t OddByteParity[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, @@ -60,11 +61,18 @@ static const uint8_t OddByteParity[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 }; -uint8_t trigger = 0; + 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 // @@ -92,6 +100,7 @@ void AppendCrc14443a(uint8_t* data, int len) ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); } +// The function LogTrace() is also used by the iClass implementation in iClass.c int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader) { // Return when trace is full @@ -149,7 +158,7 @@ static struct { static RAMFUNC int MillerDecoding(int bit) { - int error = 0; + //int error = 0; int bitright; if(!Uart.bitBuffer) { @@ -195,7 +204,7 @@ static RAMFUNC int MillerDecoding(int bit) // measured a drop in first and second half // which should not be possible Uart.state = STATE_ERROR_WAIT; - error = 0x01; + //error = 0x01; } Uart.posCnt = 0; @@ -206,7 +215,7 @@ static RAMFUNC int MillerDecoding(int bit) if(Uart.drop == DROP_SECOND_HALF) { // error, should not happen in SOC Uart.state = STATE_ERROR_WAIT; - error = 0x02; + //error = 0x02; } else { // correct SOC @@ -244,7 +253,7 @@ static RAMFUNC int MillerDecoding(int bit) // Would be STATE_MILLER_Z // but Z does not follow X, so error Uart.state = STATE_ERROR_WAIT; - error = 0x03; + //error = 0x03; } if(Uart.drop == DROP_SECOND_HALF) { // We see a '1' and stay in state X @@ -365,7 +374,7 @@ static RAMFUNC int MillerDecoding(int bit) Uart.bitCnt = 0; Uart.byteCnt = 0; Uart.parityBits = 0; - error = 0; + //error = 0; } else { Uart.highCnt = 0; @@ -415,7 +424,7 @@ static RAMFUNC int ManchesterDecoding(int v) { int bit; int modulation; - int error = 0; + //int error = 0; if(!Demod.buff) { Demod.buff = 1; @@ -472,7 +481,7 @@ static RAMFUNC int ManchesterDecoding(int v) case 0x01: Demod.samples = 0; break; } } - error = 0; + //error = 0; } } else { @@ -496,7 +505,7 @@ static RAMFUNC int ManchesterDecoding(int v) if(Demod.state!=DEMOD_ERROR_WAIT) { Demod.state = DEMOD_ERROR_WAIT; Demod.output[Demod.len] = 0xaa; - error = 0x01; + //error = 0x01; } } else if(modulation) { @@ -511,7 +520,7 @@ static RAMFUNC int ManchesterDecoding(int v) else { Demod.output[Demod.len] = 0xab; Demod.state = DEMOD_ERROR_WAIT; - error = 0x02; + //error = 0x02; } break; @@ -549,7 +558,7 @@ static RAMFUNC int ManchesterDecoding(int v) else { Demod.output[Demod.len] = 0xad; Demod.state = DEMOD_ERROR_WAIT; - error = 0x03; + //error = 0x03; } break; @@ -761,13 +770,10 @@ void RAMFUNC SnoopIso14443a(void) DbpString("COMMAND FINISHED"); - Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt); - Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]); - done: AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; - Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt); - Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]); + Dbprintf("maxBehindBy=%x, Uart.state=%x, Uart.byteCnt=%x", maxBehindBy, Uart.state, Uart.byteCnt); + Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]); LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); @@ -780,7 +786,6 @@ done: static void CodeIso14443aAsTagPar(const uint8_t *cmd, int len, uint32_t dwParity) { int i; -// int oddparity; ToSendReset(); @@ -802,9 +807,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, int len, uint32_t dwParity uint8_t b = cmd[i]; // Data bits -// oddparity = 0x01; for(j = 0; j < 8; j++) { -// oddparity ^= (b & 1); if(b & 1) { ToSend[++ToSendMax] = SEC_D; } else { @@ -813,38 +816,19 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, int len, uint32_t dwParity b >>= 1; } - // Get the parity bit + // Get the parity bit if ((dwParity >> i) & 0x01) { ToSend[++ToSendMax] = SEC_D; } else { ToSend[++ToSendMax] = SEC_E; } - - // Parity bit -// if(oddparity) { -// ToSend[++ToSendMax] = SEC_D; -// } else { -// ToSend[++ToSendMax] = SEC_E; -// } - -// if (oddparity != ((dwParity >> i) & 0x01)) -// Dbprintf("par error. i=%d", i); } // Send stopbit ToSend[++ToSendMax] = SEC_F; - // Flush the buffer in FPGA!! - for(i = 0; i < 5; i++) { - ToSend[++ToSendMax] = SEC_F; - } - // Convert from last byte pos to length ToSendMax++; - - // Add a few more for slop -// ToSend[ToSendMax++] = 0x00; -// ToSend[ToSendMax++] = 0x00; } static void CodeIso14443aAsTag(const uint8_t *cmd, int len){ @@ -1063,9 +1047,9 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); uint8_t *receivedCmd = (uint8_t *)BigBuf; int len; - int i; - int u; - uint8_t b; + //int i; + //int u; + //uint8_t b; // To control where we are in the protocol int order = 0; @@ -1077,7 +1061,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); int cmdsRecvd = 0; - int fdt_indicator; + //int fdt_indicator; memset(receivedCmd, 0x44, 400); @@ -1128,7 +1112,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); // doob - added loads of debug strings so we can see what the reader is saying to us during the sim as hi14alist is not populated // Okay, look at the command now. lastorder = order; - i = 1; // first byte transmitted + //i = 1; // first byte transmitted if(receivedCmd[0] == 0x26) { // Received a REQUEST resp = resp1; respLen = resp1Len; order = 1; @@ -1209,7 +1193,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); // Look at last parity bit to determine timing of answer if((Uart.parityBits & 0x01) || receivedCmd[0] == 0x52) { // 1236, so correction bit needed - i = 0; + //i = 0; } memset(receivedCmd, 0x44, 32); @@ -1224,9 +1208,9 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); if(respLen <= 0) continue; //---------------------------- - u = 0; - b = 0x00; - fdt_indicator = FALSE; + //u = 0; + //b = 0x00; + //fdt_indicator = FALSE; EmSendCmd14443aRaw(resp, respLen, receivedCmd[0] == 0x52); /* // Modulate Manchester @@ -1888,7 +1872,7 @@ void ReaderMifare(uint32_t parameter) byte_t nt_diff = 0; LED_A_OFF(); byte_t par = 0; - byte_t par_mask = 0xff; + //byte_t par_mask = 0xff; byte_t par_low = 0; int led_on = TRUE; uint8_t uid[8]; @@ -1932,14 +1916,14 @@ void ReaderMifare(uint32_t parameter) { if ( (parameter != 0) && (memcmp(nt, nt_noattack, 4) == 0) ) continue; - isNULL = (nt_attacked[0] = 0) && (nt_attacked[1] = 0) && (nt_attacked[2] = 0) && (nt_attacked[3] = 0); + isNULL = (nt_attacked[0] == 0) && (nt_attacked[1] == 0) && (nt_attacked[2] == 0) && (nt_attacked[3] == 0); if ( (isNULL != 0 ) && (memcmp(nt, nt_attacked, 4) != 0) ) continue; if (nt_diff == 0) { LED_A_ON(); memcpy(nt_attacked, nt, 4); - par_mask = 0xf8; + //par_mask = 0xf8; par_low = par & 0x07; } @@ -1989,582 +1973,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,10 +1981,11 @@ 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 nextCycleTimeout = 0; int res; - uint32_t timer = 0; +// uint32_t timer = 0; uint32_t selTimer = 0; uint32_t authTimer = 0; uint32_t par = 0; @@ -2584,61 +1993,59 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) uint8_t cardWRBL = 0; uint8_t cardAUTHSC = 0; uint8_t cardAUTHKEY = 0xff; // no authentication + //uint32_t cardRn = 0; + uint32_t cardRr = 0; uint32_t cuid = 0; + //uint32_t rn_enc = 0; + uint32_t ans = 0; + uint32_t cardINTREG = 0; + uint8_t cardINTBLOCK = 0; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; - uint64_t key64 = 0xffffffffffffULL; - 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_NT[] = {0x01, 0x02, 0x03, 0x04}; +// static uint8_t rAUTH_NT[] = {0x1a, 0xac, 0xff, 0x4f}; static uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00}; - + // clear trace traceLen = 0; tracing = true; + + // Authenticate response - nonce + uint32_t nonce = bytes_to_num(rAUTH_NT, 4); - // 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 - uint8_t *resp1 = (((uint8_t *)BigBuf) + EML_RESPONSES); - int resp1Len; -// uint8_t *resp2 = (((uint8_t *)BigBuf) + EML_RESPONSES + 200); -// int resp2Len; - CodeIso14443aAsTag(rAUTH_NT, sizeof(rAUTH_NT)); - memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax; - - timer = GetTickCount(); - uint32_t nonce = bytes_to_num(rAUTH_NT, 4); - uint32_t rn_enc = 0x98d76b77; // !!!!!!!!!!!!!!!!! - uint32_t ans = 0; - cuid = bytes_to_num(rUIDBCC1, 4); -/* - crypto1_create(pcs, key64); - crypto1_word(pcs, cuid ^ nonce, 0); - crypto1_word(pcs, rn_enc , 1); - crypto1_word(pcs, 0, 0); - ans = prng_successor(nonce, 96) ^ crypto1_word(pcs, 0, 0); - num_to_bytes(ans, 4, rAUTH_AT); - CodeIso14443aAsTag(rAUTH_AT, sizeof(rAUTH_AT)); - memcpy(resp2, ToSend, ToSendMax); resp2Len = ToSendMax; - Dbprintf("crypto auth time: %d", GetTickCount() - timer); -*/ // -------------------------------------- END test area // start mkseconds counter StartCountUS(); @@ -2650,7 +2057,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"); + if (MF_DBGLEVEL >= 1) Dbprintf("Started. 7buid=%d", _7BUID); // calibrate mkseconds counter GetDeltaCountUS(); while (true) { @@ -2666,7 +2073,7 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) if (cardSTATE == MFEMUL_NOFIELD) { vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10; if (vHf > MF_MINFIELDV) { - cardSTATE = MFEMUL_IDLE; + cardSTATE_TO_IDLE(); LED_A_ON(); } } @@ -2681,7 +2088,7 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) if(res) break; } - nextCycleTimeout = 0; + //nextCycleTimeout = 0; // if (len) Dbprintf("len:%d cmd: %02x %02x %02x %02x", len, receivedCmd[0], receivedCmd[1], receivedCmd[2], receivedCmd[3]); @@ -2714,86 +2121,133 @@ 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; - } + break; } // 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; - LED_B_ON(); - Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - selTimer); + if (!_7BUID) { + cardSTATE = MFEMUL_WORK; + LED_B_ON(); + if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - selTimer); + break; + } else { + cardSTATE = MFEMUL_SELECT2; + break; + } } break; } case MFEMUL_SELECT2:{ + if (!len) break; + + if (len == 2 && (receivedCmd[0] == 0x95 && receivedCmd[1] == 0x20)) { EmSendCmd(rUIDBCC2, sizeof(rUIDBCC2)); + break; + } - cuid = bytes_to_num(rUIDBCC2, 4); + // 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(); + if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer); + break; + } + + // i guess there is a command). go into the work state. + if (len != 4) break; cardSTATE = MFEMUL_WORK; - LED_B_ON(); -Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer); - break; + goto lbWORK; } case MFEMUL_AUTH1:{ if (len == 8) { -// --------------------------------- - rn_enc = bytes_to_num(receivedCmd, 4); - crypto1_create(pcs, key64); - crypto1_word(pcs, cuid ^ nonce, 0); - crypto1_word(pcs, rn_enc , 1); - crypto1_word(pcs, 0, 0); - ans = prng_successor(nonce, 96) ^ crypto1_word(pcs, 0, 0); - num_to_bytes(ans, 4, rAUTH_AT); -// --------------------------------- - EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); + // --- crypto + //rn_enc = bytes_to_num(receivedCmd, 4); + //cardRn = rn_enc ^ crypto1_word(pcs, rn_enc , 1); + cardRr = bytes_to_num(&receivedCmd[4], 4) ^ crypto1_word(pcs, 0, 0); + // test if auth OK + if (cardRr != prng_successor(nonce, 64)){ + if (MF_DBGLEVEL >= 4) Dbprintf("AUTH FAILED. cardRr=%08x, succ=%08x", cardRr, prng_successor(nonce, 64)); + cardSTATE_TO_IDLE(); + break; + } + ans = prng_successor(nonce, 96) ^ crypto1_word(pcs, 0, 0); + num_to_bytes(ans, 4, rAUTH_AT); + // --- crypto + EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); cardSTATE = MFEMUL_AUTH2; } else { - cardSTATE = MFEMUL_IDLE; - LED_B_OFF(); - LED_C_OFF(); + cardSTATE_TO_IDLE(); } if (cardSTATE != MFEMUL_AUTH2) break; } case MFEMUL_AUTH2:{ - // test auth info here... - LED_C_ON(); cardSTATE = MFEMUL_WORK; -Dbprintf("AUTH COMPLETED. sec=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - authTimer); + if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED. sec=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - authTimer); break; } case MFEMUL_WORK:{ - // auth - if (len == 4 && (receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61)) { -authTimer = GetTickCount(); -// EmSendCmd(rAUTH_NT, sizeof(rAUTH_NT)); - EmSendCmd14443aRaw(resp1, resp1Len, 0); -LogTrace(NULL, 0, GetDeltaCountUS(), 0, TRUE); -// crypto1_create(pcs, key64); -// if (cardAUTHKEY == 0xff) { // first auth -// crypto1_word(pcs, cuid ^ bytes_to_num(rAUTH_NT, 4), 0); // uid ^ nonce -// } else { // nested auth -// } - - cardAUTHSC = receivedCmd[1] / 4; // received block num - cardAUTHKEY = receivedCmd[0] - 0x60; - cardSTATE = MFEMUL_AUTH1; - nextCycleTimeout = 10; - break; - } +lbWORK: if (len == 0) break; - if (len == 0) break; - - // decrypt seqence - if (cardAUTHKEY != 0xff) mf_crypto1_decrypt(pcs, receivedCmd, len); + if (cardAUTHKEY == 0xff) { + // first authentication + if (len == 4 && (receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61)) { + authTimer = GetTickCount(); + + cardAUTHSC = receivedCmd[1] / 4; // received block num + cardAUTHKEY = receivedCmd[0] - 0x60; + + // --- crypto + crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); + ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); + num_to_bytes(nonce, 4, rAUTH_AT); + EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); + // --- crypto + +// last working revision +// EmSendCmd14443aRaw(resp1, resp1Len, 0); +// LogTrace(NULL, 0, GetDeltaCountUS(), 0, true); + + cardSTATE = MFEMUL_AUTH1; + //nextCycleTimeout = 10; + break; + } + } else { + // decrypt seqence + mf_crypto1_decrypt(pcs, receivedCmd, len); + + // nested authentication + if (len == 4 && (receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61)) { + authTimer = GetTickCount(); + + cardAUTHSC = receivedCmd[1] / 4; // received block num + cardAUTHKEY = receivedCmd[0] - 0x60; + + // --- crypto + crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); + ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); + num_to_bytes(ans, 4, rAUTH_AT); + EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); + // --- crypto + + cardSTATE = MFEMUL_AUTH1; + //nextCycleTimeout = 10; + break; + } + } // rule 13 of 7.5.3. in ISO 14443-4. chaining shall be continued // BUT... ACK --> NACK @@ -2810,7 +2264,7 @@ LogTrace(NULL, 0, GetDeltaCountUS(), 0, TRUE); // read block if (len == 4 && receivedCmd[0] == 0x30) { - if (receivedCmd[1] >= 16 * 4) { + if (receivedCmd[1] >= 16 * 4 || receivedCmd[1] / 4 != cardAUTHSC) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); break; } @@ -2823,32 +2277,72 @@ LogTrace(NULL, 0, GetDeltaCountUS(), 0, TRUE); // write block if (len == 4 && receivedCmd[0] == 0xA0) { - if (receivedCmd[1] >= 16 * 4) { + if (receivedCmd[1] >= 16 * 4 || receivedCmd[1] / 4 != cardAUTHSC) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); break; } EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); - nextCycleTimeout = 50; + //nextCycleTimeout = 50; cardSTATE = MFEMUL_WRITEBL2; cardWRBL = receivedCmd[1]; break; } + // works with cardINTREG + + // increment, decrement, restore + if (len == 4 && (receivedCmd[0] == 0xC0 || receivedCmd[0] == 0xC1 || receivedCmd[0] == 0xC2)) { + if (receivedCmd[1] >= 16 * 4 || + receivedCmd[1] / 4 != cardAUTHSC || + emlCheckValBl(receivedCmd[1])) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + break; + } + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + if (receivedCmd[0] == 0xC1) + cardSTATE = MFEMUL_INTREG_INC; + if (receivedCmd[0] == 0xC0) + cardSTATE = MFEMUL_INTREG_DEC; + if (receivedCmd[0] == 0xC2) + cardSTATE = MFEMUL_INTREG_REST; + cardWRBL = receivedCmd[1]; + + break; + } + + + // transfer + if (len == 4 && receivedCmd[0] == 0xB0) { + if (receivedCmd[1] >= 16 * 4 || receivedCmd[1] / 4 != cardAUTHSC) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + break; + } + + if (emlSetValBl(cardINTREG, cardINTBLOCK, receivedCmd[1])) + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + else + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + + break; + } + // halt if (len == 4 && (receivedCmd[0] == 0x50 && receivedCmd[1] == 0x00)) { - cardSTATE = MFEMUL_HALTED; LED_B_OFF(); LED_C_OFF(); - Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer); + cardSTATE = MFEMUL_HALTED; + if (MF_DBGLEVEL >= 4) Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer); break; } - break; - + // command not allowed if (len == 4) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); break; } + + // case break + break; } case MFEMUL_WRITEBL2:{ if (len == 18){ @@ -2857,8 +2351,46 @@ LogTrace(NULL, 0, GetDeltaCountUS(), 0, TRUE); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); cardSTATE = MFEMUL_WORK; break; + } else { + cardSTATE_TO_IDLE(); + break; } -Dbprintf("err write block: %d len:%d", cardWRBL, len); + break; + } + + case MFEMUL_INTREG_INC:{ + mf_crypto1_decrypt(pcs, receivedCmd, len); + memcpy(&ans, receivedCmd, 4); + if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + cardSTATE_TO_IDLE(); + break; + } + cardINTREG = cardINTREG + ans; + cardSTATE = MFEMUL_WORK; + break; + } + case MFEMUL_INTREG_DEC:{ + mf_crypto1_decrypt(pcs, receivedCmd, len); + memcpy(&ans, receivedCmd, 4); + if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + cardSTATE_TO_IDLE(); + break; + } + cardINTREG = cardINTREG - ans; + cardSTATE = MFEMUL_WORK; + break; + } + case MFEMUL_INTREG_REST:{ + mf_crypto1_decrypt(pcs, receivedCmd, len); + memcpy(&ans, receivedCmd, 4); + if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + cardSTATE_TO_IDLE(); + break; + } + cardSTATE = MFEMUL_WORK; break; } @@ -2873,5 +2405,5 @@ Dbprintf("err write block: %d len:%d", cardWRBL, len); memset(rAUTH_NT, 0x44, 4); LogTrace(rAUTH_NT, 4, 0, 0, TRUE); - DbpString("Emulator stopped."); + if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, traceLen); }