summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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