diff options
author | Joel Kitching <kitching@google.com> | 2019-08-28 17:45:05 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-09-23 17:54:09 +0000 |
commit | 967ba853d88b7803c73f3adb94b8717d001a077b (patch) | |
tree | 2ce2dc70ead38a5f687f2c5b822a2d19d38469f2 /firmware/2lib/include | |
parent | aaf394335cc4e287a1ffb6332311559b2b29c41f (diff) | |
download | vboot-967ba853d88b7803c73f3adb94b8717d001a077b.tar.gz |
vboot/secdata: implement vboot2 FWMP support
Implement FWMP support in vboot2. Currently, the data structure
is just accessed directly, checking to see whether its `flags`
member contains particular flags. We'd like to change this to
follow the same scheme as secdata_firmware and secdata_kernel.
This CL also updates some functions, comments, and tests related
to secdata_firmware and secdata_kernel to ensure consistency
between code for the secdata spaces.
BUG=b:124141368, chromium:972956
TEST=make clean && make runtests
BRANCH=none
Change-Id: Ia0d67532cc6e077e170ffb25d0bc587b1d53edf3
Signed-off-by: Joel Kitching <kitching@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1773088
Reviewed-by: Joel Kitching <kitching@chromium.org>
Tested-by: Joel Kitching <kitching@chromium.org>
Commit-Queue: Joel Kitching <kitching@chromium.org>
Diffstat (limited to 'firmware/2lib/include')
-rw-r--r-- | firmware/2lib/include/2api.h | 70 | ||||
-rw-r--r-- | firmware/2lib/include/2constants.h | 2 | ||||
-rw-r--r-- | firmware/2lib/include/2misc.h | 2 | ||||
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 12 | ||||
-rw-r--r-- | firmware/2lib/include/2secdata.h | 85 | ||||
-rw-r--r-- | firmware/2lib/include/2struct.h | 3 |
6 files changed, 156 insertions, 18 deletions
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index 24d85da0..9a8a2228 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -185,6 +185,15 @@ enum vb2_context_flags { * support. */ VB2_CONTEXT_DISPLAY_INIT = (1 << 20), + + /* + * Caller may set this before running vb2api_kernel_phase1. It means + * that there is no FWMP on this system, and thus default values should + * be used instead. + * + * Caller should *not* set this when FWMP is available but invalid. + */ + VB2_CONTEXT_NO_SECDATA_FWMP = (1 << 21), }; /* @@ -213,18 +222,19 @@ struct vb2_context { /* * Non-volatile data. Caller must fill this from some non-volatile - * location. If the VB2_CONTEXT_NVDATA_CHANGED flag is set when a - * vb2api function returns, caller must save the data back to the - * non-volatile location and then clear the flag. + * location before calling vb2api_fw_phase1. If the + * VB2_CONTEXT_NVDATA_CHANGED flag is set when a vb2api function + * returns, caller must save the data back to the non-volatile location + * and then clear the flag. */ uint8_t nvdata[VB2_NVDATA_SIZE_V2]; /* * Secure data for firmware verification stage. Caller must fill this - * from some secure non-volatile location. If the - * VB2_CONTEXT_SECDATA_CHANGED flag is set when a function returns, - * caller must save the data back to the secure non-volatile location - * and then clear the flag. + * from some secure non-volatile location before calling + * vb2api_fw_phase1. If the VB2_CONTEXT_SECDATA_CHANGED flag is set + * when a function returns, caller must save the data back to the + * secure non-volatile location and then clear the flag. */ uint8_t secdata_firmware[VB2_SECDATA_FIRMWARE_SIZE]; @@ -254,12 +264,24 @@ struct vb2_context { /* * Secure data for kernel verification stage. Caller must fill this - * from some secure non-volatile location. If the - * VB2_CONTEXT_SECDATA_KERNEL_CHANGED flag is set when a function + * from some secure non-volatile location before calling + * vb2api_kernel_phase1. If the VB2_CONTEXT_SECDATA_KERNEL_CHANGED + * flag is set when a function returns, caller must save the data back + * to the secure non-volatile location and then clear the flag. + */ + uint8_t secdata_kernel[VB2_SECDATA_KERNEL_SIZE]; + + /* + * Firmware management parameters (FWMP) secure data. Caller must fill + * this from some secure non-volatile location before calling + * vb2api_kernel_phase1. Since FWMP is a variable-size space, caller + * should initially fill in VB2_SECDATA_FWMP_MIN_SIZE bytes, and call + * vb2_secdata_fwmp_check() to see whether more should be read. If the + * VB2_CONTEXT_SECDATA_FWMP_CHANGED flag is set when a function * returns, caller must save the data back to the secure non-volatile * location and then clear the flag. */ - uint8_t secdata_kernel[VB2_SECDATA_KERNEL_SIZE]; + uint8_t secdata_fwmp[VB2_SECDATA_FWMP_MAX_SIZE]; }; /* Resource index for vb2ex_read_resource() */ @@ -404,7 +426,7 @@ enum vb2_pcr_digest { */ /** - * Check the validity of the firmware secure storage context. + * Check the validity of firmware secure storage context. * * Checks version and CRC. * @@ -414,7 +436,7 @@ enum vb2_pcr_digest { vb2_error_t vb2api_secdata_firmware_check(struct vb2_context *ctx); /** - * Create fresh data in the firmware secure storage context. + * Create fresh data in firmware secure storage context. * * Use this only when initializing the secure storage context on a new machine * the first time it boots. Do NOT simply use this if @@ -422,12 +444,12 @@ vb2_error_t vb2api_secdata_firmware_check(struct vb2_context *ctx); * that could allow the secure data to be rolled back to an insecure state. * * @param ctx Context pointer - * @return VB2_SUCCESS, or non-zero error code if error. + * @return size of created firmware secure storage data in bytes */ -vb2_error_t vb2api_secdata_firmware_create(struct vb2_context *ctx); +uint32_t vb2api_secdata_firmware_create(struct vb2_context *ctx); /** - * Check the validity of the kernel secure storage context. + * Check the validity of kernel secure storage context. * * Checks version, UID, and CRC. * @@ -437,7 +459,7 @@ vb2_error_t vb2api_secdata_firmware_create(struct vb2_context *ctx); vb2_error_t vb2api_secdata_kernel_check(struct vb2_context *ctx); /** - * Create fresh data in the kernel secure storage context. + * Create fresh data in kernel secure storage context. * * Use this only when initializing the secure storage context on a new machine * the first time it boots. Do NOT simply use this if @@ -445,9 +467,23 @@ vb2_error_t vb2api_secdata_kernel_check(struct vb2_context *ctx); * could allow the secure data to be rolled back to an insecure state. * * @param ctx Context pointer + * @return size of created kernel secure storage data in bytes + */ +uint32_t vb2api_secdata_kernel_create(struct vb2_context *ctx); + +/** + * Check the validity of firmware management parameters (FWMP) space. + * + * Checks size, version, and CRC. If the struct size is larger than the size + * passed in, the size pointer is set to the expected full size of the struct, + * and VB2_ERROR_SECDATA_FWMP_INCOMPLETE is returned. The caller should + * re-read the returned number of bytes, and call this function again. + * + * @param ctx Context pointer + * @param size Amount of struct which has been read * @return VB2_SUCCESS, or non-zero error code if error. */ -vb2_error_t vb2api_secdata_kernel_create(struct vb2_context *ctx); +vb2_error_t vb2api_secdata_fwmp_check(struct vb2_context *ctx, uint8_t *size); /** * Report firmware failure to vboot. diff --git a/firmware/2lib/include/2constants.h b/firmware/2lib/include/2constants.h index f8d0d317..3f80b9ae 100644 --- a/firmware/2lib/include/2constants.h +++ b/firmware/2lib/include/2constants.h @@ -24,6 +24,8 @@ /* Size of secure data spaces used by vboot */ #define VB2_SECDATA_FIRMWARE_SIZE 10 #define VB2_SECDATA_KERNEL_SIZE 13 +#define VB2_SECDATA_FWMP_MIN_SIZE 40 +#define VB2_SECDATA_FWMP_MAX_SIZE 64 /* TODO(chromium:972956): Remove once coreboot is using updated names */ #define VB2_SECDATA_SIZE 10 diff --git a/firmware/2lib/include/2misc.h b/firmware/2lib/include/2misc.h index c7970d68..b03df5f3 100644 --- a/firmware/2lib/include/2misc.h +++ b/firmware/2lib/include/2misc.h @@ -117,7 +117,7 @@ void vb2_check_recovery(struct vb2_context *ctx); * @param ctx Vboot context * @return VB2_SUCCESS, or error code on error. */ -vb2_error_t vb2_fw_parse_gbb(struct vb2_context *ctx); +vb2_error_t vb2_fw_init_gbb(struct vb2_context *ctx); /** * Check developer switch position. diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index 865ea7cf..bc612344 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -197,6 +197,18 @@ enum vb2_return_code { /* Called vb2_secdata_kernel_set() with uninitialized secdata_kernel */ VB2_ERROR_SECDATA_KERNEL_SET_UNINITIALIZED, + /* Bad size in vb2api_secdata_fwmp_check() */ + VB2_ERROR_SECDATA_FWMP_SIZE, + + /* Incomplete structure in vb2api_secdata_fwmp_check() */ + VB2_ERROR_SECDATA_FWMP_INCOMPLETE, + + /* Bad CRC in vb2api_secdata_fwmp_check() */ + VB2_ERROR_SECDATA_FWMP_CRC, + + /* Bad struct version in vb2_secdata_fwmp_check() */ + VB2_ERROR_SECDATA_FWMP_VERSION, + /********************************************************************** * Common code errors */ diff --git a/firmware/2lib/include/2secdata.h b/firmware/2lib/include/2secdata.h index 0bbce4f3..4e6fdda2 100644 --- a/firmware/2lib/include/2secdata.h +++ b/firmware/2lib/include/2secdata.h @@ -89,6 +89,44 @@ enum vb2_secdata_kernel_param { }; /*****************************************************************************/ +/* Firmware management parameters (FWMP) space */ + +#define VB2_SECDATA_FWMP_VERSION 0x10 /* 1.0 */ +#define VB2_SECDATA_FWMP_HASH_SIZE 32 /* enough for SHA-256 */ + +/* Flags for FWMP space */ +enum vb2_secdata_fwmp_flags { + VB2_SECDATA_FWMP_DEV_DISABLE_BOOT = (1 << 0), + VB2_SECDATA_FWMP_DEV_DISABLE_RECOVERY = (1 << 1), + VB2_SECDATA_FWMP_DEV_ENABLE_USB = (1 << 2), + VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY = (1 << 3), + VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY = (1 << 4), + VB2_SECDATA_FWMP_DEV_USE_KEY_HASH = (1 << 5), + /* CCD = case-closed debugging on cr50; flag implemented on cr50 */ + VB2_SECDATA_FWMP_DEV_DISABLE_CCD_UNLOCK = (1 << 6), +}; + +struct vb2_secdata_fwmp { + /* CRC-8 of fields following struct_size */ + uint8_t crc8; + + /* Structure size in bytes */ + uint8_t struct_size; + + /* Structure version (4 bits major, 4 bits minor) */ + uint8_t struct_version; + + /* Reserved; ignored by current reader */ + uint8_t reserved0; + + /* Flags; see enum vb2_secdata_fwmp_flags */ + uint32_t flags; + + /* Hash of developer kernel key */ + uint8_t dev_key_hash[VB2_SECDATA_FWMP_HASH_SIZE]; +}; + +/*****************************************************************************/ /* Firmware secure storage space functions */ /** @@ -166,4 +204,51 @@ vb2_error_t vb2_secdata_kernel_set(struct vb2_context *ctx, enum vb2_secdata_kernel_param param, uint32_t value); +/*****************************************************************************/ +/* Firmware management parameters (FWMP) space functions */ + +/** + * Generate CRC for FWMP secure storage space. + * + * Calculate CRC hash from struct_version onward. Should not be used; + * prototype only in header for use by unittests. + * + * In valid FWMP data, this CRC value should match the crc8 field. + * + * @param sec Pointer to FWMP struct + * @return 32-bit CRC hash of FWMP data + */ +uint32_t vb2_secdata_fwmp_crc(struct vb2_secdata_fwmp *sec); + +/** + * Initialize FWMP secure storage context and verify its CRC. + * + * This must be called before vb2_secdata_fwmp_get_flag/get_dev_key_hash(). + * + * @param ctx Context pointer + * @return VB2_SUCCESS, or non-zero error code if error. + */ +vb2_error_t vb2_secdata_fwmp_init(struct vb2_context *ctx); + +/** + * Read a FWMP secure storage flag value. + * + * It is unsupported to call before successfully running vb2_secdata_fwmp_init. + * In this case, vboot will fail and exit. + * + * @param ctx Context pointer + * @param flag Flag to read + * @return current flag value (0 or 1) + */ +int vb2_secdata_fwmp_get_flag(struct vb2_context *ctx, + enum vb2_secdata_fwmp_flags flag); + +/** + * Return a pointer to FWMP dev key hash. + * + * @param ctx Context pointer + * @return uint8_t pointer to dev_key_hash field + */ +uint8_t *vb2_secdata_fwmp_get_dev_key_hash(struct vb2_context *ctx); + #endif /* VBOOT_REFERENCE_2SECDATA_H_ */ diff --git a/firmware/2lib/include/2struct.h b/firmware/2lib/include/2struct.h index 4aff7ca7..52d905ae 100644 --- a/firmware/2lib/include/2struct.h +++ b/firmware/2lib/include/2struct.h @@ -79,6 +79,9 @@ enum vb2_shared_data_status { /* Secure data kernel version space initialized */ VB2_SD_STATUS_SECDATA_KERNEL_INIT = (1 << 4), + + /* FWMP secure data initialized */ + VB2_SD_STATUS_SECDATA_FWMP_INIT = (1 << 5), }; /* "V2SD" = vb2_shared_data.magic */ |