[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