summaryrefslogtreecommitdiff
path: root/firmware/2lib
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/2lib')
-rw-r--r--firmware/2lib/2api.c45
-rw-r--r--firmware/2lib/2common.c3
-rw-r--r--firmware/2lib/include/2api.h46
3 files changed, 82 insertions, 12 deletions
diff --git a/firmware/2lib/2api.c b/firmware/2lib/2api.c
index 0d1ebe86..698e2bb7 100644
--- a/firmware/2lib/2api.c
+++ b/firmware/2lib/2api.c
@@ -305,14 +305,10 @@ vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag)
/*
* Unpack the firmware data key to see which hashing algorithm we
- * should use.
- *
- * TODO: really, the firmware body should be hashed, and not signed,
- * because the signature we're checking is already signed as part of
- * the firmware preamble. But until we can change the signing scripts,
- * we're stuck with a signature here instead of a hash.
+ * should use. Zero body data size means, that signature contains
+ * metadata hash, so vb2api_get_metadata_hash() should be used instead.
*/
- if (!sd->data_key_size)
+ if (!sd->data_key_size || !pre->body_signature.data_size)
return VB2_ERROR_API_INIT_HASH_DATA_KEY;
VB2_TRY(vb2_unpack_key_buffer(&key,
@@ -369,8 +365,9 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
return VB2_ERROR_API_CHECK_HASH_TAG;
/*
- * The body signature is currently a *signature* of the body data, not
- * just its hash. So we need to verify the signature.
+ * In case of verifying a whole memory region the body signature
+ * is a *signature* of the body data, not just its hash.
+ * So we need to verify the signature.
*/
/* Unpack the data key */
@@ -433,3 +430,33 @@ union vb2_fw_boot_info vb2api_get_fw_boot_info(struct vb2_context *ctx)
return info;
}
+
+vb2_error_t vb2api_get_metadata_hash(struct vb2_context *ctx,
+ struct vb2_hash **hash_ptr_out)
+{
+ struct vb2_shared_data *sd = vb2_get_sd(ctx);
+ struct vb2_workbuf wb;
+ struct vb2_fw_preamble *pre;
+
+ vb2_workbuf_from_ctx(ctx, &wb);
+
+ if (!sd->preamble_size)
+ return VB2_ERROR_API_CHECK_HASH_PREAMBLE;
+ pre = vb2_member_of(sd, sd->preamble_offset);
+
+ /* Zero size of body signature indicates, that signature holds
+ vb2_hash inside. */
+ if (pre->body_signature.data_size)
+ return VB2_ERROR_API_INIT_HASH_DATA_KEY;
+
+ struct vb2_hash *hash =
+ (struct vb2_hash *)vb2_signature_data(&pre->body_signature);
+ const uint32_t hsize = vb2_digest_size(hash->algo);
+ if (!hsize || pre->body_signature.sig_size <
+ offsetof(struct vb2_hash, raw) + hsize)
+ return VB2_ERROR_API_CHECK_HASH_SIG_SIZE;
+
+ *hash_ptr_out = hash;
+
+ return VB2_SUCCESS;
+}
diff --git a/firmware/2lib/2common.c b/firmware/2lib/2common.c
index 1d1ad690..3d08f5b2 100644
--- a/firmware/2lib/2common.c
+++ b/firmware/2lib/2common.c
@@ -156,6 +156,9 @@ vb2_error_t vb2_verify_digest(const struct vb2_public_key *key,
/* A signature is destroyed in the process of being verified. */
uint8_t *sig_data = vb2_signature_data_mutable(sig);
+ if (!sig->data_size)
+ return VB2_ERROR_VDATA_NOT_ENOUGH_DATA;
+
if (sig->sig_size != vb2_rsa_sig_size(key->sig_alg)) {
VB2_DEBUG("Wrong data signature size for algorithm, "
"sig_size=%d, expected %d for algorithm %d.\n",
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index 03e49fe0..869d2361 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -150,19 +150,37 @@ enum vb2_pcr_digest {
* Verify the hash of each section of code/data you need to boot the RW
* firmware. For each section:
*
- * Call vb2_init_hash() to see if the hash exists.
+ * 1) Normal verification:
*
- * Load the data for the section. Call vb2_extend_hash() on the
+ * Call vb2api_init_hash() to see if the hash exists.
+ *
+ * Load the data for the section. Call vb2api_extend_hash() on the
* data as you load it. You can load it all at once and make one
* call, or load and hash-extend a block at a time.
*
- * Call vb2_check_hash() to see if the hash is valid.
+ * Call vb2api_check_hash() to see if the hash is valid.
*
* If it is valid, you may use the data and/or execute
* code from that section.
*
* If the hash was invalid, you must reboot.
*
+ * 2) Verification with CBFS integration:
+ *
+ * Call vb2api_get_metadata_hash() to get hash of CBFS metadata.
+ *
+ * Initialize CBFS using stored hash as correct metadata hash.
+ *
+ * If CBFS initialization fails because of metadata hash
+ * mismatch, you must reboot.
+ *
+ * If CBFS initialization succeeds, you may use the data
+ * and/or execute code from that section.
+ * IMPORTANT: Be aware, that to have full section
+ * verification, the CBFS_VERIFICATION has to be enabled.
+ * Initialization of CBFS volume only checks hash of files
+ * metadata, not their contents!
+ *
* At this point, firmware verification is done, and vb2_context contains the
* kernel key needed to verify the kernel. That context should be preserved
* and passed on to kernel selection. The kernel selection process may be
@@ -442,6 +460,9 @@ vb2_error_t vb2api_fw_phase3(struct vb2_context *ctx);
/**
* Initialize hashing data for the specified tag.
+ * This function is not legal when running from a coreboot image that has
+ * CONFIG_VBOOT_CBFS_INTEGRATION=y set. In that case, vb2api_get_metadata_hash()
+ * must be used instead.
*
* @param ctx Vboot context
* @param tag Tag to start hashing (enum vb2_hash_tag)
@@ -484,6 +505,23 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
uint32_t digest_out_size);
/**
+ * Get pointer to metadata hash from body signature in preamble.
+ * Body signature data size has to be zero to indicate that it contains
+ * metadata hash. This is only legal to call after vb2api_fw_phase3() has
+ * returned successfully, and will return with error otherwise.
+ * This function is only legal to call from coreboot with
+ * CONFIG_VBOOT_CBFS_INTEGRATION=y. `futility sign` will automatically detect
+ * the presence of that option in an image and prepare the correct kind
+ * of signature.
+ *
+ * @param ctx Vboot context
+ * @param hash_ptr_out pointer to output hash to
+ * @return VB2_SUCCESS, or error code on error.
+ */
+vb2_error_t vb2api_get_metadata_hash(struct vb2_context *ctx,
+ struct vb2_hash **hash_ptr_out);
+
+/**
* Get a PCR digest
*
* @param ctx Vboot context
@@ -726,6 +764,8 @@ vb2_gbb_flags_t vb2api_gbb_get_flags(struct vb2_context *ctx);
/**
* Get the size of the signed firmware body. This is only legal to call after
* vb2api_fw_phase3() has returned successfully, and will return 0 otherwise.
+ * It will also return 0 when body signature contains metadata hash instead
+ * of body hash.
*
* @param ctx Vboot context
*