From 821004776ffbf2a7d0bc321bdf094cff13dfcc09 Mon Sep 17 00:00:00 2001 From: Wim Vervoorn Date: Mon, 27 Jan 2020 15:47:44 +0100 Subject: vendorcode/eltan/security: Switch to vb2 vboot library The eltan verified_boot is using the vboot 2.1 data structures and code, as well as the fwlib21 build target, they are all deprecated. Refer to CB:37654 for more information. The verified_boot code is updated to use the vb2 structures and code and make sure only public functions are used. BUG=N/A TEST=build Change-Id: I1e1a7bce6110fe35221a4d7a47c1eb7c7074c318 Signed-off-by: Wim Vervoorn Reviewed-on: https://review.coreboot.org/c/coreboot/+/38590 Tested-by: build bot (Jenkins) Reviewed-by: Frans Hendriks --- src/security/vboot/Kconfig | 1 - src/vendorcode/eltan/security/Makefile.inc | 1 - src/vendorcode/eltan/security/include/cb_sha.h | 26 ------- src/vendorcode/eltan/security/lib/Makefile.inc | 60 --------------- src/vendorcode/eltan/security/lib/cb_sha.c | 38 ---------- src/vendorcode/eltan/security/mboot/Kconfig | 1 + src/vendorcode/eltan/security/mboot/mboot.c | 4 +- src/vendorcode/eltan/security/mboot/mboot.h | 1 - .../eltan/security/verified_boot/Kconfig | 6 +- .../eltan/security/verified_boot/Makefile.inc | 1 + .../eltan/security/verified_boot/vboot_check.c | 87 +++++++++++++--------- .../eltan/security/verified_boot/vboot_check.h | 2 +- 12 files changed, 59 insertions(+), 169 deletions(-) delete mode 100644 src/vendorcode/eltan/security/include/cb_sha.h delete mode 100644 src/vendorcode/eltan/security/lib/Makefile.inc delete mode 100644 src/vendorcode/eltan/security/lib/cb_sha.c diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig index 30b99afc8f..ea70e65256 100644 --- a/src/security/vboot/Kconfig +++ b/src/security/vboot/Kconfig @@ -17,7 +17,6 @@ menu "Verified Boot (vboot)" config VBOOT_LIB bool - depends on !VENDORCODE_ELTAN_VBOOT && !VENDORCODE_ELTAN_MBOOT help Build and link the vboot library. Makes the vboot API accessible across all coreboot stages, without enabling vboot verification. For verification, diff --git a/src/vendorcode/eltan/security/Makefile.inc b/src/vendorcode/eltan/security/Makefile.inc index 16f17fddd7..c0d9057977 100644 --- a/src/vendorcode/eltan/security/Makefile.inc +++ b/src/vendorcode/eltan/security/Makefile.inc @@ -12,7 +12,6 @@ ## GNU General Public License for more details. ## -subdirs-y += lib subdirs-y += verified_boot subdirs-y += mboot diff --git a/src/vendorcode/eltan/security/include/cb_sha.h b/src/vendorcode/eltan/security/include/cb_sha.h deleted file mode 100644 index 9a231d8a1e..0000000000 --- a/src/vendorcode/eltan/security/include/cb_sha.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2018-2019, Eltan B.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __SECURITY_CB_SHA_H__ -#define __SECURITY_CB_SHA_H__ - -#include <2rsa.h> -#include -#include - -vb2_error_t cb_sha_little_endian(enum vb2_hash_algorithm hash_alg, const uint8_t *data, - uint32_t len, uint8_t *digest); - -#endif diff --git a/src/vendorcode/eltan/security/lib/Makefile.inc b/src/vendorcode/eltan/security/lib/Makefile.inc deleted file mode 100644 index 2e11fb5a00..0000000000 --- a/src/vendorcode/eltan/security/lib/Makefile.inc +++ /dev/null @@ -1,60 +0,0 @@ -# -# This file is part of the coreboot project. -# -# Copyright (C) 2018-2019 Eltan B.V. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# - -# call with $1 = stage name to create rules for building the library -# for the stage and adding it to the stage's set of object files. -define vendor-security-lib -VEN_SEC_LIB_$(1) = $(obj)/external/ven_sec_lib-$(1)/vboot_fw21.a -VEN_SEC_CFLAGS_$(1) += $$(patsubst -I%,-I$(top)/%,\ - $$(patsubst $(src)/%.h,$(top)/$(src)/%.h,\ - $$(filter-out -I$(obj), $$(CPPFLAGS_$(1))))) -VEN_SEC_CFLAGS_$(1) += $$(CFLAGS_$(1)) -VEN_SEC_CFLAGS_$(1) += $$($(1)-c-ccopts) -VEN_SEC_CFLAGS_$(1) += -I$(abspath $(obj)) -Wno-missing-prototypes - -$$(VEN_SEC_LIB_$(1)): $(obj)/config.h - printf " MAKE $(subst $(obj)/,,$(@))\n" - +FIRMWARE_ARCH=$$(ARCHDIR-$$(ARCH-$(1)-y)) \ - CC="$$(CC_$(1))" \ - CFLAGS="$$(VEN_SEC_CFLAGS_$(1))" VBOOT2="y" \ - $(MAKE) -C $(VBOOT_SOURCE) \ - BUILD=$$(abspath $$(dir $$(VEN_SEC_LIB_$(1)))) \ - V=$(V) \ - fwlib21 -endef # vendor-security-for-stage - -CFLAGS_common += -I3rdparty/vboot/firmware/2lib/include -CFLAGS_common += -I3rdparty/vboot/firmware/lib21/include - -ifneq ($(filter y,$(CONFIG_VENDORCODE_ELTAN_VBOOT) $(CONFIG_VENDORCODE_ELTAN_MBOOT)),) - -bootblock-y += cb_sha.c -bootblock-y += ../../../../security/vboot/vboot_logic.c -$(eval $(call vendor-security-lib,bootblock)) -bootblock-srcs += $(obj)/external/ven_sec_lib-bootblock/vboot_fw21.a - -postcar-y += cb_sha.c -$(eval $(call vendor-security-lib,postcar)) -postcar-srcs += $(obj)/external/ven_sec_lib-postcar/vboot_fw21.a - -ramstage-y += cb_sha.c -$(eval $(call vendor-security-lib,ramstage)) -ramstage-srcs += $(obj)/external/ven_sec_lib-ramstage/vboot_fw21.a - -romstage-y += cb_sha.c -$(eval $(call vendor-security-lib,romstage)) -romstage-srcs += $(obj)/external/ven_sec_lib-romstage/vboot_fw21.a - -endif \ No newline at end of file diff --git a/src/vendorcode/eltan/security/lib/cb_sha.c b/src/vendorcode/eltan/security/lib/cb_sha.c deleted file mode 100644 index 20a84afacc..0000000000 --- a/src/vendorcode/eltan/security/lib/cb_sha.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2019 Eltan B.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include - -vb2_error_t cb_sha_little_endian(enum vb2_hash_algorithm hash_alg, const uint8_t *data, - uint32_t len, uint8_t *digest) -{ - int i; - int rv; - uint32_t digest_size = vb2_digest_size(hash_alg); - uint8_t result[VB2_MAX_DIGEST_SIZE]; - - if (!digest_size) - return VB2_ERROR_SHA_INIT_ALGORITHM; - - rv = vb2_digest_buffer(data, len, hash_alg, (uint8_t *)&result, digest_size); - if (rv) - return rv; - - for (i = 0; i < digest_size; ++i) { - /* use little endian */ - digest[digest_size - i - 1] = result[i]; - } - return rv; -} diff --git a/src/vendorcode/eltan/security/mboot/Kconfig b/src/vendorcode/eltan/security/mboot/Kconfig index c4e8dbabee..b95c125578 100644 --- a/src/vendorcode/eltan/security/mboot/Kconfig +++ b/src/vendorcode/eltan/security/mboot/Kconfig @@ -17,6 +17,7 @@ menu "Measured Boot (mboot)" config VENDORCODE_ELTAN_MBOOT bool "Measure firmware with mboot." default n + select VBOOT_LIB help Enabling MBOOT will use mboot to measure the components of the firmware (stages, payload, etc). diff --git a/src/vendorcode/eltan/security/mboot/mboot.c b/src/vendorcode/eltan/security/mboot/mboot.c index c5523a5fd8..4429c1f5a0 100644 --- a/src/vendorcode/eltan/security/mboot/mboot.c +++ b/src/vendorcode/eltan/security/mboot/mboot.c @@ -142,8 +142,8 @@ int mboot_hash_extend_log(uint64_t flags, uint8_t *hashData, uint32_t hashDataLe /* The hash is provided as data */ memcpy(digest->digest.sha256, (void *)hashData, hashDataLen); } else { - if (cb_sha_little_endian(VB2_HASH_SHA256, hashData, hashDataLen, - digest->digest.sha256)) + if (vb2_digest_buffer(hashData, hashDataLen, VB2_HASH_SHA256, digest->digest.sha256, + VB2_SHA256_DIGEST_SIZE)) return TPM_E_IOERROR; } diff --git a/src/vendorcode/eltan/security/mboot/mboot.h b/src/vendorcode/eltan/security/mboot/mboot.h index 79f23087c2..9cb94b11df 100644 --- a/src/vendorcode/eltan/security/mboot/mboot.h +++ b/src/vendorcode/eltan/security/mboot/mboot.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/src/vendorcode/eltan/security/verified_boot/Kconfig b/src/vendorcode/eltan/security/verified_boot/Kconfig index ab254c48d9..d6ff541744 100644 --- a/src/vendorcode/eltan/security/verified_boot/Kconfig +++ b/src/vendorcode/eltan/security/verified_boot/Kconfig @@ -18,6 +18,7 @@ config VENDORCODE_ELTAN_VBOOT bool "Enable Verified Boot" depends on !VBOOT default n + select VBOOT_LIB config VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST bool "Enable Signed Manifest" @@ -57,11 +58,10 @@ config VENDORCODE_ELTAN_VBOOT_KEY_LOCATION config VENDORCODE_ELTAN_VBOOT_KEY_FILE string "Verified boot Key File" depends on VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST - default "3rdparty/eltan/verified_boot/Keys/key.vbpubk2" + default "3rdparty/eltan/verified_boot/Keys/key.vbpubk" config VENDORCODE_ELTAN_VBOOT_KEY_SIZE int - default 610 if VENDORCODE_ELTAN_VBOOT_USE_SHA512 - default 576 + default 552 endmenu # Verified Boot (verified_boot) diff --git a/src/vendorcode/eltan/security/verified_boot/Makefile.inc b/src/vendorcode/eltan/security/verified_boot/Makefile.inc index 97d8f81c91..827535b963 100644 --- a/src/vendorcode/eltan/security/verified_boot/Makefile.inc +++ b/src/vendorcode/eltan/security/verified_boot/Makefile.inc @@ -17,6 +17,7 @@ ifneq ($(filter y,$(CONFIG_VENDORCODE_ELTAN_VBOOT) $(CONFIG_VENDORCODE_ELTAN_MBO CPPFLAGS_common += -I$(src)/security/vboot +bootblock-y += ../../../../security/vboot/vboot_logic.c bootblock-y += vboot_check.c postcar-y += vboot_check.c romstage-y += vboot_check.c diff --git a/src/vendorcode/eltan/security/verified_boot/vboot_check.c b/src/vendorcode/eltan/security/verified_boot/vboot_check.c index 461a847b71..2edd8f9a74 100644 --- a/src/vendorcode/eltan/security/verified_boot/vboot_check.c +++ b/src/vendorcode/eltan/security/verified_boot/vboot_check.c @@ -13,6 +13,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + +#define NEED_VB20_INTERNALS + #include #include #include @@ -32,12 +35,17 @@ int verified_boot_check_manifest(void) { uint8_t *buffer; - uint8_t sig_buffer[1024]; /* used to build vb21_signature */ - size_t size = 0; - struct vb2_public_key key; - struct vb2_workbuf wb; - struct vb21_signature *vb2_sig_hdr = (struct vb21_signature *)sig_buffer; - uint8_t wb_buffer[1024]; + struct vb2_context *ctx; + struct vb2_kernel_preamble *pre; + static struct vb2_shared_data *sd; + size_t size; + uint8_t wb_buffer[2800]; + + if (vb2api_init(&wb_buffer, sizeof(wb_buffer), &ctx)) { + goto fail; + } + + sd = vb2_get_sd(ctx); buffer = cbfs_boot_map_with_leak(RSA_PUBLICKEY_FILE_NAME, CBFS_TYPE_RAW, &size); if (!buffer || !size) { @@ -46,48 +54,61 @@ int verified_boot_check_manifest(void) } if ((size != CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) || - (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) { + (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) { printk(BIOS_ERR, "ERROR: Illegal public key!\n"); goto fail; } - if (vb21_unpack_key(&key, buffer, size)) { - printk(BIOS_ERR, "ERROR: Invalid public key!\n"); + /* + * Check if all items will fit into workbuffer: + * vb2_shared data, Public Key, Preamble data + */ + if ((sd->workbuf_used + size + sizeof(struct vb2_kernel_preamble) + + ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) > + sizeof(wb_buffer)) { + printk(BIOS_ERR, "ERROR: Work buffer too small\n"); goto fail; } + /* Add public key */ + sd->data_key_offset = sd->workbuf_used; + sd->data_key_size = size; + sd->workbuf_used += sd->data_key_size; + memcpy((void *)((void *)sd + (long)sd->data_key_offset), (uint8_t *)buffer, size); + + /* Fill preamble area */ + sd->preamble_size = sizeof(struct vb2_kernel_preamble); + sd->preamble_offset = sd->data_key_offset + sd->data_key_size; + sd->workbuf_used += sd->preamble_size; + pre = (struct vb2_kernel_preamble *)((void *)sd + (long)sd->preamble_offset); + + pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO; + + /* Fill body_signature (vb2_structure). RSA2048 key is used */ cbfs_boot_map_with_leak("oemmanifest.bin", CBFS_TYPE_RAW, &size); - if (size != (CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + - vb2_rsa_sig_size(VB2_SIG_RSA2048)) { + if (size != ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) { printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n"); goto fail; } - - /* prepare work buffer structure */ - wb.buf = (uint8_t *)&wb_buffer; - wb.size = sizeof(wb_buffer); - - /* Build vb2_sig_hdr buffer */ - vb2_sig_hdr->sig_offset = sizeof(struct vb21_signature) + - (CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE); - vb2_sig_hdr->sig_alg = VB2_SIG_RSA2048; - vb2_sig_hdr->sig_size = vb2_rsa_sig_size(VB2_SIG_RSA2048); - vb2_sig_hdr->hash_alg = HASH_ALG; - vb2_sig_hdr->data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE; - memcpy(&sig_buffer[sizeof(struct vb21_signature)], + pre->body_signature.data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * + DIGEST_SIZE; + pre->body_signature.sig_offset = sizeof(struct vb2_signature) + + pre->body_signature.data_size; + pre->body_signature.sig_size = size - pre->body_signature.data_size; + sd->workbuf_used += size; + memcpy((void *)((void *)&pre->body_signature + (long)sizeof(struct vb2_signature)), (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, size); - if (vb21_verify_data(&sig_buffer[sizeof(struct vb21_signature)], vb2_sig_hdr->data_size, - (struct vb21_signature *)&sig_buffer, &key, &wb)) { - printk(BIOS_ERR, "ERROR: Signature verification failed for hash table\n"); + + if (vb2api_verify_kernel_data(ctx, (void *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, + pre->body_signature.data_size)) goto fail; - } printk(BIOS_INFO, "%s: Successfully verified hash_table signature.\n", __func__); return 0; fail: - die("HASH table verification failed!\n"); + die("ERROR: HASH table verification failed!\n"); return -1; } @@ -131,20 +152,14 @@ static void verified_boot_check_buffer(const char *name, void *start, size_t siz uint32_t hash_index, int32_t pcr) { uint8_t digest[DIGEST_SIZE]; - int hash_algorithm; vb2_error_t status; printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name, start, (int)size); if (start && size) { - if (CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)) - hash_algorithm = VB2_HASH_SHA512; - else - hash_algorithm = VB2_HASH_SHA256; - status = cb_sha_little_endian(hash_algorithm, (const uint8_t *)start, size, - digest); + status = vb2_digest_buffer((const uint8_t *)start, size, HASH_ALG, digest, DIGEST_SIZE); if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC + sizeof(digest) * hash_index), digest, sizeof(digest))) || status) { diff --git a/src/vendorcode/eltan/security/verified_boot/vboot_check.h b/src/vendorcode/eltan/security/verified_boot/vboot_check.h index bd284925ae..d4f3b5ef9c 100644 --- a/src/vendorcode/eltan/security/verified_boot/vboot_check.h +++ b/src/vendorcode/eltan/security/verified_boot/vboot_check.h @@ -23,7 +23,7 @@ #include #include CONFIG_VENDORCODE_ELTAN_VBOOT_MANIFEST #include -#include +#include #include #include #include -- cgit v1.2.3