X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/af1caf6e4a0ff82f1e562053c0c3868014c74dfb..d2f487af9cc29122d86ca4f349ba825aaf98748c:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 3966d77a..aa97e6e9 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1926,7 +1926,7 @@ void ReaderMifare(bool first_try) static uint8_t mf_nr_ar3; uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); - traceLen = 0; + iso14a_clear_trace(); tracing = false; byte_t nt_diff = 0; @@ -1974,7 +1974,7 @@ void ReaderMifare(bool first_try) LED_B_OFF(); LED_C_OFF(); - + for(uint16_t i = 0; TRUE; i++) { WDT_HIT(); @@ -2113,18 +2113,22 @@ void ReaderMifare(bool first_try) tracing = TRUE; } -//----------------------------------------------------------------------------- -// MIFARE 1K simulate. -// -//----------------------------------------------------------------------------- -void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) +/** + *MIFARE 1K simulate. + * + *@param flags : + * FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK + * 4B_FLAG_UID_IN_DATA - means that there is a 4-byte UID in the data-section, we're expected to use that + * 7B_FLAG_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that + * FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later + *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is inifite + */ +void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *datain) { int cardSTATE = MFEMUL_NOFIELD; int _7BUID = 0; int vHf = 0; // in mV - //int nextCycleTimeout = 0; int res; -// uint32_t timer = 0; uint32_t selTimer = 0; uint32_t authTimer = 0; uint32_t par = 0; @@ -2132,60 +2136,83 @@ 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 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; - + uint32_t numReads = 0;//Counts numer of times reader read a block uint8_t* receivedCmd = eml_get_bigbufptr_recbuf(); uint8_t *response = eml_get_bigbufptr_sendbuf(); - static uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID + uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID + uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; + uint8_t rUIDBCC2[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; // !!! + uint8_t rSAK[] = {0x08, 0xb6, 0xdd}; + uint8_t rSAK1[] = {0x04, 0xda, 0x17}; - 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}; + uint8_t rAUTH_NT[] = {0x01, 0x02, 0x03, 0x04}; + uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00}; - 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}; + //Here, we collect UID,NT,AR,NR,UID2,NT2,AR2,NR2 + // This can be used in a reader-only attack. + // (it can also be retrieved via 'hf 14a list', but hey... + uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0}; + uint8_t ar_nr_collected = 0; // clear trace - traceLen = 0; + iso14a_clear_trace(); + tracing = true; // Authenticate response - nonce uint32_t nonce = bytes_to_num(rAUTH_NT, 4); - - // get UID from emul memory - emlGetMemBt(receivedCmd, 7, 1); - _7BUID = !(receivedCmd[0] == 0x00); - if (!_7BUID) { // ---------- 4BUID - rATQA[0] = 0x04; - emlGetMemBt(rUIDBCC1, 0, 4); + //-- Determine the UID + // Can be set from emulator memory, incoming data + // and can be 7 or 4 bytes long + if(flags & FLAG_4B_UID_IN_DATA) + { + // 4B uid comes from data-portion of packet + memcpy(rUIDBCC1,datain,4); rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; - } else { // ---------- 7BUID - rATQA[0] = 0x44; + }else if(flags & FLAG_7B_UID_IN_DATA) + { + // 7B uid comes from data-portion of packet + memcpy(&rUIDBCC1[1],datain,3); + memcpy(rUIDBCC2, datain+3, 4); + _7BUID = true; + } + else + { + // get UID from emul memory + emlGetMemBt(receivedCmd, 7, 1); + _7BUID = !(receivedCmd[0] == 0x00); + if (!_7BUID) { // ---------- 4BUID + emlGetMemBt(rUIDBCC1, 0, 4); + } else { // ---------- 7BUID + emlGetMemBt(&rUIDBCC1[1], 0, 3); + emlGetMemBt(rUIDBCC2, 3, 4); + } + } + /* + * Regardless of what method was used to set the UID, set fifth byte and modify + * the ATQA for 4 or 7-byte UID + */ + + rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; + if(_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 - -// -------------------------------------- END test area // start mkseconds counter StartCountUS(); @@ -2193,19 +2220,23 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaSetupSsc(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); SpinDelay(200); - if (MF_DBGLEVEL >= 1) Dbprintf("Started. 7buid=%d", _7BUID); + if (MF_DBGLEVEL >= 1) { + if (!_7BUID) { + Dbprintf("4B UID: %02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3]); + }else + { + Dbprintf("7B UID: (%02x)%02x%02x%02x%02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3],rUIDBCC2[0],rUIDBCC2[1] ,rUIDBCC2[2] , rUIDBCC2[3]); + } + } // calibrate mkseconds counter GetDeltaCountUS(); - while (true) { + bool finished = false; + while (!BUTTON_PRESS() && !finished) { WDT_HIT(); - if(BUTTON_PRESS()) { - break; - } - // find reader field // Vref = 3300mV, and an 10:1 voltage divider on the input // can measure voltages up to 33000 mV @@ -2216,56 +2247,54 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) LED_A_ON(); } } + if(cardSTATE == MFEMUL_NOFIELD) continue; - if (cardSTATE != MFEMUL_NOFIELD) { - res = EmGetCmd(receivedCmd, &len, RECV_CMD_SIZE); // (+ nextCycleTimeout) - if (res == 2) { - cardSTATE = MFEMUL_NOFIELD; - LEDsoff(); - continue; - } - if(res) break; - } - - //nextCycleTimeout = 0; - -// if (len) Dbprintf("len:%d cmd: %02x %02x %02x %02x", len, receivedCmd[0], receivedCmd[1], receivedCmd[2], receivedCmd[3]); - - if (len != 4 && cardSTATE != MFEMUL_NOFIELD) { // len != 4 <---- speed up the code 4 authentication - // REQ or WUP request in ANY state and WUP in HALTED state - if (len == 1 && ((receivedCmd[0] == 0x26 && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == 0x52)) { - selTimer = GetTickCount(); - EmSendCmdEx(rATQA, sizeof(rATQA), (receivedCmd[0] == 0x52)); - cardSTATE = MFEMUL_SELECT1; - - // init crypto block - LED_B_OFF(); - LED_C_OFF(); - crypto1_destroy(pcs); - cardAUTHKEY = 0xff; - } + //Now, get data + + res = EmGetCmd(receivedCmd, &len, RECV_CMD_SIZE); // (+ nextCycleTimeout) + if (res == 2) { //Field is off! + cardSTATE = MFEMUL_NOFIELD; + LEDsoff(); + continue; + }else if(res == 1) break;//return value 1 means button press + + + // REQ or WUP request in ANY state and WUP in HALTED state + if (len == 1 && ((receivedCmd[0] == 0x26 && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == 0x52)) { + selTimer = GetTickCount(); + EmSendCmdEx(rATQA, sizeof(rATQA), (receivedCmd[0] == 0x52)); + cardSTATE = MFEMUL_SELECT1; + + // init crypto block + LED_B_OFF(); + LED_C_OFF(); + crypto1_destroy(pcs); + cardAUTHKEY = 0xff; + continue; } - + switch (cardSTATE) { - case MFEMUL_NOFIELD:{ - break; - } - case MFEMUL_HALTED:{ - break; - } + case MFEMUL_NOFIELD: + case MFEMUL_HALTED: case MFEMUL_IDLE:{ break; } case MFEMUL_SELECT1:{ // select all if (len == 2 && (receivedCmd[0] == 0x93 && receivedCmd[1] == 0x20)) { + if (MF_DBGLEVEL >= 4) Dbprintf("SELECT ALL received"); EmSendCmd(rUIDBCC1, sizeof(rUIDBCC1)); break; } + if (MF_DBGLEVEL >= 4 && len == 9 && receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70 ) + { + Dbprintf("SELECT %02x%02x%02x%02x received",receivedCmd[2],receivedCmd[3],receivedCmd[4],receivedCmd[5]); + } // select card if (len == 9 && (receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) { + if (!_7BUID) EmSendCmd(rSAK, sizeof(rSAK)); else @@ -2285,6 +2314,51 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) break; } + case MFEMUL_AUTH1:{ + if( len != 8) + { + cardSTATE_TO_IDLE(); + break; + } + uint32_t ar = bytes_to_num(receivedCmd, 4); + uint32_t nr= bytes_to_num(&receivedCmd[4], 4); + + //Collect AR/NR + if(ar_nr_collected < 2){ + if(ar_nr_responses[ar_nr_collected*4+2] != ar) + {// Avoid duplicates + ar_nr_collected++; + ar_nr_responses[ar_nr_collected*4] = cuid; + ar_nr_responses[ar_nr_collected*4+1] = nonce; + ar_nr_responses[ar_nr_collected*4+2] = ar; + ar_nr_responses[ar_nr_collected*4+3] = nr; + } + } + + // --- crypto + crypto1_word(pcs, ar , 1); + cardRr = nr ^ crypto1_word(pcs, 0, 0); + + // test if auth OK + if (cardRr != prng_successor(nonce, 64)){ + if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED. cardRr=%08x, succ=%08x",cardRr, prng_successor(nonce, 64)); + //Shouldn't we respond anything here? + // Right now, we don't nack or anything, which causes the + // reader to do a WUPA after a while. /Martin + 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)); + LED_C_ON(); + cardSTATE = MFEMUL_WORK; + if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED. sector=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - authTimer); + break; + } case MFEMUL_SELECT2:{ if (!len) break; @@ -2308,86 +2382,44 @@ void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // i guess there is a command). go into the work state. if (len != 4) break; cardSTATE = MFEMUL_WORK; - goto lbWORK; - } - case MFEMUL_AUTH1:{ - if (len == 8) { - // --- crypto - rn_enc = bytes_to_num(receivedCmd, 4); - 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_TO_IDLE(); - } - if (cardSTATE != MFEMUL_AUTH2) break; - } - case MFEMUL_AUTH2:{ - LED_C_ON(); - cardSTATE = MFEMUL_WORK; - if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED. sec=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - authTimer); - break; + //goto lbWORK; + //intentional fall-through to the next case-stmt } case MFEMUL_WORK:{ -lbWORK: if (len == 0) break; - - 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); + if (len == 0) break; - cardSTATE = MFEMUL_AUTH1; - //nextCycleTimeout = 10; - break; - } - } else { + bool encrypted_data = (cardAUTHKEY != 0xFF) ; + + if(encrypted_data) + { // 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; + if (len == 4 && (receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61)) { + authTimer = GetTickCount(); + cardAUTHSC = receivedCmd[1] / 4; // received block num + cardAUTHKEY = receivedCmd[0] - 0x60; + crypto1_destroy(pcs);//Added by martin + crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); - // --- 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 + if (!encrypted_data) { // first authentication + if (MF_DBGLEVEL >= 2) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); - cardSTATE = MFEMUL_AUTH1; - //nextCycleTimeout = 10; - break; + crypto1_word(pcs, cuid ^ nonce, 0);//Update crypto state + num_to_bytes(nonce, 4, rAUTH_AT); // Send nonce + } + else{ // nested authentication + if (MF_DBGLEVEL >= 2) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY ); + ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); + num_to_bytes(ans, 4, rAUTH_AT); } + EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); + //Dbprintf("Sending rAUTH %02x%02x%02x%02x", rAUTH_AT[0],rAUTH_AT[1],rAUTH_AT[2],rAUTH_AT[3]); + cardSTATE = MFEMUL_AUTH1; + break; } - + // rule 13 of 7.5.3. in ISO 14443-4. chaining shall be continued // BUT... ACK --> NACK if (len == 1 && receivedCmd[0] == CARD_ACK) { @@ -2401,39 +2433,63 @@ lbWORK: if (len == 0) break; break; } - // read block - if (len == 4 && receivedCmd[0] == 0x30) { - if (receivedCmd[1] >= 16 * 4 || receivedCmd[1] / 4 != cardAUTHSC) { + if(len != 4) break; + + if(receivedCmd[0] == 0x30 // read block + || receivedCmd[0] == 0xA0 // write block + || receivedCmd[0] == 0xC0 + || receivedCmd[0] == 0xC1 + || receivedCmd[0] == 0xC2 // inc dec restore + || receivedCmd[0] == 0xB0) // transfer + { + if (receivedCmd[1] >= 16 * 4) + { + + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]); + break; + } + + if (receivedCmd[1] / 4 != cardAUTHSC) + { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02) on block (0x%02x) not authenticated for (0x%02x), nacking",receivedCmd[0],receivedCmd[1],cardAUTHSC); break; } + } + // read block + if (receivedCmd[0] == 0x30) { + if (MF_DBGLEVEL >= 2) { + Dbprintf("Reader reading block %d (0x%02x)",receivedCmd[1],receivedCmd[1]); + } emlGetMem(response, receivedCmd[1], 1); AppendCrc14443a(response, 16); mf_crypto1_encrypt(pcs, response, 18, &par); EmSendCmdPar(response, 18, par); + numReads++; + if(exitAfterNReads > 0 && numReads == exitAfterNReads) + { + Dbprintf("%d reads done, exiting", numReads); + finished = true; + } break; } - // write block - if (len == 4 && receivedCmd[0] == 0xA0) { - if (receivedCmd[1] >= 16 * 4 || receivedCmd[1] / 4 != cardAUTHSC) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - break; - } + if (receivedCmd[0] == 0xA0) { + if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0xA0 write block %d (%02x)",receivedCmd[1],receivedCmd[1]); + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); //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])) { + if (receivedCmd[0] == 0xC0 || receivedCmd[0] == 0xC1 || receivedCmd[0] == 0xC2) { + if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]); + + if (emlCheckValBl(receivedCmd[1])) { + if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate on block, but emlCheckValBl failed, nacking"); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); break; } @@ -2445,17 +2501,13 @@ lbWORK: if (len == 0) break; 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 (receivedCmd[0] == 0xB0) { + if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x transfer block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]); if (emlSetValBl(cardINTREG, cardINTBLOCK, receivedCmd[1])) EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); @@ -2466,20 +2518,23 @@ lbWORK: if (len == 0) break; } // halt - if (len == 4 && (receivedCmd[0] == 0x50 && receivedCmd[1] == 0x00)) { + if (receivedCmd[0] == 0x50 && receivedCmd[1] == 0x00) { LED_B_OFF(); LED_C_OFF(); cardSTATE = MFEMUL_HALTED; if (MF_DBGLEVEL >= 4) Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer); break; } - - // command not allowed - if (len == 4) { + // RATS + if (receivedCmd[0] == 0xe0) {//RATS EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); break; } + // command not allowed + if (MF_DBGLEVEL >= 4) Dbprintf("Received command not allowed, nacking"); + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + // case break break; } @@ -2541,10 +2596,43 @@ lbWORK: if (len == 0) break; // add trace trailer memset(rAUTH_NT, 0x44, 4); LogTrace(rAUTH_NT, 4, 0, 0, TRUE); - + if(flags & FLAG_INTERACTIVE)// Interactive mode flag, means we need to send ACK + { + //May just aswell send the collected ar_nr in the response aswell + cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,0,0,&ar_nr_responses,ar_nr_collected*4*4); + } + if(flags & FLAG_NR_AR_ATTACK) + { + if(ar_nr_collected > 1) + { + Dbprintf("Collected two pairs of AR/NR which can be used to extract keys from reader:"); + Dbprintf("../tools/mfcrack32 %08x %08x %08x %08x", + ar_nr_responses[0], // UID + ar_nr_responses[1], //NT + ar_nr_responses[2], //AR1 + ar_nr_responses[3], //NR1 + ar_nr_responses[6], //AR2 + ar_nr_responses[7] //NR2 + ); + }else + { + Dbprintf("Failed to obtain two AR/NR pairs!"); + if(ar_nr_collected >0) + { + Dbprintf("Only got these: UID=%08d, nonce=%08d, AR1=%08d, NR1=%08d", + ar_nr_responses[0], // UID + ar_nr_responses[1], //NT + ar_nr_responses[2], //AR1 + ar_nr_responses[3] //NR1 + ); + } + } + } if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, traceLen); } + + //----------------------------------------------------------------------------- // MIFARE sniffer. //