* Upon success, the caller is reponsible for unlinking and freeing *kernel_path
  */
 static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path,
-                            uint8_t *kernel, uint32_t *crc, Error **errp)
+                            QCryptoHash *hash0, QCryptoHash *hash1,
+                            uint32_t *crc, Error **errp)
 {
     size_t got;
     FILE *tmp_file = NULL;
+    uint8_t *kernel = g_try_malloc(size);
+    if (!kernel) {
+        error_setg(errp, "Out of memory reading kernel section");
+        goto cleanup;
+    }
 
     *kernel_path = NULL;
     if (!get_tmp_file("eif-kernel-XXXXXX", kernel_path, errp)) {
     }
 
     *crc = crc32(*crc, kernel, size);
+    if (qcrypto_hash_update(hash0, (char *)kernel, size, errp) != 0 ||
+        qcrypto_hash_update(hash1, (char *)kernel, size, errp) != 0) {
+        goto cleanup;
+    }
+    g_free(kernel);
     fclose(tmp_file);
 
     return true;
     g_free(*kernel_path);
     *kernel_path = NULL;
 
+    g_free(kernel);
     return false;
 }
 
 static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline,
+                             QCryptoHash *hash0, QCryptoHash *hash1,
                              uint32_t *crc, Error **errp)
 {
     size_t got = fread(cmdline, 1, size, f);
     }
 
     *crc = crc32(*crc, (uint8_t *)cmdline, size);
+    if (qcrypto_hash_update(hash0, cmdline, size, errp) != 0 ||
+        qcrypto_hash_update(hash1, cmdline, size, errp) != 0) {
+        return false;
+    }
     return true;
 }
 
 static bool read_eif_ramdisk(FILE *eif, FILE *initrd, uint64_t size,
-                             uint8_t *ramdisk, uint32_t *crc, Error **errp)
+                             QCryptoHash *hash0, QCryptoHash *h, uint32_t *crc,
+                             Error **errp)
 {
     size_t got;
+    bool ret = false;
+    uint8_t *ramdisk = g_try_malloc(size);
+    if (!ramdisk) {
+        error_setg(errp, "Out of memory reading initrd section");
+        goto cleanup;
+    }
 
     got = fread(ramdisk, 1, size, eif);
     if ((uint64_t) got != size) {
         error_setg(errp, "Failed to read EIF ramdisk section data");
-        return false;
+        goto cleanup;
     }
 
     got = fwrite(ramdisk, 1, size, initrd);
     if ((uint64_t) got != size) {
         error_setg(errp, "Failed to write EIF ramdisk data to temporary file");
-        return false;
+        goto cleanup;
     }
 
     *crc = crc32(*crc, ramdisk, size);
-    return true;
+    if (qcrypto_hash_update(hash0, (char *)ramdisk, size, errp) != 0 ||
+        qcrypto_hash_update(h, (char *)ramdisk, size, errp) != 0) {
+        goto cleanup;
+    }
+    ret = true;
+
+ cleanup:
+    g_free(ramdisk);
+    return ret;
 }
 
 static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size,
     return size;
 }
 
