From 6c2b1d2315f93c6afd04a5b1860cfa5756e4c72e Mon Sep 17 00:00:00 2001 From: Axel Heider Date: Wed, 21 Dec 2022 13:19:58 +0100 Subject: [PATCH] elfloader: factor out check_hash() Signed-off-by: Axel Heider --- elfloader-tool/src/common.c | 135 +++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 56 deletions(-) diff --git a/elfloader-tool/src/common.c b/elfloader-tool/src/common.c index 9846422f..19440c77 100644 --- a/elfloader-tool/src/common.c +++ b/elfloader-tool/src/common.c @@ -17,10 +17,12 @@ #include #include -#ifdef CONFIG_HASH_SHA +#if defined(CONFIG_HASH_SHA) #include "crypt_sha256.h" -#elif CONFIG_HASH_MD5 +#elif defined(CONFIG_HASH_MD5) #include "crypt_md5.h" +#elif !defined(CONFIG_HASH_NONE) +#error "invalid configuration" #endif #include "hash.h" @@ -90,6 +92,77 @@ static int ensure_phys_range_valid( return 0; } +#ifndef CONFIG_HASH_NONE +/* + * check hash of ELF + */ +static int check_hash( + void const *cpio, + size_t cpio_len, + void const *elf_blob, + size_t elf_blob_size, + char const *elf_hash_filename) +{ + /* Get the binary file that contains the Hash */ + unsigned long cpio_file_size = 0; + void const *file_hash = cpio_get_file(cpio, + cpio_len, + elf_hash_filename, + &cpio_file_size); + + /* If the file hash doesn't have a pointer, the file doesn't exist, so we + * cannot confirm the file is what we expect. + */ + if (file_hash == NULL) { + printf("ERROR: hash file '%s' doesn't exist\n", elf_hash_filename); + return -1; + } + + /* Ensure we can safely cast the CPIO API type to our preferred type. */ + _Static_assert(sizeof(cpio_file_size) <= sizeof(size_t), + "integer model mismatch"); + size_t file_hash_len = (size_t)cpio_file_size; + +#if defined(CONFIG_HASH_SHA) + uint8_t calculated_hash[32]; + hashes_t hashes = { .hash_type = SHA_256 }; +#elif defined(CONFIG_HASH_MD5) + uint8_t calculated_hash[16]; + hashes_t hashes = { .hash_type = MD5 }; +#else +#error "unsupported hash algorithm" +#endif + + if (file_hash_len < sizeof(calculated_hash)) { + printf("ERROR: hash file '%s' size %u invalid, expected at least %u\n", + elf_hash_filename, file_hash_len, sizeof(calculated_hash)); + } + + /* Print the Hash for the user to see */ + printf("Hash from ELF File: "); + print_hash(file_hash, sizeof(calculated_hash)); + + /* This does not return anything */ + get_hash(hashes, elf_blob, elf_blob_size, calculated_hash); + + /* Print the hash so the user can see they're the same or different */ + printf("Hash for ELF Input: "); + print_hash(calculated_hash, sizeof(calculated_hash)); + + /* Check the hashes are the same. There is no memcmp() in the striped down + * runtime lib of ELF Loader, so we compare here byte per byte. + */ + for (unsigned int i = 0; i < sizeof(calculated_hash); i++) { + if (((char const *)file_hash)[i] != ((char const *)calculated_hash)[i]) { + printf("ERROR: Hashes are different\n"); + return -1; + } + } + + return 0; +} +#endif /* not CONFIG_HASH_NONE */ + /* * Unpack an ELF file to the given physical address. */ @@ -217,67 +290,17 @@ static int load_elf( } #ifdef CONFIG_HASH_NONE - UNUSED_VARIABLE(cpio); UNUSED_VARIABLE(cpio_len); UNUSED_VARIABLE(elf_blob_size); UNUSED_VARIABLE(elf_hash_filename); - #else - - /* Get the binary file that contains the Hash */ - unsigned long cpio_file_size = 0; - void const *file_hash = cpio_get_file(cpio, - cpio_len, - elf_hash_filename, - &cpio_file_size); - - /* If the file hash doesn't have a pointer, the file doesn't exist, so we - * cannot confirm the file is what we expect. - */ - if (file_hash == NULL) { - printf("ERROR: hash file '%s' doesn't exist\n", elf_hash_filename); + ret = check_hash(cpio, cpio_len, elf_blob, elf_blob_size, elf_hash_filename); + if (0 != ret) { + printf("ERROR: hash check failed for %s (%d)\n", name, ret); return -1; } - - /* Ensure we can safely cast the CPIO API type to our preferred type. */ - _Static_assert(sizeof(cpio_file_size) <= sizeof(size_t), - "integer model mismatch"); - size_t file_hash_len = (size_t)cpio_file_size; - -#ifdef CONFIG_HASH_SHA - uint8_t calculated_hash[32]; - hashes_t hashes = { .hash_type = SHA_256 }; -#else - uint8_t calculated_hash[16]; - hashes_t hashes = { .hash_type = MD5 }; -#endif - - if (file_hash_len < sizeof(calculated_hash)) { - printf("ERROR: hash file '%s' size %u invalid, expected at least %u\n", - elf_hash_filename, file_hash_len, sizeof(calculated_hash)); - } - - /* Print the Hash for the user to see */ - printf("Hash from ELF File: "); - print_hash(file_hash, sizeof(calculated_hash)); - - get_hash(hashes, elf_blob, elf_blob_size, calculated_hash); - - /* Print the hash so the user can see they're the same or different */ - printf("Hash for ELF Input: "); - print_hash(calculated_hash, sizeof(calculated_hash)); - - /* Check the hashes are the same. There is no memcmp() in the striped down - * runtime lib of ELF Loader, so we compare here byte per byte. */ - for (unsigned int i = 0; i < sizeof(calculated_hash); i++) { - if (((char const *)file_hash)[i] != ((char const *)calculated_hash)[i]) { - printf("ERROR: Hashes are different\n"); - return -1; - } - } - -#endif /* CONFIG_HASH_NONE */ +#endif /* [not] CONFIG_HASH_NONE */ /* Print diagnostics. */ printf(" paddr=[%p..%p]\n", dest_paddr, dest_paddr + image_size - 1);