Skip to content

Commit

Permalink
elfloader: factor out check_hash()
Browse files Browse the repository at this point in the history
Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
Axel Heider committed Feb 1, 2024
1 parent 5e2506b commit a31566d
Showing 1 changed file with 79 additions and 56 deletions.
135 changes: 79 additions & 56 deletions elfloader-tool/src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
#include <elfloader.h>
#include <fdt.h>

#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"
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit a31566d

Please sign in to comment.