diff options
-rw-r--r-- | firmware/2lib/2secdata.c | 6 | ||||
-rw-r--r-- | firmware/2lib/include/2struct.h | 3 | ||||
-rw-r--r-- | firmware/lib20/misc.c | 19 | ||||
-rw-r--r-- | firmware/lib21/misc.c | 19 | ||||
-rw-r--r-- | tests/vb20_misc_tests.c | 3 | ||||
-rw-r--r-- | tests/vb21_misc_tests.c | 3 |
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); |