summaryrefslogtreecommitdiff
path: root/firmware/2lib
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-11-04 17:50:32 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-12 19:57:57 +0000
commit43e0a9ed6c0b332631442fcf581e7456d62e4532 (patch)
treec3bc2345e722a682a4667420e777d1079b8c4da8 /firmware/2lib
parent054c1147989d39a432923cc359d123f0d8e9390a (diff)
downloadvboot-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.c70
-rw-r--r--firmware/2lib/include/2common.h10
-rw-r--r--firmware/2lib/include/2return_codes.h6
-rw-r--r--firmware/2lib/include/2struct.h8
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).