From 2679ea098091957713fce12a510a6b43d0b4db7d Mon Sep 17 00:00:00 2001 From: Ave Date: Wed, 30 Dec 2020 05:50:25 +0300 Subject: [PATCH 1/3] emrtd info: Split EF_SOD into a separate section (only on offline) --- client/src/cmdhfemrtd.c | 66 ++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 670ea804d..0a98c58b9 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1689,8 +1689,8 @@ int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab } // Grab the hash list - uint8_t dg_hashes[16][64]; - uint8_t hash_out[64]; + uint8_t dg_hashes_sod[17][64] = { 0x00 }; + uint8_t dg_hashes_calc[17][64] = { 0x00 }; int hash_algo = 0; if (!emrtd_select_and_read(response, &resplen, dg_table[EF_SOD].fileid, ks_enc, ks_mac, ssc, BAC, use_14b)) { @@ -1699,7 +1699,7 @@ int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab return PM3_ESOFT; } - res = emrtd_parse_ef_sod_hashes(response, resplen, *dg_hashes, &hash_algo); + res = emrtd_parse_ef_sod_hashes(response, resplen, *dg_hashes_sod, &hash_algo); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to read hash list from EF_SOD. Hash checks will fail."); } @@ -1719,15 +1719,9 @@ int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab PrintAndLogEx(DEBUG, "EF_DG%i hash algo: %i", dg->dgnum, hash_algo); // Check file hash if (hash_algo != -1) { - PrintAndLogEx(DEBUG, "EF_DG%i hash on EF_SOD: %s", dg->dgnum, sprint_hex_inrow(dg_hashes[dg->dgnum], hashalg_table[hash_algo].hashlen)); - hashalg_table[hash_algo].hasher(response, resplen, hash_out); - PrintAndLogEx(DEBUG, "EF_DG%i hash calc: %s", dg->dgnum, sprint_hex_inrow(hash_out, hashalg_table[hash_algo].hashlen)); - - if (memcmp(dg_hashes[dg->dgnum], hash_out, hashalg_table[hash_algo].hashlen) == 0) { - PrintAndLogEx(SUCCESS, _GREEN_("Hash verification passed for EF_DG%i."), dg->dgnum); - } else { - PrintAndLogEx(ERR, _RED_("Hash verification failed for EF_DG%i."), dg->dgnum); - } + PrintAndLogEx(DEBUG, "EF_DG%i hash on EF_SOD: %s", dg->dgnum, sprint_hex_inrow(dg_hashes_sod[dg->dgnum], hashalg_table[hash_algo].hashlen)); + hashalg_table[hash_algo].hasher(response, resplen, dg_hashes_calc[dg->dgnum]); + PrintAndLogEx(DEBUG, "EF_DG%i hash calc: %s", dg->dgnum, sprint_hex_inrow(dg_hashes_calc[dg->dgnum], hashalg_table[hash_algo].hashlen)); } } } @@ -1771,8 +1765,8 @@ int infoHF_EMRTD_offline(const char *path) { free(data); // Grab the hash list - uint8_t dg_hashes[16][64]; - uint8_t hash_out[64]; + uint8_t dg_hashes_sod[17][64] = { 0x00 }; + uint8_t dg_hashes_calc[17][64] = { 0x00 }; int hash_algo = 0; strcpy(filepath, path); @@ -1785,7 +1779,7 @@ int infoHF_EMRTD_offline(const char *path) { return PM3_ESOFT; } - res = emrtd_parse_ef_sod_hashes(data, datalen, *dg_hashes, &hash_algo); + res = emrtd_parse_ef_sod_hashes(data, datalen, *dg_hashes_sod, &hash_algo); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to read hash list from EF_SOD. Hash checks will fail."); } @@ -1810,21 +1804,45 @@ int infoHF_EMRTD_offline(const char *path) { PrintAndLogEx(DEBUG, "EF_DG%i hash algo: %i", dg->dgnum, hash_algo); // Check file hash if (hash_algo != -1) { - PrintAndLogEx(DEBUG, "EF_DG%i hash on EF_SOD: %s", dg->dgnum, sprint_hex_inrow(dg_hashes[dg->dgnum], hashalg_table[hash_algo].hashlen)); - hashalg_table[hash_algo].hasher(data, datalen, hash_out); - PrintAndLogEx(DEBUG, "EF_DG%i hash calc: %s", dg->dgnum, sprint_hex_inrow(hash_out, hashalg_table[hash_algo].hashlen)); - - if (memcmp(dg_hashes[dg->dgnum], hash_out, hashalg_table[hash_algo].hashlen) == 0) { - PrintAndLogEx(SUCCESS, _GREEN_("Hash verification passed for EF_DG%i."), dg->dgnum); - } else { - PrintAndLogEx(ERR, _RED_("Hash verification failed for EF_DG%i."), dg->dgnum); - } + PrintAndLogEx(DEBUG, "EF_DG%i hash on EF_SOD: %s", dg->dgnum, sprint_hex_inrow(dg_hashes_sod[dg->dgnum], hashalg_table[hash_algo].hashlen)); + hashalg_table[hash_algo].hasher(data, datalen, dg_hashes_calc[dg->dgnum]); + PrintAndLogEx(DEBUG, "EF_DG%i hash calc: %s", dg->dgnum, sprint_hex_inrow(dg_hashes_calc[dg->dgnum], hashalg_table[hash_algo].hashlen)); } free(data); } } } free(filepath); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-------------------- " _CYAN_("EF_SOD") " --------------------"); + + if (hash_algo == -1) { + PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("Unknown")); + } else { + PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("%s"), hashalg_table[hash_algo].name); + + uint8_t all_zeroes[64] = { 0x00 }; + bool calc_all_zero, sod_all_zero, hash_matches; + for (int i = 1; i <= 16; i++) { + calc_all_zero = (memcmp(dg_hashes_calc[i], all_zeroes, hashalg_table[hash_algo].hashlen) == 0); + sod_all_zero = (memcmp(dg_hashes_sod[i], all_zeroes, hashalg_table[hash_algo].hashlen) == 0); + hash_matches = (memcmp(dg_hashes_sod[i], dg_hashes_calc[i], hashalg_table[hash_algo].hashlen) == 0); + // Ignore files we don't haven't read and lack hashes to + if (calc_all_zero == true && sod_all_zero == true) { + continue; + } else if (calc_all_zero == true) { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File read access denied, but is in EF_SOD"), i); + } else if (sod_all_zero == true) { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File not in EF_SOD"), i); + } else if (hash_matches == false) { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _RED_("Invalid"), i); + } else { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _GREEN_("Valid"), i); + } + } + } + return PM3_SUCCESS; } From 80f035f7ab0087acdcc330074c6cbfdb189b75c2 Mon Sep 17 00:00:00 2001 From: Ave Date: Wed, 30 Dec 2020 05:57:11 +0300 Subject: [PATCH 2/3] emrtd info: Improve EF_SOD wording --- client/src/cmdhfemrtd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 0a98c58b9..72832b112 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1832,9 +1832,9 @@ int infoHF_EMRTD_offline(const char *path) { if (calc_all_zero == true && sod_all_zero == true) { continue; } else if (calc_all_zero == true) { - PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File read access denied, but is in EF_SOD"), i); + PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File couldn't be read, but is in EF_SOD."), i); } else if (sod_all_zero == true) { - PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File not in EF_SOD"), i); + PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File is not in EF_SOD."), i); } else if (hash_matches == false) { PrintAndLogEx(SUCCESS, "EF_DG%i: " _RED_("Invalid"), i); } else { From 9f29a839a789842343a3ad0135f3f8c6f4c24708 Mon Sep 17 00:00:00 2001 From: Ave Date: Wed, 30 Dec 2020 06:03:12 +0300 Subject: [PATCH 3/3] emrtd info: Move EF_SOD print to a func, also add to online --- client/src/cmdhfemrtd.c | 65 +++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 72832b112..8789656a5 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1638,6 +1638,39 @@ static int emrtd_parse_ef_sod_hashes(uint8_t *data, size_t datalen, uint8_t *has return PM3_SUCCESS; } +static int emrtd_print_ef_sod_info(uint8_t *dg_hashes_calc, uint8_t *dg_hashes_sod, int hash_algo) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-------------------- " _CYAN_("EF_SOD") " --------------------"); + + if (hash_algo == -1) { + PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("Unknown")); + } else { + PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("%s"), hashalg_table[hash_algo].name); + + uint8_t all_zeroes[64] = { 0x00 }; + bool calc_all_zero, sod_all_zero, hash_matches; + for (int i = 1; i <= 16; i++) { + calc_all_zero = (memcmp(dg_hashes_calc + (i * 64), all_zeroes, hashalg_table[hash_algo].hashlen) == 0); + sod_all_zero = (memcmp(dg_hashes_sod + (i * 64), all_zeroes, hashalg_table[hash_algo].hashlen) == 0); + hash_matches = (memcmp(dg_hashes_sod + (i * 64), dg_hashes_calc + (i * 64), hashalg_table[hash_algo].hashlen) == 0); + // Ignore files we don't haven't read and lack hashes to + if (calc_all_zero == true && sod_all_zero == true) { + continue; + } else if (calc_all_zero == true) { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File couldn't be read, but is in EF_SOD."), i); + } else if (sod_all_zero == true) { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File is not in EF_SOD."), i); + } else if (hash_matches == false) { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _RED_("Invalid"), i); + } else { + PrintAndLogEx(SUCCESS, "EF_DG%i: " _GREEN_("Valid"), i); + } + } + } + + return PM3_SUCCESS; +} + int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_available) { uint8_t response[EMRTD_MAX_FILE_SIZE] = { 0x00 }; int resplen = 0; @@ -1727,6 +1760,9 @@ int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab } } DropField(); + + emrtd_print_ef_sod_info(*dg_hashes_calc, *dg_hashes_sod, hash_algo); + return PM3_SUCCESS; } @@ -1814,34 +1850,7 @@ int infoHF_EMRTD_offline(const char *path) { } free(filepath); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "-------------------- " _CYAN_("EF_SOD") " --------------------"); - - if (hash_algo == -1) { - PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("Unknown")); - } else { - PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("%s"), hashalg_table[hash_algo].name); - - uint8_t all_zeroes[64] = { 0x00 }; - bool calc_all_zero, sod_all_zero, hash_matches; - for (int i = 1; i <= 16; i++) { - calc_all_zero = (memcmp(dg_hashes_calc[i], all_zeroes, hashalg_table[hash_algo].hashlen) == 0); - sod_all_zero = (memcmp(dg_hashes_sod[i], all_zeroes, hashalg_table[hash_algo].hashlen) == 0); - hash_matches = (memcmp(dg_hashes_sod[i], dg_hashes_calc[i], hashalg_table[hash_algo].hashlen) == 0); - // Ignore files we don't haven't read and lack hashes to - if (calc_all_zero == true && sod_all_zero == true) { - continue; - } else if (calc_all_zero == true) { - PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File couldn't be read, but is in EF_SOD."), i); - } else if (sod_all_zero == true) { - PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File is not in EF_SOD."), i); - } else if (hash_matches == false) { - PrintAndLogEx(SUCCESS, "EF_DG%i: " _RED_("Invalid"), i); - } else { - PrintAndLogEx(SUCCESS, "EF_DG%i: " _GREEN_("Valid"), i); - } - } - } + emrtd_print_ef_sod_info(*dg_hashes_calc, *dg_hashes_sod, hash_algo); return PM3_SUCCESS; }