From: iceman1001 Date: Thu, 19 Feb 2015 10:32:11 +0000 (+0100) Subject: Merge branch 'master' of https://github.com/Proxmark/proxmark3 X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/f4a57e861d88657e58ef01cb96ce732d588ca91f Merge branch 'master' of https://github.com/Proxmark/proxmark3 Conflicts: armsrc/iclass.c client/loclass/cipher.c client/loclass/fileutils.h --- f4a57e861d88657e58ef01cb96ce732d588ca91f diff --cc armsrc/Makefile index c0070652,be08e56b..be4351d8 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@@ -43,8 -43,9 +43,10 @@@ ARMSRC = fpgaloader.c legic_prng.c \ iclass.c \ BigBuf.c \ + cipher.c \ + cipherutils.c\ + # stdint.h provided locally until GCC 4.5 becomes C99 compliant APP_CFLAGS += -I. diff --cc armsrc/iclass.c index 816cb904,a976217d..def6cc97 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@@ -45,11 -45,10 +45,12 @@@ // Needed for CRC in emulation mode; // same construction as in ISO 14443; // different initial value (CRC_ICLASS) -#include "iso14443crc.h" -#include "iso15693tools.h" +#include "../common/iso14443crc.h" +#include "../common/iso15693tools.h" +//#include "iso15693tools.h" - + #include "cipher.h" + #include "protocols.h" + static int timeout = 4096; @@@ -1149,57 -1170,90 +1172,90 @@@ int doIClassSimulation( int simulationM LED_C_ON(); // Okay, look at the command now. - if(receivedCmd[0] == 0x0a ) { + if(receivedCmd[0] == ICLASS_CMD_ACTALL ) { // Reader in anticollission phase - modulated_response = resp1; modulated_response_size = resp1Len; //order = 1; - trace_data = response1; - trace_data_size = sizeof(response1); - } else if(receivedCmd[0] == 0x0c) { + modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1; + trace_data = sof_data; + trace_data_size = sizeof(sof_data); + } else if(receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 1) { // Reader asks for anticollission CSN - modulated_response = resp2; modulated_response_size = resp2Len; //order = 2; - trace_data = response2; - trace_data_size = sizeof(response2); + modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2; + trace_data = anticoll_data; + trace_data_size = sizeof(anticoll_data); //DbpString("Reader requests anticollission CSN:"); - } else if(receivedCmd[0] == 0x81) { + } else if(receivedCmd[0] == ICLASS_CMD_SELECT) { // Reader selects anticollission CSN. // Tag sends the corresponding real CSN - modulated_response = resp3; modulated_response_size = resp3Len; //order = 3; - trace_data = response3; - trace_data_size = sizeof(response3); + modulated_response = resp_csn; modulated_response_size = resp_csn_len; //order = 3; + trace_data = csn_data; + trace_data_size = sizeof(csn_data); //DbpString("Reader selects anticollission CSN:"); - } else if(receivedCmd[0] == 0x88) { + } else if(receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // Read e-purse (88 02) - modulated_response = resp4; modulated_response_size = resp4Len; //order = 4; - trace_data = response4; - trace_data_size = sizeof(response4); + modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; + trace_data = card_challenge_data; + trace_data_size = sizeof(card_challenge_data); LED_B_ON(); - } else if(receivedCmd[0] == 0x05) { + } else if(receivedCmd[0] == ICLASS_CMD_CHECK) { // Reader random and reader MAC!!! - // Do not respond + if(simulationMode == MODE_FULLSIM) + { //This is what we must do.. + //Reader just sent us NR and MAC(k,cc * nr) + //The diversified key should be stored on block 3 + //However, from a typical dump, the key will not be there + uint8_t *diversified_key = { 0 }; + //Get the diversified key from emulator memory + memcpy(diversified_key, emulator+(8*3),8); + uint8_t ccnr[12] = { 0 }; + //Put our cc there (block 2) + memcpy(ccnr, emulator + (8 * 2), 8); + //Put nr there + memcpy(ccnr+8, receivedCmd+1,4); + //Now, calc MAC + doMAC(ccnr,diversified_key, trace_data); + trace_data_size = 4; + CodeIClassTagAnswer(trace_data , trace_data_size); + memcpy(data_response, ToSend, ToSendMax); + modulated_response = data_response; + modulated_response_size = ToSendMax; + }else + { //Not fullsim, we don't respond - // We do not know what to answer, so lets keep quiet + // We do not know what to answer, so lets keep quiet - modulated_response = resp1; modulated_response_size = 0; //order = 5; + modulated_response = resp_sof; modulated_response_size = 0; - trace_data = NULL; - trace_data_size = 0; + trace_data = NULL; + trace_data_size = 0; - if (breakAfterMacReceived){ + if (simulationMode == MODE_EXIT_AFTER_MAC){ - // dbprintf:ing ... - Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x" - ,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]); - Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len, - receivedCmd[0], receivedCmd[1], receivedCmd[2], - receivedCmd[3], receivedCmd[4], receivedCmd[5], - receivedCmd[6], receivedCmd[7], receivedCmd[8]); - if (reader_mac_buf != NULL) - { - memcpy(reader_mac_buf,receivedCmd+1,8); - } - exitLoop = true; + // dbprintf:ing ... + Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x" + ,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]); + Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len, + receivedCmd[0], receivedCmd[1], receivedCmd[2], + receivedCmd[3], receivedCmd[4], receivedCmd[5], + receivedCmd[6], receivedCmd[7], receivedCmd[8]); + if (reader_mac_buf != NULL) + { + memcpy(reader_mac_buf,receivedCmd+1,8); } + exitLoop = true; + } - } else if(receivedCmd[0] == 0x00 && len == 1) { + } + + } else if(receivedCmd[0] == ICLASS_CMD_HALT && len == 1) { // Reader ends the session - modulated_response = resp1; modulated_response_size = 0; //order = 0; + modulated_response = resp_sof; modulated_response_size = 0; //order = 0; trace_data = NULL; trace_data_size = 0; - } else { + } else if(simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){ + //Read block + uint16_t blk = receivedCmd[1]; + trace_data = emulator+(blk << 3); + trace_data_size = 8; + CodeIClassTagAnswer(trace_data , trace_data_size); + memcpy(data_response, ToSend, ToSendMax); + modulated_response = data_response; + modulated_response_size = ToSendMax; + } + else { //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44 // Never seen this command before Dbprintf("Unknown command received from reader (len=%d): %x %x %x %x %x %x %x %x %x", @@@ -1605,9 -1659,20 +1661,20 @@@ void ReaderIClass(uint8_t arg0) if(read_status == 1) datasize = 8; if(read_status == 2) datasize = 16; + //Todo, read the public blocks 1,5 aswell: + // + // 0 : CSN (we already have) + // 1 : Configuration + // 2 : e-purse (we already have) + // (3,4 write-only) + // 5 Application issuer area + // + //Then we can 'ship' back the 8 * 5 bytes of data, + // with 0xFF:s in block 3 and 4. + - LED_B_ON(); - //Send back to client, but don't bother if we already sent this - if(memcmp(last_csn, card_data, 8) != 0) + LED_B_ON(); + //Send back to client, but don't bother if we already sent this + if(memcmp(last_csn, card_data, 8) != 0) { if(!get_cc || (get_cc && read_status == 2)) diff --cc client/loclass/cipher.c index 9c1c2cfd,7c9cc873..7d3950b1 --- a/client/loclass/cipher.c +++ b/client/loclass/cipher.c @@@ -219,29 -219,29 +219,29 @@@ void MAC(uint8_t* k, BitstreamIn input BitstreamIn input_32_zeroes = {zeroes_32,sizeof(zeroes_32)*8,0}; State initState = suc(k,init(k),&input); output(k,initState,&input_32_zeroes,&out); -} +} - void doMAC(uint8_t *cc_nr_p, int length, uint8_t *div_key_p, uint8_t mac[4]) + void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { - uint8_t *cc_nr; + uint8_t cc_nr[13] = { 0 }; uint8_t div_key[8]; - cc_nr=(uint8_t*)malloc(length+1); - memcpy(cc_nr,cc_nr_p,length); + //cc_nr=(uint8_t*)malloc(length+1); + + memcpy(cc_nr,cc_nr_p,12); memcpy(div_key,div_key_p,8); - + - reverse_arraybytes(cc_nr,length); - BitstreamIn bitstream = {cc_nr,length * 8,0}; + reverse_arraybytes(cc_nr,12); + BitstreamIn bitstream = {cc_nr,12 * 8,0}; - uint8_t dest []= {0,0,0,0,0,0,0,0}; - BitstreamOut out = { dest, sizeof(dest)*8, 0 }; - MAC(div_key,bitstream, out); - //The output MAC must also be reversed - reverse_arraybytes(dest, sizeof(dest)); - memcpy(mac, dest, 4); + uint8_t dest []= {0,0,0,0,0,0,0,0}; + BitstreamOut out = { dest, sizeof(dest)*8, 0 }; + MAC(div_key,bitstream, out); + //The output MAC must also be reversed + reverse_arraybytes(dest, sizeof(dest)); + memcpy(mac,dest,4); - //printf("Calculated_MAC\t%02x%02x%02x%02x\n", dest[0],dest[1],dest[2],dest[3]); - free(cc_nr); + //free(cc_nr); return; } - + #ifndef ON_DEVICE int testMAC() { prnlog("[+] Testing MAC calculation..."); diff --cc client/loclass/fileutils.h index cfe65187,10720f76..f18472ab --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@@ -49,16 -52,9 +52,17 @@@ * @return 0 for ok, 1 for failz */ int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen); +/** + * @brief Utility function to save load binary data from a a file. This method takes a filename, + * Should only be used for fixed-size binary files + * @param fileName the name of the file + * @param data a buffer to place data in + * @param datalen the length of the data/data. + * @return + */ - int loadFile(const char *fileName, void* data, size_t datalen); + int fileExists(const char *filename); + #endif //ON_DEVICE /** * Utility function to print to console. This is used consistently within the library instead