diff options
Diffstat (limited to 'firmware/2lib/2misc.c')
-rw-r--r-- | firmware/2lib/2misc.c | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c index 48357bea..5dc0014c 100644 --- a/firmware/2lib/2misc.c +++ b/firmware/2lib/2misc.c @@ -364,214 +364,3 @@ int vb2_select_fw_slot(struct vb2_context *ctx) return VB2_SUCCESS; } - -int vb2_load_fw_keyblock(struct vb2_context *ctx) -{ - struct vb2_shared_data *sd = vb2_get_sd(ctx); - struct vb2_workbuf wb; - - uint8_t *key_data; - uint32_t key_size; - struct vb2_packed_key *packed_key; - struct vb2_public_key root_key; - - struct vb2_keyblock *kb; - uint32_t block_size; - - uint32_t sec_version; - int rv; - - vb2_workbuf_from_ctx(ctx, &wb); - - /* Read the root key */ - key_size = sd->gbb_rootkey_size; - key_data = vb2_workbuf_alloc(&wb, key_size); - if (!key_data) - return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY; - - rv = vb2ex_read_resource(ctx, VB2_RES_GBB, sd->gbb_rootkey_offset, - key_data, key_size); - if (rv) - return rv; - - /* Unpack the root key */ - rv = vb2_unpack_key(&root_key, key_data, key_size); - if (rv) - return rv; - - /* Load the firmware keyblock header after the root key */ - kb = vb2_workbuf_alloc(&wb, sizeof(*kb)); - if (!kb) - return VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER; - - rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, sizeof(*kb)); - if (rv) - return rv; - - block_size = kb->keyblock_size; - - /* - * Load the entire keyblock, now that we know how big it is. Note that - * we're loading the entire keyblock instead of just the piece after - * the header. That means we re-read the header. But that's a tiny - * amount of data, and it makes the code much more straightforward. - */ - kb = vb2_workbuf_realloc(&wb, sizeof(*kb), block_size); - if (!kb) - return VB2_ERROR_FW_KEYBLOCK_WORKBUF; - - rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size); - if (rv) - return rv; - - /* Verify the keyblock */ - rv = vb2_verify_keyblock(kb, block_size, &root_key, &wb); - 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)) - return VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK; - - sd->fw_version = kb->data_key.key_version << 16; - - /* - * Save the data key in the work buffer. This overwrites the root key - * we read above. That's ok, because now that we have the data key we - * no longer need the root key. - */ - packed_key = (struct vb2_packed_key *)key_data; - - packed_key->algorithm = kb->data_key.algorithm; - packed_key->key_version = kb->data_key.key_version; - packed_key->key_size = kb->data_key.key_size; - - /* - * Use memmove() instead of memcpy(). In theory, the destination will - * never overlap because with the source because the root key is likely - * to be at least as large as the data key, but there's no harm here in - * being paranoid. - */ - memmove(key_data + packed_key->key_offset, - (uint8_t*)&kb->data_key + kb->data_key.key_offset, - packed_key->key_size); - - /* Save the packed key offset and size */ - sd->workbuf_data_key_offset = vb2_offset_of(ctx->workbuf, key_data); - sd->workbuf_data_key_size = - packed_key->key_offset + packed_key->key_size; - - /* Preamble follows the keyblock in the vblock */ - sd->vblock_preamble_offset = kb->keyblock_size; - - /* Data key will persist in the workbuf after we return */ - ctx->workbuf_used = sd->workbuf_data_key_offset + - sd->workbuf_data_key_size; - - return VB2_SUCCESS; -} - -int vb2_load_fw_preamble(struct vb2_context *ctx) -{ - struct vb2_shared_data *sd = vb2_get_sd(ctx); - struct vb2_workbuf wb; - - uint8_t *key_data = ctx->workbuf + sd->workbuf_data_key_offset; - uint32_t key_size = sd->workbuf_data_key_size; - struct vb2_public_key data_key; - - /* Preamble goes in the next unused chunk of work buffer */ - struct vb2_fw_preamble *pre; - uint32_t pre_size; - - uint32_t sec_version; - int rv; - - vb2_workbuf_from_ctx(ctx, &wb); - - /* Unpack the firmware data key */ - if (!sd->workbuf_data_key_size) - return VB2_ERROR_FW_PREAMBLE2_DATA_KEY; - - rv = vb2_unpack_key(&data_key, key_data, key_size); - if (rv) - return rv; - - /* Load the firmware preamble header */ - pre = vb2_workbuf_alloc(&wb, sizeof(*pre)); - if (!pre) - return VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER; - - rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, - sd->vblock_preamble_offset, - pre, sizeof(*pre)); - if (rv) - return rv; - - pre_size = pre->preamble_size; - - /* Load the entire firmware preamble, now that we know how big it is */ - pre = vb2_workbuf_realloc(&wb, sizeof(*pre), pre_size); - if (!pre) - return VB2_ERROR_FW_PREAMBLE2_WORKBUF; - - rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, - sd->vblock_preamble_offset, - pre, pre_size); - if (rv) - return rv; - - /* Work buffer now contains the data subkey data and the preamble */ - - /* Verify the preamble */ - rv = vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb); - 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. - */ - if (pre->firmware_version > 0xffff) - return VB2_ERROR_FW_PREAMBLE2_VERSION_RANGE; - - /* Combine with the key version from vb2_load_fw_keyblock() */ - sd->fw_version |= pre->firmware_version; - if (sd->fw_version < sec_version) - return VB2_ERROR_FW_PREAMBLE2_VERSION_ROLLBACK; - - /* - * If this is a newer version than in secure storage, and we - * successfully booted the same slot last boot, roll forward the - * version in secure storage. - */ - if (sd->fw_version > sec_version && - sd->last_fw_slot == sd->fw_slot && - sd->last_fw_result == VB2_FW_RESULT_SUCCESS) { - - rv = vb2_secdata_set(ctx, VB2_SECDATA_VERSIONS, sd->fw_version); - if (rv) - return rv; - } - - /* Keep track of where we put the preamble */ - sd->workbuf_preamble_offset = vb2_offset_of(ctx->workbuf, pre); - sd->workbuf_preamble_size = pre_size; - - /* Preamble will persist in work buffer after we return */ - ctx->workbuf_used = sd->workbuf_preamble_offset + pre_size; - - return VB2_SUCCESS; -} |