xref: /qemu/hw/core/eif.c (revision ca80a5d026a280762e0772615f1988db542b3ade)
1 /*
2  * EIF (Enclave Image Format) related helpers
3  *
4  * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.com>
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or
7  * (at your option) any later version.  See the COPYING file in the
8  * top-level directory.
9  */
10 
11 #include "qemu/osdep.h"
12 #include "qemu/bswap.h"
13 #include "qapi/error.h"
14 #include "crypto/hash.h"
15 #include "crypto/x509-utils.h"
16 #include <zlib.h> /* for crc32 */
17 #include <cbor.h>
18 
19 #include "hw/core/eif.h"
20 
21 #define MAX_SECTIONS 32
22 
23 /* members are ordered according to field order in .eif file */
24 typedef struct EifHeader {
25     uint8_t  magic[4]; /* must be .eif in ascii i.e., [46, 101, 105, 102] */
26     uint16_t version;
27     uint16_t flags;
28     uint64_t default_memory;
29     uint64_t default_cpus;
30     uint16_t reserved;
31     uint16_t section_cnt;
32     uint64_t section_offsets[MAX_SECTIONS];
33     uint64_t section_sizes[MAX_SECTIONS];
34     uint32_t unused;
35     uint32_t eif_crc32;
36 } QEMU_PACKED EifHeader;
37 
38 /* members are ordered according to field order in .eif file */
39 typedef struct EifSectionHeader {
40     /*
41      * 0 = invalid, 1 = kernel, 2 = cmdline, 3 = ramdisk, 4 = signature,
42      * 5 = metadata
43      */
44     uint16_t section_type;
45     uint16_t flags;
46     uint64_t section_size;
47 } QEMU_PACKED EifSectionHeader;
48 
49 enum EifSectionTypes {
50     EIF_SECTION_INVALID = 0,
51     EIF_SECTION_KERNEL = 1,
52     EIF_SECTION_CMDLINE = 2,
53     EIF_SECTION_RAMDISK = 3,
54     EIF_SECTION_SIGNATURE = 4,
55     EIF_SECTION_METADATA = 5,
56     EIF_SECTION_MAX = 6,
57 };
58 
section_type_to_string(uint16_t type)59 static const char *section_type_to_string(uint16_t type)
60 {
61     const char *str;
62     switch (type) {
63     case EIF_SECTION_INVALID:
64         str = "invalid";
65         break;
66     case EIF_SECTION_KERNEL:
67         str = "kernel";
68         break;
69     case EIF_SECTION_CMDLINE:
70         str = "cmdline";
71         break;
72     case EIF_SECTION_RAMDISK:
73         str = "ramdisk";
74         break;
75     case EIF_SECTION_SIGNATURE:
76         str = "signature";
77         break;
78     case EIF_SECTION_METADATA:
79         str = "metadata";
80         break;
81     default:
82         str = "unknown";
83         break;
84     }
85 
86     return str;
87 }
88 
read_eif_header(FILE * f,EifHeader * header,uint32_t * crc,Error ** errp)89 static bool read_eif_header(FILE *f, EifHeader *header, uint32_t *crc,
90                             Error **errp)
91 {
92     size_t got;
93     size_t header_size = sizeof(*header);
94 
95     got = fread(header, 1, header_size, f);
96     if (got != header_size) {
97         error_setg(errp, "Failed to read EIF header");
98         return false;
99     }
100 
101     if (memcmp(header->magic, ".eif", 4) != 0) {
102         error_setg(errp, "Invalid EIF image. Magic mismatch.");
103         return false;
104     }
105 
106     /* Exclude header->eif_crc32 field from CRC calculation */
107     *crc = crc32(*crc, (uint8_t *)header, header_size - 4);
108 
109     header->version = be16_to_cpu(header->version);
110     header->flags = be16_to_cpu(header->flags);
111     header->default_memory = be64_to_cpu(header->default_memory);
112     header->default_cpus = be64_to_cpu(header->default_cpus);
113     header->reserved = be16_to_cpu(header->reserved);
114     header->section_cnt = be16_to_cpu(header->section_cnt);
115 
116     for (int i = 0; i < MAX_SECTIONS; ++i) {
117         header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
118     }
119 
120     for (int i = 0; i < MAX_SECTIONS; ++i) {
121         header->section_sizes[i] = be64_to_cpu(header->section_sizes[i]);
122         if (header->section_sizes[i] > SSIZE_MAX) {
123             error_setg(errp, "Invalid EIF image. Section size out of bounds");
124             return false;
125         }
126     }
127 
128     header->unused = be32_to_cpu(header->unused);
129     header->eif_crc32 = be32_to_cpu(header->eif_crc32);
130     return true;
131 }
132 
read_eif_section_header(FILE * f,EifSectionHeader * section_header,uint32_t * crc,Error ** errp)133 static bool read_eif_section_header(FILE *f, EifSectionHeader *section_header,
134                                     uint32_t *crc, Error **errp)
135 {
136     size_t got;
137     size_t section_header_size = sizeof(*section_header);
138 
139     got = fread(section_header, 1, section_header_size, f);
140     if (got != section_header_size) {
141         error_setg(errp, "Failed to read EIF section header");
142         return false;
143     }
144 
145     *crc = crc32(*crc, (uint8_t *)section_header, section_header_size);
146 
147     section_header->section_type = be16_to_cpu(section_header->section_type);
148     section_header->flags = be16_to_cpu(section_header->flags);
149     section_header->section_size = be64_to_cpu(section_header->section_size);
150     return true;
151 }
152 
153 /*
154  * Upon success, the caller is responsible for unlinking and freeing *tmp_path.
155  */
get_tmp_file(const char * template,char ** tmp_path,Error ** errp)156 static bool get_tmp_file(const char *template, char **tmp_path, Error **errp)
157 {
158     int tmp_fd;
159 
160     *tmp_path = NULL;
161     tmp_fd = g_file_open_tmp(template, tmp_path, NULL);
162     if (tmp_fd < 0 || *tmp_path == NULL) {
163         error_setg(errp, "Failed to create temporary file for template %s",
164                    template);
165         return false;
166     }
167 
168     close(tmp_fd);
169     return true;
170 }
171 
safe_fclose(FILE * f)172 static void safe_fclose(FILE *f)
173 {
174     if (f) {
175         fclose(f);
176     }
177 }
178 
safe_unlink(char * f)179 static void safe_unlink(char *f)
180 {
181     if (f) {
182         unlink(f);
183     }
184 }
185 
186 /*
187  * Upon success, the caller is reponsible for unlinking and freeing *kernel_path
188  */
read_eif_kernel(FILE * f,uint64_t size,char ** kernel_path,QCryptoHash * hash0,QCryptoHash * hash1,uint32_t * crc,Error ** errp)189 static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path,
190                             QCryptoHash *hash0, QCryptoHash *hash1,
191                             uint32_t *crc, Error **errp)
192 {
193     size_t got;
194     FILE *tmp_file = NULL;
195     uint8_t *kernel = g_try_malloc(size);
196     if (!kernel) {
197         error_setg(errp, "Out of memory reading kernel section");
198         goto cleanup;
199     }
200 
201     *kernel_path = NULL;
202     if (!get_tmp_file("eif-kernel-XXXXXX", kernel_path, errp)) {
203         goto cleanup;
204     }
205 
206     tmp_file = fopen(*kernel_path, "wb");
207     if (tmp_file == NULL) {
208         error_setg_errno(errp, errno, "Failed to open temporary file %s",
209                          *kernel_path);
210         goto cleanup;
211     }
212 
213     got = fread(kernel, 1, size, f);
214     if ((uint64_t) got != size) {
215         error_setg(errp, "Failed to read EIF kernel section data");
216         goto cleanup;
217     }
218 
219     got = fwrite(kernel, 1, size, tmp_file);
220     if ((uint64_t) got != size) {
221         error_setg(errp, "Failed to write EIF kernel section data to temporary"
222                    " file");
223         goto cleanup;
224     }
225 
226     *crc = crc32(*crc, kernel, size);
227     if (qcrypto_hash_update(hash0, (char *)kernel, size, errp) != 0 ||
228         qcrypto_hash_update(hash1, (char *)kernel, size, errp) != 0) {
229         goto cleanup;
230     }
231     g_free(kernel);
232     fclose(tmp_file);
233 
234     return true;
235 
236  cleanup:
237     safe_fclose(tmp_file);
238 
239     safe_unlink(*kernel_path);
240     g_free(*kernel_path);
241     *kernel_path = NULL;
242 
243     g_free(kernel);
244     return false;
245 }
246 
read_eif_cmdline(FILE * f,uint64_t size,char * cmdline,QCryptoHash * hash0,QCryptoHash * hash1,uint32_t * crc,Error ** errp)247 static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline,
248                              QCryptoHash *hash0, QCryptoHash *hash1,
249                              uint32_t *crc, Error **errp)
250 {
251     size_t got = fread(cmdline, 1, size, f);
252     if ((uint64_t) got != size) {
253         error_setg(errp, "Failed to read EIF cmdline section data");
254         return false;
255     }
256 
257     *crc = crc32(*crc, (uint8_t *)cmdline, size);
258     if (qcrypto_hash_update(hash0, cmdline, size, errp) != 0 ||
259         qcrypto_hash_update(hash1, cmdline, size, errp) != 0) {
260         return false;
261     }
262     return true;
263 }
264 
read_eif_ramdisk(FILE * eif,FILE * initrd,uint64_t size,QCryptoHash * hash0,QCryptoHash * h,uint32_t * crc,Error ** errp)265 static bool read_eif_ramdisk(FILE *eif, FILE *initrd, uint64_t size,
266                              QCryptoHash *hash0, QCryptoHash *h, uint32_t *crc,
267                              Error **errp)
268 {
269     size_t got;
270     bool ret = false;
271     uint8_t *ramdisk = g_try_malloc(size);
272     if (!ramdisk) {
273         error_setg(errp, "Out of memory reading initrd section");
274         goto cleanup;
275     }
276 
277     got = fread(ramdisk, 1, size, eif);
278     if ((uint64_t) got != size) {
279         error_setg(errp, "Failed to read EIF ramdisk section data");
280         goto cleanup;
281     }
282 
283     got = fwrite(ramdisk, 1, size, initrd);
284     if ((uint64_t) got != size) {
285         error_setg(errp, "Failed to write EIF ramdisk data to temporary file");
286         goto cleanup;
287     }
288 
289     *crc = crc32(*crc, ramdisk, size);
290     if (qcrypto_hash_update(hash0, (char *)ramdisk, size, errp) != 0 ||
291         qcrypto_hash_update(h, (char *)ramdisk, size, errp) != 0) {
292         goto cleanup;
293     }
294     ret = true;
295 
296  cleanup:
297     g_free(ramdisk);
298     return ret;
299 }
300 
get_signature_fingerprint_sha384(FILE * eif,uint64_t size,uint8_t * sha384,uint32_t * crc,Error ** errp)301 static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size,
302                                              uint8_t *sha384,
303                                              uint32_t *crc,
304                                              Error **errp)
305 {
306     size_t got;
307     g_autofree uint8_t *sig = NULL;
308     g_autofree uint8_t *cert = NULL;
309     cbor_item_t *item = NULL;
310     cbor_item_t *pcr0 = NULL;
311     size_t len;
312     size_t hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
313     struct cbor_pair *pair;
314     struct cbor_load_result result;
315     bool ret = false;
316 
317     sig = g_try_malloc(size);
318     if (!sig) {
319         error_setg(errp, "Out of memory reading signature section");
320         goto cleanup;
321     }
322 
323     got = fread(sig, 1, size, eif);
324     if ((uint64_t) got != size) {
325         error_setg(errp, "Failed to read EIF signature section data");
326         goto cleanup;
327     }
328 
329     *crc = crc32(*crc, sig, size);
330 
331     item = cbor_load(sig, size, &result);
332     if (!item || result.error.code != CBOR_ERR_NONE) {
333         error_setg(errp, "Failed to load signature section data as CBOR");
334         goto cleanup;
335     }
336     if (!cbor_isa_array(item) || cbor_array_size(item) < 1) {
337         error_setg(errp, "Invalid signature CBOR");
338         goto cleanup;
339     }
340     pcr0 = cbor_array_get(item, 0);
341     if (!pcr0) {
342         error_setg(errp, "Failed to get PCR0 signature");
343         goto cleanup;
344     }
345     if (!cbor_isa_map(pcr0) || cbor_map_size(pcr0) != 2) {
346         error_setg(errp, "Invalid signature CBOR");
347         goto cleanup;
348     }
349     pair = cbor_map_handle(pcr0);
350     if (!cbor_isa_string(pair->key) || cbor_string_length(pair->key) != 19 ||
351         memcmp(cbor_string_handle(pair->key), "signing_certificate", 19) != 0) {
352         error_setg(errp, "Invalid signautre CBOR");
353         goto cleanup;
354     }
355     if (!cbor_isa_array(pair->value)) {
356         error_setg(errp, "Invalid signature CBOR");
357         goto cleanup;
358     }
359     len = cbor_array_size(pair->value);
360     if (len == 0) {
361         error_setg(errp, "Invalid signature CBOR");
362         goto cleanup;
363     }
364     cert = g_try_malloc(len);
365     if (!cert) {
366         error_setg(errp, "Out of memory reading signature section");
367         goto cleanup;
368     }
369 
370     for (int i = 0; i < len; ++i) {
371         cbor_item_t *tmp = cbor_array_get(pair->value, i);
372         if (!tmp) {
373             error_setg(errp, "Invalid signature CBOR");
374             goto cleanup;
375         }
376         if (!cbor_isa_uint(tmp) || cbor_int_get_width(tmp) != CBOR_INT_8) {
377             cbor_decref(&tmp);
378             error_setg(errp, "Invalid signature CBOR");
379             goto cleanup;
380         }
381         cert[i] = cbor_get_uint8(tmp);
382         cbor_decref(&tmp);
383     }
384 
385     if (qcrypto_get_x509_cert_fingerprint(cert, len, QCRYPTO_HASH_ALGO_SHA384,
386                                           sha384, &hash_len, errp)) {
387         goto cleanup;
388     }
389 
390     ret = true;
391 
392  cleanup:
393     if (pcr0) {
394         cbor_decref(&pcr0);
395     }
396     if (item) {
397         cbor_decref(&item);
398     }
399     return ret;
400 }
401 
402 /* Expects file to have offset 0 before this function is called */
get_file_size(FILE * f,Error ** errp)403 static long get_file_size(FILE *f, Error **errp)
404 {
405     long size;
406 
407     if (fseek(f, 0, SEEK_END) != 0) {
408         error_setg_errno(errp, errno, "Failed to seek to the end of file");
409         return -1;
410     }
411 
412     size = ftell(f);
413     if (size == -1) {
414         error_setg_errno(errp, errno, "Failed to get offset");
415         return -1;
416     }
417 
418     if (fseek(f, 0, SEEK_SET) != 0) {
419         error_setg_errno(errp, errno, "Failed to seek back to the start");
420         return -1;
421     }
422 
423     return size;
424 }
425 
get_SHA384_hash(QCryptoHash * h,uint8_t * hash,Error ** errp)426 static bool get_SHA384_hash(QCryptoHash *h, uint8_t *hash, Error **errp)
427 {
428     size_t hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
429     return qcrypto_hash_finalize_bytes(h, &hash, &hash_len, errp) == 0;
430 }
431 
432 /*
433  * Upon success, the caller is reponsible for unlinking and freeing
434  * *kernel_path, *initrd_path and freeing *cmdline.
435  */
read_eif_file(const char * eif_path,const char * machine_initrd,char ** kernel_path,char ** initrd_path,char ** cmdline,uint8_t * image_hash,uint8_t * bootstrap_hash,uint8_t * app_hash,uint8_t * fingerprint_hash,bool * signature_found,Error ** errp)436 bool read_eif_file(const char *eif_path, const char *machine_initrd,
437                    char **kernel_path, char **initrd_path, char **cmdline,
438                    uint8_t *image_hash, uint8_t *bootstrap_hash,
439                    uint8_t *app_hash, uint8_t *fingerprint_hash,
440                    bool *signature_found, Error **errp)
441 {
442     FILE *f = NULL;
443     FILE *machine_initrd_f = NULL;
444     FILE *initrd_path_f = NULL;
445     long machine_initrd_size;
446     uint32_t crc = 0;
447     EifHeader eif_header;
448     bool seen_sections[EIF_SECTION_MAX] = {false};
449     /* kernel + ramdisks + cmdline SHA384 hash */
450     g_autoptr(QCryptoHash) hash0 = NULL;
451     /* kernel + boot ramdisk + cmdline SHA384 hash */
452     g_autoptr(QCryptoHash) hash1 = NULL;
453     /* application ramdisk(s) SHA384 hash */
454     g_autoptr(QCryptoHash) hash2 = NULL;
455 
456     *signature_found = false;
457     *kernel_path = *initrd_path = *cmdline = NULL;
458 
459     hash0 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
460     if (!hash0) {
461         goto cleanup;
462     }
463     hash1 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
464     if (!hash1) {
465         goto cleanup;
466     }
467     hash2 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
468     if (!hash2) {
469         goto cleanup;
470     }
471 
472     f = fopen(eif_path, "rb");
473     if (f == NULL) {
474         error_setg_errno(errp, errno, "Failed to open %s", eif_path);
475         goto cleanup;
476     }
477 
478     if (!read_eif_header(f, &eif_header, &crc, errp)) {
479         goto cleanup;
480     }
481 
482     if (eif_header.version < 4) {
483         error_setg(errp, "Expected EIF version 4 or greater");
484         goto cleanup;
485     }
486 
487     if (eif_header.flags != 0) {
488         error_setg(errp, "Expected EIF flags to be 0");
489         goto cleanup;
490     }
491 
492     if (eif_header.section_cnt > MAX_SECTIONS) {
493         error_setg(errp, "EIF header section count must not be greater than "
494                    "%d but found %d", MAX_SECTIONS, eif_header.section_cnt);
495         goto cleanup;
496     }
497 
498     for (int i = 0; i < eif_header.section_cnt; ++i) {
499         EifSectionHeader hdr;
500         uint16_t section_type;
501 
502         if (eif_header.section_offsets[i] > OFF_MAX) {
503             error_setg(errp, "Invalid EIF image. Section offset out of bounds");
504             goto cleanup;
505         }
506         if (fseek(f, eif_header.section_offsets[i], SEEK_SET) != 0) {
507             error_setg_errno(errp, errno, "Failed to offset to %" PRIu64 " in EIF file",
508                              eif_header.section_offsets[i]);
509             goto cleanup;
510         }
511 
512         if (!read_eif_section_header(f, &hdr, &crc, errp)) {
513             goto cleanup;
514         }
515 
516         if (hdr.flags != 0) {
517             error_setg(errp, "Expected EIF section header flags to be 0");
518             goto cleanup;
519         }
520 
521         if (eif_header.section_sizes[i] != hdr.section_size) {
522             error_setg(errp, "EIF section size mismatch between header and "
523                        "section header: header %" PRIu64 ", section header %" PRIu64,
524                        eif_header.section_sizes[i],
525                        hdr.section_size);
526             goto cleanup;
527         }
528 
529         section_type = hdr.section_type;
530 
531         switch (section_type) {
532         case EIF_SECTION_KERNEL:
533             if (seen_sections[EIF_SECTION_KERNEL]) {
534                 error_setg(errp, "Invalid EIF image. More than 1 kernel "
535                            "section");
536                 goto cleanup;
537             }
538 
539             if (!read_eif_kernel(f, hdr.section_size, kernel_path, hash0,
540                                  hash1, &crc, errp)) {
541                 goto cleanup;
542             }
543 
544             break;
545         case EIF_SECTION_CMDLINE:
546         {
547             uint64_t size;
548             if (seen_sections[EIF_SECTION_CMDLINE]) {
549                 error_setg(errp, "Invalid EIF image. More than 1 cmdline "
550                            "section");
551                 goto cleanup;
552             }
553             size = hdr.section_size;
554             *cmdline = g_try_malloc(size + 1);
555             if (!*cmdline) {
556                 error_setg(errp, "Out of memory reading command line section");
557                 goto cleanup;
558             }
559             if (!read_eif_cmdline(f, size, *cmdline, hash0, hash1, &crc,
560                                   errp)) {
561                 goto cleanup;
562             }
563             (*cmdline)[size] = '\0';
564 
565             break;
566         }
567         case EIF_SECTION_RAMDISK:
568         {
569             QCryptoHash *h = hash2;
570             if (!seen_sections[EIF_SECTION_RAMDISK]) {
571                 /*
572                  * If this is the first time we are seeing a ramdisk section,
573                  * we need to:
574                  * 1) hash it into bootstrap (hash1) instead of app (hash2)
575                  *    along with image (hash0)
576                  * 2) create the initrd temporary file.
577                  */
578                 h = hash1;
579                 if (!get_tmp_file("eif-initrd-XXXXXX", initrd_path, errp)) {
580                     goto cleanup;
581                 }
582                 initrd_path_f = fopen(*initrd_path, "wb");
583                 if (initrd_path_f == NULL) {
584                     error_setg_errno(errp, errno, "Failed to open file %s",
585                                      *initrd_path);
586                     goto cleanup;
587                 }
588             }
589 
590             if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, hash0, h,
591                                   &crc, errp)) {
592                 goto cleanup;
593             }
594 
595             break;
596         }
597         case EIF_SECTION_SIGNATURE:
598             *signature_found = true;
599             if (!get_signature_fingerprint_sha384(f, hdr.section_size,
600                                                   fingerprint_hash, &crc,
601                                                   errp)) {
602                 goto cleanup;
603             }
604             break;
605         default:
606             /* other sections including invalid or unknown sections */
607         {
608             uint8_t *buf;
609             size_t got;
610             uint64_t size = hdr.section_size;
611             buf = g_try_malloc(size);
612             if (!buf) {
613                 error_setg(errp, "Out of memory reading unknown section");
614                 goto cleanup;
615             }
616             got = fread(buf, 1, size, f);
617             if ((uint64_t) got != size) {
618                 g_free(buf);
619                 error_setg(errp, "Failed to read EIF %s section data",
620                            section_type_to_string(section_type));
621                 goto cleanup;
622             }
623             crc = crc32(crc, buf, size);
624             g_free(buf);
625             break;
626         }
627         }
628 
629         if (section_type < EIF_SECTION_MAX) {
630             seen_sections[section_type] = true;
631         }
632     }
633 
634     if (!seen_sections[EIF_SECTION_KERNEL]) {
635         error_setg(errp, "Invalid EIF image. No kernel section.");
636         goto cleanup;
637     }
638     if (!seen_sections[EIF_SECTION_CMDLINE]) {
639         error_setg(errp, "Invalid EIF image. No cmdline section.");
640         goto cleanup;
641     }
642     if (!seen_sections[EIF_SECTION_RAMDISK]) {
643         error_setg(errp, "Invalid EIF image. No ramdisk section.");
644         goto cleanup;
645     }
646 
647     if (eif_header.eif_crc32 != crc) {
648         error_setg(errp, "CRC mismatch. Expected %u but header has %u.",
649                    crc, eif_header.eif_crc32);
650         goto cleanup;
651     }
652 
653     /*
654      * Let's append the initrd file from "-initrd" option if any. Although
655      * we pass the crc pointer to read_eif_ramdisk, it is not useful anymore.
656      * We have already done the crc mismatch check above this code.
657      */
658     if (machine_initrd) {
659         machine_initrd_f = fopen(machine_initrd, "rb");
660         if (machine_initrd_f == NULL) {
661             error_setg_errno(errp, errno, "Failed to open initrd file %s",
662                              machine_initrd);
663             goto cleanup;
664         }
665 
666         machine_initrd_size = get_file_size(machine_initrd_f, errp);
667         if (machine_initrd_size == -1) {
668             goto cleanup;
669         }
670 
671         if (!read_eif_ramdisk(machine_initrd_f, initrd_path_f,
672                               machine_initrd_size, hash0, hash2, &crc, errp)) {
673             goto cleanup;
674         }
675     }
676 
677     if (!get_SHA384_hash(hash0, image_hash, errp)) {
678         goto cleanup;
679     }
680     if (!get_SHA384_hash(hash1, bootstrap_hash, errp)) {
681         goto cleanup;
682     }
683     if (!get_SHA384_hash(hash2, app_hash, errp)) {
684         goto cleanup;
685     }
686 
687     fclose(f);
688     fclose(initrd_path_f);
689     safe_fclose(machine_initrd_f);
690     return true;
691 
692  cleanup:
693     safe_fclose(f);
694     safe_fclose(initrd_path_f);
695     safe_fclose(machine_initrd_f);
696 
697     safe_unlink(*kernel_path);
698     g_free(*kernel_path);
699     *kernel_path = NULL;
700 
701     safe_unlink(*initrd_path);
702     g_free(*initrd_path);
703     *initrd_path = NULL;
704 
705     g_free(*cmdline);
706     *cmdline = NULL;
707 
708     return false;
709 }
710