summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorJakub Czapiga <jacz@semihalf.com>2022-08-04 17:13:06 +0200
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-10-12 17:41:55 +0000
commit0ca7a9e4dad2e9780690524ced9273fa07052179 (patch)
tree9078489dc0f6e8e79aaf3ff80f2358b5dbc7e814 /firmware
parentaaeb307f882d0c2e1284636e8423af1d216f6362 (diff)
downloadvboot-0ca7a9e4dad2e9780690524ced9273fa07052179.tar.gz
firmware: host: futility: Add CBFS metadata hash supportstabilize-15183.14.B
This patch adds support for signing and verification of coreboot images supporting VBOOT_CBFS_INTEGRATION. Images with config option CONFIG_VBOOT_CBFS_INTEGRATION=y will be signed with CBFS metadata hash in signature. vb2api_get_metadata_hash() should be used to extract hash value from VBLOCK and then should be used to verify CBFS metadata. To support full verification, CBFS file data verification should also be enabled and correctly handled. BUG=b:197114807 TEST=build with CB:66909 and boot on volteer/voxel with CONFIG_VBOOT_CBFS_INTEGRATION=y BRANCH=none Signed-off-by: Jakub Czapiga <czapiga@google.com> Change-Id: I4075c84820949be24c423ed14e291c89a0032863 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3811754 Commit-Queue: Julius Werner <jwerner@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
Diffstat (limited to 'firmware')
-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
*