diff options
Diffstat (limited to 'firmware/2lib')
-rw-r--r-- | firmware/2lib/2api.c | 45 | ||||
-rw-r--r-- | firmware/2lib/2common.c | 3 | ||||
-rw-r--r-- | firmware/2lib/include/2api.h | 46 |
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 * |