summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2015-02-10 17:08:22 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-02-12 00:41:33 +0000
commit187f069f8999d879193d380f374a890c114ad98d (patch)
treee03b5e59e7eb3f199f7daac83f6688bc88223024
parent05987b159acb9737707b9ef92b818ac434ef8c3d (diff)
downloadvboot-stabilize-6783.B.tar.gz
vboot2: Add more precise recovery reasons to firmware verificationstabilize-6783.B
vboot1 kept track of an internal "LoadFirmware() check" value for both firmware slots and encoded the value for the slot that managed to go further in the verification flow into a special range of recovery reasons. vboot2 instead uses the generic "invalid RW" reason for all firmware verification failures and communicates further information through the subcode. While the subcode may be good enough for developers, it's difficult to communicate failure reasons to "normal" users (like non-firmware developers) on the TAB screen. Currently we just display a couple of numbers that people won't know how to interpret and "RW firmware failed signature check" for any verification error (including rollback, which might be the most commonly encountered in practice). Since our recovery reason space is big enough (and we don't reuse old numbers anyway), we might as well reuse the more precise numbers (and strings) from vboot1 to communicate the failure reason, even if we don't implement its "which slot came further" algorithm. This patch translates the most common/useful VBSD_LF_CHECK numbers into plain VB2_RECOVERY reasons and uses them where appropriate. CQ-DEPEND=CL:248400 BRANCH=veyron BUG=None TEST=make runtests VBOOT2=1 test_that my_jerry firmware_CorruptBothFwSigAB firmware_CorruptBothFwBodyAB firmware_RollbackFirmware (Confirmed that matched recovery reasons are the more precise ones in the 0x10-0x1F range.) Change-Id: I51ecf1b820d1faa40405cb84377380d6f3f6ca1d Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/248392 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--firmware/2lib/include/2recovery_reasons.h23
-rw-r--r--firmware/lib20/api.c2
-rw-r--r--firmware/lib20/misc.c29
-rw-r--r--firmware/lib21/misc.c29
4 files changed, 55 insertions, 28 deletions
diff --git a/firmware/2lib/include/2recovery_reasons.h b/firmware/2lib/include/2recovery_reasons.h
index c305dd62..3633fe1b 100644
--- a/firmware/2lib/include/2recovery_reasons.h
+++ b/firmware/2lib/include/2recovery_reasons.h
@@ -48,15 +48,20 @@ enum vb2_nv_recovery {
/* Test error from LoadFirmware() (deprecated) */
VB2_RECOVERY_RO_TEST_LF = 0x09,
- /*
- * RW firmware failed signature check (neither RW firmware slot was
- * valid). Recovery reason is VB2_RECOVERY_RO_INVALID_RW_CHECK_MIN +
- * the check value for the slot which came closest to validating; see
- * VBSD_LF_CHECK_* in vboot_struct.h.
- */
- // TODO: pass back those codes from vboot2?
- VB2_RECOVERY_RO_INVALID_RW_CHECK_MIN = 0x10,
- VB2_RECOVERY_RO_INVALID_RW_CHECK_MAX = 0x1F,
+ /* Latest tried RW firmware keyblock verification failed */
+ VB2_RECOVERY_FW_KEYBLOCK = 0x13,
+
+ /* Latest tried RW firmware key version too old */
+ VB2_RECOVERY_FW_KEY_ROLLBACK = 0x14,
+
+ /* Latest tried RW firmware preamble verification failed */
+ VB2_RECOVERY_FW_PREAMBLE = 0x16,
+
+ /* Latest tried RW firmware version too old */
+ VB2_RECOVERY_FW_ROLLBACK = 0x17,
+
+ /* Latest tried RW firmware body verification failed */
+ VB2_RECOVERY_FW_BODY = 0x1b,
/*
* Firmware boot failure outside of verified boot (RAM init, missing
diff --git a/firmware/lib20/api.c b/firmware/lib20/api.c
index 3fa492ee..55c59ead 100644
--- a/firmware/lib20/api.c
+++ b/firmware/lib20/api.c
@@ -189,7 +189,7 @@ int vb2api_check_hash(struct vb2_context *ctx)
*/
rv = vb2_verify_digest(&key, &pre->body_signature, digest, &wb);
if (rv)
- vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
+ vb2_fail(ctx, VB2_RECOVERY_FW_BODY, rv);
return rv;
}
diff --git a/firmware/lib20/misc.c b/firmware/lib20/misc.c
index 815d5ebe..a446022d 100644
--- a/firmware/lib20/misc.c
+++ b/firmware/lib20/misc.c
@@ -74,14 +74,20 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
/* Verify the keyblock */
rv = vb2_verify_keyblock(kb, block_size, &root_key, &wb);
- if (rv)
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_KEYBLOCK, rv);
return rv;
+ }
/* Key version is the upper 16 bits of the composite firmware version */
if (kb->data_key.key_version > 0xffff)
- return VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
- if (kb->data_key.key_version < (sd->fw_version_secdata >> 16))
- return VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
+ rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
+ if (!rv && kb->data_key.key_version < (sd->fw_version_secdata >> 16))
+ rv = VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_KEY_ROLLBACK, rv);
+ return rv;
+ }
sd->fw_version = kb->data_key.key_version << 16;
@@ -174,20 +180,25 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
/* Verify the preamble */
rv = vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb);
- if (rv)
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_PREAMBLE, rv);
return rv;
+ }
/*
* Firmware version is the lower 16 bits of the composite firmware
* version.
*/
if (pre->firmware_version > 0xffff)
- return VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
-
+ rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
/* Combine with the key version from vb2_load_fw_keyblock() */
sd->fw_version |= pre->firmware_version;
- if (sd->fw_version < sd->fw_version_secdata)
- return VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
+ if (!rv && sd->fw_version < sd->fw_version_secdata)
+ rv = VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_ROLLBACK, rv);
+ return rv;
+ }
/*
* If this is a newer version than in secure storage, and we
diff --git a/firmware/lib21/misc.c b/firmware/lib21/misc.c
index f29b6e42..92322a9c 100644
--- a/firmware/lib21/misc.c
+++ b/firmware/lib21/misc.c
@@ -104,8 +104,10 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
/* Verify the keyblock */
rv = vb2_verify_keyblock(kb, kb->c.total_size, &root_key, &wb);
- if (rv)
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_KEYBLOCK, rv);
return rv;
+ }
/* Preamble follows the keyblock in the vblock */
sd->vblock_preamble_offset = kb->c.total_size;
@@ -114,9 +116,13 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
/* Key version is the upper 16 bits of the composite firmware version */
if (packed_key->key_version > 0xffff)
- return VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
- if (packed_key->key_version < (sd->fw_version_secdata >> 16))
- return VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
+ rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
+ if (!rv && packed_key->key_version < (sd->fw_version_secdata >> 16))
+ rv = VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_KEY_ROLLBACK, rv);
+ return rv;
+ }
sd->fw_version = packed_key->key_version << 16;
@@ -179,8 +185,10 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
/* Verify the preamble */
rv = vb2_verify_fw_preamble(pre, pre->c.total_size, &data_key, &wb);
- if (rv)
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_PREAMBLE, rv);
return rv;
+ }
/* Move the preamble down now that the data key is no longer used */
memmove(key_data, pre, pre->c.total_size);
@@ -194,12 +202,15 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
* version.
*/
if (pre->fw_version > 0xffff)
- return VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
-
+ rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
/* Combine with the key version from vb2_load_fw_keyblock() */
sd->fw_version |= pre->fw_version;
- if (sd->fw_version < sd->fw_version_secdata)
- return VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
+ if (!rv && sd->fw_version < sd->fw_version_secdata)
+ rv = VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_FW_ROLLBACK, rv);
+ return rv;
+ }
/*
* If this is a newer version than in secure storage, and we