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 <wvervoorn@eltan.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38590
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Frans Hendriks <fhendriks@eltan.com>
diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig
index 30b99af..ea70e65 100644
--- a/src/security/vboot/Kconfig
+++ b/src/security/vboot/Kconfig
@@ -17,7 +17,6 @@
 
 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 16f17fd..c0d9057 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 9a231d8..0000000
--- 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 <vb21_common.h>
-#include <vb2_api.h>
-
-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 2e11fb5..0000000
--- 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 20a84af..0000000
--- 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 <cb_sha.h>
-
-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 c4e8dba..b95c125 100644
--- a/src/vendorcode/eltan/security/mboot/Kconfig
+++ b/src/vendorcode/eltan/security/mboot/Kconfig
@@ -17,6 +17,7 @@
 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 c5523a5..4429c1f 100644
--- a/src/vendorcode/eltan/security/mboot/mboot.c
+++ b/src/vendorcode/eltan/security/mboot/mboot.c
@@ -142,8 +142,8 @@
 		/* 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 79f2308..9cb94b1 100644
--- a/src/vendorcode/eltan/security/mboot/mboot.h
+++ b/src/vendorcode/eltan/security/mboot/mboot.h
@@ -20,7 +20,6 @@
 #include <arch/io.h>
 #include <arch/acpi.h>
 #include <string.h>
-#include <cb_sha.h>
 #include <console/console.h>
 #include <cbfs.h>
 #include <lib.h>
diff --git a/src/vendorcode/eltan/security/verified_boot/Kconfig b/src/vendorcode/eltan/security/verified_boot/Kconfig
index ab254c4..d6ff541 100644
--- a/src/vendorcode/eltan/security/verified_boot/Kconfig
+++ b/src/vendorcode/eltan/security/verified_boot/Kconfig
@@ -18,6 +18,7 @@
 	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_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 97d8f81..827535b 100644
--- a/src/vendorcode/eltan/security/verified_boot/Makefile.inc
+++ b/src/vendorcode/eltan/security/verified_boot/Makefile.inc
@@ -17,6 +17,7 @@
 
 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 461a847..2edd8f9 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 <boot_device.h>
 #include <bootmem.h>
 #include <cbfs.h>
@@ -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 @@
 	}
 
 	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 @@
 				       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 bd28492..d4f3b5e 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 <lib.h>
 #include CONFIG_VENDORCODE_ELTAN_VBOOT_MANIFEST
 #include <console/console.h>
-#include <cb_sha.h>
+#include <vb2_sha.h>
 #include <string.h>
 #include <program_loading.h>
 #include <mboot.h>