diff options
author | Randall Spangler <rspangler@chromium.org> | 2014-11-04 17:50:32 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-12 19:57:57 +0000 |
commit | 43e0a9ed6c0b332631442fcf581e7456d62e4532 (patch) | |
tree | c3bc2345e722a682a4667420e777d1079b8c4da8 /firmware/2lib | |
parent | 054c1147989d39a432923cc359d123f0d8e9390a (diff) | |
download | vboot-43e0a9ed6c0b332631442fcf581e7456d62e4532.tar.gz |
vboot2: Add code and tests for verifying vb2_fw_preamble2
This is the last low-level data structure verification code for the
new data structures. Subsequent changes are the next level up the
food chain.
BUG=chromium:423882
BRANCH=none
TEST=VBOOT2=1 make runtests
Change-Id: I2e45106c27447eb624c1ed562e40b98088249742
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/228360
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'firmware/2lib')
-rw-r--r-- | firmware/2lib/2common2.c | 70 | ||||
-rw-r--r-- | firmware/2lib/include/2common.h | 10 | ||||
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 6 | ||||
-rw-r--r-- | firmware/2lib/include/2struct.h | 8 |
4 files changed, 89 insertions, 5 deletions
diff --git a/firmware/2lib/2common2.c b/firmware/2lib/2common2.c index 1dcf53d1..099f7c1f 100644 --- a/firmware/2lib/2common2.c +++ b/firmware/2lib/2common2.c @@ -366,3 +366,73 @@ int vb2_verify_keyblock2(struct vb2_keyblock2 *block, /* If we're still here, no signature matched the key GUID */ return VB2_ERROR_KEYBLOCK_SIG_GUID; } + +int vb2_verify_fw_preamble2(struct vb2_fw_preamble2 *preamble, + uint32_t size, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb) +{ + struct vb2_signature2 *sig; + uint32_t min_offset = 0, hash_offset; + int rv, i; + + /* Check magic number */ + if (preamble->c.magic != VB2_MAGIC_FW_PREAMBLE2) + return VB2_ERROR_PREAMBLE_MAGIC; + + /* Make sure common header is good */ + rv = vb2_verify_common_header(preamble, size); + if (rv) + return rv; + + /* + * Check for compatible version. No need to check minor version, since + * that's compatible across readers matching the major version, and we + * haven't added any new fields. + */ + if (preamble->c.struct_version_major != VB2_FW_PREAMBLE2_VERSION_MAJOR) + return VB2_ERROR_PREAMBLE_HEADER_VERSION; + + /* Make sure header is big enough */ + if (preamble->c.fixed_size < sizeof(*preamble)) + return VB2_ERROR_PREAMBLE_SIZE; + + /* Make sure all hash signatures are inside */ + hash_offset = preamble->hash_offset; + for (i = 0; i < preamble->hash_count; i++, hash_offset = min_offset) { + /* Make sure signature is inside preamble */ + rv = vb2_verify_common_subobject(preamble, &min_offset, + hash_offset); + if (rv) + return rv; + + sig = (struct vb2_signature2 *) + ((uint8_t *)preamble + hash_offset); + + /* Verify the signature integrity */ + rv = vb2_verify_signature2( + sig, preamble->c.total_size - hash_offset); + if (rv) + return rv; + + /* Hashes must all be unsigned */ + if (sig->sig_alg != VB2_SIG_NONE) + return VB2_ERROR_PREAMBLE_HASH_SIGNED; + } + + /* Make sure signature is inside preamble */ + rv = vb2_verify_common_subobject(preamble, &min_offset, + preamble->sig_offset); + if (rv) + return rv; + + /* Verify preamble signature */ + sig = (struct vb2_signature2 *)((uint8_t *)preamble + + preamble->sig_offset); + + rv = vb2_verify_data2(preamble, preamble->sig_offset, sig, key, wb); + if (rv) + return rv; + + return VB2_SUCCESS; +} diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h index 0f7012cb..d26ccfce 100644 --- a/firmware/2lib/include/2common.h +++ b/firmware/2lib/include/2common.h @@ -410,7 +410,10 @@ int vb2_verify_keyblock2(struct vb2_keyblock2 *block, const struct vb2_public_key *key, const struct vb2_workbuf *wb); -/* Size of work buffer sufficient for vb2_verify_fw_preamble() worst case */ +/* + * Size of work buffer sufficient for vb2_verify_fw_preamble() or + * vb2_verify_fw_preamble2() worst case. + */ #define VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES /** @@ -429,4 +432,9 @@ int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble, const struct vb2_public_key *key, const struct vb2_workbuf *wb); +int vb2_verify_fw_preamble2(struct vb2_fw_preamble2 *preamble, + uint32_t size, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb); + #endif /* VBOOT_REFERENCE_VBOOT_2COMMON_H_ */ diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index 054655ee..4ff84468 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -302,6 +302,12 @@ enum vb2_return_code { /* Kernel subkey outside preamble */ VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE, + /* Bad magic number */ + VB2_ERROR_PREAMBLE_MAGIC, + + /* Hash is signed */ + VB2_ERROR_PREAMBLE_HASH_SIGNED, + /********************************************************************** * Misc higher-level code errors */ diff --git a/firmware/2lib/include/2struct.h b/firmware/2lib/include/2struct.h index e988f3f9..3f208325 100644 --- a/firmware/2lib/include/2struct.h +++ b/firmware/2lib/include/2struct.h @@ -491,9 +491,9 @@ struct vb2_keyblock2 { #define EXPECTED_VB2_KEYBLOCK2_SIZE (EXPECTED_VB2_STRUCT_COMMON_SIZE + 16) -/* Current version of vb2_preamble2 struct */ -#define VB2_PREAMBLE2_VERSION_MAJOR 3 -#define VB2_PREAMBLE2_VERSION_MINOR 0 +/* Current version of vb2_fw_preamble2 struct */ +#define VB2_FW_PREAMBLE2_VERSION_MAJOR 3 +#define VB2_FW_PREAMBLE2_VERSION_MINOR 0 /* * Firmware preamble @@ -501,7 +501,7 @@ struct vb2_keyblock2 { * The preamble data must be arranged like this: * 1) vb2_fw_preamble2 header struct h * 2) Preamble description (pointed to by h.c.fixed_size) - * 3) Hash table (pointed to by h.hash_table_offset) + * 3) Hashes (pointed to by h.hash_offset) * 4) Signature (pointed to by h.sig_offset) * * The signature 4) must cover all the data from 1), 2), 3). |