|
17 | 17 | #include <elfloader.h> |
18 | 18 | #include <fdt.h> |
19 | 19 |
|
20 | | -#ifdef CONFIG_HASH_SHA |
| 20 | +#if defined(CONFIG_HASH_SHA) |
21 | 21 | #include "crypt_sha256.h" |
22 | | -#elif CONFIG_HASH_MD5 |
| 22 | +#elif defined(CONFIG_HASH_MD5) |
23 | 23 | #include "crypt_md5.h" |
| 24 | +#elif !defined(CONFIG_HASH_NONE) |
| 25 | +#error "invalid configuration" |
24 | 26 | #endif |
25 | 27 |
|
26 | 28 | #include "hash.h" |
@@ -90,6 +92,77 @@ static int ensure_phys_range_valid( |
90 | 92 | return 0; |
91 | 93 | } |
92 | 94 |
|
| 95 | +#ifndef CONFIG_HASH_NONE |
| 96 | +/* |
| 97 | + * check hash of ELF |
| 98 | + */ |
| 99 | +static int check_hash( |
| 100 | + void const *cpio, |
| 101 | + size_t cpio_len, |
| 102 | + void const *elf_blob, |
| 103 | + size_t elf_blob_size, |
| 104 | + char const *elf_hash_filename) |
| 105 | +{ |
| 106 | + /* Get the binary file that contains the Hash */ |
| 107 | + unsigned long cpio_file_size = 0; |
| 108 | + void const *file_hash = cpio_get_file(cpio, |
| 109 | + cpio_len, |
| 110 | + elf_hash_filename, |
| 111 | + &cpio_file_size); |
| 112 | + |
| 113 | + /* If the file hash doesn't have a pointer, the file doesn't exist, so we |
| 114 | + * cannot confirm the file is what we expect. |
| 115 | + */ |
| 116 | + if (file_hash == NULL) { |
| 117 | + printf("ERROR: hash file '%s' doesn't exist\n", elf_hash_filename); |
| 118 | + return -1; |
| 119 | + } |
| 120 | + |
| 121 | + /* Ensure we can safely cast the CPIO API type to our preferred type. */ |
| 122 | + _Static_assert(sizeof(cpio_file_size) <= sizeof(size_t), |
| 123 | + "integer model mismatch"); |
| 124 | + size_t file_hash_len = (size_t)cpio_file_size; |
| 125 | + |
| 126 | +#if defined(CONFIG_HASH_SHA) |
| 127 | + uint8_t calculated_hash[32]; |
| 128 | + hashes_t hashes = { .hash_type = SHA_256 }; |
| 129 | +#elif defined(CONFIG_HASH_MD5) |
| 130 | + uint8_t calculated_hash[16]; |
| 131 | + hashes_t hashes = { .hash_type = MD5 }; |
| 132 | +#else |
| 133 | +#error "unsupported hash algorithm" |
| 134 | +#endif |
| 135 | + |
| 136 | + if (file_hash_len < sizeof(calculated_hash)) { |
| 137 | + printf("ERROR: hash file '%s' size %u invalid, expected at least %u\n", |
| 138 | + elf_hash_filename, file_hash_len, sizeof(calculated_hash)); |
| 139 | + } |
| 140 | + |
| 141 | + /* Print the Hash for the user to see */ |
| 142 | + printf("Hash from ELF File: "); |
| 143 | + print_hash(file_hash, sizeof(calculated_hash)); |
| 144 | + |
| 145 | + /* This does not return anything */ |
| 146 | + get_hash(hashes, elf_blob, elf_blob_size, calculated_hash); |
| 147 | + |
| 148 | + /* Print the hash so the user can see they're the same or different */ |
| 149 | + printf("Hash for ELF Input: "); |
| 150 | + print_hash(calculated_hash, sizeof(calculated_hash)); |
| 151 | + |
| 152 | + /* Check the hashes are the same. There is no memcmp() in the striped down |
| 153 | + * runtime lib of ELF Loader, so we compare here byte per byte. |
| 154 | + */ |
| 155 | + for (unsigned int i = 0; i < sizeof(calculated_hash); i++) { |
| 156 | + if (((char const *)file_hash)[i] != ((char const *)calculated_hash)[i]) { |
| 157 | + printf("ERROR: Hashes are different\n"); |
| 158 | + return -1; |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + return 0; |
| 163 | +} |
| 164 | +#endif /* not CONFIG_HASH_NONE */ |
| 165 | + |
93 | 166 | /* |
94 | 167 | * Unpack an ELF file to the given physical address. |
95 | 168 | */ |
@@ -217,67 +290,17 @@ static int load_elf( |
217 | 290 | } |
218 | 291 |
|
219 | 292 | #ifdef CONFIG_HASH_NONE |
220 | | - |
221 | 293 | UNUSED_VARIABLE(cpio); |
222 | 294 | UNUSED_VARIABLE(cpio_len); |
223 | 295 | UNUSED_VARIABLE(elf_blob_size); |
224 | 296 | UNUSED_VARIABLE(elf_hash_filename); |
225 | | - |
226 | 297 | #else |
227 | | - |
228 | | - /* Get the binary file that contains the Hash */ |
229 | | - unsigned long cpio_file_size = 0; |
230 | | - void const *file_hash = cpio_get_file(cpio, |
231 | | - cpio_len, |
232 | | - elf_hash_filename, |
233 | | - &cpio_file_size); |
234 | | - |
235 | | - /* If the file hash doesn't have a pointer, the file doesn't exist, so we |
236 | | - * cannot confirm the file is what we expect. |
237 | | - */ |
238 | | - if (file_hash == NULL) { |
239 | | - printf("ERROR: hash file '%s' doesn't exist\n", elf_hash_filename); |
| 298 | + ret = check_hash(cpio, cpio_len, elf_blob, elf_blob_size, elf_hash_filename); |
| 299 | + if (0 != ret) { |
| 300 | + printf("ERROR: hash check failed for %s (%d)\n", name, ret); |
240 | 301 | return -1; |
241 | 302 | } |
242 | | - |
243 | | - /* Ensure we can safely cast the CPIO API type to our preferred type. */ |
244 | | - _Static_assert(sizeof(cpio_file_size) <= sizeof(size_t), |
245 | | - "integer model mismatch"); |
246 | | - size_t file_hash_len = (size_t)cpio_file_size; |
247 | | - |
248 | | -#ifdef CONFIG_HASH_SHA |
249 | | - uint8_t calculated_hash[32]; |
250 | | - hashes_t hashes = { .hash_type = SHA_256 }; |
251 | | -#else |
252 | | - uint8_t calculated_hash[16]; |
253 | | - hashes_t hashes = { .hash_type = MD5 }; |
254 | | -#endif |
255 | | - |
256 | | - if (file_hash_len < sizeof(calculated_hash)) { |
257 | | - printf("ERROR: hash file '%s' size %u invalid, expected at least %u\n", |
258 | | - elf_hash_filename, file_hash_len, sizeof(calculated_hash)); |
259 | | - } |
260 | | - |
261 | | - /* Print the Hash for the user to see */ |
262 | | - printf("Hash from ELF File: "); |
263 | | - print_hash(file_hash, sizeof(calculated_hash)); |
264 | | - |
265 | | - get_hash(hashes, elf_blob, elf_blob_size, calculated_hash); |
266 | | - |
267 | | - /* Print the hash so the user can see they're the same or different */ |
268 | | - printf("Hash for ELF Input: "); |
269 | | - print_hash(calculated_hash, sizeof(calculated_hash)); |
270 | | - |
271 | | - /* Check the hashes are the same. There is no memcmp() in the striped down |
272 | | - * runtime lib of ELF Loader, so we compare here byte per byte. */ |
273 | | - for (unsigned int i = 0; i < sizeof(calculated_hash); i++) { |
274 | | - if (((char const *)file_hash)[i] != ((char const *)calculated_hash)[i]) { |
275 | | - printf("ERROR: Hashes are different\n"); |
276 | | - return -1; |
277 | | - } |
278 | | - } |
279 | | - |
280 | | -#endif /* CONFIG_HASH_NONE */ |
| 303 | +#endif /* [not] CONFIG_HASH_NONE */ |
281 | 304 |
|
282 | 305 | /* Print diagnostics. */ |
283 | 306 | printf(" paddr=[%p..%p]\n", dest_paddr, dest_paddr + image_size - 1); |
|
0 commit comments