summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/2lib/2secdata.c6
-rw-r--r--firmware/2lib/include/2struct.h3
-rw-r--r--firmware/lib20/misc.c19
-rw-r--r--firmware/lib21/misc.c19
-rw-r--r--tests/vb20_misc_tests.c3
-rw-r--r--tests/vb21_misc_tests.c3
6 files changed, 21 insertions, 32 deletions
diff --git a/firmware/2lib/2secdata.c b/firmware/2lib/2secdata.c
index 2987e037..0c5a34e4 100644
--- a/firmware/2lib/2secdata.c
+++ b/firmware/2lib/2secdata.c
@@ -53,6 +53,12 @@ int vb2_secdata_init(struct vb2_context *ctx)
if (rv)
return rv;
+ /* Read this now to make sure crossystem has it even in rec mode. */
+ rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS,
+ &sd->fw_version_secdata);
+ if (rv)
+ return rv;
+
/* Set status flag */
sd->status |= VB2_SD_STATUS_SECDATA_INIT;
// TODO: unit test for that
diff --git a/firmware/2lib/include/2struct.h b/firmware/2lib/include/2struct.h
index 95cf73c7..3339a30d 100644
--- a/firmware/2lib/include/2struct.h
+++ b/firmware/2lib/include/2struct.h
@@ -88,6 +88,9 @@ struct vb2_shared_data {
*/
uint32_t fw_version;
+ /* Version stored in secdata (must be <= fw_version to boot). */
+ uint32_t fw_version_secdata;
+
/*
* Status flags for this boot; see enum vb2_shared_data_status. Status
* is "what we've done"; flags above are "decisions we've made".
diff --git a/firmware/lib20/misc.c b/firmware/lib20/misc.c
index 89e46ec6..815d5ebe 100644
--- a/firmware/lib20/misc.c
+++ b/firmware/lib20/misc.c
@@ -27,7 +27,6 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
struct vb2_keyblock *kb;
uint32_t block_size;
- uint32_t sec_version;
int rv;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -78,15 +77,10 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
if (rv)
return rv;
- /* Read the secure key version */
- rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
- if (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 < (sec_version >> 16))
+ if (kb->data_key.key_version < (sd->fw_version_secdata >> 16))
return VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
sd->fw_version = kb->data_key.key_version << 16;
@@ -140,7 +134,6 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
struct vb2_fw_preamble *pre;
uint32_t pre_size;
- uint32_t sec_version;
int rv;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -184,11 +177,6 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
if (rv)
return rv;
- /* Read the secure key version */
- rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
- if (rv)
- return rv;
-
/*
* Firmware version is the lower 16 bits of the composite firmware
* version.
@@ -198,7 +186,7 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
/* Combine with the key version from vb2_load_fw_keyblock() */
sd->fw_version |= pre->firmware_version;
- if (sd->fw_version < sec_version)
+ if (sd->fw_version < sd->fw_version_secdata)
return VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
/*
@@ -206,10 +194,11 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
* successfully booted the same slot last boot, roll forward the
* version in secure storage.
*/
- if (sd->fw_version > sec_version &&
+ if (sd->fw_version > sd->fw_version_secdata &&
sd->last_fw_slot == sd->fw_slot &&
sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
+ sd->fw_version_secdata = sd->fw_version;
rv = vb2_secdata_set(ctx, VB2_SECDATA_VERSIONS, sd->fw_version);
if (rv)
return rv;
diff --git a/firmware/lib21/misc.c b/firmware/lib21/misc.c
index 384d44ed..f29b6e42 100644
--- a/firmware/lib21/misc.c
+++ b/firmware/lib21/misc.c
@@ -73,7 +73,6 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
struct vb2_public_key root_key;
struct vb2_keyblock *kb;
- uint32_t sec_version;
int rv;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -111,17 +110,12 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
/* Preamble follows the keyblock in the vblock */
sd->vblock_preamble_offset = kb->c.total_size;
- /* Read the secure key version */
- rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
- if (rv)
- return rv;
-
packed_key = (struct vb2_packed_key *)((uint8_t *)kb + kb->key_offset);
/* 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 < (sec_version >> 16))
+ if (packed_key->key_version < (sd->fw_version_secdata >> 16))
return VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
sd->fw_version = packed_key->key_version << 16;
@@ -162,7 +156,6 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
/* Preamble goes in the next unused chunk of work buffer */
struct vb2_fw_preamble *pre;
- uint32_t sec_version;
int rv;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -196,11 +189,6 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
/* Data key is now gone */
sd->workbuf_data_key_offset = sd->workbuf_data_key_size = 0;
- /* Read the secure key version */
- rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
- if (rv)
- return rv;
-
/*
* Firmware version is the lower 16 bits of the composite firmware
* version.
@@ -210,7 +198,7 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
/* Combine with the key version from vb2_load_fw_keyblock() */
sd->fw_version |= pre->fw_version;
- if (sd->fw_version < sec_version)
+ if (sd->fw_version < sd->fw_version_secdata)
return VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
/*
@@ -218,10 +206,11 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
* successfully booted the same slot last boot, roll forward the
* version in secure storage.
*/
- if (sd->fw_version > sec_version &&
+ if (sd->fw_version > sd->fw_version_secdata &&
sd->last_fw_slot == sd->fw_slot &&
sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
+ sd->fw_version_secdata = sd->fw_version;
rv = vb2_secdata_set(ctx, VB2_SECDATA_VERSIONS, sd->fw_version);
if (rv)
return rv;
diff --git a/tests/vb20_misc_tests.c b/tests/vb20_misc_tests.c
index 45985dd9..65ceea97 100644
--- a/tests/vb20_misc_tests.c
+++ b/tests/vb20_misc_tests.c
@@ -81,7 +81,8 @@ static void reset_common_data(enum reset_type t)
mock_verify_preamble_retval = VB2_SUCCESS;
/* Set up mock data for verifying keyblock */
- vb2_secdata_set(&cc, VB2_SECDATA_VERSIONS, 0x20002);
+ sd->fw_version_secdata = 0x20002;
+ vb2_secdata_set(&cc, VB2_SECDATA_VERSIONS, sd->fw_version_secdata);
sd->gbb_rootkey_offset = vb2_offset_of(&mock_gbb, &mock_gbb.rootkey);
sd->gbb_rootkey_size = sizeof(mock_gbb.rootkey_data);
diff --git a/tests/vb21_misc_tests.c b/tests/vb21_misc_tests.c
index af2c0792..826c3fb1 100644
--- a/tests/vb21_misc_tests.c
+++ b/tests/vb21_misc_tests.c
@@ -84,7 +84,8 @@ static void reset_common_data(enum reset_type t)
mock_verify_preamble_retval = VB2_SUCCESS;
/* Set up mock data for verifying keyblock */
- vb2_secdata_set(&ctx, VB2_SECDATA_VERSIONS, 0x20002);
+ sd->fw_version_secdata = 0x20002;
+ vb2_secdata_set(&ctx, VB2_SECDATA_VERSIONS, sd->fw_version_secdata);
sd->gbb_rootkey_offset = vb2_offset_of(&mock_gbb, &mock_gbb.rootkey);
sd->gbb_rootkey_size = sizeof(mock_gbb.rootkey_data);