-static bool get_SHA384_digest(GList *list, uint8_t *digest, Error **errp)
+static bool get_SHA384_hash(QCryptoHash *h, uint8_t *hash, Error **errp)
 {
-    size_t digest_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
-    size_t list_len = g_list_length(list);
-    struct iovec *iovec_list = g_new0(struct iovec, list_len);
-    bool ret = true;
-    GList *l;
-    int i;
-
-    for (i = 0, l = list; l != NULL; l = l->next, i++) {
-        iovec_list[i] = *(struct iovec *) l->data;
-    }
-
-    if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALGO_SHA384, iovec_list, list_len,
-                            &digest, &digest_len, errp) < 0) {
-        ret = false;
-    }
-
-    g_free(iovec_list);
-    return ret;
-}
-
-static void free_iovec(struct iovec *iov)
-{
-    if (iov) {
-        g_free(iov->iov_base);
-        g_free(iov);
-    }
+    size_t hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
+    return qcrypto_hash_finalize_bytes(h, &hash, &hash_len, errp) == 0;
 }
 
 /*
  */
 bool read_eif_file(const char *eif_path, const char *machine_initrd,
                    char **kernel_path, char **initrd_path, char **cmdline,
-                   uint8_t *image_sha384, uint8_t *bootstrap_sha384,
-                   uint8_t *app_sha384, uint8_t *fingerprint_sha384,
+                   uint8_t *image_hash, uint8_t *bootstrap_hash,
+                   uint8_t *app_hash, uint8_t *fingerprint_hash,
                    bool *signature_found, Error **errp)
 {
     FILE *f = NULL;
     uint32_t crc = 0;
     EifHeader eif_header;
     bool seen_sections[EIF_SECTION_MAX] = {false};
-    /* kernel + ramdisks + cmdline sha384 hash */
-    GList *iov_PCR0 = NULL;
-    /* kernel + boot ramdisk + cmdline sha384 hash */
-    GList *iov_PCR1 = NULL;
-    /* application ramdisk(s) hash */
-    GList *iov_PCR2 = NULL;
-    uint8_t *ptr = NULL;
-    struct iovec *iov_ptr = NULL;
+    /* kernel + ramdisks + cmdline SHA384 hash */
+    g_autoptr(QCryptoHash) hash0 = NULL;
+    /* kernel + boot ramdisk + cmdline SHA384 hash */
+    g_autoptr(QCryptoHash) hash1 = NULL;
+    /* application ramdisk(s) SHA384 hash */
+    g_autoptr(QCryptoHash) hash2 = NULL;
 
     *signature_found = false;
     *kernel_path = *initrd_path = *cmdline = NULL;
 
+    hash0 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
+    if (!hash0) {
+        goto cleanup;
+    }
+    hash1 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
+    if (!hash1) {
+        goto cleanup;
+    }
+    hash2 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
+    if (!hash2) {
+        goto cleanup;
+    }
+
     f = fopen(eif_path, "rb");
     if (f == NULL) {
         error_setg_errno(errp, errno, "Failed to open %s", eif_path);
                 goto cleanup;
             }
 
-            ptr = g_try_malloc(hdr.section_size);
-            if (!ptr) {
-                error_setg(errp, "Out of memory reading kernel section");
-                goto cleanup;
-            }
-
-            iov_ptr = g_malloc(sizeof(struct iovec));
-            iov_ptr->iov_base = ptr;
-            iov_ptr->iov_len = hdr.section_size;
-
-            iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
-            iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
-
-            if (!read_eif_kernel(f, hdr.section_size, kernel_path, ptr, &crc,
-                                 errp)) {
+            if (!read_eif_kernel(f, hdr.section_size, kernel_path, hash0,
+                                 hash1, &crc, errp)) {
                 goto cleanup;
             }
 
         case EIF_SECTION_CMDLINE:
         {
             uint64_t size;
-            uint8_t *cmdline_copy;
             if (seen_sections[EIF_SECTION_CMDLINE]) {
                 error_setg(errp, "Invalid EIF image. More than 1 cmdline "
                            "section");
                 error_setg(errp, "Out of memory reading command line section");
                 goto cleanup;
             }
-            if (!read_eif_cmdline(f, size, *cmdline, &crc, errp)) {
+            if (!read_eif_cmdline(f, size, *cmdline, hash0, hash1, &crc,
+                                  errp)) {
                 goto cleanup;
             }
             (*cmdline)[size] = '\0';
 
-            /*
-             * We make a copy of '*cmdline' for putting it in iovecs so that
-             * we can easily free all the iovec entries later as we cannot
-             * free '*cmdline' which is used by the caller.
-             */
-            cmdline_copy = g_memdup2(*cmdline, size);
-
-            iov_ptr = g_malloc(sizeof(struct iovec));
-            iov_ptr->iov_base = cmdline_copy;
-            iov_ptr->iov_len = size;
-
-            iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
-            iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
             break;
         }
         case EIF_SECTION_RAMDISK:
         {
+            QCryptoHash *h = hash2;
             if (!seen_sections[EIF_SECTION_RAMDISK]) {
                 /*
                  * If this is the first time we are seeing a ramdisk section,
-                 * we need to create the initrd temporary file.
+                 * we need to:
+                 * 1) hash it into bootstrap (hash1) instead of app (hash2)
+                 *    along with image (hash0)
+                 * 2) create the initrd temporary file.
                  */
+                h = hash1;
                 if (!get_tmp_file("eif-initrd-XXXXXX", initrd_path, errp)) {
                     goto cleanup;
                 }
                 }
             }
 
-            ptr = g_try_malloc(hdr.section_size);
-            if (!ptr) {
-                error_setg(errp, "Out of memory reading initrd section");
-                goto cleanup;
-            }
-
-            iov_ptr = g_malloc(sizeof(struct iovec));
-            iov_ptr->iov_base = ptr;
-            iov_ptr->iov_len = hdr.section_size;
-
-            iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
-            /*
-             * If it's the first ramdisk, we need to hash it into bootstrap
-             * i.e., iov_PCR1, otherwise we need to hash it into app i.e.,
-             * iov_PCR2.
-             */
-            if (!seen_sections[EIF_SECTION_RAMDISK]) {
-                iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
-            } else {
-                iov_PCR2 = g_list_append(iov_PCR2, iov_ptr);
-            }
-
-            if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, ptr,
+            if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, hash0, h,
                                   &crc, errp)) {
                 goto cleanup;
             }
         case EIF_SECTION_SIGNATURE:
             *signature_found = true;
             if (!get_signature_fingerprint_sha384(f, hdr.section_size,
-                                                  fingerprint_sha384, &crc,
+                                                  fingerprint_hash, &crc,
                                                   errp)) {
                 goto cleanup;
             }
             goto cleanup;
         }
 
