diff options
author | Joel Kitching <kitching@google.com> | 2021-04-14 15:13:28 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-06-15 19:35:52 +0000 |
commit | c6cf8890532a7b78b6cb3dc534145f500444dae2 (patch) | |
tree | 4e03d65225afd988a7cdb56bb6ee36e025bd01d2 | |
parent | ba23df230a9efe7f6aed8faab4dda944f62f76da (diff) | |
download | vboot-c6cf8890532a7b78b6cb3dc534145f500444dae2.tar.gz |
vboot/vboot_kernel: move kernel/fw struct functions
Relocate currently-in-use kernel struct functions out
of lib20 namespace, and into:
* 2struct.c for functions required at runtime
* host_common.c for functions required by host
Relocate firmware struct functions from 2common.c
into 2struct.c
vb2_common.h may be deleted as a result.
This CL is part of a series to merge vboot1 and vboot2.0
kernel verification code; see b/181739551.
BUG=b:181739551
TEST=make clean && make runtests
BRANCH=none
Signed-off-by: Joel Kitching <kitching@google.com>
Change-Id: Ic162d9633b6112ddc4a819b3e58d313dc484f304
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2825269
Tested-by: Joel Kitching <kitching@chromium.org>
Commit-Queue: Joel Kitching <kitching@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | firmware/2lib/2common.c | 150 | ||||
-rw-r--r-- | firmware/2lib/2struct.c | 317 | ||||
-rw-r--r-- | firmware/2lib/include/2common.h | 40 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c | 5 | ||||
-rw-r--r-- | firmware/lib20/api_kernel.c | 3 | ||||
-rw-r--r-- | firmware/lib20/include/vb2_common.h | 74 | ||||
-rw-r--r-- | firmware/lib20/kernel.c | 180 | ||||
-rw-r--r-- | futility/cmd_show.c | 1 | ||||
-rw-r--r-- | futility/cmd_sign.c | 1 | ||||
-rw-r--r-- | futility/cmd_vbutil_kernel.c | 1 | ||||
-rw-r--r-- | futility/file_type_bios.c | 1 | ||||
-rw-r--r-- | futility/updater.c | 1 | ||||
-rw-r--r-- | futility/updater_archive.c | 1 | ||||
-rw-r--r-- | futility/vb1_helper.c | 1 | ||||
-rw-r--r-- | host/lib/host_common.c | 19 | ||||
-rw-r--r-- | host/lib/host_keyblock.c | 1 | ||||
-rw-r--r-- | host/lib/include/host_common.h | 14 | ||||
-rw-r--r-- | tests/vb20_kernel_tests.c | 1 | ||||
-rw-r--r-- | tests/vb2_common3_tests.c | 2 | ||||
-rw-r--r-- | tests/vboot_kernel_tests.c | 1 |
21 files changed, 394 insertions, 422 deletions
@@ -410,6 +410,7 @@ FWLIB_SRCS = \ firmware/2lib/2sha256.c \ firmware/2lib/2sha512.c \ firmware/2lib/2sha_utility.c \ + firmware/2lib/2struct.c \ firmware/2lib/2stub_hwcrypto.c \ firmware/2lib/2tpm_bootmode.c \ firmware/lib/cgptlib/cgptlib.c \ @@ -522,6 +523,7 @@ HOSTLIB_SRCS = \ firmware/2lib/2sha256.c \ firmware/2lib/2sha512.c \ firmware/2lib/2sha_utility.c \ + firmware/2lib/2struct.c \ firmware/2lib/2stub.c \ firmware/2lib/2stub_hwcrypto.c \ firmware/lib/cgptlib/cgptlib_internal.c \ diff --git a/firmware/2lib/2common.c b/firmware/2lib/2common.c index 8267f8ce..fa0585e3 100644 --- a/firmware/2lib/2common.c +++ b/firmware/2lib/2common.c @@ -8,8 +8,6 @@ #include "2common.h" #include "2rsa.h" -#include "2sha.h" -#include "2sysincludes.h" vb2_error_t vb2_safe_memcmp(const void *s1, const void *s2, size_t size) { @@ -231,151 +229,3 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size, return vb2_verify_digest(key, sig, digest, &wblocal); } - -vb2_error_t vb2_check_keyblock(const struct vb2_keyblock *block, uint32_t size, - const struct vb2_signature *sig) -{ - if(size < sizeof(*block)) { - VB2_DEBUG("Not enough space for keyblock header.\n"); - return VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER; - } - - if (memcmp(block->magic, VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE)) { - VB2_DEBUG("Not a valid verified boot keyblock.\n"); - return VB2_ERROR_KEYBLOCK_MAGIC; - } - - if (block->header_version_major != VB2_KEYBLOCK_VERSION_MAJOR) { - VB2_DEBUG("Incompatible keyblock header version.\n"); - return VB2_ERROR_KEYBLOCK_HEADER_VERSION; - } - - if (size < block->keyblock_size) { - VB2_DEBUG("Not enough data for keyblock.\n"); - return VB2_ERROR_KEYBLOCK_SIZE; - } - - if (vb2_verify_signature_inside(block, block->keyblock_size, sig)) { - VB2_DEBUG("Keyblock signature off end of block\n"); - return VB2_ERROR_KEYBLOCK_SIG_OUTSIDE; - } - - /* Make sure advertised signature data sizes are valid. */ - if (block->keyblock_size < sig->data_size) { - VB2_DEBUG("Signature calculated past end of block\n"); - return VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH; - } - - /* Verify we signed enough data */ - if (sig->data_size < sizeof(struct vb2_keyblock)) { - VB2_DEBUG("Didn't sign enough data\n"); - return VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE; - } - - /* Verify data key is inside the block and inside signed data */ - if (vb2_verify_packed_key_inside(block, block->keyblock_size, - &block->data_key)) { - VB2_DEBUG("Data key off end of keyblock\n"); - return VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE; - } - if (vb2_verify_packed_key_inside(block, sig->data_size, - &block->data_key)) { - VB2_DEBUG("Data key off end of signed data\n"); - return VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED; - } - - return VB2_SUCCESS; -} - -vb2_error_t vb2_verify_keyblock(struct vb2_keyblock *block, uint32_t size, - const struct vb2_public_key *key, - const struct vb2_workbuf *wb) -{ - struct vb2_signature *sig = &block->keyblock_signature; - vb2_error_t rv; - - /* Validity check keyblock before attempting signature check of data */ - VB2_TRY(vb2_check_keyblock(block, size, sig)); - - VB2_DEBUG("Checking keyblock signature...\n"); - rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb); - if (rv) { - VB2_DEBUG("Invalid keyblock signature.\n"); - return VB2_ERROR_KEYBLOCK_SIG_INVALID; - } - - /* Success */ - return VB2_SUCCESS; -} - -vb2_error_t vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble, - uint32_t size, - const struct vb2_public_key *key, - const struct vb2_workbuf *wb) -{ - struct vb2_signature *sig = &preamble->preamble_signature; - - VB2_DEBUG("Verifying preamble.\n"); - - /* Validity checks before attempting signature of data */ - if(size < sizeof(*preamble)) { - VB2_DEBUG("Not enough data for preamble header\n"); - return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER; - } - if (preamble->header_version_major != - VB2_FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) { - VB2_DEBUG("Incompatible firmware preamble header version.\n"); - return VB2_ERROR_PREAMBLE_HEADER_VERSION; - } - - if (preamble->header_version_minor < 1) { - VB2_DEBUG("Only preamble header 2.1+ supported\n"); - return VB2_ERROR_PREAMBLE_HEADER_OLD; - } - - if (size < preamble->preamble_size) { - VB2_DEBUG("Not enough data for preamble.\n"); - return VB2_ERROR_PREAMBLE_SIZE; - } - - /* Check signature */ - if (vb2_verify_signature_inside(preamble, preamble->preamble_size, - sig)) { - VB2_DEBUG("Preamble signature off end of preamble\n"); - return VB2_ERROR_PREAMBLE_SIG_OUTSIDE; - } - - /* Make sure advertised signature data sizes are valid. */ - if (preamble->preamble_size < sig->data_size) { - VB2_DEBUG("Signature calculated past end of the block\n"); - return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH; - } - - if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) { - VB2_DEBUG("Preamble signature validation failed\n"); - return VB2_ERROR_PREAMBLE_SIG_INVALID; - } - - /* Verify we signed enough data */ - if (sig->data_size < sizeof(struct vb2_fw_preamble)) { - VB2_DEBUG("Didn't sign enough data\n"); - return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE; - } - - /* Verify body signature is inside the signed data */ - if (vb2_verify_signature_inside(preamble, sig->data_size, - &preamble->body_signature)) { - VB2_DEBUG("Firmware body signature off end of preamble\n"); - return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE; - } - - /* Verify kernel subkey is inside the signed data */ - if (vb2_verify_packed_key_inside(preamble, sig->data_size, - &preamble->kernel_subkey)) { - VB2_DEBUG("Kernel subkey off end of preamble\n"); - return VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE; - } - - /* Success */ - return VB2_SUCCESS; -} diff --git a/firmware/2lib/2struct.c b/firmware/2lib/2struct.c new file mode 100644 index 00000000..a16f8690 --- /dev/null +++ b/firmware/2lib/2struct.c @@ -0,0 +1,317 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Functions for reading, checking and verifying firmware and + * kernel data structures. + */ + +#include "2common.h" + +vb2_error_t vb2_check_keyblock(const struct vb2_keyblock *block, uint32_t size, + const struct vb2_signature *sig) +{ + if(size < sizeof(*block)) { + VB2_DEBUG("Not enough space for keyblock header.\n"); + return VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER; + } + + if (memcmp(block->magic, VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE)) { + VB2_DEBUG("Not a valid verified boot keyblock.\n"); + return VB2_ERROR_KEYBLOCK_MAGIC; + } + + if (block->header_version_major != VB2_KEYBLOCK_VERSION_MAJOR) { + VB2_DEBUG("Incompatible keyblock header version.\n"); + return VB2_ERROR_KEYBLOCK_HEADER_VERSION; + } + + if (size < block->keyblock_size) { + VB2_DEBUG("Not enough data for keyblock.\n"); + return VB2_ERROR_KEYBLOCK_SIZE; + } + + if (vb2_verify_signature_inside(block, block->keyblock_size, sig)) { + VB2_DEBUG("Keyblock signature off end of block\n"); + return VB2_ERROR_KEYBLOCK_SIG_OUTSIDE; + } + + /* Make sure advertised signature data sizes are valid. */ + if (block->keyblock_size < sig->data_size) { + VB2_DEBUG("Signature calculated past end of block\n"); + return VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH; + } + + /* Verify we signed enough data */ + if (sig->data_size < sizeof(struct vb2_keyblock)) { + VB2_DEBUG("Didn't sign enough data\n"); + return VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE; + } + + /* Verify data key is inside the block and inside signed data */ + if (vb2_verify_packed_key_inside(block, block->keyblock_size, + &block->data_key)) { + VB2_DEBUG("Data key off end of keyblock\n"); + return VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE; + } + if (vb2_verify_packed_key_inside(block, sig->data_size, + &block->data_key)) { + VB2_DEBUG("Data key off end of signed data\n"); + return VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED; + } + + return VB2_SUCCESS; +} + +vb2_error_t vb2_verify_keyblock(struct vb2_keyblock *block, uint32_t size, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb) +{ + struct vb2_signature *sig = &block->keyblock_signature; + vb2_error_t rv; + + /* Validity check keyblock before attempting signature check of data */ + VB2_TRY(vb2_check_keyblock(block, size, sig)); + + VB2_DEBUG("Checking keyblock signature...\n"); + rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb); + if (rv) { + VB2_DEBUG("Invalid keyblock signature.\n"); + return VB2_ERROR_KEYBLOCK_SIG_INVALID; + } + + /* Success */ + return VB2_SUCCESS; +} + +vb2_error_t vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble, + uint32_t size, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb) +{ + struct vb2_signature *sig = &preamble->preamble_signature; + + VB2_DEBUG("Verifying preamble.\n"); + + /* Validity checks before attempting signature of data */ + if(size < sizeof(*preamble)) { + VB2_DEBUG("Not enough data for preamble header\n"); + return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER; + } + if (preamble->header_version_major != + VB2_FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) { + VB2_DEBUG("Incompatible firmware preamble header version.\n"); + return VB2_ERROR_PREAMBLE_HEADER_VERSION; + } + + if (preamble->header_version_minor < 1) { + VB2_DEBUG("Only preamble header 2.1+ supported\n"); + return VB2_ERROR_PREAMBLE_HEADER_OLD; + } + + if (size < preamble->preamble_size) { + VB2_DEBUG("Not enough data for preamble.\n"); + return VB2_ERROR_PREAMBLE_SIZE; + } + + /* Check signature */ + if (vb2_verify_signature_inside(preamble, preamble->preamble_size, + sig)) { + VB2_DEBUG("Preamble signature off end of preamble\n"); + return VB2_ERROR_PREAMBLE_SIG_OUTSIDE; + } + + /* Make sure advertised signature data sizes are valid. */ + if (preamble->preamble_size < sig->data_size) { + VB2_DEBUG("Signature calculated past end of the block\n"); + return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH; + } + + if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) { + VB2_DEBUG("Preamble signature validation failed\n"); + return VB2_ERROR_PREAMBLE_SIG_INVALID; + } + + /* Verify we signed enough data */ + if (sig->data_size < sizeof(struct vb2_fw_preamble)) { + VB2_DEBUG("Didn't sign enough data\n"); + return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE; + } + + /* Verify body signature is inside the signed data */ + if (vb2_verify_signature_inside(preamble, sig->data_size, + &preamble->body_signature)) { + VB2_DEBUG("Firmware body signature off end of preamble\n"); + return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE; + } + + /* Verify kernel subkey is inside the signed data */ + if (vb2_verify_packed_key_inside(preamble, sig->data_size, + &preamble->kernel_subkey)) { + VB2_DEBUG("Kernel subkey off end of preamble\n"); + return VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE; + } + + /* Success */ + return VB2_SUCCESS; +} + +uint32_t vb2_kernel_get_flags(const struct vb2_kernel_preamble *preamble) +{ + if (preamble->header_version_minor < 2) + return 0; + + return preamble->flags; +} + +test_mockable +vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block, + uint32_t size, + const struct vb2_workbuf *wb) +{ + const struct vb2_signature *sig = &block->keyblock_hash; + struct vb2_workbuf wblocal = *wb; + struct vb2_digest_context *dc; + uint8_t *digest; + uint32_t digest_size; + + /* Validity check keyblock before attempting hash check of data */ + VB2_TRY(vb2_check_keyblock(block, size, sig)); + + VB2_DEBUG("Checking keyblock hash...\n"); + + /* Digest goes at start of work buffer */ + digest_size = vb2_digest_size(VB2_HASH_SHA512); + digest = vb2_workbuf_alloc(&wblocal, digest_size); + if (!digest) + return VB2_ERROR_VDATA_WORKBUF_DIGEST; + + /* Hashing requires temp space for the context */ + dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc)); + if (!dc) + return VB2_ERROR_VDATA_WORKBUF_HASHING; + + VB2_TRY(vb2_digest_init(dc, VB2_HASH_SHA512)); + + VB2_TRY(vb2_digest_extend(dc, (const uint8_t *)block, sig->data_size)); + + VB2_TRY(vb2_digest_finalize(dc, digest, digest_size)); + + if (vb2_safe_memcmp(vb2_signature_data(sig), digest, + digest_size) != 0) { + VB2_DEBUG("Invalid keyblock hash.\n"); + return VB2_ERROR_KEYBLOCK_HASH_INVALID_IN_DEV_MODE; + } + + /* Success */ + return VB2_SUCCESS; +} + +test_mockable +vb2_error_t vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble, + uint32_t size, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb) +{ + struct vb2_signature *sig = &preamble->preamble_signature; + uint32_t min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_0_SIZE; + + VB2_DEBUG("Verifying kernel preamble.\n"); + + /* Make sure it's even safe to look at the struct */ + if(size < min_size) { + VB2_DEBUG("Not enough data for preamble header.\n"); + return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER; + } + if (preamble->header_version_major != + VB2_KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) { + VB2_DEBUG("Incompatible kernel preamble header version.\n"); + return VB2_ERROR_PREAMBLE_HEADER_VERSION; + } + + if (preamble->header_version_minor >= 2) + min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_2_SIZE; + else if (preamble->header_version_minor == 1) + min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_1_SIZE; + if(preamble->preamble_size < min_size) { + VB2_DEBUG("Preamble size too small for header.\n"); + return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER; + } + if (size < preamble->preamble_size) { + VB2_DEBUG("Not enough data for preamble.\n"); + return VB2_ERROR_PREAMBLE_SIZE; + } + + /* Check signature */ + if (vb2_verify_signature_inside(preamble, preamble->preamble_size, + sig)) { + VB2_DEBUG("Preamble signature off end of preamble\n"); + return VB2_ERROR_PREAMBLE_SIG_OUTSIDE; + } + + /* Make sure advertised signature data sizes are valid. */ + if (preamble->preamble_size < sig->data_size) { + VB2_DEBUG("Signature calculated past end of the block\n"); + return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH; + } + + if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) { + VB2_DEBUG("Preamble signature validation failed\n"); + return VB2_ERROR_PREAMBLE_SIG_INVALID; + } + + /* Verify we signed enough data */ + if (sig->data_size < sizeof(struct vb2_fw_preamble)) { + VB2_DEBUG("Didn't sign enough data\n"); + return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE; + } + + /* Verify body signature is inside the signed data */ + if (vb2_verify_signature_inside(preamble, sig->data_size, + &preamble->body_signature)) { + VB2_DEBUG("Body signature off end of preamble\n"); + return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE; + } + + /* + * If bootloader is present, verify it's covered by the body + * signature. + */ + if (preamble->bootloader_size) { + const void *body_ptr = + (const void *)(uintptr_t)preamble->body_load_address; + const void *bootloader_ptr = + (const void *)(uintptr_t)preamble->bootloader_address; + if (vb2_verify_member_inside(body_ptr, + preamble->body_signature.data_size, + bootloader_ptr, + preamble->bootloader_size, + 0, 0)) { + VB2_DEBUG("Bootloader off end of signed data\n"); + return VB2_ERROR_PREAMBLE_BOOTLOADER_OUTSIDE; + } + } + + /* + * If vmlinuz header is present, verify it's covered by the body + * signature. + */ + if (preamble->header_version_minor >= 1 && + preamble->vmlinuz_header_size) { + const void *body_ptr = + (const void *)(uintptr_t)preamble->body_load_address; + const void *vmlinuz_header_ptr = (const void *) + (uintptr_t)preamble->vmlinuz_header_address; + if (vb2_verify_member_inside(body_ptr, + preamble->body_signature.data_size, + vmlinuz_header_ptr, + preamble->vmlinuz_header_size, + 0, 0)) { + VB2_DEBUG("Vmlinuz header off end of signed data\n"); + return VB2_ERROR_PREAMBLE_VMLINUZ_HEADER_OUTSIDE; + } + } + + /* Success */ + return VB2_SUCCESS; +} diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h index 13ea40f5..918c50dd 100644 --- a/firmware/2lib/include/2common.h +++ b/firmware/2lib/include/2common.h @@ -428,4 +428,44 @@ vb2_error_t vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble, const struct vb2_public_key *key, const struct vb2_workbuf *wb); +/** + * Get the flags for the kernel preamble. + * + * @param preamble Preamble to check + * @return Flags for the preamble. Old preamble versions (<2.2) return 0. + */ +uint32_t vb2_kernel_get_flags(const struct vb2_kernel_preamble *preamble); + +/** + * Verify a keyblock using its hash. + * + * Header fields are also checked for validity. Does not verify key index or key + * block flags. Use this for self-signed keyblocks in developer mode. + * + * @param block Keyblock to verify + * @param size Size of keyblock buffer + * @param key Key to use to verify block + * @param wb Work buffer + * @return VB2_SUCCESS, or non-zero error code if error. + */ +vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block, + uint32_t size, + const struct vb2_workbuf *wb); + +/** + * Check the validity of a kernel preamble using a public key. + * + * The signature in the preamble is destroyed during the check. + * + * @param preamble Preamble to verify + * @param size Size of preamble buffer + * @param key Key to use to verify preamble + * @param wb Work buffer + * @return VB2_SUCCESS, or non-zero error code if error. + */ +vb2_error_t vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble, + uint32_t size, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb); + #endif /* VBOOT_REFERENCE_2COMMON_H_ */ diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index c0874881..e2a71caa 100644 --- a/firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c @@ -10,18 +10,13 @@ #include "2misc.h" #include "2nvstorage.h" #include "2packed_key.h" -#include "2rsa.h" -#include "2sha.h" #include "2secdata.h" #include "2sysincludes.h" #include "cgptlib.h" #include "cgptlib_internal.h" #include "gpt_misc.h" #include "load_kernel_fw.h" -#include "vb2_common.h" #include "vboot_api.h" -#include "vboot_kernel.h" -#include "vboot_struct.h" #define LOWEST_TPM_VERSION 0xffffffff diff --git a/firmware/lib20/api_kernel.c b/firmware/lib20/api_kernel.c index 9ab85222..403e932e 100644 --- a/firmware/lib20/api_kernel.c +++ b/firmware/lib20/api_kernel.c @@ -7,14 +7,13 @@ */ #include "2api.h" +#include "2common.h" #include "2misc.h" #include "2nvstorage.h" #include "2rsa.h" #include "2secdata.h" #include "2sha.h" #include "2sysincludes.h" -#include "vb2_common.h" -#include "vboot_struct.h" vb2_error_t vb2api_load_kernel_vblock(struct vb2_context *ctx) { diff --git a/firmware/lib20/include/vb2_common.h b/firmware/lib20/include/vb2_common.h deleted file mode 100644 index 3db04377..00000000 --- a/firmware/lib20/include/vb2_common.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Common functions between firmware and kernel verified boot. - */ - -#ifndef VBOOT_REFERENCE_VB2_COMMON_H_ -#define VBOOT_REFERENCE_VB2_COMMON_H_ - -#include "2api.h" -#include "2common.h" -#include "2return_codes.h" -#include "2sha.h" -#include "2struct.h" -#include "2sysincludes.h" - -struct vb2_public_key; - -/** - * Verify a keyblock using its hash. - * - * Header fields are also checked for validity. Does not verify key index or key - * block flags. Use this for self-signed keyblocks in developer mode. - * - * @param block Keyblock to verify - * @param size Size of keyblock buffer - * @param key Key to use to verify block - * @param wb Work buffer - * @return VB2_SUCCESS, or non-zero error code if error. - */ -vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block, - uint32_t size, - const struct vb2_workbuf *wb); - -/** - * Check the validity of a kernel preamble using a public key. - * - * The signature in the preamble is destroyed during the check. - * - * @param preamble Preamble to verify - * @param size Size of preamble buffer - * @param key Key to use to verify preamble - * @param wb Work buffer - * @return VB2_SUCCESS, or non-zero error code if error. - */ -vb2_error_t vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble, - uint32_t size, - const struct vb2_public_key *key, - const struct vb2_workbuf *wb); - -/** - * Retrieve the 16-bit vmlinuz header address and size from the preamble. - * - * Size 0 means there is no 16-bit vmlinuz header present. Old preamble - * versions (<2.1) return 0 for both fields. - * - * @param preamble Preamble to check - * @param vmlinuz_header_address Destination for header address - * @param vmlinuz_header_size Destination for header size - */ -void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble, - uint64_t *vmlinuz_header_address, - uint32_t *vmlinuz_header_size); - -/** - * Get the flags for the kernel preamble. - * - * @param preamble Preamble to check - * @return Flags for the preamble. Old preamble versions (<2.2) return 0. - */ -uint32_t vb2_kernel_get_flags(const struct vb2_kernel_preamble *preamble); - -#endif /* VBOOT_REFERENCE_VB2_COMMON_H_ */ diff --git a/firmware/lib20/kernel.c b/firmware/lib20/kernel.c index b3a24367..81ded659 100644 --- a/firmware/lib20/kernel.c +++ b/firmware/lib20/kernel.c @@ -12,7 +12,6 @@ #include "2secdata.h" #include "2sha.h" #include "2sysincludes.h" -#include "vb2_common.h" /** * Returns non-zero if the kernel needs to have a valid signature, instead of @@ -35,49 +34,6 @@ static int vb2_need_signed_kernel(struct vb2_context *ctx) return 0; } -test_mockable -vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block, - uint32_t size, - const struct vb2_workbuf *wb) -{ - const struct vb2_signature *sig = &block->keyblock_hash; - struct vb2_workbuf wblocal = *wb; - struct vb2_digest_context *dc; - uint8_t *digest; - uint32_t digest_size; - - /* Validity check keyblock before attempting hash check of data */ - VB2_TRY(vb2_check_keyblock(block, size, sig)); - - VB2_DEBUG("Checking keyblock hash...\n"); - - /* Digest goes at start of work buffer */ - digest_size = vb2_digest_size(VB2_HASH_SHA512); - digest = vb2_workbuf_alloc(&wblocal, digest_size); - if (!digest) - return VB2_ERROR_VDATA_WORKBUF_DIGEST; - - /* Hashing requires temp space for the context */ - dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc)); - if (!dc) - return VB2_ERROR_VDATA_WORKBUF_HASHING; - - VB2_TRY(vb2_digest_init(dc, VB2_HASH_SHA512)); - - VB2_TRY(vb2_digest_extend(dc, (const uint8_t *)block, sig->data_size)); - - VB2_TRY(vb2_digest_finalize(dc, digest, digest_size)); - - if (vb2_safe_memcmp(vb2_signature_data(sig), digest, - digest_size) != 0) { - VB2_DEBUG("Invalid keyblock hash.\n"); - return VB2_ERROR_KEYBLOCK_HASH_INVALID_IN_DEV_MODE; - } - - /* Success */ - return VB2_SUCCESS; -} - vb2_error_t vb2_load_kernel_keyblock(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); @@ -223,115 +179,6 @@ vb2_error_t vb2_load_kernel_keyblock(struct vb2_context *ctx) return VB2_SUCCESS; } -test_mockable -vb2_error_t vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble, - uint32_t size, - const struct vb2_public_key *key, - const struct vb2_workbuf *wb) -{ - struct vb2_signature *sig = &preamble->preamble_signature; - uint32_t min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_0_SIZE; - - VB2_DEBUG("Verifying kernel preamble.\n"); - - /* Make sure it's even safe to look at the struct */ - if(size < min_size) { - VB2_DEBUG("Not enough data for preamble header.\n"); - return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER; - } - if (preamble->header_version_major != - VB2_KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) { - VB2_DEBUG("Incompatible kernel preamble header version.\n"); - return VB2_ERROR_PREAMBLE_HEADER_VERSION; - } - - if (preamble->header_version_minor >= 2) - min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_2_SIZE; - else if (preamble->header_version_minor == 1) - min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_1_SIZE; - if(preamble->preamble_size < min_size) { - VB2_DEBUG("Preamble size too small for header.\n"); - return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER; - } - if (size < preamble->preamble_size) { - VB2_DEBUG("Not enough data for preamble.\n"); - return VB2_ERROR_PREAMBLE_SIZE; - } - - /* Check signature */ - if (vb2_verify_signature_inside(preamble, preamble->preamble_size, - sig)) { - VB2_DEBUG("Preamble signature off end of preamble\n"); - return VB2_ERROR_PREAMBLE_SIG_OUTSIDE; - } - - /* Make sure advertised signature data sizes are valid. */ - if (preamble->preamble_size < sig->data_size) { - VB2_DEBUG("Signature calculated past end of the block\n"); - return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH; - } - - if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) { - VB2_DEBUG("Preamble signature validation failed\n"); - return VB2_ERROR_PREAMBLE_SIG_INVALID; - } - - /* Verify we signed enough data */ - if (sig->data_size < sizeof(struct vb2_fw_preamble)) { - VB2_DEBUG("Didn't sign enough data\n"); - return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE; - } - - /* Verify body signature is inside the signed data */ - if (vb2_verify_signature_inside(preamble, sig->data_size, - &preamble->body_signature)) { - VB2_DEBUG("Body signature off end of preamble\n"); - return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE; - } - - /* - * If bootloader is present, verify it's covered by the body - * signature. - */ - if (preamble->bootloader_size) { - const void *body_ptr = - (const void *)(uintptr_t)preamble->body_load_address; - const void *bootloader_ptr = - (const void *)(uintptr_t)preamble->bootloader_address; - if (vb2_verify_member_inside(body_ptr, - preamble->body_signature.data_size, - bootloader_ptr, - preamble->bootloader_size, - 0, 0)) { - VB2_DEBUG("Bootloader off end of signed data\n"); - return VB2_ERROR_PREAMBLE_BOOTLOADER_OUTSIDE; - } - } - - /* - * If vmlinuz header is present, verify it's covered by the body - * signature. - */ - if (preamble->header_version_minor >= 1 && - preamble->vmlinuz_header_size) { - const void *body_ptr = - (const void *)(uintptr_t)preamble->body_load_address; - const void *vmlinuz_header_ptr = (const void *) - (uintptr_t)preamble->vmlinuz_header_address; - if (vb2_verify_member_inside(body_ptr, - preamble->body_signature.data_size, - vmlinuz_header_ptr, - preamble->vmlinuz_header_size, - 0, 0)) { - VB2_DEBUG("Vmlinuz header off end of signed data\n"); - return VB2_ERROR_PREAMBLE_VMLINUZ_HEADER_OUTSIDE; - } - } - - /* Success */ - return VB2_SUCCESS; -} - vb2_error_t vb2_load_kernel_preamble(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); @@ -421,30 +268,3 @@ vb2_error_t vb2_load_kernel_preamble(struct vb2_context *ctx) return VB2_SUCCESS; } - -void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble, - uint64_t *vmlinuz_header_address, - uint32_t *vmlinuz_header_size) -{ - if (preamble->header_version_minor < 1) { - *vmlinuz_header_address = 0; - *vmlinuz_header_size = 0; - } else { - /* - * Set header and size only if the preamble header version is > - * 2.1 as they don't exist in version 2.0 (Note that we don't - * need to check header_version_major; if that's not 2 then - * vb2_verify_kernel_preamble() would have already failed. - */ - *vmlinuz_header_address = preamble->vmlinuz_header_address; - *vmlinuz_header_size = preamble->vmlinuz_header_size; - } -} - -uint32_t vb2_kernel_get_flags(const struct vb2_kernel_preamble *preamble) -{ - if (preamble->header_version_minor < 2) - return 0; - - return preamble->flags; -} diff --git a/futility/cmd_show.c b/futility/cmd_show.c index f3b91631..716b2b2b 100644 --- a/futility/cmd_show.c +++ b/futility/cmd_show.c @@ -31,7 +31,6 @@ #include "host_key21.h" #include "util_misc.h" #include "vb1_helper.h" -#include "vb2_common.h" /* Options */ struct show_option_s show_option = { diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index 6243e3a8..9bfa7fdb 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -29,7 +29,6 @@ #include "kernel_blob.h" #include "util_misc.h" #include "vb1_helper.h" -#include "vb2_common.h" /* Options */ struct sign_option_s sign_option = { diff --git a/futility/cmd_vbutil_kernel.c b/futility/cmd_vbutil_kernel.c index 27cbb9bc..7268bee2 100644 --- a/futility/cmd_vbutil_kernel.c +++ b/futility/cmd_vbutil_kernel.c @@ -26,7 +26,6 @@ #include "host_common.h" #include "kernel_blob.h" #include "vb1_helper.h" -#include "vb2_common.h" /* Global opts */ static int opt_verbose; diff --git a/futility/file_type_bios.c b/futility/file_type_bios.c index 7e805f50..fe0b223e 100644 --- a/futility/file_type_bios.c +++ b/futility/file_type_bios.c @@ -16,7 +16,6 @@ #include "futility_options.h" #include "host_common.h" #include "vb1_helper.h" -#include "vb2_common.h" static const char * const fmap_name[] = { "GBB", /* BIOS_FMAP_GBB */ diff --git a/futility/updater.c b/futility/updater.c index fa008542..87ac6fd8 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -14,7 +14,6 @@ #include "host_misc.h" #include "updater.h" #include "util_misc.h" -#include "vb2_common.h" #define REMOVE_WP_URL "https://goo.gl/ces83U" diff --git a/futility/updater_archive.c b/futility/updater_archive.c index f2475b6a..4ad5287f 100644 --- a/futility/updater_archive.c +++ b/futility/updater_archive.c @@ -33,7 +33,6 @@ #include "host_misc.h" #include "updater.h" #include "util_misc.h" -#include "vb2_common.h" /* * A firmware update package (archive) is a file packed by either shar(1) or diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c index ecb193b5..39bb16ae 100644 --- a/futility/vb1_helper.c +++ b/futility/vb1_helper.c @@ -21,7 +21,6 @@ #include "kernel_blob.h" #include "util_misc.h" #include "vb1_helper.h" -#include "vb2_common.h" /****************************************************************************/ /* Here are globals containing all the bits & pieces I'm working on. diff --git a/host/lib/host_common.c b/host/lib/host_common.c index 1dc7a542..82a59542 100644 --- a/host/lib/host_common.c +++ b/host/lib/host_common.c @@ -133,3 +133,22 @@ struct vb2_kernel_preamble *vb2_create_kernel_preamble( /* Return the header */ return h; } + +void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble, + uint64_t *vmlinuz_header_address, + uint32_t *vmlinuz_header_size) +{ + if (preamble->header_version_minor < 1) { + *vmlinuz_header_address = 0; + *vmlinuz_header_size = 0; + } else { + /* + * Set header and size only if the preamble header version is > + * 2.1 as they don't exist in version 2.0 (Note that we don't + * need to check header_version_major; if that's not 2 then + * vb2_verify_kernel_preamble() would have already failed. + */ + *vmlinuz_header_address = preamble->vmlinuz_header_address; + *vmlinuz_header_size = preamble->vmlinuz_header_size; + } +} diff --git a/host/lib/host_keyblock.c b/host/lib/host_keyblock.c index a7dbedef..e5634ced 100644 --- a/host/lib/host_keyblock.c +++ b/host/lib/host_keyblock.c @@ -17,7 +17,6 @@ #include "host_key21.h" #include "host_keyblock.h" #include "host_key.h" -#include "vb2_common.h" struct vb2_keyblock *vb2_create_keyblock( const struct vb2_packed_key *data_key, diff --git a/host/lib/include/host_common.h b/host/lib/include/host_common.h index 55b15d3b..a37a6c9a 100644 --- a/host/lib/include/host_common.h +++ b/host/lib/include/host_common.h @@ -64,4 +64,18 @@ struct vb2_kernel_preamble *vb2_create_kernel_preamble( uint32_t desired_size, const struct vb2_private_key *signing_key); +/** + * Retrieve the 16-bit vmlinuz header address and size from the preamble. + * + * Size 0 means there is no 16-bit vmlinuz header present. Old preamble + * versions (<2.1) return 0 for both fields. + * + * @param preamble Preamble to check + * @param vmlinuz_header_address Destination for header address + * @param vmlinuz_header_size Destination for header size + */ +void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble, + uint64_t *vmlinuz_header_address, + uint32_t *vmlinuz_header_size); + #endif /* VBOOT_REFERENCE_HOST_COMMON_H_ */ diff --git a/tests/vb20_kernel_tests.c b/tests/vb20_kernel_tests.c index e71e5ce7..8766114a 100644 --- a/tests/vb20_kernel_tests.c +++ b/tests/vb20_kernel_tests.c @@ -15,7 +15,6 @@ #include "2secdata.h" #include "2sysincludes.h" #include "test_common.h" -#include "vb2_common.h" /* Common context for tests */ static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE] diff --git a/tests/vb2_common3_tests.c b/tests/vb2_common3_tests.c index 42192225..58052040 100644 --- a/tests/vb2_common3_tests.c +++ b/tests/vb2_common3_tests.c @@ -7,6 +7,7 @@ #include <stdio.h> +#include "2common.h" #include "2rsa.h" #include "2sysincludes.h" #include "file_keys.h" @@ -15,7 +16,6 @@ #include "host_key.h" #include "host_signature.h" #include "test_common.h" -#include "vb2_common.h" static void resign_keyblock(struct vb2_keyblock *h, const struct vb2_private_key *key) diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c index 01b8b342..7d088ae6 100644 --- a/tests/vboot_kernel_tests.c +++ b/tests/vboot_kernel_tests.c @@ -20,7 +20,6 @@ #include "host_common.h" #include "load_kernel_fw.h" #include "test_common.h" -#include "vb2_common.h" #include "vboot_api.h" #include "vboot_kernel.h" |