diff options
author | Joel Kitching <kitching@google.com> | 2019-05-23 15:33:54 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-07 22:40:03 +0000 |
commit | 3eb00efa4eb30e02d1b3197dafc5975fdcbe5914 (patch) | |
tree | a60cece3b500976279a32bb7e71d4ba993d4400e | |
parent | 96d5a58cbe65d762c64dc0e8f5ecc7af397015a4 (diff) | |
download | vboot-3eb00efa4eb30e02d1b3197dafc5975fdcbe5914.tar.gz |
vboot: rewrite GBB functions and API
Old vboot1-style GBB accessor functions were awkwardly located
within region-init.c.
Rewrite GBB accessor functions for vboot2, and formally expose
HWID retrieval function via vboot2 API. workbuf is used for
key retrieval functions, while a buffer provided by the caller
is used for HWID retrieval function.
Reintroduce vboot_display_tests to `make runtests` test suite.
Move GBB tests from vboot_display_tests to vb2_gbb_tests.
Properly propagate vb2_workbuf objects within the function call
stack (vb2_load_partition).
BUG=b:124141368, chromium:954774
TEST=Build and flash to eve, check that Chrome OS boots
TEST=Build with CL:1627469 applied, check HWID
TEST=make clean && make runtests
BRANCH=none
Change-Id: I398d1329f0b092de35aac73d98dfd9aee6e4e7de
Signed-off-by: Joel Kitching <kitching@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1584488
Tested-by: Joel Kitching <kitching@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Commit-Queue: Jason Clinton <jclinton@chromium.org>
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | firmware/2lib/2gbb.c | 124 | ||||
-rw-r--r-- | firmware/2lib/include/2api.h | 17 | ||||
-rw-r--r-- | firmware/2lib/include/2common.h | 1 | ||||
-rw-r--r-- | firmware/2lib/include/2constants.h | 3 | ||||
-rw-r--r-- | firmware/2lib/include/2gbb.h | 48 | ||||
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 8 | ||||
-rw-r--r-- | firmware/include/gbb_access.h | 58 | ||||
-rw-r--r-- | firmware/lib/region-init.c | 91 | ||||
-rw-r--r-- | firmware/lib/vboot_api_kernel.c | 17 | ||||
-rw-r--r-- | firmware/lib/vboot_display.c | 59 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c | 20 | ||||
-rw-r--r-- | firmware/lib/vboot_ui.c | 1 | ||||
-rw-r--r-- | firmware/lib/vboot_ui_menu.c | 1 | ||||
-rw-r--r-- | firmware/lib20/include/vb2_common.h | 3 | ||||
-rw-r--r-- | tests/vb2_gbb_tests.c | 350 | ||||
-rw-r--r-- | tests/vb2_misc_tests.c | 9 | ||||
-rw-r--r-- | tests/vboot_api_kernel5_tests.c | 23 | ||||
-rw-r--r-- | tests/vboot_display_tests.c | 82 | ||||
-rw-r--r-- | tests/vboot_kernel_tests.c | 21 |
21 files changed, 662 insertions, 280 deletions
@@ -32,7 +32,6 @@ VBINIT_SRCS = \ firmware/lib/utility.c \ firmware/lib/vboot_api_init.c \ firmware/lib/vboot_common_init.c \ - firmware/lib/region-init.c \ # Additional firmware library sources needed by VbSelectFirmware() call VBSF_SRCS = \ @@ -336,7 +336,6 @@ BDBLIB = ${BUILD}/bdb.a # Firmware library sources needed by VbInit() call VBINIT_SRCS = \ firmware/lib/vboot_common_init.c \ - firmware/lib/region-init.c # Additional firmware library sources needed by VbSelectFirmware() call VBSF_SRCS = \ @@ -364,6 +363,7 @@ FWLIB2X_SRCS = \ firmware/2lib/2api.c \ firmware/2lib/2common.c \ firmware/2lib/2crc8.c \ + firmware/2lib/2gbb.c \ firmware/2lib/2misc.c \ firmware/2lib/2nvstorage.c \ firmware/2lib/2packed_key.c \ @@ -758,6 +758,7 @@ TEST_NAMES += ${TEST_FUTIL_NAMES} TEST2X_NAMES = \ tests/vb2_api_tests \ tests/vb2_common_tests \ + tests/vb2_gbb_tests \ tests/vb2_misc_tests \ tests/vb2_nvstorage_tests \ tests/vb2_rsa_utility_tests \ @@ -1388,12 +1389,14 @@ endif ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel6_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_detach_menu_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_common_tests + ${RUNTEST} ${BUILD_RUN}/tests/vboot_display_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_kernel_tests .PHONY: run2tests run2tests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/vb2_api_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_common_tests + ${RUNTEST} ${BUILD_RUN}/tests/vb2_gbb_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_misc_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_nvstorage_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_rsa_utility_tests diff --git a/firmware/2lib/2gbb.c b/firmware/2lib/2gbb.c new file mode 100644 index 00000000..75eed57e --- /dev/null +++ b/firmware/2lib/2gbb.c @@ -0,0 +1,124 @@ +/* Copyright 2019 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. + * + * GBB accessor functions. + */ + +#include "2common.h" +#include "2misc.h" + +static int vb2_gbb_read_key(struct vb2_context *ctx, + uint32_t offset, + uint32_t *size, + struct vb2_packed_key **keyp, + struct vb2_workbuf *wb) +{ + struct vb2_workbuf wblocal = *wb; + int rv; + + /* Check offset and size. */ + if (offset < sizeof(struct vb2_gbb_header)) + return VB2_ERROR_GBB_INVALID; + if (*size < sizeof(**keyp)) + return VB2_ERROR_GBB_INVALID; + + /* GBB header might be padded. Retrieve the vb2_packed_key + header so we can find out what the real size is. */ + *keyp = vb2_workbuf_alloc(&wblocal, sizeof(**keyp)); + if (!*keyp) + return VB2_ERROR_GBB_WORKBUF; + rv = vb2ex_read_resource(ctx, VB2_RES_GBB, offset, *keyp, + sizeof(**keyp)); + if (rv) + return rv; + + rv = vb2_verify_packed_key_inside(*keyp, *size, *keyp); + if (rv) + return rv; + + /* Deal with a zero-size key (used in testing). */ + *size = (*keyp)->key_offset + (*keyp)->key_size; + if (*size < sizeof(**keyp)) + *size = sizeof(**keyp); + + /* Now that we know the real size of the key, retrieve the key + data, and write it on the workbuf, directly after vb2_packed_key. */ + *keyp = vb2_workbuf_realloc(&wblocal, sizeof(**keyp), *size); + if (!*keyp) + return VB2_ERROR_GBB_WORKBUF; + + rv = vb2ex_read_resource(ctx, VB2_RES_GBB, + offset + sizeof(**keyp), + (void *)*keyp + sizeof(**keyp), + *size - sizeof(**keyp)); + if (!rv) + *wb = wblocal; + return rv; +} + +int vb2_gbb_read_root_key(struct vb2_context *ctx, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb) +{ + struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); + uint32_t size_in = gbb->rootkey_size; + int ret = vb2_gbb_read_key(ctx, gbb->rootkey_offset, + &size_in, keyp, wb); + if (size) + *size = size_in; + return ret; +} + +int vb2_gbb_read_recovery_key(struct vb2_context *ctx, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb) +{ + struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); + uint32_t size_in = gbb->recovery_key_size; + int ret = vb2_gbb_read_key(ctx, gbb->recovery_key_offset, + &size_in, keyp, wb); + if (size) + *size = size_in; + return ret; +} + +int vb2api_gbb_read_hwid(struct vb2_context *ctx, + char *hwid, + uint32_t *size) +{ + struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); + uint32_t i; + int ret; + + if (gbb->hwid_size == 0) { + VB2_DEBUG("invalid HWID size %d\n", gbb->hwid_size); + return VB2_ERROR_GBB_INVALID; + } + + if (*size > VB2_GBB_HWID_MAX_SIZE) + *size = VB2_GBB_HWID_MAX_SIZE; + if (*size > gbb->hwid_size) + *size = gbb->hwid_size; + + ret = vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->hwid_offset, + hwid, *size); + if (ret) { + VB2_DEBUG("read resource failure: %d\n", ret); + return ret; + } + + /* Count HWID size, and ensure that it fits in the given buffer. */ + for (i = 0; i < *size; i++) { + if (hwid[i] == '\0') { + *size = i + 1; + break; + } + } + if (hwid[*size - 1] != '\0') + return VB2_ERROR_INVALID_PARAMETER; + + return VB2_SUCCESS; +} diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index e7964e28..341517d9 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -643,6 +643,23 @@ int vb2api_verify_kernel_data(struct vb2_context *ctx, */ int vb2api_kernel_phase3(struct vb2_context *ctx); +/** + * Read the hardware ID from the GBB, and store it onto the given buffer. + * + * @param ctx Vboot context. + * @param hwid Buffer to store HWID, which will be null-terminated. + * @param size Maximum size of HWID including null terminator. HWID + * length may not exceed 256 (VB2_GBB_HWID_MAX_SIZE), so + * this value is suggested. If size is too small, then + * VB2_ERROR_INVALID_PARAMETER is returned. Actual size + * of the output HWID string is returned in this pointer, + * also including null terminator. + * @return VB2_SUCCESS, or error code on error. + */ +int vb2api_gbb_read_hwid(struct vb2_context *ctx, + char *hwid, + uint32_t *size); + /*****************************************************************************/ /* APIs provided by the caller to verified boot */ diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h index be8a4ec5..81f56df5 100644 --- a/firmware/2lib/include/2common.h +++ b/firmware/2lib/include/2common.h @@ -9,6 +9,7 @@ #define VBOOT_REFERENCE_VBOOT_2COMMON_H_ #include "2api.h" +#include "2gbb.h" #include "2return_codes.h" #include "2sha.h" #include "2struct.h" diff --git a/firmware/2lib/include/2constants.h b/firmware/2lib/include/2constants.h index 81d1cc56..ef772ef6 100644 --- a/firmware/2lib/include/2constants.h +++ b/firmware/2lib/include/2constants.h @@ -64,4 +64,7 @@ * macro for us we'll be safe and use that. */ #define VB2_WORKBUF_ALIGN __BIGGEST_ALIGNMENT__ +/* Maximum length of a HWID in bytes, counting terminating null. */ +#define VB2_GBB_HWID_MAX_SIZE 256 + #endif /* VBOOT_REFERENCE_2CONSTANTS_H_ */ diff --git a/firmware/2lib/include/2gbb.h b/firmware/2lib/include/2gbb.h new file mode 100644 index 00000000..6ad0eb3b --- /dev/null +++ b/firmware/2lib/include/2gbb.h @@ -0,0 +1,48 @@ +/* Copyright 2019 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. + * + * GBB accessor functions. + */ + +#ifndef VBOOT_REFERENCE_VBOOT_2GBB_H_ +#define VBOOT_REFERENCE_VBOOT_2GBB_H_ + +#include "2common.h" + +struct vb2_packed_key; +struct vb2_workbuf; + +/** + * Read the root key from the GBB, and store it onto the given workbuf. + * + * @param ctx Vboot context. + * @param keyp Returns a pointer to the key. The caller may discard + * workbuf state if it wants to free the key. + * @param size If pointer is non-NULL, returns the total size of key, + * including data. + * @param wb Workbuf for data storage. + * @return VB2_SUCCESS, or error code on error. + */ +int vb2_gbb_read_root_key(struct vb2_context *ctx, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb); + +/** + * Read the recovery key from the GBB, and store it onto the given workbuf. + * + * @param ctx Vboot context. + * @param keyp Returns a pointer to the key. The caller may discard + * workbuf state if it wants to free the key. + * @param size If pointer is non-NULL, returns the total size of key, + * including data. + * @param wb Workbuf for data storage. + * @return VB2_SUCCESS, or error code on error. + */ +int vb2_gbb_read_recovery_key(struct vb2_context *ctx, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb); + +#endif /* VBOOT_REFERENCE_VBOOT_2GBB_H_ */ diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index 5992806d..15ec97f6 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -361,7 +361,7 @@ enum vb2_return_code { /* Work buffer unaligned in vb2_init_context() */ VB2_ERROR_INITCTX_WORKBUF_ALIGN, - /* Work buffer too small in vb2_fw_parse_gbb() */ + /* Work buffer too small in GBB-related function */ VB2_ERROR_GBB_WORKBUF, /* Bad magic number in vb2_read_gbb_header() */ @@ -503,6 +503,12 @@ enum vb2_return_code { /* Bad magic number in vb2_shared_data structure */ VB2_ERROR_SHARED_DATA_MAGIC, + /* Some part of GBB data is invalid */ + VB2_ERROR_GBB_INVALID, + + /* Invalid parameter */ + VB2_ERROR_INVALID_PARAMETER, + /********************************************************************** * API-level errors */ diff --git a/firmware/include/gbb_access.h b/firmware/include/gbb_access.h deleted file mode 100644 index 09a88fa0..00000000 --- a/firmware/include/gbb_access.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2013 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. - * - * Access to portions of the GBB using the region API. - */ - -#ifndef VBOOT_REFERENCE_GBB_ACCESS_H_ -#define VBOOT_REFERENCE_GBB_ACCESS_H_ - -#include "vboot_api.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct vb2_context; -struct VbPublicKey; - -/** - * Read the root key from the GBB - * - * @param ctx Vboot context - * @param keyp Returns a pointer to the key. The caller must call - * free() on the key when finished with it. - * @return VBERROR_... error, VBERROR_SUCCESS on success, - */ -VbError_t VbGbbReadRootKey(struct vb2_context *ctx, - struct VbPublicKey **keyp); - -/** - * Read the recovery key from the GBB - * - * @param ctx Vboot context - * @param keyp Returns a pointer to the key. The caller must call - * free() on the key when finished with it. - * @return VBERROR_... error, VBERROR_SUCCESS on success, - */ -VbError_t VbGbbReadRecoveryKey(struct vb2_context *ctx, - struct VbPublicKey **keyp); - -/** - * Read the hardware ID from the GBB - * - * @param ctx Vboot context - * @param hwid Place to put HWID, which will be null-terminated - * @param max_size Maximum size of HWID including terminated null - * character (suggest 256). If this size is too small - * then VBERROR_INVALID_PARAMETER is returned. - * @return VBERROR_... error, VBERROR_SUCCESS on success, - */ -VbError_t VbGbbReadHWID(struct vb2_context *ctx, char *hwid, uint32_t max_size); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/firmware/lib/region-init.c b/firmware/lib/region-init.c deleted file mode 100644 index 9e3c2bc3..00000000 --- a/firmware/lib/region-init.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2013 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. - * - * High-level firmware API for loading and verifying rewritable firmware. - * (Firmware portion) - */ - -#include "2sysincludes.h" -#include "2common.h" -#include "2misc.h" - -#include "sysincludes.h" -#include "gbb_access.h" -#include "load_kernel_fw.h" -#include "utility.h" -#include "vboot_api.h" -#include "vboot_struct.h" - -static VbError_t VbGbbReadData(struct vb2_context *ctx, - uint32_t offset, uint32_t size, void *buf) -{ - if (vb2ex_read_resource(ctx, VB2_RES_GBB, offset, buf, size)) - return VBERROR_INVALID_GBB; - return VBERROR_SUCCESS; -} - -VbError_t VbGbbReadHWID(struct vb2_context *ctx, char *hwid, uint32_t max_size) -{ - struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); - - if (!max_size) - return VBERROR_INVALID_PARAMETER; - *hwid = '\0'; - StrnAppend(hwid, "{INVALID}", max_size); - if (!ctx) - return VBERROR_INVALID_GBB; - - if (0 == gbb->hwid_size) { - VB2_DEBUG("VbHWID(): invalid hwid size\n"); - return VBERROR_SUCCESS; /* oddly enough! */ - } - - if (gbb->hwid_size > max_size) { - VB2_DEBUG("VbDisplayDebugInfo(): invalid hwid offset/size\n"); - return VBERROR_INVALID_PARAMETER; - } - - return VbGbbReadData(ctx, gbb->hwid_offset, - gbb->hwid_size, hwid); -} - -static VbError_t VbGbbReadKey(struct vb2_context *ctx, uint32_t offset, - VbPublicKey **keyp) -{ - VbPublicKey hdr, *key; - VbError_t ret; - uint32_t size; - - ret = VbGbbReadData(ctx, offset, sizeof(VbPublicKey), &hdr); - if (ret) - return ret; - - /* Deal with a zero-size key (used in testing) */ - size = hdr.key_offset + hdr.key_size; - if (size < sizeof(hdr)) - size = sizeof(hdr); - key = malloc(size); - ret = VbGbbReadData(ctx, offset, size, key); - if (ret) { - free(key); - return ret; - } - - *keyp = key; - return VBERROR_SUCCESS; -} - -VbError_t VbGbbReadRootKey(struct vb2_context *ctx, VbPublicKey **keyp) -{ - struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); - - return VbGbbReadKey(ctx, gbb->rootkey_offset, keyp); -} - -VbError_t VbGbbReadRecoveryKey(struct vb2_context *ctx, VbPublicKey **keyp) -{ - struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); - - return VbGbbReadKey(ctx, gbb->recovery_key_offset, keyp); -} diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c index 35f33813..bde6f82e 100644 --- a/firmware/lib/vboot_api_kernel.c +++ b/firmware/lib/vboot_api_kernel.c @@ -13,7 +13,6 @@ #include "2nvstorage.h" #include "2rsa.h" #include "ec_sync.h" -#include "gbb_access.h" #include "load_kernel_fw.h" #include "rollback_index.h" #include "utility.h" @@ -463,7 +462,7 @@ VbError_t VbVerifyMemoryBootImage( VbSelectAndLoadKernelParams *kparams, void *boot_image, size_t image_size) { - VbPublicKey* kernel_subkey = NULL; + struct vb2_packed_key *kernel_subkey = NULL; uint8_t *kbuf; VbKeyBlockHeader *key_block; VbKernelPreambleHeader *preamble; @@ -473,6 +472,9 @@ VbError_t VbVerifyMemoryBootImage( uint32_t allow_fastboot_full_cap = 0; struct vb2_workbuf wb; + /* Allocate work buffer */ + vb2_workbuf_from_ctx(ctx, &wb); + VbError_t retval = vb2_kernel_setup(ctx, shared, kparams); if (retval) goto fail; @@ -508,7 +510,8 @@ VbError_t VbVerifyMemoryBootImage( hash_only = 1; } else { /* Get recovery key. */ - retval = VbGbbReadRecoveryKey(ctx, &kernel_subkey); + retval = vb2_gbb_read_recovery_key(ctx, &kernel_subkey, + NULL, &wb); if (VBERROR_SUCCESS != retval) { VB2_DEBUG("Gbb Read Recovery key failed.\n"); goto fail; @@ -518,9 +521,6 @@ VbError_t VbVerifyMemoryBootImage( /* If we fail at any step, retval returned would be invalid kernel. */ retval = VBERROR_INVALID_KERNEL_FOUND; - /* Allocate work buffer */ - vb2_workbuf_from_ctx(ctx, &wb); - /* Verify the key block. */ key_block = (VbKeyBlockHeader *)kbuf; struct vb2_keyblock *keyblock2 = (struct vb2_keyblock *)kbuf; @@ -531,8 +531,7 @@ VbError_t VbVerifyMemoryBootImage( /* Unpack kernel subkey */ struct vb2_public_key kernel_subkey2; if (VB2_SUCCESS != - vb2_unpack_key(&kernel_subkey2, - (struct vb2_packed_key *)kernel_subkey)) { + vb2_unpack_key(&kernel_subkey2, kernel_subkey)) { VB2_DEBUG("Unable to unpack kernel subkey\n"); goto fail; } @@ -609,8 +608,6 @@ VbError_t VbVerifyMemoryBootImage( fail: vb2_kernel_cleanup(ctx); - if (NULL != kernel_subkey) - free(kernel_subkey); return retval; } diff --git a/firmware/lib/vboot_display.c b/firmware/lib/vboot_display.c index 1f80a651..6ef692f7 100644 --- a/firmware/lib/vboot_display.c +++ b/firmware/lib/vboot_display.c @@ -12,7 +12,6 @@ #include "2misc.h" #include "2nvstorage.h" #include "2sha.h" -#include "gbb_access.h" #include "utility.h" #include "vboot_api.h" #include "vboot_common.h" @@ -274,19 +273,27 @@ VbError_t VbDisplayDebugInfo(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); + struct vb2_workbuf wb; VbSharedDataHeader *shared = sd->vbsd; char buf[DEBUG_INFO_SIZE] = ""; char sha1sum[VB2_SHA1_DIGEST_SIZE * 2 + 1]; - char hwid[256]; uint32_t used = 0; - VbPublicKey *key; - VbError_t ret; + int ret; uint32_t i; + vb2_workbuf_from_ctx(ctx, &wb); + /* Add hardware ID */ - VbGbbReadHWID(ctx, hwid, sizeof(hwid)); - used += StrnAppend(buf + used, "HWID: ", DEBUG_INFO_SIZE - used); - used += StrnAppend(buf + used, hwid, DEBUG_INFO_SIZE - used); + { + char hwid[VB2_GBB_HWID_MAX_SIZE]; + uint32_t size = sizeof(hwid); + ret = vb2api_gbb_read_hwid(ctx, hwid, &size); + if (ret) + strcpy(hwid, "{INVALID}"); + used += StrnAppend(buf + used, "HWID: ", + DEBUG_INFO_SIZE - used); + used += StrnAppend(buf + used, hwid, DEBUG_INFO_SIZE - used); + } /* Add recovery reason and subcode */ i = vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE); @@ -359,24 +366,30 @@ VbError_t VbDisplayDebugInfo(struct vb2_context *ctx) gbb->flags, 16, 8); /* Add sha1sum for Root & Recovery keys */ - ret = VbGbbReadRootKey(ctx, &key); - if (!ret) { - FillInSha1Sum(sha1sum, key); - free(key); - used += StrnAppend(buf + used, "\ngbb.rootkey: ", - DEBUG_INFO_SIZE - used); - used += StrnAppend(buf + used, sha1sum, - DEBUG_INFO_SIZE - used); + { + struct vb2_packed_key *key; + struct vb2_workbuf wblocal = wb; + ret = vb2_gbb_read_root_key(ctx, &key, NULL, &wblocal); + if (!ret) { + FillInSha1Sum(sha1sum, (VbPublicKey *)key); + used += StrnAppend(buf + used, "\ngbb.rootkey: ", + DEBUG_INFO_SIZE - used); + used += StrnAppend(buf + used, sha1sum, + DEBUG_INFO_SIZE - used); + } } - ret = VbGbbReadRecoveryKey(ctx, &key); - if (!ret) { - FillInSha1Sum(sha1sum, key); - free(key); - used += StrnAppend(buf + used, "\ngbb.recovery_key: ", - DEBUG_INFO_SIZE - used); - used += StrnAppend(buf + used, sha1sum, - DEBUG_INFO_SIZE - used); + { + struct vb2_packed_key *key; + struct vb2_workbuf wblocal = wb; + ret = vb2_gbb_read_recovery_key(ctx, &key, NULL, &wblocal); + if (!ret) { + FillInSha1Sum(sha1sum, (VbPublicKey *)key); + used += StrnAppend(buf + used, "\ngbb.recovery_key: ", + DEBUG_INFO_SIZE - used); + used += StrnAppend(buf + used, sha1sum, + DEBUG_INFO_SIZE - used); + } } /* If we're in dev-mode, show the kernel subkey that we expect, too. */ diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index 7195bdb0..741890e4 100644 --- a/firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c @@ -16,7 +16,6 @@ #include "2sha.h" #include "cgptlib.h" #include "cgptlib_internal.h" -#include "gbb_access.h" #include "gpt_misc.h" #include "load_kernel_fw.h" #include "rollback_index.h" @@ -309,6 +308,7 @@ enum vb2_load_partition_flags { * @param params Load-kernel parameters * @param min_version Minimum kernel version from TPM * @param shpart Destination for verification results + * @param wb Workbuf for data storage * @return VB2_SUCCESS, or non-zero error code. */ static int vb2_load_partition(struct vb2_context *ctx, @@ -317,10 +317,10 @@ static int vb2_load_partition(struct vb2_context *ctx, uint32_t flags, LoadKernelParams *params, uint32_t min_version, - VbSharedDataKernelPart *shpart) + VbSharedDataKernelPart *shpart, + struct vb2_workbuf *wb) { - struct vb2_workbuf wblocal; - vb2_workbuf_from_ctx(ctx, &wblocal); + struct vb2_workbuf wblocal = *wb; /* Allocate kernel header buffer in workbuf */ uint8_t *kbuf = vb2_workbuf_alloc(&wblocal, KBUF_SIZE); @@ -429,6 +429,7 @@ static int vb2_load_partition(struct vb2_context *ctx, VbError_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params) { struct vb2_shared_data *sd = vb2_get_sd(ctx); + struct vb2_workbuf wb; VbSharedDataHeader *shared = sd->vbsd; VbSharedDataKernelCall *shcall = NULL; struct vb2_packed_key *recovery_key = NULL; @@ -438,6 +439,8 @@ VbError_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params) VbError_t retval = VBERROR_UNKNOWN; int recovery = VB2_RECOVERY_LK_UNSPECIFIED; + vb2_workbuf_from_ctx(ctx, &wb); + /* Clear output params in case we fail */ params->partition_number = 0; params->bootloader_address = 0; @@ -461,8 +464,8 @@ VbError_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params) struct vb2_packed_key *kernel_subkey; if (kBootRecovery == shcall->boot_mode) { /* Use the recovery key to verify the kernel */ - retval = VbGbbReadRecoveryKey(ctx, - (VbPublicKey **)&recovery_key); + retval = vb2_gbb_read_recovery_key(ctx, &recovery_key, + NULL, &wb); if (VBERROR_SUCCESS != retval) goto load_kernel_exit; kernel_subkey = recovery_key; @@ -547,7 +550,8 @@ VbError_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params) lpflags, params, shared->kernel_version_tpm, - shpart); + shpart, + &wb); VbExStreamClose(stream); if (rv != VB2_SUCCESS) { @@ -656,8 +660,6 @@ load_kernel_exit: VBERROR_SUCCESS != retval ? recovery : VB2_RECOVERY_NOT_REQUESTED); - free(recovery_key); - shcall->return_code = (uint8_t)retval; return retval; } diff --git a/firmware/lib/vboot_ui.c b/firmware/lib/vboot_ui.c index 7fc7a307..8a990047 100644 --- a/firmware/lib/vboot_ui.c +++ b/firmware/lib/vboot_ui.c @@ -13,7 +13,6 @@ #include "2nvstorage.h" #include "2rsa.h" #include "ec_sync.h" -#include "gbb_access.h" #include "load_kernel_fw.h" #include "rollback_index.h" #include "tlcl.h" diff --git a/firmware/lib/vboot_ui_menu.c b/firmware/lib/vboot_ui_menu.c index 3fdf77cb..c3268d1e 100644 --- a/firmware/lib/vboot_ui_menu.c +++ b/firmware/lib/vboot_ui_menu.c @@ -11,7 +11,6 @@ #include "2nvstorage.h" #include "2rsa.h" #include "ec_sync.h" -#include "gbb_access.h" #include "load_kernel_fw.h" #include "rollback_index.h" #include "utility.h" diff --git a/firmware/lib20/include/vb2_common.h b/firmware/lib20/include/vb2_common.h index 4cb0e5a5..2f70d544 100644 --- a/firmware/lib20/include/vb2_common.h +++ b/firmware/lib20/include/vb2_common.h @@ -13,8 +13,11 @@ #include "2return_codes.h" #include "2sha.h" #include "2struct.h" +#include "2sysincludes.h" #include "vb2_struct.h" +struct vb2_public_key; + /* * Helper functions to get data pointed to by a public key or signature. */ diff --git a/tests/vb2_gbb_tests.c b/tests/vb2_gbb_tests.c new file mode 100644 index 00000000..0c5eff5e --- /dev/null +++ b/tests/vb2_gbb_tests.c @@ -0,0 +1,350 @@ +/* Copyright 2019 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. + * + * Tests for GBB library. + */ + +#include "2common.h" +#include "2misc.h" +#include "test_common.h" + +/* Mock data */ +static char gbb_data[4096 + sizeof(struct vb2_gbb_header)]; +static struct vb2_gbb_header *gbb = (struct vb2_gbb_header *)gbb_data; +static struct vb2_packed_key *rootkey; +static struct vb2_context ctx; +static struct vb2_workbuf wb; +static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]; + +static void set_gbb_hwid(const char *hwid, size_t size) +{ + memcpy(gbb_data + gbb->hwid_offset, hwid, size); + gbb->hwid_size = size; +} + +static void reset_common_data(void) +{ + int gbb_used; + + memset(gbb_data, 0, sizeof(gbb_data)); + gbb->header_size = sizeof(*gbb); + gbb->major_version = VB2_GBB_MAJOR_VER; + gbb->minor_version = VB2_GBB_MINOR_VER; + gbb->flags = 0; + gbb_used = sizeof(struct vb2_gbb_header); + + gbb->recovery_key_offset = gbb_used; + gbb->recovery_key_size = 64; + gbb_used += gbb->recovery_key_size; + gbb->rootkey_offset = gbb_used; + gbb->rootkey_size = sizeof(struct vb2_packed_key); + gbb_used += gbb->rootkey_size; + + rootkey = ((void *)gbb + gbb->rootkey_offset); + rootkey->key_offset = sizeof(*rootkey); + + gbb->hwid_offset = gbb_used; + const char hwid_src[] = "Test HWID"; + set_gbb_hwid(hwid_src, sizeof(hwid_src)); + + memset(workbuf, 0, sizeof(workbuf)); + memset(&ctx, 0, sizeof(ctx)); + ctx.workbuf = workbuf; + ctx.workbuf_size = sizeof(workbuf); + vb2_init_context(&ctx); + vb2_workbuf_from_ctx(&ctx, &wb); +} + +/* Mocks */ +struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c) +{ + return gbb; +} + +int vb2ex_read_resource(struct vb2_context *c, + enum vb2_resource_index index, + uint32_t offset, + void *buf, + uint32_t size) +{ + uint8_t *rptr; + uint32_t rsize; + + switch(index) { + case VB2_RES_GBB: + rptr = (uint8_t *)&gbb_data; + rsize = sizeof(gbb_data); + break; + default: + return VB2_ERROR_EX_READ_RESOURCE_INDEX; + } + + if (offset > rsize || offset + size > rsize) + return VB2_ERROR_EX_READ_RESOURCE_SIZE; + + memcpy(buf, rptr + offset, size); + return VB2_SUCCESS; +} + +/* Tests */ +static void key_tests(void) +{ + /* Assume that root key and recovery key are dealt with using the same + code in our GBB library functions. */ + struct vb2_packed_key *keyp; + struct vb2_workbuf wborig; + const char key_data[] = "HELLOWORLD"; + uint32_t size; + + /* gbb.offset < sizeof(vb2_gbb_header) */ + reset_common_data(); + wborig = wb; + gbb->rootkey_offset = sizeof(*gbb) - 1; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_GBB_INVALID, + "gbb.rootkey offset too small"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* gbb.offset > gbb_data */ + reset_common_data(); + wborig = wb; + gbb->rootkey_offset = sizeof(gbb_data) + 1; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_EX_READ_RESOURCE_SIZE, + "gbb.rootkey offset too large"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* gbb.size < sizeof(vb2_packed_key) */ + reset_common_data(); + wborig = wb; + gbb->rootkey_size = sizeof(*rootkey) - 1; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_GBB_INVALID, + "gbb.rootkey size too small"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* sizeof(vb2_packed_key) > workbuf.size */ + reset_common_data(); + wborig = wb; + wb.size = sizeof(*rootkey) - 1; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_GBB_WORKBUF, + "workbuf size too small for vb2_packed_key header"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* packed_key.offset < sizeof(vb2_packed_key) */ + reset_common_data(); + wborig = wb; + rootkey->key_size = 1; + rootkey->key_offset = sizeof(*rootkey) - 1; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_INSIDE_DATA_OVERLAP, + "rootkey offset too small"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* packed_key.offset > gbb_data */ + reset_common_data(); + wborig = wb; + rootkey->key_size = 1; + rootkey->key_offset = sizeof(gbb_data) + 1; + gbb->rootkey_size = rootkey->key_offset + rootkey->key_size; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_EX_READ_RESOURCE_SIZE, + "rootkey size too large"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* packed_key.size > workbuf.size */ + reset_common_data(); + wborig = wb; + rootkey->key_size = wb.size + 1; + gbb->rootkey_size = rootkey->key_offset + rootkey->key_size + 1; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_GBB_WORKBUF, + "workbuf size too small for vb2_packed_key contents"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* gbb.size < sizeof(vb2_packed_key) + packed_key.size */ + reset_common_data(); + wborig = wb; + rootkey->key_size = 2; + gbb->rootkey_size = rootkey->key_offset + rootkey->key_size - 1; + TEST_EQ(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + VB2_ERROR_INSIDE_DATA_OUTSIDE, + "rootkey size exceeds gbb.rootkey size"); + TEST_TRUE(wb.buf == wborig.buf, + " workbuf restored on error"); + + /* gbb.size == sizeof(vb2_packed_key) + packed_key.size */ + reset_common_data(); + wborig = wb; + rootkey->key_size = sizeof(key_data); + memcpy((void *)rootkey + rootkey->key_offset, + key_data, sizeof(key_data)); + gbb->rootkey_size = rootkey->key_offset + rootkey->key_size; + TEST_SUCC(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + "succeeds when gbb.rootkey and rootkey sizes agree"); + TEST_TRUE(wb.size < wborig.size, + " workbuf shrank on success"); + TEST_EQ(memcmp(rootkey, keyp, rootkey->key_offset + rootkey->key_size), + 0, " copied key data successfully"); + TEST_EQ(size, rootkey->key_offset + rootkey->key_size, + " correct size returned"); + + /* gbb.size > sizeof(vb2_packed_key) + packed_key.size + packed_key.offset = +0 */ + reset_common_data(); + wborig = wb; + rootkey->key_size = 1; + gbb->rootkey_size = rootkey->key_offset + rootkey->key_size + 1; + TEST_SUCC(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + "succeeds when gbb.rootkey is padded after key"); + TEST_TRUE(wb.size < wborig.size, + " workbuf shrank on success"); + TEST_EQ(size, rootkey->key_offset + rootkey->key_size, + " correct size returned"); + + /* gbb.size > sizeof(vb2_packed_key) + packed_key.size + packed_key.offset = +1 */ + reset_common_data(); + wborig = wb; + rootkey->key_offset = sizeof(*rootkey) + 1; + rootkey->key_size = 1; + gbb->rootkey_size = rootkey->key_offset + rootkey->key_size; + TEST_SUCC(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + "succeeds when gbb.rootkey is padded before key"); + TEST_TRUE(wb.size < wborig.size, + " workbuf shrank on success"); + TEST_EQ(size, rootkey->key_offset + rootkey->key_size, + " correct size returned"); + + /* packed_key.size = 0, packed_key.offset = +1 */ + reset_common_data(); + wborig = wb; + rootkey->key_offset = sizeof(*rootkey) + 1; + rootkey->key_size = 0; + gbb->rootkey_size = rootkey->key_offset + rootkey->key_size + 1; + TEST_SUCC(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + "succeeds when gbb.rootkey is padded; empty test key"); + TEST_TRUE(wb.size < wborig.size, + " workbuf shrank on success"); + TEST_EQ(size, rootkey->key_offset + rootkey->key_size, + " correct size returned"); + + /* packed_key.size = 0, packed_key.offset = -1 */ + reset_common_data(); + wborig = wb; + rootkey->key_offset = sizeof(*rootkey) - 1; + rootkey->key_size = 0; + gbb->rootkey_size = sizeof(*rootkey) + rootkey->key_size + 1; + TEST_SUCC(vb2_gbb_read_root_key(&ctx, &keyp, &size, &wb), + "succeeds when gbb.rootkey is padded; empty test key"); + TEST_TRUE(wb.size < wborig.size, + " workbuf shrank on success"); + TEST_EQ(size, sizeof(*rootkey), " correct size returned"); +} + +static void hwid_tests(void) +{ + char hwid[VB2_GBB_HWID_MAX_SIZE]; + uint32_t size; + + /* GBB HWID size = 0 */ + { + reset_common_data(); + gbb->hwid_size = 0; + size = VB2_GBB_HWID_MAX_SIZE; + TEST_EQ(vb2api_gbb_read_hwid(&ctx, hwid, &size), + VB2_ERROR_GBB_INVALID, + "GBB HWID size invalid (HWID missing)"); + } + + /* GBB HWID offset > GBB size */ + { + reset_common_data(); + gbb->hwid_offset = sizeof(gbb_data) + 1; + size = VB2_GBB_HWID_MAX_SIZE; + TEST_EQ(vb2api_gbb_read_hwid(&ctx, hwid, &size), + VB2_ERROR_EX_READ_RESOURCE_SIZE, + "GBB HWID offset invalid"); + } + + /* buffer size < HWID size */ + { + const char hwid_src[] = "Test HWID"; + reset_common_data(); + set_gbb_hwid(hwid_src, sizeof(hwid_src)); + size = sizeof(hwid_src) - 1; + TEST_EQ(vb2api_gbb_read_hwid(&ctx, hwid, &size), + VB2_ERROR_INVALID_PARAMETER, + "HWID too large for buffer"); + } + + /* GBB HWID size < HWID size */ + { + const char hwid_src[] = "Test HWID"; + reset_common_data(); + set_gbb_hwid(hwid_src, sizeof(hwid_src) - 1); + size = sizeof(hwid_src); + TEST_EQ(vb2api_gbb_read_hwid(&ctx, hwid, &size), + VB2_ERROR_INVALID_PARAMETER, + "HWID larger than GBB HWID size"); + } + + /* buffer size == HWID size */ + { + const char hwid_src[] = "Test HWID"; + reset_common_data(); + set_gbb_hwid(hwid_src, sizeof(hwid_src)); + size = sizeof(hwid_src); + TEST_SUCC(vb2api_gbb_read_hwid(&ctx, hwid, &size), + "read normal HWID"); + TEST_EQ(strcmp(hwid, "Test HWID"), 0, " HWID correct"); + TEST_EQ(strlen(hwid) + 1, size, " HWID size consistent"); + TEST_EQ(strlen(hwid), strlen("Test HWID"), + " HWID size correct"); + } + + /* buffer size > HWID size */ + { + const char hwid_src[] = "Test HWID"; + reset_common_data(); + set_gbb_hwid(hwid_src, sizeof(hwid_src)); + size = sizeof(hwid_src) + 1; + TEST_SUCC(vb2api_gbb_read_hwid(&ctx, hwid, &size), + "read normal HWID"); + TEST_EQ(strcmp(hwid, "Test HWID"), 0, " HWID correct"); + TEST_EQ(strlen(hwid) + 1, size, " HWID size consistent"); + TEST_EQ(strlen(hwid), strlen("Test HWID"), + " HWID size correct"); + } + + /* HWID with garbage */ + { + const char hwid_src[] = "Test HWID\0garbagegarbage"; + reset_common_data(); + set_gbb_hwid(hwid_src, sizeof(hwid_src)); + size = VB2_GBB_HWID_MAX_SIZE; + TEST_SUCC(vb2api_gbb_read_hwid(&ctx, hwid, &size), + "read HWID with garbage"); + TEST_EQ(strcmp(hwid, "Test HWID"), 0, " HWID correct"); + TEST_EQ(strlen(hwid) + 1, size, " HWID size consistent"); + TEST_EQ(strlen(hwid), strlen("Test HWID"), + " HWID size correct"); + } +} + +int main(int argc, char* argv[]) +{ + key_tests(); + hwid_tests(); + + return gTestSuccess ? 0 : 255; +} diff --git a/tests/vb2_misc_tests.c b/tests/vb2_misc_tests.c index d36dd44f..3c262633 100644 --- a/tests/vb2_misc_tests.c +++ b/tests/vb2_misc_tests.c @@ -52,6 +52,10 @@ static void reset_common_data(void) }; /* Mocked functions */ +struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c) +{ + return &gbb; +} int vb2ex_read_resource(struct vb2_context *c, enum vb2_resource_index index, @@ -77,11 +81,6 @@ int vb2ex_tpm_clear_owner(struct vb2_context *c) } /* Tests */ -struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c) -{ - return &gbb; -} - static void init_context_tests(void) { /* Use our own context struct so we can re-init it */ diff --git a/tests/vboot_api_kernel5_tests.c b/tests/vboot_api_kernel5_tests.c index 42cc8e36..efaef8bd 100644 --- a/tests/vboot_api_kernel5_tests.c +++ b/tests/vboot_api_kernel5_tests.c @@ -34,6 +34,7 @@ static VbSelectAndLoadKernelParams kparams; static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data; static struct vb2_gbb_header gbb; +static struct vb2_packed_key mock_key; static uint8_t kernel_buffer[80000]; static int key_block_verify_fail; /* 0=ok, 1=sig, 2=hash */ @@ -58,7 +59,9 @@ static void ResetMocks(void) gbb.minor_version = VB2_GBB_MINOR_VER; gbb.flags = 0; gbb.rootkey_offset = sizeof(gbb); - gbb.rootkey_size = sizeof(VbPublicKey); + gbb.rootkey_size = sizeof(struct vb2_packed_key); + + memset(&mock_key, 0, sizeof(mock_key)); /* ctx.workbuf will be initialized by VbVerifyMemoryBootImage. */ memset(&ctx, 0, sizeof(ctx)); @@ -121,6 +124,24 @@ int vb2ex_read_resource(struct vb2_context *c, return VB2_SUCCESS; } +int vb2_gbb_read_root_key(struct vb2_context *c, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb) +{ + *keyp = &mock_key; + return VB2_SUCCESS; +} + +int vb2_gbb_read_recovery_key(struct vb2_context *c, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb) +{ + *keyp = &mock_key; + return VB2_SUCCESS; +} + int vb2_unpack_key_buffer(struct vb2_public_key *key, const uint8_t *buf, uint32_t size) diff --git a/tests/vboot_display_tests.c b/tests/vboot_display_tests.c index 3d65825e..c509e365 100644 --- a/tests/vboot_display_tests.c +++ b/tests/vboot_display_tests.c @@ -15,7 +15,6 @@ #include "2misc.h" #include "2nvstorage.h" #include "2struct.h" -#include "gbb_access.h" #include "host_common.h" #include "test_common.h" #include "vboot_common.h" @@ -25,11 +24,9 @@ /* Mock data */ static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data; -static char gbb_data[4096 + sizeof(struct vb2_gbb_header)]; -static struct vb2_gbb_header *gbb = (struct vb2_gbb_header *)gbb_data; static char debug_info[4096]; static struct vb2_context ctx; -struct vb2_shared_data *sd; +static struct vb2_shared_data *sd; static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]; static uint32_t mock_localization_count; static uint32_t mock_altfw_mask; @@ -37,30 +34,9 @@ static uint32_t mock_altfw_mask; /* Reset mock data (for use before each test) */ static void ResetMocks(void) { - int gbb_used; - - memset(gbb_data, 0, sizeof(gbb_data)); - gbb->major_version = VB2_GBB_MAJOR_VER; - gbb->minor_version = VB2_GBB_MINOR_VER; - gbb->flags = 0; - gbb_used = sizeof(struct vb2_gbb_header); - - gbb->hwid_offset = gbb_used; - strcpy(gbb_data + gbb->hwid_offset, "Test HWID"); - gbb->hwid_size = strlen(gbb_data + gbb->hwid_offset) + 1; - gbb_used = (gbb_used + gbb->hwid_size + 7) & ~7; - mock_localization_count = 3; mock_altfw_mask = 3 << 1; /* This mask selects 1 and 2 */ - gbb->header_size = sizeof(*gbb); - gbb->rootkey_offset = gbb_used; - gbb->rootkey_size = 64; - gbb_used += 64; - gbb->recovery_key_offset = gbb_used; - gbb->recovery_key_size = 64; - gbb_used += 64; - memset(&ctx, 0, sizeof(ctx)); ctx.workbuf = workbuf; ctx.workbuf_size = sizeof(workbuf); @@ -77,36 +53,6 @@ static void ResetMocks(void) } /* Mocks */ -struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c) -{ - return gbb; -} - -int vb2ex_read_resource(struct vb2_context *c, - enum vb2_resource_index index, - uint32_t offset, - void *buf, - uint32_t size) -{ - uint8_t *rptr; - uint32_t rsize; - - switch(index) { - case VB2_RES_GBB: - rptr = (uint8_t *)&gbb_data; - rsize = sizeof(gbb_data); - break; - default: - return VB2_ERROR_EX_READ_RESOURCE_INDEX; - } - - if (offset > rsize || offset + size > rsize) - return VB2_ERROR_EX_READ_RESOURCE_SIZE; - - memcpy(buf, rptr + offset, size); - return VB2_SUCCESS; -} - VbError_t VbExGetLocalizationCount(uint32_t *count) { if (mock_localization_count == 0xffffffff) @@ -130,37 +76,17 @@ VbError_t VbExDisplayDebugInfo(const char *info_str, int full_info) /* Test displaying debug info */ static void DebugInfoTest(void) { - char hwid[256]; int i; /* Recovery string should be non-null for any code */ for (i = 0; i < 0x100; i++) TEST_PTR_NEQ(RecoveryReasonString(i), NULL, "Non-null reason"); - /* HWID should come from the gbb */ - ResetMocks(); - VbGbbReadHWID(&ctx, hwid, sizeof(hwid)); - TEST_EQ(strcmp(hwid, "Test HWID"), 0, "HWID"); - - ResetMocks(); - gbb->hwid_size = 0; - VbGbbReadHWID(&ctx, hwid, sizeof(hwid)); - TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID missing"); - - ResetMocks(); - gbb->hwid_offset = sizeof(gbb_data) + 1; - VbGbbReadHWID(&ctx, hwid, sizeof(hwid)); - TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID past end"); - - ResetMocks(); - gbb->hwid_size = sizeof(gbb_data); - VbGbbReadHWID(&ctx, hwid, sizeof(hwid)); - TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID overflow"); - /* Display debug info */ ResetMocks(); - VbDisplayDebugInfo(&ctx); - TEST_NEQ(*debug_info, '\0', "Some debug info was displayed"); + TEST_SUCC(VbDisplayDebugInfo(&ctx), + "Display debug info"); + TEST_NEQ(*debug_info, '\0', " Some debug info was displayed"); } /* Test display key checking */ diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c index 1711ceed..1c7440cf 100644 --- a/tests/vboot_kernel_tests.c +++ b/tests/vboot_kernel_tests.c @@ -75,6 +75,7 @@ static GptHeader *mock_gpt_secondary = static uint8_t mock_digest[VB2_SHA256_DIGEST_SIZE] = {12, 34, 56, 78}; static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]; static struct vb2_context ctx; +static struct vb2_packed_key mock_key; /** * Prepare a valid GPT header that will pass CheckHeader() tests @@ -178,6 +179,8 @@ static void ResetMocks(void) ctx.workbuf_size = sizeof(workbuf); vb2_nv_init(&ctx); + memset(&mock_key, 0, sizeof(mock_key)); + struct vb2_shared_data *sd = vb2_get_sd(&ctx); sd->vbsd = shared; @@ -200,6 +203,24 @@ int vb2ex_read_resource(struct vb2_context *c, return VB2_SUCCESS; } +int vb2_gbb_read_root_key(struct vb2_context *c, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb) +{ + *keyp = &mock_key; + return VB2_SUCCESS; +} + +int vb2_gbb_read_recovery_key(struct vb2_context *c, + struct vb2_packed_key **keyp, + uint32_t *size, + struct vb2_workbuf *wb) +{ + *keyp = &mock_key; + return VB2_SUCCESS; +} + VbError_t VbExDiskRead(VbExDiskHandle_t h, uint64_t lba_start, uint64_t lba_count, void *buffer) { |