[coreboot-gerrit] Change in ...coreboot[master]: security{tpm, verified_boot, mboot}:Add measured and verified boot.
Frans Hendriks (Code Review)
gerrit at coreboot.org
Fri Dec 14 12:27:00 CET 2018
Frans Hendriks has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/30218
Change subject: security{tpm,verified_boot,mboot}:Add measured and verified boot.
......................................................................
security{tpm,verified_boot,mboot}:Add measured and verified boot.
coreboot supports verfied boot based on ChromeOS verified boot.
No verified boot support without dependency on ChromeOS is available.
Create measured boot (security/mboot) and verified_boot
(security/verified_boot) directories. These features use the security/lib
which is a 'wrapper' using only sha1, sha256 and sha512 of
3rdparty/vboot/firmware.
prog_locate_hook() is added and used to start verified boot.
At board level can be specified with parts of SPI must be verified and/or
measured.
BUG=N/A
TEST=Created verified binary and verify logging on Portwell PQ-M107
Change-Id: Ic1d5a21d40b6a31886777e8e9fe7b28c860f1a80
Signed-off-by: Frans Hendriks <fhendriks at eltan.com>
---
M src/device/pci_device.c
M src/include/program_loading.h
M src/lib/prog_loaders.c
M src/security/Kconfig
M src/security/Makefile.inc
A src/security/include/cb_sha1.h
A src/security/include/cb_sha256.h
A src/security/include/cb_sha512.h
A src/security/include/cryptolib.h
A src/security/lib/Makefile.inc
A src/security/lib/cb_sha1.c
A src/security/lib/cb_sha256.c
A src/security/lib/cb_sha512.c
A src/security/mboot/Kconfig
A src/security/mboot/Makefile.inc
A src/security/mboot/mboot.c
A src/security/mboot/mboot.h
M src/security/tpm/tss.h
M src/security/tpm/tss/tcg-2.0/tss.c
M src/security/tpm/tss/tcg-2.0/tss_marshaling.c
M src/security/tpm/tss/tcg-2.0/tss_structures.h
A src/security/verified_boot/Kconfig
A src/security/verified_boot/Makefile.inc
A src/security/verified_boot/vboot_check.c
A src/security/verified_boot/vboot_check.h
25 files changed, 2,109 insertions(+), 21 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/30218/1
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index e35c22c..3e6316a 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -16,6 +16,7 @@
* Copyright (C) 2005-2009 coresystems GmbH
* (Written by Stefan Reinauer <stepan at coresystems.de> for coresystems GmbH)
* Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 2018 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
@@ -802,6 +803,11 @@
if (!should_run_oprom(dev))
return;
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT)
+ if (!verified_boot_should_run_oprom(rom))
+ return;
+#endif
+
run_bios(dev, (unsigned long)ram);
gfx_set_init_done(1);
printk(BIOS_DEBUG, "VGA Option ROM was run\n");
diff --git a/src/include/program_loading.h b/src/include/program_loading.h
index 468f0b3..a382daf 100644
--- a/src/include/program_loading.h
+++ b/src/include/program_loading.h
@@ -3,6 +3,7 @@
*
* Copyright 2015 Google Inc.
* Copyright (C) 2014 Imagination Technologies
+ * Copyright (C) 2018 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
@@ -136,6 +137,7 @@
/* Locate the identified program to run. Return 0 on success. < 0 on error. */
int prog_locate(struct prog *prog);
+int prog_locate_hook(struct prog *prog);
/* Run the program described by prog. */
void prog_run(struct prog *prog);
diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c
index a9c9add..1d18b7a 100644
--- a/src/lib/prog_loaders.c
+++ b/src/lib/prog_loaders.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright 2015 Google Inc.
+ * Copyright (C) 2018 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
@@ -39,6 +40,9 @@
{
struct cbfsf file;
+ if (prog_locate_hook(prog))
+ return -1;
+
cbfs_prepare_program_locate();
if (cbfs_boot_locate(&file, prog_name(prog), NULL))
@@ -74,6 +78,7 @@
halt();
}
+int __weak prog_locate_hook(struct prog *prog) {return 0;}
void __weak stage_cache_add(int stage_id,
const struct prog *stage) {}
void __weak stage_cache_load_stage(int stage_id,
diff --git a/src/security/Kconfig b/src/security/Kconfig
index 6a334ac..24d5e34 100644
--- a/src/security/Kconfig
+++ b/src/security/Kconfig
@@ -1,6 +1,7 @@
## This file is part of the coreboot project.
##
## Copyright (C) 2017 Facebook Inc.
+## Copyright (C) 2018 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
@@ -12,5 +13,7 @@
## GNU General Public License for more details.
##
-source "src/security/vboot/Kconfig"
+source "src/security/mboot/Kconfig"
source "src/security/tpm/Kconfig"
+source "src/security/vboot/Kconfig"
+source "src/security/verified_boot/Kconfig"
diff --git a/src/security/Makefile.inc b/src/security/Makefile.inc
index a940b82..d325265 100644
--- a/src/security/Makefile.inc
+++ b/src/security/Makefile.inc
@@ -1,2 +1,29 @@
-subdirs-y += vboot
+## This file is part of the coreboot project.
+##
+## Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+## Copyright (C) 2017 Facebook Inc.
+## Copyright (C) 2018 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.
+##
+
+subdirs-y += lib
+subdirs-$(CONFIG_MBOOT) += mboot
subdirs-y += tpm
+subdirs-y += vboot
+subdirs-$(CONFIG_VERIFIED_BOOT) += verified_boot
+
+ifeq ($(CONFIG_TPM2),y)
+CPPFLAGS_common += -I$(src)/security/include
+else
+ifeq ($(CONFIG_MBOOT),y)
+CPPFLAGS_common += -I$(src)/security/include
+endif
+endif
diff --git a/src/security/include/cb_sha1.h b/src/security/include/cb_sha1.h
new file mode 100644
index 0000000..3b72355
--- /dev/null
+++ b/src/security/include/cb_sha1.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018. 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_SHA1_H__
+#define __SECURITY_SHA1_H__
+
+uint8_t *cb_sha1(const uint8_t *data, uint64_t len, uint8_t *digest);
+
+#endif
diff --git a/src/security/include/cb_sha256.h b/src/security/include/cb_sha256.h
new file mode 100644
index 0000000..89e98c7
--- /dev/null
+++ b/src/security/include/cb_sha256.h
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018. 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_SHA256_H__
+#define __SECURITY_SHA256_H__
+
+uint8_t* cb_sha256(const uint8_t *data, uint64_t len, uint8_t *digest);
+uint8_t* cb_sha256_ex(const uint8_t *data, uint64_t len, uint8_t *digest,
+ bool endian);
+
+#endif
diff --git a/src/security/include/cb_sha512.h b/src/security/include/cb_sha512.h
new file mode 100644
index 0000000..fa04f8a1
--- /dev/null
+++ b/src/security/include/cb_sha512.h
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018. 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_SHA512_H__
+#define __SECURITY_SHA512_H__
+
+uint8_t* cb_sha512(const uint8_t *data, uint64_t len, uint8_t *digest);
+uint8_t* cb_sha512_ex(const uint8_t *data, uint64_t len, uint8_t *digest,
+ bool endian);
+
+#endif
diff --git a/src/security/include/cryptolib.h b/src/security/include/cryptolib.h
new file mode 100644
index 0000000..21eb188
--- /dev/null
+++ b/src/security/include/cryptolib.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018. 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_CRYPTOLIB_H__
+#define __SECURITY_CRYPTOLIB_H__
+
+#define NEED_VB2_SHA_LIBRARY
+
+#include <2rsa.h>
+#include <vb21_common.h>
+#include <vb2_api.h>
+
+#include "cb_sha1.h"
+#include "cb_sha512.h"
+#include "cb_sha256.h"
+
+#endif
diff --git a/src/security/lib/Makefile.inc b/src/security/lib/Makefile.inc
new file mode 100644
index 0000000..c6c0fc0
--- /dev/null
+++ b/src/security/lib/Makefile.inc
@@ -0,0 +1,53 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2015 - 2016 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2017 - 2018 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.
+#
+
+SECURITYLIB_INCLUDES = -I3rdparty/vboot/firmware/2lib/include -I3rdparty/vboot/firmware/lib21/include
+
+CPPFLAGS_common+=$(SECURITYLIB_INCLUDES)
+
+ifeq ($(CONFIG_VERIFIED_BOOT),y)
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += ../../../3rdparty/vboot/firmware/2lib/2common.c
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += ../../../3rdparty/vboot/firmware/2lib/2rsa.c
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += ../../../3rdparty/vboot/firmware/2lib/2sha_utility.c
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += ../../../3rdparty/vboot/firmware/lib21/packed_key.c
+ifeq ($(CONFIG_VERIFIED_BOOT_USE_SHA512),y)
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += cb_sha512.c
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += ../../../3rdparty/vboot/firmware/2lib/2sha512.c
+else
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += cb_sha256.c
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += ../../../3rdparty/vboot/firmware/2lib/2sha256.c
+endif
+endif
+
+ifeq ($(CONFIG_MBOOT),y)
+ramstage-y += ../../../3rdparty/vboot/firmware/2lib/2sha1.c
+ramstage-y += ../../../3rdparty/vboot/firmware/2lib/2sha512.c
+ramstage-y += ../../../3rdparty/vboot/firmware/2lib/2sha256.c
+ramstage-y += cb_sha1.c
+ramstage-y += cb_sha512.c
+ramstage-y += cb_sha256.c
+
+romstage-y += ../../../3rdparty/vboot/firmware/2lib/2common.c
+romstage-y += ../../../3rdparty/vboot/firmware/2lib/2rsa.c
+romstage-y += ../../../3rdparty/vboot/firmware/2lib/2sha1.c
+romstage-y += ../../../3rdparty/vboot/firmware/2lib/2sha256.c
+romstage-y += ../../../3rdparty/vboot/firmware/2lib/2sha512.c
+romstage-y += ../../../3rdparty/vboot/firmware/2lib/2sha_utility.c
+romstage-y += ../../../3rdparty/vboot/firmware/lib21/packed_key.c
+romstage-y += cb_sha1.c
+romstage-y += cb_sha512.c
+romstage-y += cb_sha256.c
+endif
diff --git a/src/security/lib/cb_sha1.c b/src/security/lib/cb_sha1.c
new file mode 100644
index 0000000..cc9e176
--- /dev/null
+++ b/src/security/lib/cb_sha1.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 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 <security/include/cryptolib.h>
+
+uint8_t *cb_sha1(const uint8_t* data, uint64_t len, uint8_t* digest)
+{
+ struct vb2_sha1_context ctx;
+
+ vb2_sha1_init(&ctx);
+ vb2_sha1_update(&ctx, data, len);
+ vb2_sha1_finalize(&ctx, digest);
+
+ return digest;
+}
diff --git a/src/security/lib/cb_sha256.c b/src/security/lib/cb_sha256.c
new file mode 100644
index 0000000..082947b
--- /dev/null
+++ b/src/security/lib/cb_sha256.c
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 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 <security/include/cryptolib.h>
+
+uint8_t* cb_sha256_ex(const uint8_t* data, uint64_t len, uint8_t* digest,
+ bool endian)
+{
+ int i;
+ const uint8_t* input_ptr;
+ uint8_t result[VB2_SHA256_DIGEST_SIZE];
+ uint8_t *result_ptr;
+ uint64_t remaining_len;
+ struct vb2_sha256_context ctx;
+
+ vb2_sha256_init(&ctx);
+
+ input_ptr = data;
+ remaining_len = len;
+
+ /* Process data in at most UINT32_MAX byte chunks at a time. */
+ while (remaining_len) {
+ uint32_t block_size;
+ block_size = (uint32_t) ((remaining_len >= UINT32_MAX) ?
+ UINT32_MAX : remaining_len);
+ vb2_sha256_update(&ctx, input_ptr, block_size);
+ remaining_len -= block_size;
+ input_ptr += block_size;
+ }
+
+ result_ptr = result;
+ vb2_sha256_finalize(&ctx, result_ptr);
+ for (i = 0; i < VB2_SHA256_DIGEST_SIZE; ++i) {
+ if (endian) {
+ /* use big endian here */
+ digest[i] = *result_ptr++;
+ } else {
+ /* use little endian here */
+ digest[VB2_SHA256_DIGEST_SIZE - i - 1] = *result_ptr++;
+ }
+ }
+ return digest;
+}
+
+uint8_t* cb_sha256(const uint8_t* data, uint64_t len, uint8_t* digest)
+{
+ /* Returned the little endian SHA256 digest */
+ return cb_sha256_ex(data, len, digest, 0);
+}
diff --git a/src/security/lib/cb_sha512.c b/src/security/lib/cb_sha512.c
new file mode 100644
index 0000000..0d6e6eb
--- /dev/null
+++ b/src/security/lib/cb_sha512.c
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 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 <security/include/cryptolib.h>
+
+uint8_t* cb_sha512_ex(const uint8_t* data, uint64_t len, uint8_t* digest,
+ bool endian)
+{
+ int i;
+ const uint8_t* input_ptr;
+ uint8_t result[VB2_SHA512_DIGEST_SIZE];
+ uint8_t *result_ptr;
+ uint64_t remaining_len;
+ struct vb2_sha512_context ctx;
+
+ vb2_sha512_init(&ctx);
+
+ input_ptr = data;
+ remaining_len = len;
+
+ /* Process data in at most UINT32_MAX byte chunks at a time. */
+ while (remaining_len) {
+ uint32_t block_size;
+ block_size = (uint32_t) ((remaining_len >= UINT32_MAX) ?
+ UINT32_MAX : remaining_len);
+ vb2_sha512_update(&ctx, input_ptr, block_size);
+ remaining_len -= block_size;
+ input_ptr += block_size;
+ }
+
+ result_ptr = result;
+ vb2_sha512_finalize(&ctx, result_ptr);
+ for (i = 0; i < VB2_SHA512_DIGEST_SIZE; ++i) {
+ if (endian) {
+ /* use big endian here */
+ digest[i] = *result_ptr++;
+ } else {
+ /* use little endian here */
+ digest[VB2_SHA512_DIGEST_SIZE - i - 1] = *result_ptr++;
+ }
+ }
+ return digest;
+}
+
+uint8_t* cb_sha512(const uint8_t* data, uint64_t len, uint8_t* digest)
+{
+ /* Returned the little endian SHA512 digest */
+ return cb_sha512_ex(data, len, digest, 0);
+}
diff --git a/src/security/mboot/Kconfig b/src/security/mboot/Kconfig
new file mode 100644
index 0000000..b262f6d
--- /dev/null
+++ b/src/security/mboot/Kconfig
@@ -0,0 +1,43 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2018 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.
+##
+
+menu "Measured Boot (mboot)"
+
+config MBOOT
+ bool "Measure firmware with mboot."
+ default n
+ help
+ Enabling MBOOT will use mboot to measure the components of the firmware
+ (stages, payload, etc).
+
+config CRTM_VERSION_STRING
+ string "default CRTM version"
+ default "default CRTM version"
+
+config MBOOT_UEFI_SUPPORT
+ bool "Enable mboot UEFI support"
+ default n
+ depends on MBOOT
+ help
+ Add some specific items for UEFI support (not implemented yet)
+
+config MBOOT_EVENTLOG
+ bool "Enable mboot eventlog"
+ default n
+ default y if MBOOT_UEFI_SUPPORT
+ depends on MBOOT
+ help
+ Not only extend the PCRS but also log the events (not implemented yet)
+
+endmenu # Measured Boot (mboot)
diff --git a/src/security/mboot/Makefile.inc b/src/security/mboot/Makefile.inc
new file mode 100644
index 0000000..619b477
--- /dev/null
+++ b/src/security/mboot/Makefile.inc
@@ -0,0 +1,23 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2018 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.
+##
+
+ifeq ($(CONFIG_MBOOT),y)
+
+CPPFLAGS_common += -I$(src)/security/mboot
+
+romstage-y += mboot.c
+ramstage-y += mboot.c
+
+endif # CONFIG_MBOOT
diff --git a/src/security/mboot/mboot.c b/src/security/mboot/mboot.c
new file mode 100644
index 0000000..6ed7999
--- /dev/null
+++ b/src/security/mboot/mboot.c
@@ -0,0 +1,591 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corporation
+ * Copyright (C) 2018 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 <mboot.h>
+#include <assert.h>
+#include <build.h>
+#include <vb2_api.h>
+
+/*
+ * Get the list of currently active PCR banks in TPM.
+ *
+ * @retval A map of active PCR banks.
+ */
+EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void)
+{
+ int status;
+ TPML_PCR_SELECTION Pcrs;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP tpmHashAlgorithmBitmap = 0;
+ uint32_t activePcrBanks = 0;
+ uint32_t index;
+
+ status = tpm2_get_capability_pcrs(&Pcrs);
+ if (status != TPM_SUCCESS) {
+ tpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;
+ activePcrBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;
+ } else {
+ for (index = 0; index < Pcrs.count; index++) {
+ switch (Pcrs.pcrSelections[index].hash) {
+ case TPM_ALG_SHA1:
+ tpmHashAlgorithmBitmap |=
+ EFI_TCG2_BOOT_HASH_ALG_SHA1;
+ if (!is_zero_buffer(
+ Pcrs.pcrSelections[index].pcrSelect,
+ Pcrs.pcrSelections[index].sizeofSelect))
+ activePcrBanks |=
+ EFI_TCG2_BOOT_HASH_ALG_SHA1;
+ break;
+ case TPM_ALG_SHA256:
+ tpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256;
+ if (!is_zero_buffer(
+ Pcrs.pcrSelections[index].pcrSelect,
+ Pcrs.pcrSelections[index].sizeofSelect))
+ activePcrBanks |=
+ EFI_TCG2_BOOT_HASH_ALG_SHA256;
+ break;
+ case TPM_ALG_SHA384:
+ case TPM_ALG_SHA512:
+ case TPM_ALG_SM3_256:
+ default:
+ printk(BIOS_DEBUG, "%s: unsupported algorithm "
+ "reported - 0x%x\n", __FUNCTION__,
+ Pcrs.pcrSelections[index].hash);
+ break;
+ }
+ }
+ }
+ printk(BIOS_DEBUG, "Tcg2 Capability values from TPM\n");
+ printk(BIOS_DEBUG, "tpmHashAlgorithmBitmap - 0x%08x\n",
+ tpmHashAlgorithmBitmap);
+ printk(BIOS_DEBUG, "activePcrBanks - 0x%08x\n",
+ activePcrBanks);
+
+ return activePcrBanks;
+}
+
+/*
+ * tpm2_get_capability_pcrs
+ *
+ * Return the TPM PCR information.
+ *
+ * This function parses the data got from tlcl_getcapability and returns the
+ * PcrSelection.
+ *
+ * @param[out] Pcrs The Pcr Selection
+ *
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR The command was unsuccessful.
+ */
+int tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs)
+{
+ TPMS_CAPABILITY_DATA TpmCap;
+ TPMI_YES_NO MoreData;
+ int status;
+ int index;
+
+ status = tlcl_getcapability(TPM_CAP_PCRS, 0, 1, &MoreData, &TpmCap);
+ if (status == TPM_SUCCESS) {
+ Pcrs->count = TpmCap.data.assignedPCR.count;
+ printk(BIOS_DEBUG, "Pcrs->count = %d\n", Pcrs->count);
+ for (index = 0; index < Pcrs->count; index++) {
+ Pcrs->pcrSelections[index].hash =
+ swab16(TpmCap.data.assignedPCR.pcrSelections[index].hash);
+ printk(BIOS_DEBUG, "Pcrs->pcrSelections[index].hash = 0x%x\n",
+ Pcrs->pcrSelections[index].hash);
+ Pcrs->pcrSelections[index].sizeofSelect =
+ TpmCap.data.assignedPCR.pcrSelections[index].sizeofSelect;
+ memcpy(Pcrs->pcrSelections[index].pcrSelect,
+ TpmCap.data.assignedPCR.pcrSelections[index].pcrSelect,
+ Pcrs->pcrSelections[index].sizeofSelect);
+ }
+ }
+ return status;
+}
+
+/*
+ * mboot_hash_extend_log
+ *
+ * Calculates the hash over the data and extends it in active PCR banks and
+ * then logs them in the event log.
+ *
+ * @param[in] activePcr bitmap of active PCR banks in TPM.
+ * @param[in] flags flags associated with hash data. Currently unused.
+ * @param[in] hashData data to be hashed.
+ * @param[in] hashDataLen length of the data to be hashed.
+ * @param[in] newEventHdr event header in TCG_PCR_EVENT2 format.
+ * @param[in] eventLog description of the event.
+ * @param[in] invalid invalidate the pcr
+ *
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR Unexpected device behavior.
+ */
+int mboot_hash_extend_log(EFI_TCG2_EVENT_ALGORITHM_BITMAP activePcr,
+ uint64_t flags, uint8_t *hashData, uint32_t hashDataLen,
+ TCG_PCR_EVENT2_HDR *newEventHdr, uint8_t *eventLog, uint8_t invalid)
+{
+ int status;
+ TPMT_HA *digest = NULL;
+ int digest_num = 0;
+
+ printk(BIOS_DEBUG, "%s: Hash Data Length: %zu bytes\n", __FUNCTION__,
+ (size_t)hashDataLen);
+
+ if (invalid){
+ digest = &(newEventHdr->digest.digests[digest_num]);
+ digest->digest.invalidate_pcrs = 1;
+ digest->hashAlg = TPM_ALG_ERROR;
+ digest_num++;
+ } else {
+ /*
+ * Generate SHA1 hash if SHA1 PCR bank is active in TPM
+ * currently
+ */
+ if (activePcr & EFI_TCG2_BOOT_HASH_ALG_SHA1) {
+ digest = &(newEventHdr->digest.digests[digest_num]);
+ if (flags & MBOOT_HASH_PROVIDED) {
+ /* The hash is provided as data */
+ memcpy(digest->digest.sha1, (void *)hashData,
+ SHA1_DIGEST_SIZE);
+ } else {
+ cb_sha1((const uint8_t *)hashData, hashDataLen,
+ digest->digest.sha1);
+ }
+
+ digest->hashAlg = TPM_ALG_SHA1;
+ digest_num++;
+
+ printk(BIOS_DEBUG, "%s: SHA1 Hash Digest:\n", __FUNCTION__);
+ mboot_print_buffer (digest->digest.sha1, SHA1_DIGEST_SIZE);
+ }
+
+ /*
+ * Generate SHA256 hash if SHA256 PCR bank is active in TPM
+ * currently
+ */
+ if (activePcr & EFI_TCG2_BOOT_HASH_ALG_SHA256) {
+ digest = &(newEventHdr->digest.digests[digest_num]);
+ if (flags & MBOOT_HASH_PROVIDED) {
+ /* The hash is provided as data */
+ memcpy(digest->digest.sha256,
+ (void *)hashData, hashDataLen);
+ } else {
+ cb_sha256(hashData, hashDataLen, digest->digest.sha256);
+ }
+ digest->hashAlg = TPM_ALG_SHA256;
+ digest_num++;
+
+ printk(BIOS_DEBUG, "%s: SHA256 Hash Digest:\n", __FUNCTION__);
+ mboot_print_buffer(digest->digest.sha256, SHA256_DIGEST_SIZE);
+ }
+ }
+
+ newEventHdr->digest.count = digest_num;
+
+ status = tlcl_extend_ex(
+ newEventHdr->pcrIndex,
+ &(newEventHdr->digest)
+ );
+
+#if IS_ENABLED(CONFIG_MBOOT_EVENTLOG)
+ /* Perform the logging of the measurement */
+ if (status == TPM_SUCCESS) {
+ status = log_event_tcg_20_format(newEventHdr, eventLog);
+ /* If SHA1 PCR bank is active, log the event in TCG 1.2 format tool */
+ if (activePcr & EFI_TCG2_BOOT_HASH_ALG_SHA1)
+ status = log_event_tcg_12_format(newEventHdr, eventLog);
+ }
+#endif
+
+ if (status != TPM_SUCCESS)
+ printk(BIOS_DEBUG, "%s: returned 0x%x\n", __FUNCTION__, status);
+
+ return status;
+}
+
+/*
+ * invalidate_pcrs
+ *
+ * Invalidate PCRs 0-7 with extending 1 after tpm failure.
+ */
+void invalidate_pcrs(void)
+{
+ int status, pcr;
+ TCG_PCR_EVENT2_HDR tcgEventHdr;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrs;
+ uint8_t invalidate;
+
+ ActivePcrs = tpm2_get_active_pcrs();
+ invalidate = 1;
+
+ for (pcr=0; pcr < 8; pcr++) {
+ printk(BIOS_DEBUG, "%s: Invalidating PCR %d\n", __FUNCTION__, pcr);
+ memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
+ tcgEventHdr.pcrIndex = pcr;
+ tcgEventHdr.eventType = EV_NO_ACTION;
+ tcgEventHdr.eventSize = (uint32_t) sizeof(invalidate);
+
+ status = mboot_hash_extend_log(ActivePcrs, 0,
+ (uint8_t *)&invalidate, tcgEventHdr.eventSize,
+ &tcgEventHdr, (uint8_t *)"Invalidate PCR", invalidate);
+
+ if (status != TPM_SUCCESS)
+ printk(BIOS_DEBUG, "%s: invalidating pcr %d returned"
+ " 0x%x\n", __FUNCTION__, pcr, status);
+ }
+}
+
+/*
+ * is_zero_buffer
+ *
+ * Check if buffer is all zero.
+ *
+ * @param[in] buffer Buffer to be checked.
+ * @param[in] size Size of buffer to be checked.
+ *
+ * @retval TRUE buffer is all zero.
+ * @retval FALSE buffer is not all zero.
+ */
+int is_zero_buffer(void *buffer, unsigned int size)
+{
+ uint8_t *ptr;
+
+ ptr = buffer;
+ while (size--) {
+ if (*(ptr++) != 0)
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Prints command or response buffer for debugging purposes.
+ *
+ * @param[in] Buffer Buffer to print.
+ * @param[in] BufferSize Buffer data length.
+ *
+ * @retval None
+ */
+void mboot_print_buffer(uint8_t *buffer, uint32_t bufferSize)
+{
+ uint32_t index;
+
+ printk(BIOS_DEBUG, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n",
+ (unsigned int)*buffer, bufferSize);
+ for (index = 0; index < bufferSize; index++) {
+ printk(BIOS_DEBUG, "%02x ", *(buffer + index));
+ if ((index+1) % 16 == 0)
+ printk(BIOS_DEBUG, "\n");
+ }
+ printk(BIOS_DEBUG, "\n");
+}
+
+/*
+ * measures and logs the specified cbfs file.
+ *
+ * @param[in] activePcr bitmap of active PCR banks in TPM.
+ * @param[in] name name of the cbfs file to measure
+ * @param[in] type data type of the cbfs file.
+ * @param[in] pcr pcr to extend.
+ * @param[in] evenType tcg event type.
+ * @param[in] event_msg description of the event.
+ *
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR Unexpected device behavior.
+ */
+int mb_measure_log_worker(EFI_TCG2_EVENT_ALGORITHM_BITMAP activePcr,
+ const char *name, uint32_t type, uint32_t pcr,
+ TCG_EVENTTYPE eventType, const char *event_msg)
+{
+ int status;
+ TCG_PCR_EVENT2_HDR tcgEventHdr;
+ uint8_t *base;
+ size_t size;
+
+ printk(BIOS_DEBUG, "%s: Measure %s\n", __FUNCTION__, name);
+ base = cbfs_boot_map_with_leak(name, type, &size);
+
+ if (base == NULL) {
+ printk(BIOS_DEBUG, "%s: CBFS locate fail: %s\n", __FUNCTION__,
+ name);
+ return VB2_ERROR_READ_FILE_OPEN;
+ } else {
+ printk(BIOS_DEBUG, "%s: CBFS locate success: %s\n",
+ __FUNCTION__, name);
+ }
+ memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
+ tcgEventHdr.pcrIndex = pcr;
+ tcgEventHdr.eventType = eventType;
+ if (event_msg)
+ tcgEventHdr.eventSize = (uint32_t) strlen(event_msg);
+
+ status = mboot_hash_extend_log(activePcr, 0, base, size, &tcgEventHdr,
+ (uint8_t *)event_msg, 0);
+ return status;
+}
+
+#ifdef __PRE_RAM__
+/*
+ * Called from early romstage
+ *
+ *mb_entry
+ *
+ * initializes measured boot mechanism, initializes the
+ * tpm library and starts the tpm called by mb_measure
+ *
+ * The function can be overridden at the mainboard level my simply creating a
+ * function with the same name there.
+ *
+ * @param[in] wake_from_s3 1 if we are waking from S3, 0 standard boot
+ *
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR Unexpected device behavior.
+**/
+
+int __attribute__((weak)) mb_entry(int wake_from_s3)
+{
+ int status;
+
+ /* Initialize TPM driver. */
+ printk(BIOS_DEBUG, "%s: tlcl_lib_init\n", __FUNCTION__);
+ if (tlcl_lib_init() != VB2_SUCCESS) {
+ printk(BIOS_ERR, "%s: TPM driver initialization failed.\n",
+ __FUNCTION__);
+ return TPM_E_IOERROR;
+ }
+
+ if (wake_from_s3) {
+ printk(BIOS_DEBUG, "%s: tlcl_resume\n", __FUNCTION__);
+ status = tlcl_resume();
+ } else {
+ printk(BIOS_DEBUG, "%s: tlcl_startup\n", __FUNCTION__);
+ status = tlcl_startup();
+ }
+
+ if (status)
+ printk(BIOS_ERR, "%s: StartUp failed 0x%x!\n", __FUNCTION__,
+ status);
+
+ return status;
+}
+
+/*
+ *
+ * mb_measure
+ *
+ * initial call to the measured boot mechanism, initializes the
+ * tpm library, starts the tpm and performs the measurements defined by
+ * the coreboot platform.
+ *
+ * The pcrs will be invalidated if the measurement fails
+ *
+ * The function can be overridden at the mainboard level my simply creating a
+ * function with the same name there.
+ *
+ * @param[in] wake_from_s3 1 if we are waking from S3, 0 standard boot
+ *
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR Unexpected device behavior.
+ */
+
+int __attribute__((weak))mb_measure(int wake_from_s3)
+{
+ uint32_t status;
+
+ status = mb_entry(wake_from_s3);
+ if (status == TPM_SUCCESS) {
+ printk(BIOS_DEBUG, "%s: StartUp, successful!\n", __FUNCTION__);
+ status = mb_measure_log_start();
+ if (status == TPM_SUCCESS) {
+ printk(BIOS_DEBUG, "%s: Measuring, successful!\n",
+ __FUNCTION__);
+ } else {
+ invalidate_pcrs();
+ printk(BIOS_ERR, "%s: Measuring returned 0x%x "
+ "unsuccessful! PCRs invalidated.\n",
+ __FUNCTION__, status);
+ }
+ } else {
+ invalidate_pcrs();
+ printk(BIOS_ERR, "%s: StartUp returned 0x%x, unsuccessful!"
+ "PCRs invalidated.\n", __FUNCTION__, status);
+ }
+ return status;
+}
+
+/*
+ *
+ * mb_measure_log_start
+ *
+ * performs the measurements defined by the the board routines.
+ *
+ * The logging is defined by the mb_log_list structure and mb_log_list_count.
+ *
+ * These items need to be defined in the mainboard part of the mboot
+ * implementation
+ *
+ * The function can be overridden at the mainboard level my simply creating a
+ * function with the same name there.
+ *
+ * @param[in] none
+ *
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR Unexpected device behavior.
+ */
+int __attribute__((weak))mb_measure_log_start(void)
+{
+ int status;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrs;
+ uint32_t i;
+
+ ActivePcrs = tpm2_get_active_pcrs();
+
+ if (ActivePcrs == 0x0) {
+ printk(BIOS_DEBUG, "%s: No Active PCR Bank in TPM.\n",
+ __FUNCTION__);
+ return TPM_E_IOERROR;
+ }
+
+#if IS_ENABLED(CONFIG_MBOOT_UEFI_SUPPORT)
+ status = log_efi_specid_event(ActivePcrs);
+
+ if (status != TPM_SUCCESS) {
+ printk(BIOS_DEBUG, "%s: Fail! Specification ID version event"
+ "can't be logged. ABORTING!!!\n", __FUNCTION__);
+ return status;
+ }
+#endif
+ status = mb_crtm(ActivePcrs);
+ if (status == TPM_SUCCESS) {
+ printk(BIOS_DEBUG, "%s: Success! CRTM Version measured.\n",
+ __FUNCTION__);
+ } else {
+ printk(BIOS_DEBUG, "%s: Fail! CRTM Version can't be measured."
+ " ABORTING!!!\n", __FUNCTION__);
+ return status;
+ }
+
+ /* Log the items defined by the mainboard */
+ for (i = 0; i < mb_log_list_count; i++) {
+ status = mb_measure_log_worker(
+ ActivePcrs, mb_log_list[i].cbfs_name,
+ mb_log_list[i].cbfs_type, mb_log_list[i].pcr,
+ mb_log_list[i].eventType,
+ mb_log_list[i].event_msg);
+ if (status == TPM_SUCCESS)
+ {
+ printk(BIOS_DEBUG, "%s: Success! %s measured to pcr"
+ "%d.\n", __FUNCTION__, mb_log_list[i].cbfs_name,
+ mb_log_list[i].pcr);
+ } else {
+ printk(BIOS_DEBUG, "%s: Fail! %s can't be measured."
+ "ABORTING!!!\n", __FUNCTION__,
+ mb_log_list[i].cbfs_name);
+ return status;
+ }
+ }
+ return status;
+}
+
+static const uint8_t crtm_version[] = CONFIG_CRTM_VERSION_STRING \
+ COREBOOT_VERSION COREBOOT_EXTRA_VERSION " " COREBOOT_BUILD;
+
+#if IS_ENABLED(CONFIG_MBOOT_EVENTLOG)
+static const uint8_t me_message[] = "HASH RETURNED BY ME";
+#endif
+
+/*
+ *
+ * mb_crtm
+ *
+ * measures the crtm version. this consists of a string than can be
+ * defined using make menuconfig and automatically generated version
+ * information.
+ *
+ * The function can be overridden at the mainboard level my simply creating a
+ * function with the same name there.
+ *
+ * @param[in] activePcr bitmap of the support
+ *
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR Unexpected device behavior.
+**/
+int __attribute__((weak))mb_crtm(EFI_TCG2_EVENT_ALGORITHM_BITMAP activePcr)
+{
+ int status;
+ TCG_PCR_EVENT2_HDR tcgEventHdr;
+ uint8_t hash[SHA256_DIGEST_SIZE];
+
+ /* Use FirmwareVersion string to represent CRTM version. */
+ printk(BIOS_DEBUG, "%s: Measure CRTM Version\n", __FUNCTION__);
+ memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
+ tcgEventHdr.pcrIndex = MBOOT_PCR_INDEX_0;
+ tcgEventHdr.eventType = EV_S_CRTM_VERSION;
+ tcgEventHdr.eventSize = sizeof(crtm_version);
+ printk(BIOS_DEBUG, "%s: EventSize - %u\n", __FUNCTION__,
+ tcgEventHdr.eventSize);
+
+ status = mboot_hash_extend_log(activePcr, 0, (uint8_t *)crtm_version,
+ tcgEventHdr.eventSize, &tcgEventHdr, (uint8_t *) crtm_version,
+ 0);
+
+ if (status) {
+ printk(BIOS_DEBUG, "Measure CRTM Version returned 0x%x\n",
+ status);
+ goto mb_crtm_end;
+ }
+
+ status = get_intel_me_hash(hash);
+
+ if (status) {
+ printk(BIOS_DEBUG, "get_intel_me_hash returned 0x%x\n", status);
+ status = TPM_E_IOERROR;
+ goto mb_crtm_end;
+ }
+
+ /* Add the me hash */
+ printk(BIOS_DEBUG, "%s: Add the hash returned by the ME\n",
+ __FUNCTION__);
+ memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
+ tcgEventHdr.pcrIndex = MBOOT_PCR_INDEX_0;
+ tcgEventHdr.eventType = EV_S_CRTM_CONTENTS;
+
+#if IS_ENABLED(CONFIG_MBOOT_EVENTLOG)
+ tcgEventHdr.eventSize = sizeof(me_message);
+ printk(BIOS_DEBUG, "%s: EventSize - %u\n", __FUNCTION__,
+ tcgEventHdr.eventSize);
+#else
+ tcgEventHdr.eventSize = 0;
+#endif
+
+ status = mboot_hash_extend_log(activePcr, MBOOT_HASH_PROVIDED, hash,
+ sizeof(hash), &tcgEventHdr,
+#if IS_ENABLED(CONFIG_MBOOT_EVENTLOG)
+ (uint8_t *) me_message,
+#else
+ NULL,
+#endif
+ 0);
+
+ if (status)
+ printk(BIOS_DEBUG, "Add ME hash returned 0x%x\n", status);
+
+mb_crtm_end:
+ if (status)
+ printk(BIOS_DEBUG, "%s: returned 0x%x\n", __FUNCTION__, status);
+
+ return status;
+}
+#endif // __PRE_RAM__
diff --git a/src/security/mboot/mboot.h b/src/security/mboot/mboot.h
new file mode 100644
index 0000000..1449e4e
--- /dev/null
+++ b/src/security/mboot/mboot.h
@@ -0,0 +1,135 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corporation
+ * Copyright (C) 2018 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 MBOOT_H
+#define MBOOT_H
+
+#include <arch/io.h>
+#include <arch/acpi.h>
+#include <string.h>
+#include <console/console.h>
+#include <security/include/cryptolib.h>
+#include <cbfs.h>
+#include <lib.h>
+#include <boot/coreboot_tables.h>
+#include <security/tpm/tss/tcg-2.0/tss_structures.h>
+#include <security/tpm/tss.h>
+
+/* TPM2 interface */
+#define EFI_TPM2_ACPI_TABLE_START_METHOD_TIS 6
+#define TPM_SHA1_160_HASH_LEN 0x14
+
+/* Part 2, section 5.4: TPM_DIGEST */
+typedef struct tdTPM_DIGEST{
+ int8_t digest[TPM_SHA1_160_HASH_LEN];
+} TPM_DIGEST;
+
+/* Index to a PCR register */
+typedef uint32_t TPM_PCRINDEX;
+typedef uint32_t TCG_EVENTTYPE;
+typedef TPM_PCRINDEX TCG_PCRINDEX;
+typedef TPM_DIGEST TCG_DIGEST;
+
+/* TCG_PCR_EVENT_HDR */
+typedef struct tdTCG_PCR_EVENT_HDR {
+ TCG_PCRINDEX pcrIndex;
+ TCG_EVENTTYPE eventType;
+ TCG_DIGEST digest;
+ uint32_t eventSize;
+} __packed TCG_PCR_EVENT_HDR;
+
+/* TCG_PCR_EVENT2_HDR */
+typedef struct tdTCG_PCR_EVENT2_HDR {
+ TCG_PCRINDEX pcrIndex;
+ TCG_EVENTTYPE eventType;
+ TPML_DIGEST_VALUES digest;
+ uint32_t eventSize;
+} __packed TCG_PCR_EVENT2_HDR;
+
+typedef uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP;
+
+#define EFI_TCG2_BOOT_HASH_ALG_SHA1 0x00000001
+#define EFI_TCG2_BOOT_HASH_ALG_SHA256 0x00000002
+#define EFI_TCG2_BOOT_HASH_ALG_SHA384 0x00000004
+#define EFI_TCG2_BOOT_HASH_ALG_SHA512 0x00000008
+#define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x00000010
+
+/* Standard event types */
+#define EV_POST_CODE ((TCG_EVENTTYPE) 0x00000001)
+#define EV_NO_ACTION ((TCG_EVENTTYPE) 0x00000003)
+#define EV_SEPARATOR ((TCG_EVENTTYPE) 0x00000004)
+#define EV_S_CRTM_CONTENTS ((TCG_EVENTTYPE) 0x00000007)
+#define EV_S_CRTM_VERSION ((TCG_EVENTTYPE) 0x00000008)
+#define EV_CPU_MICROCODE ((TCG_EVENTTYPE) 0x00000009)
+#define EV_TABLE_OF_DEVICES ((TCG_EVENTTYPE) 0x0000000B)
+
+#define MBOOT_PCR_INDEX_0 0x0
+#define MBOOT_PCR_INDEX_1 0x1
+#define MBOOT_PCR_INDEX_2 0x2
+#define MBOOT_PCR_INDEX_3 0x3
+#define MBOOT_PCR_INDEX_4 0x4
+#define MBOOT_PCR_INDEX_5 0x5
+#define MBOOT_PCR_INDEX_6 0x6
+#define MBOOT_PCR_INDEX_7 0x7
+
+/*
+ * used to indicate a hash is provide so there is no need to perform the
+ * measurement
+ */
+#define MBOOT_HASH_PROVIDED (0x00000001)
+
+
+int is_zero_buffer(void *, unsigned int);
+
+int mboot_hash_extend_log(EFI_TCG2_EVENT_ALGORITHM_BITMAP activePcr,
+ uint64_t flags, uint8_t *hashData, uint32_t hashDataLen,
+ TCG_PCR_EVENT2_HDR *newEventHdr, uint8_t *eventLog, uint8_t invalid);
+
+void mboot_print_buffer(uint8_t *buffer, uint32_t bufferSize);
+
+int mb_crtm(EFI_TCG2_EVENT_ALGORITHM_BITMAP activePcr);
+
+typedef struct {
+ const char *cbfs_name;
+ uint32_t cbfs_type;
+ uint32_t pcr;
+ TCG_EVENTTYPE eventType;
+ const char *event_msg;
+} mboot_measure_item_t;
+
+int mb_measure_log_worker(EFI_TCG2_EVENT_ALGORITHM_BITMAP activePcr,
+ const char *name, uint32_t type, uint32_t pcr,
+ TCG_EVENTTYPE eventType, const char *event_msg);
+
+int mb_measure_log_start(void);
+void invalidate_pcrs(void);
+
+EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void);
+
+int tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs);
+
+extern const mboot_measure_item_t mb_log_list[];
+extern const uint32_t mb_log_list_count;
+
+int mb_measure(int wake_from_s3);
+int mb_entry(int wake_from_s3);
+
+int log_event_tcg_20_format(TCG_PCR_EVENT2_HDR *, uint8_t *);
+int log_event_tcg_12_format(TCG_PCR_EVENT2_HDR *, uint8_t *);
+
+int get_intel_me_hash(uint8_t *hash);
+
+#endif /* MBOOT_H */
diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h
index c4f2608..79596e5 100644
--- a/src/security/tpm/tss.h
+++ b/src/security/tpm/tss.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Copyright (C) 2018 Eltan B.V.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -121,6 +122,37 @@
*/
uint32_t tlcl_continue_self_test(void);
+#if IS_ENABLED(CONFIG_TPM2)
+
+/**
+ * Issue tpm get capability command
+ */
+uint32_t tlcl_getcapability(TPM_CAP Capability, uint32_t Property,
+ uint32_t PropertyCount, TPMI_YES_NO *MoreData,
+ TPMS_CAPABILITY_DATA *CapabilityData );
+
+/**
+ * Issue more flexible process command
+ */
+void *tpm_process_command_ex(TPM_CC command, void *command_body,
+ size_t command_size, size_t *response_size, bool marshal);
+
+/*
+ * tlcl_extend command that allows more digests to be passed in at the same
+ * time
+ */
+uint32_t tlcl_extend_ex(int pcr_num, const TPML_DIGEST_VALUES *in_digests);
+
+/**
+ * Return size of digest.
+ *
+ * @param[in] HashAlgo Hash algorithm
+ *
+ * @return size of digest
+ */
+uint16_t tlcl_get_hash_size_from_algo(TPMI_ALG_HASH hashAlgo);
+#endif
+
/**
* Write [length] bytes of [data] to space at [index]. The TPM error code is
* returned.
@@ -144,7 +176,7 @@
uint32_t tlcl_physical_presence_cmd_enable(void);
/**
- * Finalize the physical presence settings: sofware PP is enabled, hardware PP
+ * Finalize the physical presence settings: software PP is enabled, hardware PP
* is disabled, and the lifetime lock is set. The TPM error code is returned.
*/
uint32_t tlcl_finalize_physical_presence(void);
diff --git a/src/security/tpm/tss/tcg-2.0/tss.c b/src/security/tpm/tss/tcg-2.0/tss.c
index e579bff..21619ec 100644
--- a/src/security/tpm/tss/tcg-2.0/tss.c
+++ b/src/security/tpm/tss/tcg-2.0/tss.c
@@ -1,5 +1,6 @@
/*
* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Copyright 2017-2018 Eltan B.V.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -15,6 +16,12 @@
#include "tss_structures.h"
#include "tss_marshaling.h"
+static INTERNAL_HASH_INFO mHashInfo[] = {
+ {TPM_ALG_ERROR, 1},
+ {TPM_ALG_SHA1, SHA1_DIGEST_SIZE},
+ {TPM_ALG_SHA256, SHA256_DIGEST_SIZE},
+};
+
/*
* This file provides interface between firmware and TPM2 device. The TPM1.2
* API was copied as is and relevant functions modified to comply with the
@@ -53,6 +60,49 @@
return tpm_unmarshal_response(command, &ib);
}
+void *tpm_process_command_ex(TPM_CC command, void *command_body,
+ size_t command_size, size_t *response_size, bool marshal)
+{
+ struct obuf ob;
+ struct ibuf ib;
+ size_t out_size;
+ size_t in_size;
+ const uint8_t *sendb;
+ /* Command/response buffer. */
+ static uint8_t cr_buffer[TPM_BUFFER_SIZE] CAR_GLOBAL;
+
+ uint8_t *cr_buffer_ptr = car_get_var_ptr(cr_buffer);
+
+ if (marshal) {
+ obuf_init(&ob, cr_buffer_ptr, sizeof(cr_buffer));
+ if (tpm_marshal_command(command, command_body, &ob) < 0) {
+ printk(BIOS_ERR, "command %#x\n", command);
+ return NULL;
+ }
+ sendb = obuf_contents(&ob, &out_size);
+ } else {
+
+ sendb = command_body;
+ out_size = command_size;
+ }
+
+ in_size = sizeof(cr_buffer);
+ if (tis_sendrecv(sendb, out_size, cr_buffer_ptr, &in_size)) {
+ printk(BIOS_ERR, "tpm transaction failed\n");
+ return NULL;
+ }
+
+ ibuf_init(&ib, cr_buffer_ptr, in_size);
+
+ if (response_size)
+ *response_size = in_size;
+
+ if (marshal)
+ return tpm_unmarshal_response(command, &ib);
+ else
+ return cr_buffer_ptr;
+}
+
static uint32_t tlcl_send_startup(TPM_SU type)
{
struct tpm2_startup startup;
@@ -68,7 +118,7 @@
}
printk(BIOS_INFO, "%s: Startup return code is %x\n",
- __func__, response->hdr.tpm_code);
+ __func__, response->hdr.tpm_code);
switch (response->hdr.tpm_code) {
case TPM_RC_INITIALIZE:
@@ -130,7 +180,7 @@
* sha256 digest.
*/
uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
- uint8_t *out_digest)
+ uint8_t *out_digest)
{
struct tpm2_pcr_extend_cmd pcr_ext_cmd;
struct tpm2_response *response;
@@ -139,11 +189,69 @@
pcr_ext_cmd.digests.count = 1;
pcr_ext_cmd.digests.digests[0].hashAlg = TPM_ALG_SHA256;
memcpy(pcr_ext_cmd.digests.digests[0].digest.sha256, in_digest,
- sizeof(pcr_ext_cmd.digests.digests[0].digest.sha256));
+ sizeof(TPMU_HA));
response = tpm_process_command(TPM2_PCR_Extend, &pcr_ext_cmd);
printk(BIOS_INFO, "%s: response is %x\n",
+ __func__, response ? response->hdr.tpm_code : -1);
+ if (!response || response->hdr.tpm_code)
+ return TPM_E_IOERROR;
+
+ return TPM_SUCCESS;
+}
+
+/*
+ * Handle multiple digests (SHA1 and SHA256 at the moment)
+ */
+uint32_t tlcl_extend_ex(int pcr_num, const TPML_DIGEST_VALUES *in_digests)
+{
+ struct tpm2_pcr_extend_cmd pcr_ext_cmd;
+ struct tpm2_response *response;
+ int i;
+
+ pcr_ext_cmd.pcrHandle = HR_PCR + pcr_num;
+ pcr_ext_cmd.digests.count = in_digests->count;
+
+ printk(BIOS_SPEW, "%s: pcr = %d\n", __FUNCTION__, pcr_num );
+ printk(BIOS_SPEW, "%s: in_digests->count = %d\n", __FUNCTION__,
+ in_digests->count);
+
+ for (i = 0; i < in_digests->count ; i++) {
+
+ pcr_ext_cmd.digests.digests[i].hashAlg =
+ in_digests->digests[i].hashAlg;
+ memcpy( (void *) pcr_ext_cmd.digests.digests[i].digest.sha256,
+ (void *) in_digests->digests[i].digest.sha256,
+ sizeof(TPMU_HA));
+
+ printk (BIOS_SPEW, "%s: in_digests[%d]->hash_alg = 0x%x\n",
+ __FUNCTION__, i, in_digests->digests[i].hashAlg);
+ }
+
+ response = tpm_process_command(TPM2_PCR_Extend, &pcr_ext_cmd);
+
+ //
+ // Check if we are invalidating the pcrs, ignore the error if this is the case
+ //
+ if (in_digests->count == 1) {
+ if (in_digests->digests[0].hashAlg == TPM_ALG_ERROR) {
+ if (in_digests->digests[0].digest.invalidate_pcrs == 1) {
+ if (response) {
+ if ((response->hdr.tpm_code &
+ ~TPM_RC_N_MASK) == (TPM_RC_P |
+ TPM_RC_HASH)){
+ printk(BIOS_SPEW, "%s:"
+ " TPM_RC_HASH returned this is"
+ " expected\n", __func__ );
+ return TPM_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+
+ printk(BIOS_INFO, "%s: response is 0x%x\n",
__func__, response ? response->hdr.tpm_code : -1);
if (!response || response->hdr.tpm_code)
return TPM_E_IOERROR;
@@ -178,13 +286,22 @@
uint32_t tlcl_lib_init(void)
{
uint8_t done = car_get_var(tlcl_init_done);
+
+ printk(BIOS_SPEW, "%s: tlcl_init_done is %d\n", __FUNCTION__, done );
if (done)
return VB2_SUCCESS;
- if (tis_init())
+ printk(BIOS_SPEW, "%s: calling tis_init\n", __FUNCTION__);
+ if (tis_init()) {
+ printk(BIOS_ERR, "%s: tis_init returned error\n", __FUNCTION__);
return VB2_ERROR_UNKNOWN;
- if (tis_open())
+ }
+
+ printk(BIOS_SPEW, "%s: calling tis_open\n", __FUNCTION__);
+ if (tis_open()) {
+ printk(BIOS_ERR, "%s: tis_open returned error\n", __FUNCTION__);
return VB2_ERROR_UNKNOWN;
+ }
car_set_var(tlcl_init_done, 1);
@@ -361,3 +478,61 @@
return TPM_SUCCESS;
}
+
+/*
+ * Issue the tpm2 get capability command
+ *
+ * Please note that the CapabilityData is not unmarshalled.
+ */
+uint32_t tlcl_getcapability(TPM_CAP Capability, uint32_t Property,
+ uint32_t PropertyCount, TPMI_YES_NO *MoreData,
+ TPMS_CAPABILITY_DATA *CapabilityData)
+{
+ struct tpm2_get_capability cmd;
+ struct tpm2_response *response;
+ size_t response_size;
+
+ cmd.capability = Capability;
+ cmd.property = Property;
+ cmd.propertyCount = PropertyCount;
+
+ if (PropertyCount > 1) {
+ printk(BIOS_ERR, "%s: PropertyCount more than one not supported"
+ " yet\n", __func__ );
+ }
+
+ response = tpm_process_command_ex(TPM2_GetCapability, &cmd, 0, &response_size, 1);
+
+ if (!response) {
+ printk(BIOS_ERR, "%s: Command Failed\n", __func__ );
+ return TPM_E_IOERROR;
+ }
+
+ if (MoreData)
+ *MoreData = response->gc.more_data;
+ memcpy(CapabilityData, &response->gc.cd, response_size -
+ sizeof(TPMI_YES_NO) - sizeof(struct tpm_header));
+ return TPM_SUCCESS;
+}
+
+/**
+ Return size of digest.
+
+ @param[in] HashAlgo Hash algorithm
+
+ @return size of digest
+**/
+
+uint16_t tlcl_get_hash_size_from_algo(TPMI_ALG_HASH hashAlgo)
+{
+ uint16_t index;
+
+ for (index = 0; index < sizeof(mHashInfo)/sizeof(mHashInfo[0]);
+ index++) {
+ if (mHashInfo[index].hashAlgo == hashAlgo)
+ return mHashInfo[index].hashSize;
+ }
+ printk(BIOS_SPEW, "%s: unknown hash algorithm %d\n", __FUNCTION__,
+ hashAlgo );
+ return 0;
+}
diff --git a/src/security/tpm/tss/tcg-2.0/tss_marshaling.c b/src/security/tpm/tss/tcg-2.0/tss_marshaling.c
index 49ac5e8..183b903 100644
--- a/src/security/tpm/tss/tcg-2.0/tss_marshaling.c
+++ b/src/security/tpm/tss/tcg-2.0/tss_marshaling.c
@@ -1,5 +1,6 @@
/*
* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Copyright (C) 2018 Eltan B.V.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -12,6 +13,7 @@
#include "tss_marshaling.h"
#include <security/tpm/tss/vendor/cr50/cr50.h>
+#include <security/tpm/tss.h>
static uint16_t tpm_tag CAR_GLOBAL; /* Depends on the command type. */
@@ -82,7 +84,7 @@
rc |= marshal_TPMI_ALG_HASH(ob, tpmtha->hashAlg);
rc |= obuf_write(ob, tpmtha->digest.sha256,
- sizeof(tpmtha->digest.sha256));
+ tlcl_get_hash_size_from_algo(tpmtha->hashAlg));
return rc;
}
@@ -398,6 +400,22 @@
rc |= ibuf_read_be32(ib, &pp->value);
}
break;
+ case TPM_CAP_PCRS:
+ if (ibuf_read_be32(ib, &gcr->cd.data.assignedPCR.count))
+ return -1;
+ if (gcr->cd.data.assignedPCR.count > ARRAY_SIZE
+ (gcr->cd.data.assignedPCR.pcrSelections)) {
+ printk(BIOS_INFO, "%s:%s:%d - %d - too many properties\n",
+ __FILE__, __func__, __LINE__,
+ gcr->cd.data.assignedPCR.count);
+ return -1;
+ }
+ for (i = 0; i < gcr->cd.data.assignedPCR.count; i++) {
+ TPMS_PCR_SELECTION *pp =
+ gcr->cd.data.assignedPCR.pcrSelections + i;
+ rc |= ibuf_read(ib, pp, sizeof(TPMS_PCR_SELECTION));
+ }
+ break;
default:
printk(BIOS_ERR,
"%s:%d - unable to unmarshal capability response",
@@ -448,12 +466,12 @@
}
/*
- * Let's ignore the authorisation section. It should be 5 bytes total,
+ * Let's ignore the authorization section. It should be 5 bytes total,
* just confirm that this is the case and report any discrepancy.
*/
if (ibuf_remaining(ib) != 5)
printk(BIOS_ERR,
- "%s:%d - unexpected authorisation seciton size %zd\n",
+ "%s:%d - unexpected authorization section size %zd\n",
__func__, __LINE__, ibuf_remaining(ib));
ibuf_oob_drain(ib, ibuf_remaining(ib));
diff --git a/src/security/tpm/tss/tcg-2.0/tss_structures.h b/src/security/tpm/tss/tcg-2.0/tss_structures.h
index 2bac633..0f2787a 100644
--- a/src/security/tpm/tss/tcg-2.0/tss_structures.h
+++ b/src/security/tpm/tss/tcg-2.0/tss_structures.h
@@ -1,5 +1,6 @@
/*
* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Copyright 2017-2018 Eltan B.V.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -22,6 +23,12 @@
#define TPM2_RC_SUCCESS 0
#define TPM2_RC_NV_DEFINED 0x14c
+//
+// We set this to two here as we only support SHA1 and SHA256 right now.
+// Should be updated when additional algorithms are supported
+//
+#define HASH_COUNT 2
+
/* Basic TPM2 types. */
typedef uint16_t TPM_SU;
typedef uint16_t TPM_ALG_ID;
@@ -36,12 +43,28 @@
typedef TPM_HANDLE TPM_RH;
/* Some hardcoded algorithm values. */
-#define TPM_ALG_HMAC ((TPM_ALG_ID)0x0005)
-#define TPM_ALG_NULL ((TPM_ALG_ID)0x0010)
-#define TPM_ALG_SHA1 ((TPM_ALG_ID)0x0004)
-#define TPM_ALG_SHA256 ((TPM_ALG_ID)0x000b)
+// Table 7 - TPM_ALG_ID Constants
+#define TPM_ALG_ERROR ((TPM_ALG_ID)0x0000)
+#define TPM_ALG_HMAC ((TPM_ALG_ID)0x0005)
+#define TPM_ALG_NULL ((TPM_ALG_ID)0x0010)
+#define TPM_ALG_SHA1 ((TPM_ALG_ID)0x0004)
+#define TPM_ALG_SHA256 ((TPM_ALG_ID)0x000b)
+#define TPM_ALG_SHA384 ((TPM_ALG_ID)0x000C)
+#define TPM_ALG_SHA512 ((TPM_ALG_ID)0x000D)
+#define TPM_ALG_SM3_256 ((TPM_ALG_ID)0x0012)
+// Annex A Algorithm Constants
+
+// Table 205 - Defines for SHA1 Hash Values
+#define SHA1_DIGEST_SIZE 20
+// Table 206 - Defines for SHA256 Hash Values
#define SHA256_DIGEST_SIZE 32
+// Table 207 - Defines for SHA384 Hash Values
+//#define SHA384_DIGEST_SIZE 48
+// Table 208 - Defines for SHA512 Hash Values
+#define SHA512_DIGEST_SIZE 64
+// Table 209 - Defines for SM3_256 Hash Values
+//#define SM3_256_DIGEST_SIZE 32
/* Some hardcoded hierarchies. */
#define TPM_RH_NULL 0x40000007
@@ -79,6 +102,12 @@
space is defined by the lower 16 bits. */
#define TPM_CC_VENDOR_BIT_MASK 0x20000000
+// Table 15 - TPM_RC Constants (Actions)
+#define RC_FMT1 (TPM_RC)(0x080)
+#define TPM_RC_HASH (TPM_RC)(RC_FMT1 + 0x003)
+#define TPM_RC_P (TPM_RC)(0x040)
+#define TPM_RC_N_MASK (TPM_RC)(0xF00)
+
/* Startup values. */
#define TPM_SU_CLEAR 0
#define TPM_SU_STATE 1
@@ -144,7 +173,9 @@
};
/* Various TPM capability types to use when querying the device. */
+// Table 21 - TPM_CAP Constants
typedef uint32_t TPM_CAP;
+#define TPM_CAP_PCRS ((TPM_CAP)0x00000005)
#define TPM_CAP_TPM_PROPERTIES ((TPM_CAP)0x00000006)
typedef TPM_HANDLE TPMI_RH_NV_AUTH;
@@ -224,16 +255,37 @@
sizeof(TPMI_YES_NO) - sizeof(TPM_CAP) - sizeof(uint32_t))
#define MAX_TPM_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PROPERTY))
+#define IMPLEMENTATION_PCR 24
+#define PLATFORM_PCR 24
+
+#define PCR_SELECT_MIN ((PLATFORM_PCR + 7) / 8)
+#define PCR_SELECT_MAX ((IMPLEMENTATION_PCR + 7) / 8)
+
/* Somewhat arbitrary, leave enough room for command wrappers. */
#define MAX_NV_BUFFER_SIZE (TPM_BUFFER_SIZE - sizeof(struct tpm_header) - 50)
+// Table 81 - TPMS_PCR_SELECTION Structure
+typedef struct {
+ TPMI_ALG_HASH hash;
+ uint8_t sizeofSelect;
+ uint8_t pcrSelect[PCR_SELECT_MAX];
+} __packed TPMS_PCR_SELECTION;
+
+// Table 98 - TPML_PCR_SELECTION Structure
+typedef struct {
+ uint32_t count;
+ TPMS_PCR_SELECTION pcrSelections[HASH_COUNT];
+} __packed TPML_PCR_SELECTION;
+
+// Table 100 - TPML_TAGGED_TPM_PROPERTY Structure
typedef struct {
uint32_t count;
TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
} TPML_TAGGED_TPM_PROPERTY;
typedef union {
- TPML_TAGGED_TPM_PROPERTY tpmProperties;
+ TPML_TAGGED_TPM_PROPERTY tpmProperties;
+ TPML_PCR_SELECTION assignedPCR;
} TPMU_CAPABILITIES;
typedef struct {
@@ -271,22 +323,30 @@
} TPM2B_MAX_NV_BUFFER;
/*
- * This is a union, but as of now we support just one digest - sha256, so
- * there is just one element.
+ * This is a union, but as of now we support just sha1 and sha256
*/
+// Table 66 - TPMU_HA Union
typedef union {
- uint8_t sha256[SHA256_DIGEST_SIZE];
+ uint8_t invalidate_pcrs;
+ uint8_t sha1[SHA1_DIGEST_SIZE];
+ uint8_t sha256[SHA256_DIGEST_SIZE];
} TPMU_HA;
typedef struct {
+ TPMI_ALG_HASH hashAlgo;
+ uint16_t hashSize;
+} INTERNAL_HASH_INFO;
+
+typedef struct {
TPMI_ALG_HASH hashAlg;
TPMU_HA digest;
} TPMT_HA;
+// Table 96 -- TPML_DIGEST_VALUES Structure <I/O>
typedef struct {
uint32_t count;
- TPMT_HA digests[1]; /* Limit max number of hashes to 1. */
-} TPML_DIGEST_VALUES;
+ TPMT_HA digests[HASH_COUNT];
+} __packed TPML_DIGEST_VALUES;
struct nv_read_response {
uint32_t params_size;
diff --git a/src/security/verified_boot/Kconfig b/src/security/verified_boot/Kconfig
new file mode 100644
index 0000000..09a86a6
--- /dev/null
+++ b/src/security/verified_boot/Kconfig
@@ -0,0 +1,61 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2018 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.
+##
+
+menu "Verified Boot (verified_boot)"
+
+config VERIFIED_BOOT
+ bool "Enable Verified Boot"
+ default n
+
+config VERIFIED_BOOT_SIGNED_MANIFEST
+ bool "Enable Signed Manifest"
+ depends on VERIFIED_BOOT
+ default n
+
+config VERIFIED_BOOT_USE_SHA512
+ bool "SHA512 hashes"
+ depends on VERIFIED_BOOT
+ default n
+ help
+ Use SHA512 for the vboot operations, this applies to the
+ digests in the manifest and the manifest digest.
+
+config OEM_MANIFEST_LOC
+ hex "Manifest Location"
+ default 0xFFFFF840
+
+config VERIFIED_BOOT_MANIFEST
+ string "Verified boot manifest file"
+ default "mainboard/vendor/board/manifest.h"
+
+config OEM_MANIFEST_ITEMS
+ int "Manifest Items"
+ default 10
+
+config OEM_MANIFEST_ITEM_SIZE
+ int
+ default 64 if VERIFIED_BOOT_USE_SHA512
+ default 32
+
+config VERIFIED_BOOT_KEY_LOCATION
+ hex "Verified boot Key Location"
+ depends on VERIFIED_BOOT_SIGNED_MANIFEST
+ default 0xFFFFF500
+
+config VERIFIED_BOOT_KEY_SIZE
+ int
+ default 554 if VERIFIED_BOOT_USE_SHA512
+ default 520
+
+endmenu # Verified Boot (verified_boot)
diff --git a/src/security/verified_boot/Makefile.inc b/src/security/verified_boot/Makefile.inc
new file mode 100644
index 0000000..23044b4
--- /dev/null
+++ b/src/security/verified_boot/Makefile.inc
@@ -0,0 +1,47 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2018 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.
+##
+
+ifeq ($(CONFIG_VERIFIED_BOOT),y)
+
+CPPFLAGS_common += -I$(src)/security/verified_boot
+
+bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += vboot_check.c
+romstage-y += vboot_check.c
+ramstage-y += vboot_check.c
+
+cbfs-files-y += oemmanifest.bin
+oemmanifest.bin-file := $(obj)/oemmanifest.bin
+oemmanifest.bin-position := $(CONFIG_OEM_MANIFEST_LOC)
+oemmanifest.bin-type := 0x50
+
+$(obj)/oemmanifest.bin:
+ifeq ($(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST),y)
+ dd if=/dev/zero of=$@ seek=8 bs=$(CONFIG_OEM_MANIFEST_ITEM_SIZE) count=$(CONFIG_OEM_MANIFEST_ITEMS)
+else # ($(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST),y)
+ dd if=/dev/zero of=$@ bs=$(CONFIG_OEM_MANIFEST_ITEM_SIZE) count=$(CONFIG_OEM_MANIFEST_ITEMS)
+endif # ($(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST),y)
+
+ifeq ($(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST),y)
+cbfs-files-y += vboot_public_key.bin
+vboot_public_key.bin-file := $(obj)/vboot_public_key.bin
+vboot_public_key.bin-position := $(CONFIG_VERIFIED_BOOT_KEY_LOCATION)
+vboot_public_key.bin-type := 0x50
+
+$(obj)/vboot_public_key.bin:
+ dd if=/dev/zero of=$@ bs=$(CONFIG_VERIFIED_BOOT_KEY_SIZE) count=1
+
+endif # ($(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST),y)
+
+endif # CONFIG_VERIFIED_BOOT
diff --git a/src/security/verified_boot/vboot_check.c b/src/security/verified_boot/vboot_check.c
new file mode 100644
index 0000000..ab5f8d6
--- /dev/null
+++ b/src/security/verified_boot/vboot_check.c
@@ -0,0 +1,468 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ * Copyright (C) 2017-2018 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 <vboot_check.h>
+
+#define RSA_PUBLICKEY_FILE_NAME "vboot_public_key.bin"
+
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT_USE_SHA512)
+#define DIGEST_SIZE SHA512_DIGEST_SIZE
+#else
+#define DIGEST_SIZE SHA256_DIGEST_SIZE
+#endif
+
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST)
+int verified_boot_check_manifest(void)
+{
+ struct vb2_public_key key;
+ uint8_t digest[DIGEST_SIZE];
+ size_t size = 0;
+ uint8_t* signature = NULL;
+ uint8_t *buffer;
+ const struct vb2_workbuf wb;
+
+ cbfs_boot_map_with_leak("oemmanifest.bin", CBFS_TYPE_RAW, &size);
+
+ if (size != (CONFIG_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + 256) {
+ printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n");
+ goto fail;
+ }
+
+ buffer = cbfs_boot_map_with_leak(RSA_PUBLICKEY_FILE_NAME,
+ CBFS_TYPE_RAW, &size);
+
+ size = DIGEST_SIZE;
+ if (!vb2_unpack_key_data(&key, buffer, size)) {
+ printk(BIOS_ERR, "ERROR: Unable to create RSA Public Key !\n");
+ return -1;
+ }
+
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT_USE_SHA512)
+ key.hash_alg = VB2_HASH_SHA512;
+#else
+ key.sig_alg = VB2_HASH_SHA256;
+#endif
+
+ //
+ // Create a big endian digest
+ //
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT_USE_SHA512)
+ cb_sha512_ex((const uint8_t*)CONFIG_OEM_MANIFEST_LOC,
+ CONFIG_OEM_MANIFEST_ITEMS * DIGEST_SIZE, digest, 1);
+#else
+ cb_sha256_ex((const uint8_t*)CONFIG_OEM_MANIFEST_LOC,
+ CONFIG_OEM_MANIFEST_ITEMS * DIGEST_SIZE, digest, 1);
+#endif
+
+ signature = (uint8_t*)CONFIG_OEM_MANIFEST_LOC +
+ CONFIG_OEM_MANIFEST_ITEMS * DIGEST_SIZE;
+
+ /* TODO * parameter 4 is vb2_workbuf workflow */
+ if (!vb2_rsa_verify_digest(&key, signature, digest, &wb)) {
+ printk(BIOS_ERR, "ERROR: Signature verification failed for"
+ "hash table !!\n");
+ goto fail;
+ }
+
+ printk(BIOS_DEBUG, "%s: Successfully verified hash_table signature.\n",
+ __FUNCTION__);
+ return 0;
+
+fail:
+ die("HASH table verification failed!\n");
+ return -1;
+}
+#endif
+
+#if IS_ENABLED(CONFIG_MBOOT)
+#ifndef __BOOTBLOCK__
+
+/*
+
+ * measure_item
+
+ * extends the defined pcr using the hash calculated by the verified boot
+ * routines.
+ *
+ * @param[in] pcr PCR to extend
+ * @param[in] *hashData Pointer to the hash data
+ * @param[in] hashDataLen Length of the hash data
+ * @param[in] *event_msg Message to log or display
+ * @param[in] eventType Event type to use when logging
+
+ * @retval TPM_SUCCESS Operation completed successfully.
+ * @retval TPM_E_IOERROR Unexpected device behavior.
+ */
+static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
+ int8_t *event_msg, TCG_EVENTTYPE eventType)
+{
+ int status = TPM_SUCCESS;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrs;
+ TCG_PCR_EVENT2_HDR tcgEventHdr;
+
+ ActivePcrs = tpm2_get_active_pcrs();
+
+ memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
+ tcgEventHdr.pcrIndex = pcr;
+ tcgEventHdr.eventType = eventType;
+ if (event_msg) {
+ status = mboot_hash_extend_log(ActivePcrs, MBOOT_HASH_PROVIDED,
+ hashData, hashDataLen, &tcgEventHdr,
+ (uint8_t*)event_msg, 0);
+ if (status == TPM_SUCCESS) {
+ printk(BIOS_DEBUG, "%s: Success! %s measured to pcr"
+ "%d.\n", __FUNCTION__, event_msg, pcr);
+ } else {
+ printk(BIOS_DEBUG, "%s: Fail! %s can't be measured. "
+ "ABORTING!!!\n", __FUNCTION__, event_msg);
+ return status;
+ }
+ }
+ return status;
+}
+#endif
+#endif //IS_ENABLED(CONFIG_MBOOT)
+
+
+static void verified_boot_check_buffer(const char *name, void *start,
+ size_t size, uint32_t hash_index
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ ,int32_t pcr
+#endif
+#endif
+ )
+{
+ uint8_t digest[DIGEST_SIZE];
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ int status;
+#endif
+#endif
+ printk(BIOS_INFO, "%s: %s HASH verification buffer %p size %d\n",
+ __FUNCTION__, name, start, (int) size);
+
+ if (start && size) {
+
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT_USE_SHA512)
+ cb_sha512((const uint8_t*)start, size, digest);
+#else
+ cb_sha256((const uint8_t*)start, size, digest);
+#endif
+
+ if (memcmp((void *)((uint8_t *)CONFIG_OEM_MANIFEST_LOC +
+ sizeof(digest) * hash_index), digest, sizeof(digest))) {
+ printk(BIOS_INFO, "%s: buffer hash\n", __FUNCTION__);
+ hexdump(digest, sizeof(digest));
+ printk(BIOS_INFO, "%s: manifest hash\n", __FUNCTION__);
+ hexdump((void *)((uint8_t *)CONFIG_OEM_MANIFEST_LOC +
+ sizeof(digest) * hash_index), sizeof(digest));
+ printk(BIOS_EMERG, "%s ", name);
+ die("HASH verification failed!\n");
+ } else {
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ if (pcr != -1) {
+ printk(BIOS_INFO, "%s: measuring %s\n",
+ __FUNCTION__, name);
+ status = measure_item(pcr, digest,
+ sizeof(digest), (int8_t *)name,
+ 0);
+ }
+#endif
+#endif
+ printk(BIOS_INFO, "%s HASH verification success\n",
+ name);
+ }
+ } else {
+ printk(BIOS_EMERG, "Invalid buffer ");
+ die("HASH verification failed!\n");
+ }
+}
+
+void verified_boot_check_cbfsfile(const char *name, uint32_t type,
+ uint32_t hash_index, void **buffer, uint32_t *filesize
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ ,int32_t pcr
+#endif //IS_ENABLED(CONFIG_MBOOT)
+#endif
+ )
+{
+ void *start;
+ size_t size;
+
+ start = cbfs_boot_map_with_leak(name, type & ~VERIFIED_BOOT_COPY_BLOCK,
+ &size);
+ if (start && size) {
+ /*
+ * Speed up processing by copying the file content to memory
+ * first
+ */
+#ifndef __PRE_RAM__
+ if ((type & VERIFIED_BOOT_COPY_BLOCK) && (buffer) && (*buffer)
+ && ((uint32_t) start >
+ (uint32_t)(~(CONFIG_CBFS_SIZE-1)))) {
+ printk(BIOS_INFO, "%s: move buffer to "
+ "memory\n", __FUNCTION__);
+ /* Move the file to a memory bufferof which we know it
+ * doesn't harm
+ */
+ memcpy(*buffer, start, size);
+ start = *buffer;
+ printk(BIOS_INFO, "%s: done\n", __FUNCTION__);
+ }
+#endif // __PRE_RAM__
+ verified_boot_check_buffer(name, start, size, hash_index
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ ,pcr
+#endif //IS_ENABLED(CONFIG_MBOOT)
+#endif
+ );
+ } else {
+ printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n",
+ name);
+ die("HASH verification failed!\n");
+ }
+ if (buffer)
+ *buffer = start;
+ if (filesize)
+ *filesize = size;
+}
+
+void process_verify_list(const verify_item_t list[])
+{
+ int i = 0;
+
+ while (list[i].type != VERIFY_TERMINATOR) {
+ switch (list[i].type) {
+ case VERIFY_FILE:
+ verified_boot_check_cbfsfile(list[i].name,
+ list[i].data.file.cbfs_type,
+ list[i].hash_index, NULL, NULL
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ ,list[i].pcr
+#endif //IS_ENABLED(CONFIG_MBOOT)
+#endif
+ );
+ if (list[i].data.file.related_items) {
+ printk(BIOS_SPEW, "process related"
+ "items\n");
+ process_verify_list((verify_item_t *)
+ list[i].data.file.related_items);
+ }
+ break;
+ case VERIFY_BLOCK:
+ verified_boot_check_buffer(list[i].name,
+ (void *) list[i].data.block.start,
+ list[i].data.block.size,
+ list[i].hash_index
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ ,list[i].pcr
+#endif //IS_ENABLED(CONFIG_MBOOT)
+#endif
+ );
+ break;
+ default:
+ printk(BIOS_EMERG, "INVALID TYPE IN VERIFY"
+ "LIST 0x%x\n", list[i].type);
+ die("HASH verification failed!\n");
+ }
+ i++;
+ }
+}
+#ifndef __BOOTBLOCK__
+
+static void process_named_list(const verify_item_t list[], const char *name,
+ void **buffer, uint32_t *size)
+{
+ int i = 0;
+
+ while (list[i].type != VERIFY_TERMINATOR) {
+ switch (list[i].type) {
+ case VERIFY_FILE:
+ if (!strcmp(name, list[i].name)) {
+ if (list[i].data.file.related_items) {
+ printk(BIOS_SPEW, "process"
+ "related items\n");
+ process_verify_list((verify_item_t *)list[i].data.file.related_items);
+ printk(BIOS_SPEW, "process related items done\n");
+ }
+ verified_boot_check_cbfsfile(
+ list[i].name,
+ list[i].data.file.cbfs_type,
+ list[i].hash_index, buffer,
+ size
+#ifndef __BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+ ,list[i].pcr
+#endif
+#endif
+ );
+ return;
+ }
+ break;
+ default:
+ printk(BIOS_EMERG, "INVALID TYPE IN NAMED LIST"
+ "0x%x\n", list[i].type);
+ die("HASH verification failed!\n");
+ }
+ i++;
+ }
+ printk(BIOS_EMERG, "%s NOT IN LIST\n", name);
+ die("HASH verification failed!\n");
+}
+#endif
+
+#ifdef __BOOTBLOCK__
+/*
+ * BOOTBLOCK
+ */
+
+extern verify_item_t bootblock_verify_list[];
+
+void verified_boot_bootblock_check(void)
+{
+ printk(BIOS_SPEW, "%s: processing bootblock items\n", __FUNCTION__);
+
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST)
+ printk(BIOS_SPEW, "%s: check the manifest\n", __FUNCTION__);
+ if (verified_boot_check_manifest() != 0)
+ die("invalid manifest");
+#endif //IS_ENABLED(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST)
+ printk(BIOS_SPEW, "%s: process bootblock verify list\n", __FUNCTION__);
+ process_verify_list(bootblock_verify_list);
+}
+
+#endif //__BOOTBLOCK__
+
+
+#ifdef __ROMSTAGE__
+/*
+ * ROMSTAGE
+ */
+
+extern verify_item_t ramstage_verify_list[];
+
+int prog_locate_hook(struct prog *prog)
+{
+ if (prog->type == PROG_RAMSTAGE) {
+ process_named_list(ramstage_verify_list, prog->name, NULL,
+ NULL);
+ }
+ return 0;
+}
+
+extern verify_item_t romstage_verify_list[];
+
+void verified_boot_early_check(void)
+{
+ printk(BIOS_SPEW, "%s: processing early items\n", __FUNCTION__);
+
+#if !IS_ENABLED(CONFIG_C_ENVIRONMENT_BOOTBLOCK)
+#if IS_ENABLED(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST)
+ printk(BIOS_SPEW, "%s: check the manifest\n", __FUNCTION__);
+ if (verified_boot_check_manifest() != 0)
+ die("invalid manifest")
+#endif //IS_ENABLED(CONFIG_VERIFIED_BOOT_SIGNED_MANIFEST)
+#endif //!IS_ENABLED(CONFIG_C_ENVIRONMENT_BOOTBLOCK)
+ printk(BIOS_SPEW, "%s: process early verify list\n", __FUNCTION__);
+ process_verify_list(romstage_verify_list);
+}
+#endif //__ROMSTAGE__
+
+#ifdef __RAMSTAGE__
+/*
+ * RAM STAGE
+ */
+
+static int process_oprom_list(const verify_item_t list[],
+ struct rom_header *rom_header)
+{
+ int i = 0;
+ struct pci_data *rom_data;
+ uint32_t viddevid = 0;
+
+ if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
+ printk(BIOS_ERR, "Incorrect expansion ROM header "
+ "signature %04x DONT START\n",
+ le32_to_cpu(rom_header->signature));
+ return 0;
+ }
+
+ rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
+
+ viddevid |= (rom_data->vendor << 16);
+ viddevid |= rom_data->device;
+
+ while (list[i].type != VERIFY_TERMINATOR) {
+ switch (list[i].type) {
+ case VERIFY_OPROM:
+ if (viddevid == list[i].data.oprom.viddev) {
+ verified_boot_check_buffer(list[i].name,
+ (void *) rom_header,
+ rom_header->size * 512,
+ list[i].hash_index
+#if IS_ENABLED(CONFIG_MBOOT)
+ ,list[i].pcr
+#endif
+ );
+ if (list[i].data.oprom.related_items) {
+ printk(BIOS_SPEW, "%s: process"
+ " related items\n",
+ __FUNCTION__);
+ process_verify_list((verify_item_t *)list[i].data.oprom.related_items);
+ }
+ printk(BIOS_SPEW, "%s: option rom can"
+ "be started\n", __FUNCTION__);
+ return 1;
+ }
+ break;
+ default:
+ printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION"
+ " ROM LIST 0x%x\n", __FUNCTION__,
+ list[i].type);
+ die("HASH verification failed!\n");
+ }
+ i++;
+ }
+ printk(BIOS_ERR, "%s: option rom not in list DONT START\n",
+ __FUNCTION__);
+ return 0;
+}
+
+extern verify_item_t payload_verify_list[];
+
+int prog_locate_hook(struct prog *prog)
+{
+ if (prog->type == PROG_PAYLOAD) {
+ void *buffer = (void*) 0x01000000;
+ printk(BIOS_SPEW, "%s: requesting %s\n", __FUNCTION__, prog->name);
+ process_named_list(payload_verify_list, prog->name, &buffer, NULL);
+ printk(BIOS_SPEW, "%s: running allowed\n", __FUNCTION__);
+ }
+ return 0;
+}
+
+extern verify_item_t oprom_verify_list[];
+
+int verified_boot_should_run_oprom(struct rom_header *rom_header)
+{
+ return process_oprom_list(oprom_verify_list, rom_header);
+}
+#endif //__PRE_RAM__
diff --git a/src/security/verified_boot/vboot_check.h b/src/security/verified_boot/vboot_check.h
new file mode 100644
index 0000000..de5fd20
--- /dev/null
+++ b/src/security/verified_boot/vboot_check.h
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ * Copyright (C) 2017-2018 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 VBOOT_CHECK_H
+#define VBOOT_CHECK_H
+
+#include <cbfs.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <lib.h>
+#include CONFIG_VERIFIED_BOOT_MANIFEST
+#include <console/console.h>
+#include <security/include/cryptolib.h>
+#include <string.h>
+#include <program_loading.h>
+#if IS_ENABLED(CONFIG_MBOOT)
+#include <mboot.h>
+#endif
+
+#define VERIFIED_BOOT_COPY_BLOCK 0x80000000
+/* These method verifies the SHA256 hash over the 'named' CBFS component.
+ * 'type' denotes the type of CBFS component i.e. stage, payload or fsp.
+ */
+#ifdef __BOOTBLOCK__
+void verified_boot_bootblock_check(void);
+#endif
+#ifdef __ROMSTAGE__
+void verified_boot_early_check(void);
+#endif
+
+int verified_boot_check_manifest(void);
+
+#ifdef __BOOTBLOCK__
+void verified_boot_check_cbfsfile(const char *name, uint32_t type,
+ uint32_t hash_index, void **buffer, uint32_t *filesize);
+#else //__BOOTBLOCK__
+#if IS_ENABLED(CONFIG_MBOOT)
+void verified_boot_check_cbfsfile(const char *name, uint32_t type,
+ uint32_t hash_index, void **buffer, uint32_t *filesize, int32_t pcr);
+#else
+void verified_boot_check_cbfsfile(const char *name, uint32_t type,
+ uint32_t hash_index, void **buffer, uint32_t *filesize);
+#endif
+#endif //__BOOTBLOCK__
+
+
+typedef enum {
+
+ VERIFY_TERMINATOR = 0,
+ VERIFY_FILE,
+ VERIFY_BLOCK,
+ VERIFY_OPROM
+
+} verify_type;
+
+typedef struct {
+ verify_type type;
+ const char *name;
+ union {
+ struct {
+ const void *related_items;
+ uint32_t cbfs_type;
+ } file;
+ struct {
+ const void *start;
+ uint32_t size;
+ } block;
+ struct {
+ const void *related_items;
+ uint32_t viddev;
+ } oprom;
+ } data;
+ uint32_t hash_index;
+#if IS_ENABLED(CONFIG_MBOOT)
+ int32_t pcr;
+#endif //IS_ENABLED(CONFIG_MBOOT)
+} verify_item_t;
+
+void process_verify_list(const verify_item_t list[]);
+
+#endif //VBOOT_CHECK_H
--
To view, visit https://review.coreboot.org/c/coreboot/+/30218
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ic1d5a21d40b6a31886777e8e9fe7b28c860f1a80
Gerrit-Change-Number: 30218
Gerrit-PatchSet: 1
Gerrit-Owner: Frans Hendriks <fhendriks at eltan.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20181214/df007371/attachment-0001.html>
More information about the coreboot-gerrit
mailing list