From 8c22ef076b5c3a53bfc8f0039838484caa9fc2ff Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 20 May 2020 08:58:28 +0200 Subject: [PATCH] expanded from u16 -> u32 for keys to be loaded --- client/src/cmdflashmem.c | 14 +++++++++++++- client/src/cmdhficlass.c | 41 ++++++++++++++++++++-------------------- client/src/cmdhficlass.h | 8 ++++---- client/src/cmdhfmf.c | 8 ++++---- client/src/cmdhfmfdes.c | 30 ++++++++++++++++++----------- client/src/cmdhfmfp.c | 9 +++++---- client/src/cmdlft55xx.c | 4 ++-- client/src/fileutils.c | 10 +++++----- client/src/fileutils.h | 6 +++--- 9 files changed, 76 insertions(+), 54 deletions(-) diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index debe77089..e1761a81b 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -168,7 +168,7 @@ static int CmdFlashMemLoad(const char *Cmd) { return PM3_EINVARG; } size_t datalen = 0; - uint16_t keycount = 0; + uint32_t keycount = 0; int res = 0; uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); @@ -180,6 +180,10 @@ static int CmdFlashMemLoad(const char *Cmd) { free(data); return PM3_EFILE; } + // limited space on flash mem + if (keycount > 0xFFFF) + keycount &= 0xFFFF; + data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; datalen += 2; @@ -191,6 +195,10 @@ static int CmdFlashMemLoad(const char *Cmd) { free(data); return PM3_EFILE; } + // limited space on flash mem + if (keycount > 0xFFFF) + keycount &= 0xFFFF; + data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; datalen += 2; @@ -202,6 +210,10 @@ static int CmdFlashMemLoad(const char *Cmd) { free(data); return PM3_EFILE; } + // limited space on flash mem + if (keycount > 0xFFFF) + keycount &= 0xFFFF; + data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; datalen += 2; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 73b9a6b18..61aea9de6 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2411,17 +2411,6 @@ 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 < ICLASS_AUTH_RETRY && !got_csn; i++) { @@ -2436,6 +2425,16 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { return PM3_ESOFT; } + uint8_t *keyBlock = NULL; + uint32_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { + free(keyBlock); + return res; + } + pre = calloc(keycount, sizeof(iclass_premac_t)); if (!pre) { DropField(); @@ -2678,7 +2677,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, "MAC_TAG | %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); uint8_t *keyBlock = NULL; - uint16_t keycount = 0; + uint32_t keycount = 0; // load keys int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); @@ -2737,11 +2736,12 @@ static int CmdHFiClassLookUp(const char *Cmd) { } // precalc diversified keys and their MAC -void GenerateMacFrom(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, uint32_t 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}; - for (int i = 0; i < keycnt; i++) { +//iceman: threading + for (uint32_t i = 0; i < keycnt; i++) { memcpy(key, keys + 8 * i, 8); @@ -2754,11 +2754,12 @@ void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, } } -void GenerateMacKeyFrom(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, uint32_t keycnt, iclass_prekey_t *list) { uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - for (int i = 0; i < keycnt; i++) { +//iceman: threading + for (uint32_t i = 0; i < keycnt; i++) { memcpy(list[i].key, keys + 8 * i, 8); @@ -2774,13 +2775,13 @@ void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit } // print diversified keys -void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list) { +void PrintPreCalcMac(uint8_t *keys, uint32_t keycnt, iclass_premac_t *pre_list) { - iclass_prekey_t *b = calloc(keycnt, sizeof(iclass_prekey_t)); + iclass_prekey_t *b = calloc(keycnt, sizeof(iclass_prekey_t)); if (!b) return; - for (int i = 0; i < keycnt; i++) { + for (uint32_t i = 0; i < keycnt; i++) { memcpy(b[i].key, keys + 8 * i, 8); memcpy(b[i].mac, pre_list[i].mac, 4); } @@ -2788,7 +2789,7 @@ void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list) { free(b); } -void PrintPreCalc(iclass_prekey_t *list, int itemcnt) { +void PrintPreCalc(iclass_prekey_t *list, uint32_t itemcnt) { PrintAndLogEx(NORMAL, "-----+------------------+---------"); PrintAndLogEx(NORMAL, "#key | key | mac"); PrintAndLogEx(NORMAL, "-----+------------------+---------"); diff --git a/client/src/cmdhficlass.h b/client/src/cmdhficlass.h index 73304d4d0..53880d647 100644 --- a/client/src/cmdhficlass.h +++ b/client/src/cmdhficlass.h @@ -33,8 +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); -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); +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_premac_t *list); +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_prekey_t *list); +void PrintPreCalcMac(uint8_t *keys, uint32_t keycnt, iclass_premac_t *pre_list); +void PrintPreCalc(iclass_prekey_t *list, uint32_t itemcnt); #endif diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 0a11a8a25..560ed0a16 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1904,7 +1904,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool calibrate = true; // Attack key storage variables uint8_t *keyBlock = NULL; - uint16_t key_cnt = 0; + uint32_t key_cnt = 0; sector_t *e_sector; uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; int block_cnt = MIFARE_1K_MAXBLOCK; @@ -2169,7 +2169,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { for (int j = 0; j < 2; j++) { // Check if the key is known if (e_sector[i].foundKey[j] == 0) { - for (int k = 0; k < key_cnt; k++) { + for (uint32_t k = 0; k < key_cnt; k++) { printf("."); fflush(stdout); if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) { @@ -2186,13 +2186,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { fflush(stdout); } else { - int chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; + uint32_t chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; bool firstChunk = true, lastChunk = false; for (uint8_t strategy = 1; strategy < 3; strategy++) { PrintAndLogEx(INFO, "running strategy %u", strategy); // main keychunk loop - for (int i = 0; i < key_cnt; i += chunksize) { + for (uint32_t i = 0; i < key_cnt; i += chunksize) { if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index dc285d9cf..7dd07655b 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -3561,7 +3561,11 @@ static int CmdHF14ADesAuth(const char *Cmd) { return PM3_SUCCESS; } -static void DesFill2bPattern(uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t *deskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], size_t *aeskeyListLen, uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], size_t *k3kkeyListLen, uint32_t *startPattern) { +static void DesFill2bPattern( + uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], uint32_t *deskeyListLen, + uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], uint32_t *aeskeyListLen, + uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], uint32_t *k3kkeyListLen, uint32_t *startPattern) { + for (uint32_t pt = *startPattern; pt < 0x10000; pt++) { if (*deskeyListLen != MAX_KEYS_LIST_LEN) { deskeyList[*deskeyListLen][0] = (pt >> 8) & 0xff; @@ -3598,7 +3602,11 @@ static void DesFill2bPattern(uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t *d (*startPattern)++; } -static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t deskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], size_t aeskeyListLen, uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], size_t k3kkeyListLen, uint8_t foundKeys[4][0xE][24 + 1], bool *result) { +static int AuthCheckDesfire(uint8_t *aid, + uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], uint32_t deskeyListLen, + uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], uint32_t aeskeyListLen, + uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], uint32_t k3kkeyListLen, + uint8_t foundKeys[4][0xE][24 + 1], bool *result) { uint32_t curaid = (aid[0] & 0xFF) + ((aid[1] & 0xFF) << 8) + ((aid[2] & 0xFF) << 16); @@ -3689,7 +3697,7 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ if (usedkeys[keyno] == 1 && foundKeys[0][keyno][0] == 0) { - for (int curkey = 0; curkey < deskeyListLen; curkey++) { + for (uint32_t curkey = 0; curkey < deskeyListLen; curkey++) { payload.keylen = 8; memcpy(payload.key, deskeyList[curkey], 8); @@ -3728,7 +3736,7 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ if (usedkeys[keyno] == 1 && foundKeys[1][keyno][0] == 0) { - for (int curkey = 0; curkey < aeskeyListLen; curkey++) { + for (uint32_t curkey = 0; curkey < aeskeyListLen; curkey++) { payload.keylen = 16; memcpy(payload.key, aeskeyList[curkey], 16); @@ -3767,7 +3775,7 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ if (usedkeys[keyno] == 1 && foundKeys[2][keyno][0] == 0) { - for (int curkey = 0; curkey < aeskeyListLen; curkey++) { + for (uint32_t curkey = 0; curkey < aeskeyListLen; curkey++) { payload.keylen = 16; memcpy(payload.key, aeskeyList[curkey], 16); @@ -3806,7 +3814,7 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ if (usedkeys[keyno] == 1 && foundKeys[3][keyno][0] == 0) { - for (int curkey = 0; curkey < k3kkeyListLen; curkey++) { + for (uint32_t curkey = 0; curkey < k3kkeyListLen; curkey++) { payload.keylen = 24; memcpy(payload.key, k3kkeyList[curkey], 24); payload.mode = MFDES_AUTH_ISO; @@ -3846,9 +3854,9 @@ static int CmdHF14aDesChk(const char *Cmd) { uint8_t deskeyList[MAX_KEYS_LIST_LEN][8] = {{0}}; uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16] = {{0}}; uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][MAX_KEY_LEN] = {{0}}; - size_t deskeyListLen = 0; - size_t aeskeyListLen = 0; - size_t k3kkeyListLen = 0; + uint32_t deskeyListLen = 0; + uint32_t aeskeyListLen = 0; + uint32_t k3kkeyListLen = 0; uint8_t foundKeys[4][0xE][24 + 1] = {{{0}}}; CLIParserInit("hf mfdes chk", @@ -3972,7 +3980,7 @@ static int CmdHF14aDesChk(const char *Cmd) { // dictionary mode size_t endFilePosition = 0; if (dict_filenamelen) { - uint16_t keycnt = 0; + uint32_t keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 8, &keycnt, 0, &endFilePosition, true); deskeyListLen = keycnt; if (endFilePosition) @@ -4049,7 +4057,7 @@ static int CmdHF14aDesChk(const char *Cmd) { if (dict_filenamelen && endFilePosition) { if (!verbose) printf("d"); - uint16_t keycnt = 0; + uint32_t keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false); deskeyListLen = keycnt; keycnt = 0; diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index bc6854b26..27c606203 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -1027,7 +1027,7 @@ static int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyA return PM3_SUCCESS; } -static void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyListLen, uint32_t *startPattern) { +static void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], uint32_t *keyListLen, uint32_t *startPattern) { for (uint32_t pt = *startPattern; pt < 0x10000; pt++) { keyList[*keyListLen][0] = (pt >> 8) & 0xff; keyList[*keyListLen][1] = pt & 0xff; @@ -1045,7 +1045,7 @@ static void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_ static int CmdHFMFPChk(const char *Cmd) { int res; uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}}; - size_t keyListLen = 0; + uint32_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}}; CLIParserInit("hf mfp chk", @@ -1149,6 +1149,7 @@ static int CmdHFMFPChk(const char *Cmd) { uint8_t endKeyAB = 1; if (keyA && !keyB) endKeyAB = 0; + if (!keyA && keyB) startKeyAB = 1; @@ -1170,7 +1171,7 @@ static int CmdHFMFPChk(const char *Cmd) { // dictionary mode size_t endFilePosition = 0; if (dict_filenamelen) { - uint16_t keycnt = 0; + uint32_t keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition, true); keyListLen = keycnt; if (endFilePosition) @@ -1210,7 +1211,7 @@ static int CmdHFMFPChk(const char *Cmd) { if (dict_filenamelen && endFilePosition) { if (!verbose) printf("d"); - uint16_t keycnt = 0; + uint32_t keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false); keyListLen = keycnt; continue; diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 572a07549..9b54aef8f 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -3045,7 +3045,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { } if (use_pwd_file) { - uint16_t keycount = 0; + uint32_t keycount = 0; int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 4, &keycount); if (res != PM3_SUCCESS || keycount == 0 || keyBlock == NULL) { @@ -3056,7 +3056,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { return PM3_ESOFT; } - for (uint16_t c = 0; c < keycount; ++c) { + for (uint32_t c = 0; c < keycount; ++c) { if (!session.pm3_present) { PrintAndLogEx(WARNING, "Device offline\n"); diff --git a/client/src/fileutils.c b/client/src/fileutils.c index ac9196e4c..4e5573747 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -996,7 +996,7 @@ out: return retval; } -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint32_t *keycnt) { // t5577 == 4bytes // mifare == 6 bytes // mf plus == 16 bytes @@ -1009,7 +1009,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u return loadFileDICTIONARYEx(preferredName, data, 0, datalen, keylen, keycnt, 0, NULL, true); } -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint32_t *keycnt, size_t startFilePosition, size_t *endFilePosition, bool verbose) { if (data == NULL) return PM3_EINVARG; @@ -1025,7 +1025,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale keylen <<= 1; char line[255]; - uint16_t vkeycnt = 0; + uint32_t vkeycnt = 0; size_t counter = 0; int retval = PM3_SUCCESS; @@ -1097,7 +1097,7 @@ out: return retval; } -int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) { +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt) { int retval = PM3_SUCCESS; @@ -1141,7 +1141,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key while (fgets(line, sizeof(line), f)) { // check if we have enough space (if not allocate more) - if ((((size_t)(*keycnt)) * (keylen >> 1)) >= mem_size) { + if ((*keycnt * (keylen >> 1)) >= mem_size) { mem_size += block_size; *pdata = realloc(*pdata, mem_size); diff --git a/client/src/fileutils.h b/client/src/fileutils.h index 2f55a3c1a..603144e67 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -210,7 +210,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ * @param keycnt key count that lays in data. may be NULL * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint32_t *keycnt); /** * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. @@ -228,7 +228,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u * @param verbose print messages if true * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint32_t *keycnt, size_t startFilePosition, size_t *endFilePosition, bool verbose); /** @@ -240,7 +240,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale * @param keylen the number of bytes a key per row is * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt); +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt); /** * @brief Utility function to check and convert old mfu dump format to new