-        ptr = g_try_malloc(machine_initrd_size);
-        if (!ptr) {
-            error_setg(errp, "Out of memory reading initrd file");
-            goto cleanup;
-        }
-
-        iov_ptr = g_malloc(sizeof(struct iovec));
-        iov_ptr->iov_base = ptr;
-        iov_ptr->iov_len = machine_initrd_size;
-
-        iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
-        iov_PCR2 = g_list_append(iov_PCR2, iov_ptr);
-
         if (!read_eif_ramdisk(machine_initrd_f, initrd_path_f,
-                              machine_initrd_size, ptr, &crc, errp)) {
+                              machine_initrd_size, hash0, hash2, &crc, errp)) {
             goto cleanup;
         }
     }
 
-    if (!get_SHA384_digest(iov_PCR0, image_sha384, errp)) {
+    if (!get_SHA384_hash(hash0, image_hash, errp)) {
         goto cleanup;
     }
-    if (!get_SHA384_digest(iov_PCR1, bootstrap_sha384, errp)) {
+    if (!get_SHA384_hash(hash1, bootstrap_hash, errp)) {
         goto cleanup;
     }
-    if (!get_SHA384_digest(iov_PCR2, app_sha384, errp)) {
+    if (!get_SHA384_hash(hash2, app_hash, errp)) {
         goto cleanup;
     }
 
-    /*
-     * We only need to free iov_PCR0 entries because iov_PCR1 and
-     * iov_PCR2 iovec entries are subsets of iov_PCR0 iovec entries.
-     */
-    g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec);
-    g_list_free(iov_PCR1);
-    g_list_free(iov_PCR2);
     fclose(f);
     fclose(initrd_path_f);
     safe_fclose(machine_initrd_f);
     return true;
 
  cleanup:
-    g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec);
-    g_list_free(iov_PCR1);
-    g_list_free(iov_PCR2);
-
     safe_fclose(f);
     safe_fclose(initrd_path_f);
     safe_fclose(machine_initrd_f);