From 979f3aba2eb24a6c9c66d6cd2b2c8a425834a2ca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 07:47:17 +0200 Subject: [PATCH] chg: 'hf iclass chk' chg: 'hf iclass lookup' - use fileutils load dictionary instead. chg: 'hf iclass encrypt' - start w change to allow for key parameter --- client/cmdhficlass.c | 401 ++++++++++++++++++++++--------------------- client/cmdhficlass.h | 6 +- 2 files changed, 204 insertions(+), 203 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 51bc323fc..30b2a0560 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -76,20 +76,25 @@ static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt f "); + PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt f k "); + PrintAndLogEx(NORMAL, " options"); + PrintAndLogEx(NORMAL, " f filename of dump"); + PrintAndLogEx(NORMAL, " k 16 bytes hex"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_12312342343.bin"); + PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin"); + PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin k 000102030405060708090a0b0c0d0e0f"); return PM3_SUCCESS; } static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt "); + PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt d k "); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass encrypt 0102030405060708"); + PrintAndLogEx(NORMAL, " hf iclass encrypt d 0102030405060708"); + PrintAndLogEx(NORMAL, " hf iclass encrypt d 0102030405060708 k 00112233445566778899AABBCCDDEEFF"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -541,11 +546,11 @@ static int CmdHFiClassSim(const char *Cmd) { tries++; if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); - return 0; + return PM3_EOPABORTED; } if (tries > 20) { PrintAndLogEx(WARNING, "\ntimeout while waiting for reply."); - return 0; + return PM3_ETIMEOUT; } } uint8_t num_mac = resp.oldarg[1]; @@ -559,7 +564,7 @@ static int CmdHFiClassSim(const char *Cmd) { uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); - return 2; + return PM3_EMALLOC; } memset(dump, 0, datalen);//<-- Need zeroes for the EPURSE - field (offical) @@ -590,11 +595,11 @@ static int CmdHFiClassSim(const char *Cmd) { tries++; if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); - return 0; + return PM3_EOPABORTED; } if (tries > 20) { PrintAndLogEx(WARNING, "\ntimeout while waiting for reply."); - return 0; + return PM3_ETIMEOUT; } } uint8_t num_mac = resp.oldarg[1]; @@ -608,7 +613,7 @@ static int CmdHFiClassSim(const char *Cmd) { uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); - return 2; + return PM3_EMALLOC; } #define MAC_ITEM_SIZE 24 @@ -681,54 +686,85 @@ static int CmdHFiClassReader_Replay(const char *Cmd) { static int CmdHFiClassELoad(const char *Cmd) { - char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf_iclass_eload(); - - if (ctmp != 'f') return usage_hf_iclass_eload(); - - //File handling and reading - char filename[FILE_PATH_SIZE]; - - if (param_getstr(Cmd, 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + DumpFileType_t dftype = BIN; + char filename[FILE_PATH_SIZE] = {0}; + bool errors = false; + uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_eload(); + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); - return 1; + errors = true; + break; + } + cmdp += 2; + break; + case 'j': + dftype = JSON; + cmdp++; + break; + case 'e': + dftype = EML; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); + //Validations + if (errors || cmdp == 0) { + usage_hf_iclass_eload(); + return PM3_EINVARG; + } + + + uint8_t *dump = calloc(2048, sizeof(uint8_t)); + if (!dump) { + PrintAndLogEx(ERR, "error, cannot allocate memory "); + return PM3_EMALLOC; + } + + size_t bytes_read = 2048; + int res = 0; + + switch ( dftype ) { + case BIN: { + res = loadFile(filename, ".bin", (void*)&dump, 2048, &bytes_read); + break; + } + case EML: { + res = loadFileEML(filename, dump, &bytes_read); + break; + } + case JSON: { + res = loadFileJSON(filename, dump, 2048, &bytes_read); + break; + } + default: + PrintAndLogEx(ERR, "No dictionary loaded"); + return PM3_ESOFT; + } + + if ( res != PM3_SUCCESS ) { + free(dump); return PM3_EFILE; } - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(ERR, "error, when getting filesize"); - fclose(f); - return 1; + uint8_t *newdump = realloc(dump, bytes_read); + if (newdump == NULL) { + free(dump); + return PM3_EMALLOC; + } else { + dump = newdump; } - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(ERR, "error, cannot allocate memory "); - fclose(f); - return 1; - } - - size_t bytes_read = fread(dump, 1, fsize, f); - fclose(f); - printIclassDumpInfo(dump); - //Validate - - if (bytes_read < fsize) { - PrintAndLogEx(ERR, "error, could only read %d bytes (should be %d)", bytes_read, fsize); - free(dump); - return 1; - } // fast push mode conn.block_after_ACK = true; @@ -754,26 +790,23 @@ static int CmdHFiClassELoad(const char *Cmd) { return PM3_SUCCESS; } -static int readKeyfile(const char *filename, size_t len, uint8_t *buffer) { - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); +static int readKeyfile(const char *filename, size_t len, uint8_t **buffer) { + + char *path; + int res = searchFile(&path, PM3_USER_DIRECTORY, filename, ".bin"); + if (res != PM3_SUCCESS) { + PrintAndLogEx(INFO, "res: %d Curr path:: %s", res, path); return PM3_EFILE; } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - size_t bytes_read = fread(buffer, 1, len, f); - fclose(f); - if (fsize != len) { - PrintAndLogEx(WARNING, "Warning, file size is %d, expected %d", fsize, len); - return 1; - } + size_t datalen = 0; + res = loadFile(path, ".bin", (void*)*buffer, len, &datalen); + if ( res != PM3_SUCCESS ) + return res; - if (bytes_read != len) { - PrintAndLogEx(WARNING, "Warning, could only read %d bytes, expected %d", bytes_read, len); - return 1; + if (datalen != len) { + PrintAndLogEx(ERR, "ERROR, Wrong filesize. Got %d bytes, expected %d", datalen, len); + return PM3_EFILE; } return PM3_SUCCESS; } @@ -784,7 +817,9 @@ static int CmdHFiClassDecrypt(const char *Cmd) { if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt(); uint8_t key[16] = { 0 }; - if (readKeyfile("iclass_decryptionkey.bin", 16, key)) return usage_hf_iclass_decrypt(); + uint8_t *keyptr = key; + if (readKeyfile("iclass_decryptionkey", sizeof(key), &keyptr) != PM3_SUCCESS) + return usage_hf_iclass_decrypt(); PrintAndLogEx(SUCCESS, "decryption key loaded from file"); @@ -861,41 +896,69 @@ static int CmdHFiClassDecrypt(const char *Cmd) { saveFile(outfilename, ".bin", decrypted, fsize); saveFileEML(outfilename, decrypted, fsize, 8); + saveFileJSON(outfilename, jsfIclass, decrypted, fsize); + printIclassDumpContents(decrypted, 1, (fsize / 8), fsize); free(decrypted); return PM3_SUCCESS; } -static int iClassEncryptBlkData(uint8_t *blkData) { - uint8_t key[16] = { 0 }; - if (readKeyfile("iclass_decryptionkey.bin", 16, key)) { - usage_hf_iclass_encrypt(); - return 1; - } - PrintAndLogEx(SUCCESS, "decryption file found"); - uint8_t encryptedData[16]; - uint8_t *encrypted = encryptedData; +static void iClassEncryptBlkData(uint8_t *blk_data, uint8_t *key) { + uint8_t encrypted_data[16]; + uint8_t *encrypted = encrypted_data; mbedtls_des3_context ctx; mbedtls_des3_set2key_enc(&ctx, key); - - mbedtls_des3_crypt_ecb(&ctx, blkData, encrypted); - memcpy(blkData, encrypted, 8); - return 1; + mbedtls_des3_crypt_ecb(&ctx, blk_data, encrypted); + memcpy(blk_data, encrypted, 8); } static int CmdHFiClassEncryptBlk(const char *Cmd) { - uint8_t blkData[8] = {0}; - char opt = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_encrypt(); + bool errors = false; + bool have_key = false; + uint8_t blk_data[8] = {0}; + uint8_t key[16] = {0}; + uint8_t *keyptr = key; + uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_encrypt(); + case 'd': //get the bytes to encrypt - if (param_gethex(Cmd, 0, blkData, 16)) { - PrintAndLogEx(NORMAL, "BlockData must include 16 HEX symbols"); - return 0; + if (param_gethex(Cmd, cmdp + 1, blk_data, 16) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Block data must include 16 HEX symbols"); + errors = true;; + } + cmdp += 2; + break; + case 'k': + if (param_gethex(Cmd, cmdp + 1, key, 32) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); + errors = true;; + } + have_key = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - if (!iClassEncryptBlkData(blkData)) return 0; - printvar("encrypted block", blkData, 8); + if (errors || cmdp < 1) return usage_hf_iclass_encrypt(); + + if ( have_key == false ) { + if (readKeyfile("./iclass_decryptionkey", sizeof(key), &keyptr) != PM3_SUCCESS) { + return usage_hf_iclass_encrypt(); + } + PrintAndLogEx(SUCCESS, "Loaded transport key from decryption file"); + } + + iClassEncryptBlkData(blk_data, key); + + printvar("encrypted block", blk_data, 8); return PM3_SUCCESS; } @@ -1593,7 +1656,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { char opt = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) < 1 || opt == 'h') - usage_hf_iclass_loclass(); + return usage_hf_iclass_loclass(); if (opt == 'f') { char fileName[FILE_PATH_SIZE] = {0}; @@ -1601,7 +1664,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { return bruteforceFileNoKeys(fileName); } else { PrintAndLogEx(WARNING, "You must specify a filename"); - return 0; + return PM3_EFILE; } } else if (opt == 't') { int errors = testCipherUtils(); @@ -2001,10 +2064,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; uint8_t fileNameLen = 0; - - uint8_t *keyBlock = NULL; iclass_premac_t *pre = NULL; - int keycnt = 0; // time uint64_t t1 = msclock(); @@ -2042,35 +2102,36 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { if (errors) return usage_hf_iclass_chk(); + uint8_t *keyBlock = NULL; + uint16_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void**)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { + free(keyBlock); + return res; + } + // Get CSN / UID and CCNR PrintAndLogEx(SUCCESS, "Reading tag CSN"); for (uint8_t i = 0; i < 10 && !got_csn; i++) { - if (select_only(CSN, CCNR, false, false)) { - got_csn = true; - } else { + got_csn = select_only(CSN, CCNR, false, false); + if ( got_csn == false ) PrintAndLogEx(WARNING, "one more try\n"); } - } - if (!got_csn) { - PrintAndLogEx(WARNING, "can't select card, aborting..."); + if ( got_csn == false ) { + PrintAndLogEx(WARNING, "Tried 10 times. Can't select card, aborting..."); return PM3_ESOFT; } - // load keys into keyblock - int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { - free(keyBlock); - return PM3_EFILE; - } - - pre = calloc(keycnt, sizeof(iclass_premac_t)); + pre = calloc(keycount, sizeof(iclass_premac_t)); if (!pre) { free(keyBlock); return PM3_EMALLOC; } - PrintAndLogEx(SUCCESS, "Generating diversified keys, MAC"); + PrintAndLogEx(SUCCESS, "Generating diversified keys"); if (use_elite) PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); if (use_raw) @@ -2080,17 +2141,13 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { PrintAndLogEx(SUCCESS, "Tag info"); PrintAndLogEx(SUCCESS, "CSN | %s", sprint_hex(CSN, sizeof(CSN))); PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR))); - res = GenerateMacFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, pre); - if (res > 0) { - free(keyBlock); - free(pre); - return PM3_ESOFT; - } + + GenerateMacFrom(CSN, CCNR, use_raw, use_elite, keyBlock, keycount, pre); //PrintPreCalcMac(keyBlock, keycnt, pre); // max 42 keys inside USB_COMMAND. 512/4 = 103 mac - uint32_t chunksize = keycnt > (PM3_CMD_DATA_SIZE / 4) ? (PM3_CMD_DATA_SIZE / 4) : keycnt; + uint32_t chunksize = keycount > (PM3_CMD_DATA_SIZE / 4) ? (PM3_CMD_DATA_SIZE / 4) : keycount; bool lastChunk = false; // fast push mode @@ -2100,7 +2157,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { uint8_t found_offset = 0; uint32_t key_offset = 0; // main keychunk loop - for (uint32_t key_offset = 0; key_offset < keycnt; key_offset += chunksize) { + for (uint32_t key_offset = 0; key_offset < keycount; key_offset += chunksize) { uint64_t t2 = msclock(); uint8_t timeout = 0; @@ -2110,10 +2167,10 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { goto out; } - uint32_t keys = ((keycnt - key_offset) > chunksize) ? chunksize : keycnt - key_offset; + uint32_t keys = ((keycount - key_offset) > chunksize) ? chunksize : keycount - key_offset; // last chunk? - if (keys == keycnt - key_offset) { + if (keys == keycount - key_offset) { lastChunk = true; // Disable fast mode on last command conn.block_after_ACK = false; @@ -2146,20 +2203,20 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { case 1: { found_debit = true; - PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] found key %s (index %u)" + PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] idx [%u] - found key "_YELLOW_("%s") , key_offset - , keycnt + , keycount , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" - , sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8) , found_offset + , sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8) ); break; } case 0: { PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d] : %.1fs [%s]" , key_offset - , keycnt + , keycount , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" ); @@ -2193,7 +2250,7 @@ out: if ( memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { memcpy(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8); - PrintAndLogEx(SUCCESS, "Added found key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i); + PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i); break; } } @@ -2235,12 +2292,9 @@ static int CmdHFiClassLookUp(const char *Cmd) { uint8_t cmdp = 0x00; char filename[FILE_PATH_SIZE] = {0}; - uint8_t fileNameLen = 0; - uint8_t *keyBlock = NULL; iclass_prekey_t *prekey = NULL; - int keycnt = 0, len = 0; - + int len = 0; // if empty string if (strlen(Cmd) == 0) errors = true; // time @@ -2251,8 +2305,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { case 'h': return usage_hf_iclass_lookup(); case 'f': - fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - if (fileNameLen < 1) { + if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) < 1 ) { PrintAndLogEx(WARNING, "No filename found after f"); errors = true; } @@ -2311,54 +2364,54 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR))); PrintAndLogEx(SUCCESS, "MAC_TAG | %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); - int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { + uint8_t *keyBlock = NULL; + uint16_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void**)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { free(keyBlock); - return 1; + return res; } + //iclass_prekey_t - prekey = calloc(keycnt, sizeof(iclass_prekey_t)); + prekey = calloc(keycount, sizeof(iclass_prekey_t)); if (!prekey) { free(keyBlock); - return 1; + return PM3_EMALLOC; } - PrintAndLogEx(FAILED, "Generating diversified keys and MAC"); - res = GenerateFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, prekey); - if (res > 0) { - free(keyBlock); - free(prekey); - return 1; - } + PrintAndLogEx(INFO, "Generating diversified keys"); + GenerateMacKeyFrom(CSN, CCNR, use_raw, use_elite, keyBlock, keycount, prekey); - PrintAndLogEx(FAILED, "Sorting"); + PrintAndLogEx(INFO, "Sorting"); // sort mac list. - qsort(prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); + qsort(prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); //PrintPreCalc(prekey, keycnt); - PrintAndLogEx(FAILED, "Searching"); + PrintAndLogEx(INFO, "Searching"); iclass_prekey_t *item; iclass_prekey_t lookup; memcpy(lookup.mac, MAC_TAG, 4); // binsearch - item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); + item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); t1 = msclock() - t1; PrintAndLogEx(NORMAL, "\nTime in iclass : %.0f seconds\n", (float)t1 / 1000.0); // foudn if (item != NULL) { - PrintAndLogEx(SUCCESS, "\n[debit] found key %s", sprint_hex(item->key, 8)); + PrintAndLogEx(SUCCESS, "[debit] found key " _YELLOW_("%s"), sprint_hex(item->key, 8)); for (uint8_t i=0; i< ICLASS_KEYS_MAX; i++) { // simple check for preexistences if ( memcmp(item->key, iClass_Key_Table[i], 8) == 0 ) break; if ( memcmp(iClass_Key_Table[i] , "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { memcpy(iClass_Key_Table[i], item->key, 8); - PrintAndLogEx(SUCCESS, "Added found key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")"to view", i); + PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")"to view", i); break; } } @@ -2370,58 +2423,8 @@ static int CmdHFiClassLookUp(const char *Cmd) { return PM3_SUCCESS; } -int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { - - char buf[17]; - FILE *f; - uint8_t *p; - int keyitems = 0; - - if (!(f = fopen(filename, "r"))) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - return 1; - } - - while (fgets(buf, sizeof(buf), f)) { - if (strlen(buf) < 16 || buf[15] == '\n') - continue; - - //goto next line - while (fgetc(f) != '\n' && !feof(f)) {}; - - //The line start with # is comment, skip - if (buf[0] == '#') - continue; - - // doesn't this only test first char only? - if (!isxdigit(buf[0])) { - PrintAndLogEx(ERR, "file content error. '%s' must include 16 HEX symbols", buf); - continue; - } - - // null terminator (skip the rest of the line) - buf[16] = 0; - - p = realloc(*keys, 8 * (keyitems += 64)); - if (!p) { - PrintAndLogEx(ERR, "cannot allocate memory for default keys"); - fclose(f); - return 2; - } - *keys = p; - - memset(*keys + 8 * (*keycnt), 0, 8); - num_to_bytes(strtoull(buf, NULL, 16), 8, *keys + 8 * (*keycnt)); - (*keycnt)++; - memset(buf, 0, sizeof(buf)); - } - fclose(f); - PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") "keys from %s", *keycnt, filename); - return PM3_SUCCESS; -} - // precalc diversified keys and their MAC -int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list) { +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list) { uint8_t key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -2436,10 +2439,9 @@ int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_e doMAC(CCNR, div_key, list[i].mac); } - return PM3_SUCCESS; } -int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list) { +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list) { uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -2456,7 +2458,6 @@ int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit // generate MAC doMAC(CCNR, div_key, list[i].mac); } - return PM3_SUCCESS; } // print diversified keys diff --git a/client/cmdhficlass.h b/client/cmdhficlass.h index 9f2b5caac..73304d4d0 100644 --- a/client/cmdhficlass.h +++ b/client/cmdhficlass.h @@ -12,6 +12,7 @@ #define CMDHFICLASS_H__ #include "common.h" +#include "fileutils.h" typedef struct iclass_block { uint8_t d[8]; @@ -32,9 +33,8 @@ int readIclass(bool loop, bool verbose); void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize); void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite); -int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt); -int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list); -int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list); +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list); +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list); void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list); void PrintPreCalc(iclass_prekey_t *list, int itemcnt); #endif