security/vboot: Add measured boot mode

* Introduce a measured boot mode into vboot.
* Add hook for stage measurements in prog_loader and cbfs.
* Implement and hook-up CRTM in vboot and check for suspend.

Change-Id: I339a2f1051e44f36aba9f99828f130592a09355e
Signed-off-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Signed-off-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-on: https://review.coreboot.org/c/29547
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/Documentation/index.md b/Documentation/index.md
index 58ec11d..dd8714c 100644
--- a/Documentation/index.md
+++ b/Documentation/index.md
@@ -167,6 +167,7 @@
 * [Code of Conduct](community/code_of_conduct.md)
 * [Community forums](community/forums.md)
 * [coreboot at conferences](community/conferences.md)
+* [Security](security.md)
 * [Payloads](payloads.md)
 * [Distributions](distributions.md)
 * [Timestamps](timestamp.md)
diff --git a/Documentation/security.md b/Documentation/security.md
new file mode 100644
index 0000000..73b167f
--- /dev/null
+++ b/Documentation/security.md
@@ -0,0 +1,5 @@
+# Security
+
+## Google VBoot2 Measured boot extension
+
+- [Measured Boot](vboot/measured_boot.md)
diff --git a/Documentation/security/vboot/measured_boot.md b/Documentation/security/vboot/measured_boot.md
new file mode 100644
index 0000000..3ec3729
--- /dev/null
+++ b/Documentation/security/vboot/measured_boot.md
@@ -0,0 +1,58 @@
+# Measured Boot
+coreboot measured boot is implemented as Google Verified Boot extension. This
+means in order to use it, vboot needs to be available for your platform.
+
+## IBB/CRTM
+The "Initial Boot Block" or "Core Root of Trust for Measurement" is the first
+code block loaded at reset vector and measured by a DRTM solution.
+In case SRTM mode is active, the IBB measures itself before measuring the next
+code block. In coreboot, cbfs files which are part of the IBB are identified
+by a metatdata tag. This makes it possible to have platform specific IBB
+measurements without hardcoding them.
+
+## Known Limitations
+At the moment measuring IBB dynamically and FMAP partitions are not possible but
+will be added later to the implementation.
+
+Also SoCs making use of VBOOT_RETURN_FROM_VERSTAGE are not able to use the
+measured boot extension because of platform constraints.
+
+## SRTM Mode
+The "Static Root of Trust for Measurement" is the easiest way doing measurements
+by measuring code before it is loaded.
+
+![][srtm]
+
+[srtm]: srtm.png
+
+## DRTM Mode
+The "Dynamic Root of Trust for Measurement" is realised by platform features
+like Intel TXT or Boot Guard. The features provide a way of loading a signed
+"Authenticated Code Module" aka signed blob. Most of these features are also
+a "Trusted Execution Environment", e.g. Intel TXT.
+
+DRTM gives you the ability of measuring the IBB from a higher Root of Trust
+instead of doing it yourself without any hardware support.
+
+## Platform Configuration Register
+Normally PCR 0-7 are reserved for firmware usage. In coreboot we use just 4 PCR
+banks in order to store the measurements. coreboot uses the SHA-1 or SHA-256
+hash algorithm depending on the TPM specification for measurements. PCR-4 to
+PCR-7 are left empty.
+
+### PCR-0
+_Hash:_ SHA1
+_Description:_ Google VBoot GBB flags.
+
+### PCR-1
+_Hash:_ SHA1/SHA256
+_Description:_ Google VBoot GBB HWID.
+
+### PCR-2
+_Hash:_ SHA1/SHA256
+_Description:_ Core Root of Trust for Measurement which includes all stages,
+data and blobs.
+
+### PCR-3
+_Hash:_ SHA1/SHA256
+_Description:_ Runtime data like hwinfo.hex or MRC cache.
diff --git a/Documentation/security/vboot/srtm.png b/Documentation/security/vboot/srtm.png
new file mode 100644
index 0000000..365fa39
--- /dev/null
+++ b/Documentation/security/vboot/srtm.png
Binary files differ
diff --git a/src/cpu/intel/haswell/Makefile.inc b/src/cpu/intel/haswell/Makefile.inc
index c317c09..1fa71c9 100644
--- a/src/cpu/intel/haswell/Makefile.inc
+++ b/src/cpu/intel/haswell/Makefile.inc
@@ -4,6 +4,8 @@
 romstage-y += tsc_freq.c
 romstage-y += ../car/romstage.c
 
+postcar-y += tsc_freq.c
+
 ramstage-y += acpi.c
 ramstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
 ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smmrelocate.c
diff --git a/src/cpu/intel/model_2065x/Makefile.inc b/src/cpu/intel/model_2065x/Makefile.inc
index ec8643a..043141a 100644
--- a/src/cpu/intel/model_2065x/Makefile.inc
+++ b/src/cpu/intel/model_2065x/Makefile.inc
@@ -12,6 +12,7 @@
 
 ramstage-y += tsc_freq.c
 romstage-y += tsc_freq.c
+postcar-y += tsc_freq.c
 smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c
 
 ramstage-y += acpi.c
diff --git a/src/cpu/intel/model_206ax/Makefile.inc b/src/cpu/intel/model_206ax/Makefile.inc
index d193e60..e1fa879 100644
--- a/src/cpu/intel/model_206ax/Makefile.inc
+++ b/src/cpu/intel/model_206ax/Makefile.inc
@@ -19,6 +19,7 @@
 
 ramstage-y += tsc_freq.c
 romstage-y += tsc_freq.c
+postcar-y += tsc_freq.c
 smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c
 
 smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index a5c9f85..3e2ccf3 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -26,6 +26,7 @@
 #include <timestamp.h>
 #include <fmap.h>
 #include "fmap_config.h"
+#include <security/vboot/vboot_crtm.h>
 
 #define ERROR(x...) printk(BIOS_ERR, "CBFS: " x)
 #define LOG(x...) printk(BIOS_INFO, "CBFS: " x)
@@ -59,7 +60,12 @@
 		return -1;
 	}
 
-	return cbfs_locate(fh, &rdev, name, type);
+	int ret = cbfs_locate(fh, &rdev, name, type);
+	if (!ret)
+		if (vboot_measure_cbfs_hook(fh, name))
+			return -1;
+
+	return ret;
 }
 
 void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size)
@@ -79,13 +85,13 @@
 }
 
 int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name,
-		const char *name, uint32_t *type)
+			       const char *name, uint32_t *type)
 {
 	struct region_device rdev;
 
 	if (fmap_locate_area_as_rdev(region_name, &rdev)) {
 		LOG("%s region not found while looking for %s\n",
-			region_name, name);
+		    region_name, name);
 		return -1;
 	}
 
@@ -107,7 +113,7 @@
 
 	case CBFS_COMPRESS_LZ4:
 		if ((ENV_BOOTBLOCK || ENV_VERSTAGE) &&
-		    !IS_ENABLED(CONFIG_COMPRESS_PRERAM_STAGES))
+			!IS_ENABLED(CONFIG_COMPRESS_PRERAM_STAGES))
 			return 0;
 
 		/* Load the compressed image to the end of the available memory
@@ -130,7 +136,7 @@
 		if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_POSTCAR_STAGE))
 			return 0;
 		if ((ENV_ROMSTAGE || ENV_POSTCAR)
-			&& !IS_ENABLED(CONFIG_COMPRESS_RAMSTAGE))
+		    && !IS_ENABLED(CONFIG_COMPRESS_RAMSTAGE))
 			return 0;
 		void *map = rdev_mmap(rdev, offset, in_size);
 		if (map == NULL)
@@ -157,9 +163,9 @@
 
 static void tohex16(unsigned int val, char *dest)
 {
-	dest[0] = tohex4(val>>12);
-	dest[1] = tohex4((val>>8) & 0xf);
-	dest[2] = tohex4((val>>4) & 0xf);
+	dest[0] = tohex4(val >> 12);
+	dest[1] = tohex4((val >> 8) & 0xf);
+	dest[2] = tohex4((val >> 4) & 0xf);
 	dest[3] = tohex4(val & 0xf);
 }
 
@@ -167,8 +173,8 @@
 {
 	char name[17] = "pciXXXX,XXXX.rom";
 
-	tohex16(vendor, name+3);
-	tohex16(device, name+8);
+	tohex16(vendor, name + 3);
+	tohex16(device, name + 8);
 
 	return cbfs_boot_map_with_leak(name, CBFS_TYPE_OPTIONROM, NULL);
 }
@@ -202,8 +208,9 @@
 		return 0;
 
 	if (cbfsf_decompression_info(&fh, &compression_algo,
-				     &decompressed_size) < 0
-				     || decompressed_size > buf_size)
+				     &decompressed_size)
+		    < 0
+	    || decompressed_size > buf_size)
 		return 0;
 
 	return cbfs_load_and_decompress(&fh.data, 0, region_device_sz(&fh.data),
@@ -249,7 +256,7 @@
 	/* Hacky way to not load programs over read only media. The stages
 	 * that would hit this path initialize themselves. */
 	if (ENV_VERSTAGE && !IS_ENABLED(CONFIG_NO_XIP_EARLY_STAGES) &&
-	    IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED)) {
+		IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED)) {
 		void *mapping = rdev_mmap(fh, foffset, fsize);
 		rdev_munmap(fh, mapping);
 		if (mapping == load)
@@ -354,7 +361,7 @@
 			continue;
 
 		LOG("'%s' located CBFS at [%zx:%zx)\n",
-			ops->name, props->offset, props->offset + props->size);
+		    ops->name, props->offset, props->offset + props->size);
 
 		return 0;
 	}
diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c
index 285f18d..b8ebf7b 100644
--- a/src/security/tpm/tspi/tspi.c
+++ b/src/security/tpm/tspi/tspi.c
@@ -90,7 +90,6 @@
 	default:
 		printk(BIOS_ERR, "TPM: Resume failed (%#x).\n", result);
 		break;
-
 	}
 
 	return result;
@@ -215,8 +214,6 @@
 	if (result != TPM_SUCCESS)
 		return result;
 
-	tcpa_log_add_table_entry(name, pcr, digest, digest_len);
-
 	return TPM_SUCCESS;
 }
 
@@ -240,7 +237,7 @@
 	}
 	if (IS_ENABLED(CONFIG_TPM1))
 		hash_alg = VB2_HASH_SHA1;
-	else  /* CONFIG_TPM2 */
+	else /* CONFIG_TPM2 */
 		hash_alg = VB2_HASH_SHA256;
 
 	digest_len = vb2_digest_size(hash_alg);
@@ -258,7 +255,7 @@
 		len = MIN(sizeof(buf), region_device_sz(rdev) - offset);
 		if (rdev_readat(rdev, buf, offset, len) < 0) {
 			printk(BIOS_ERR, "TPM: Not able to read region %s.\n",
-					rname);
+			       rname);
 			return TPM_E_READ_FAILURE;
 		}
 		if (vb2_digest_extend(&ctx, buf, len)) {
diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig
index a3e9b86..a382e67 100644
--- a/src/security/vboot/Kconfig
+++ b/src/security/vboot/Kconfig
@@ -26,6 +26,22 @@
 
 if VBOOT
 
+config VBOOT_MEASURED_BOOT
+	bool "Enable Measured Boot"
+	default n
+	depends on !VBOOT_MOCK_SECDATA
+	depends on !VBOOT_RETURN_FROM_VERSTAGE
+	help
+	  Enables measured boot mode in vboot (experimental)
+
+config VBOOT_MEASURED_BOOT_RUNTIME_DATA
+	string "Runtime data whitelist"
+	default ""
+	depends on VBOOT_MEASURED_BOOT
+	help
+	  Runtime data whitelist of cbfs filenames. Needs to be a comma separated
+	  list
+
 config VBOOT_SLOTS_RW_A
 	bool "Firmware RO + RW_A"
 	help
@@ -37,7 +53,6 @@
 	help
 	  Have two update partitions beside the RO partition.
 
-
 config VBOOT_VBNV_CMOS
 	bool
 	default n
diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc
index 0c32d94..6d2096d 100644
--- a/src/security/vboot/Makefile.inc
+++ b/src/security/vboot/Makefile.inc
@@ -69,6 +69,13 @@
 ramstage-y += vboot_common.c
 postcar-y += vboot_common.c
 
+ifeq ($(CONFIG_VBOOT_MEASURED_BOOT),y)
+verstage-y += vboot_crtm.c
+romstage-y += vboot_crtm.c
+ramstage-y += vboot_crtm.c
+postcar-y += vboot_crtm.c
+endif
+
 bootblock-y += common.c
 verstage-y += vboot_logic.c
 verstage-y += common.c
diff --git a/src/security/vboot/vboot_crtm.c b/src/security/vboot/vboot_crtm.c
new file mode 100644
index 0000000..768986f
--- /dev/null
+++ b/src/security/vboot/vboot_crtm.c
@@ -0,0 +1,144 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Facebook Inc.
+ *
+ * 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 <console/console.h>
+#include <fmap.h>
+#include <security/vboot/vboot_crtm.h>
+#include <security/vboot/misc.h>
+
+uint32_t vboot_init_crtm(void)
+{
+	struct prog bootblock = PROG_INIT(PROG_BOOTBLOCK, "bootblock");
+	struct prog verstage =
+		PROG_INIT(PROG_VERSTAGE, CONFIG_CBFS_PREFIX "/verstage");
+	struct prog romstage =
+		PROG_INIT(PROG_ROMSTAGE, CONFIG_CBFS_PREFIX "/romstage");
+
+	/* measure bootblock from RO */
+	struct cbfsf bootblock_data;
+	struct region_device bootblock_fmap;
+	if (fmap_locate_area_as_rdev("BOOTBLOCK", &bootblock_fmap) == 0) {
+		if (tpm_measure_region(&bootblock_fmap,
+				       TPM_CRTM_PCR,
+				       prog_name(&bootblock)))
+			return VB2_ERROR_UNKNOWN;
+	} else {
+		if (cbfs_boot_locate(&bootblock_data,
+			prog_name(&bootblock), NULL) == 0) {
+			cbfs_file_data(prog_rdev(&bootblock), &bootblock_data);
+
+			if (tpm_measure_region(prog_rdev(&bootblock),
+					       TPM_CRTM_PCR,
+					       prog_name(&bootblock)))
+				return VB2_ERROR_UNKNOWN;
+		} else {
+			printk(BIOS_INFO,
+			       "VBOOT: Couldn't measure bootblock into CRTM!\n");
+			return VB2_ERROR_UNKNOWN;
+		}
+	}
+
+	if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) {
+		struct cbfsf romstage_data;
+		/* measure romstage from RO */
+		if (cbfs_boot_locate(&romstage_data,
+			prog_name(&romstage), NULL) == 0) {
+			cbfs_file_data(prog_rdev(&romstage), &romstage_data);
+
+			if (tpm_measure_region(prog_rdev(&romstage),
+					       TPM_CRTM_PCR,
+					       CONFIG_CBFS_PREFIX "/romstage"))
+				return VB2_ERROR_UNKNOWN;
+		} else {
+			printk(BIOS_INFO,
+			       "VBOOT: Couldn't measure %s into CRTM!\n",
+			       CONFIG_CBFS_PREFIX "/romstage");
+			return VB2_ERROR_UNKNOWN;
+		}
+	}
+
+	if (IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE)) {
+		struct cbfsf verstage_data;
+		/* measure verstage from RO */
+		if (cbfs_boot_locate(&verstage_data,
+			prog_name(&verstage), NULL) == 0) {
+			cbfs_file_data(prog_rdev(&verstage), &verstage_data);
+
+			if (tpm_measure_region(prog_rdev(&verstage),
+					       TPM_CRTM_PCR,
+					       CONFIG_CBFS_PREFIX "/verstage"))
+				return VB2_ERROR_UNKNOWN;
+		} else {
+			printk(BIOS_INFO,
+			       "VBOOT: Couldn't measure %s into CRTM!\n",
+			       CONFIG_CBFS_PREFIX "/verstage");
+			return VB2_ERROR_UNKNOWN;
+		}
+	}
+
+	return VB2_SUCCESS;
+}
+
+static bool is_runtime_data(const char *name)
+{
+	const char *whitelist = CONFIG_VBOOT_MEASURED_BOOT_RUNTIME_DATA;
+	size_t whitelist_len = sizeof(CONFIG_VBOOT_MEASURED_BOOT_RUNTIME_DATA) - 1;
+	size_t name_len = strlen(name);
+	int i;
+
+	if (!whitelist_len || !name_len)
+		return false;
+
+	for (i = 0; (i + name_len) <= whitelist_len; i++) {
+		if (!strcmp(whitelist + i, name))
+			return true;
+	}
+
+	return false;
+}
+
+uint32_t vboot_measure_cbfs_hook(struct cbfsf *fh, const char *name)
+{
+	uint32_t pcr_index;
+	uint32_t cbfs_type;
+	struct region_device rdev;
+
+	if (!vb2_logic_executed())
+		return 0;
+
+	cbfsf_file_type(fh, &cbfs_type);
+	cbfs_file_data(&rdev, fh);
+
+	switch (cbfs_type) {
+	case CBFS_TYPE_MRC:
+	case CBFS_TYPE_MRC_CACHE:
+		pcr_index = TPM_RUNTIME_DATA_PCR;
+		break;
+	case CBFS_TYPE_STAGE:
+	case CBFS_TYPE_SELF:
+	case CBFS_TYPE_FIT:
+		pcr_index = TPM_CRTM_PCR;
+		break;
+	default:
+		if (is_runtime_data(name))
+			pcr_index = TPM_RUNTIME_DATA_PCR;
+		else
+			pcr_index = TPM_CRTM_PCR;
+		break;
+	}
+
+	return tpm_measure_region(&rdev, pcr_index,
+				  name);
+}
diff --git a/src/security/vboot/vboot_crtm.h b/src/security/vboot/vboot_crtm.h
new file mode 100644
index 0000000..84ee9e6
--- /dev/null
+++ b/src/security/vboot/vboot_crtm.h
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Facebook Inc.
+ *
+ * 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_VBOOT_CRTM_H__
+#define __SECURITY_VBOOT_CRTM_H__
+
+#include <program_loading.h>
+#include <security/tpm/tspi.h>
+#include <types.h>
+#include <cbfs.h>
+
+/* CRTM */
+#define TPM_CRTM_PCR 2
+
+/* PCR for measuring data which changes during runtime
+ * e.g. CMOS, NVRAM...
+ */
+#define TPM_RUNTIME_DATA_PCR 3
+
+/*
+ * Initializes the Core Root of Trust for Measurements
+ * in coreboot. The initial code in a chain of trust must measure
+ * itself.
+ *
+ * Summary:
+ *  + Measures bootblock in CBFS or BOOTBLOCK FMAP partition.
+ *  + If vboot starts in romstage, it measures the romstage
+ *    in CBFS.
+ *  + Measure the verstage if it is compiled as separate
+ *    stage.
+ *
+ * Takes the current vboot context as parameter for s3 checks.
+ * returns on success VB2_SUCCESS, else a vboot error.
+ */
+uint32_t vboot_init_crtm(void);
+
+#if (IS_ENABLED(CONFIG_VBOOT_MEASURED_BOOT) && \
+!ENV_BOOTBLOCK && !ENV_DECOMPRESSOR && !ENV_SMM)
+/*
+ * Measures cbfs data via hook (cbfs)
+ * fh is the cbfs file handle to measure
+ * return 0 if successful, else an error
+ */
+uint32_t vboot_measure_cbfs_hook(struct cbfsf *fh, const char *name);
+
+#else
+#define vboot_measure_cbfs_hook(fh, name) 0
+#endif
+
+#endif /* __VBOOT_VBOOT_CRTM_H__ */
diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c
index 1b24160..00bbae6 100644
--- a/src/security/vboot/vboot_logic.c
+++ b/src/security/vboot/vboot_logic.c
@@ -24,6 +24,7 @@
 #include <vb2_api.h>
 #include <security/vboot/misc.h>
 #include <security/vboot/vbnv.h>
+#include <security/vboot/vboot_crtm.h>
 
 #include "antirollback.h"
 
@@ -86,24 +87,21 @@
 }
 
 /* No-op stubs that can be overridden by SoCs with hardware crypto support. */
-__weak
-int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
-			       uint32_t data_size)
+__weak int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+				      uint32_t data_size)
 {
 	return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
 }
 
-__weak
-int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
+__weak int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
 {
-	BUG();	/* Should never get called if init() returned an error. */
+	BUG(); /* Should never get called if init() returned an error. */
 	return VB2_ERROR_UNKNOWN;
 }
 
-__weak
-int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
+__weak int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
 {
-	BUG();	/* Should never get called if init() returned an error. */
+	BUG(); /* Should never get called if init() returned an error. */
 	return VB2_ERROR_UNKNOWN;
 }
 
@@ -249,7 +247,7 @@
 }
 
 static int locate_firmware(struct vb2_context *ctx,
-				struct region_device *fw_main)
+			   struct region_device *fw_main)
 {
 	const char *name;
 
@@ -281,7 +279,7 @@
 static uint32_t extend_pcrs(struct vb2_context *ctx)
 {
 	return vboot_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
-	       vboot_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
+		   vboot_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
 }
 
 /**
@@ -309,7 +307,7 @@
 	 * does verification of memory init and thus must ensure it resumes with
 	 * the same slot that it booted from. */
 	if (IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) &&
-	    vboot_platform_is_resuming())
+		vboot_platform_is_resuming())
 		ctx.flags |= VB2_CONTEXT_S3_RESUME;
 
 	/* Read secdata from TPM. Initialize TPM if secdata not found. We don't
@@ -319,8 +317,15 @@
 	antirollback_read_space_firmware(&ctx);
 	timestamp_add_now(TS_END_TPMINIT);
 
+	/* Enable measured boot mode */
+	if (IS_ENABLED(CONFIG_VBOOT_MEASURED_BOOT) &&
+		!(ctx.flags & VB2_CONTEXT_S3_RESUME)) {
+		if (vboot_init_crtm() != VB2_SUCCESS)
+			die("Initializing measured boot mode failed!");
+	}
+
 	if (IS_ENABLED(CONFIG_VBOOT_PHYSICAL_DEV_SWITCH) &&
-	    get_developer_mode_switch())
+		get_developer_mode_switch())
 		ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
 
 	if (get_recovery_mode_switch()) {
@@ -330,7 +335,7 @@
 	}
 
 	if (IS_ENABLED(CONFIG_VBOOT_WIPEOUT_SUPPORTED) &&
-	    get_wipeout_mode_switch())
+		get_wipeout_mode_switch())
 		ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
 
 	if (IS_ENABLED(CONFIG_VBOOT_LID_SWITCH) && !get_lid_switch())
@@ -350,7 +355,7 @@
 		if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
 			printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
 			save_if_needed(&ctx);
-			extend_pcrs(&ctx);	/* ignore failures */
+			extend_pcrs(&ctx); /* ignore failures */
 			timestamp_add_now(TS_END_VBOOT);
 			return;
 		}
diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc
index 0f6290b..d553e8c 100644
--- a/src/soc/amd/stoneyridge/Makefile.inc
+++ b/src/soc/amd/stoneyridge/Makefile.inc
@@ -89,6 +89,7 @@
 postcar-y += sb_util.c
 postcar-y += nb_util.c
 postcar-$(CONFIG_VBOOT_MEASURED_BOOT) += i2c.c
+postcar-y += tsc_freq.c
 
 ramstage-y += BiosCallOuts.c
 ramstage-y += i2c.c
diff --git a/src/soc/intel/baytrail/Makefile.inc b/src/soc/intel/baytrail/Makefile.inc
index 1debea9..0d4bac5 100644
--- a/src/soc/intel/baytrail/Makefile.inc
+++ b/src/soc/intel/baytrail/Makefile.inc
@@ -14,6 +14,7 @@
 postcar-y += memmap.c
 ramstage-y += tsc_freq.c
 romstage-y += tsc_freq.c
+postcar-y += tsc_freq.c
 smm-y += tsc_freq.c
 ramstage-y += spi.c
 smm-y += spi.c
diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc
index fabbc2b..d5fe1ab 100644
--- a/src/soc/intel/braswell/Makefile.inc
+++ b/src/soc/intel/braswell/Makefile.inc
@@ -16,6 +16,8 @@
 romstage-y += pmutil.c
 romstage-y += tsc_freq.c
 
+postcar-y += tsc_freq.c
+
 ramstage-y += acpi.c
 ramstage-y += chip.c
 ramstage-y += cpu.c
diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc
index acb71fe..1caf67a 100644
--- a/src/soc/intel/broadwell/Makefile.inc
+++ b/src/soc/intel/broadwell/Makefile.inc
@@ -61,6 +61,7 @@
 ramstage-y += tsc_freq.c
 romstage-y += tsc_freq.c
 smm-y      += tsc_freq.c
+postcar-y  += tsc_freq.c
 bootblock-$(CONFIG_USBDEBUG) += usb_debug.c
 romstage-$(CONFIG_USBDEBUG) += usb_debug.c
 ramstage-$(CONFIG_USBDEBUG) += usb_debug.c
diff --git a/src/soc/intel/fsp_baytrail/Makefile.inc b/src/soc/intel/fsp_baytrail/Makefile.inc
index d8c4f71..5ed635d 100644
--- a/src/soc/intel/fsp_baytrail/Makefile.inc
+++ b/src/soc/intel/fsp_baytrail/Makefile.inc
@@ -32,6 +32,7 @@
 romstage-y += memmap.c
 ramstage-y += tsc_freq.c
 romstage-y += tsc_freq.c
+postcar-y += tsc_freq.c
 smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c
 ramstage-y += spi.c
 smm-$(CONFIG_HAVE_SMI_HANDLER) += spi.c
diff --git a/src/soc/intel/fsp_broadwell_de/Makefile.inc b/src/soc/intel/fsp_broadwell_de/Makefile.inc
index 26653b6..0a23170 100644
--- a/src/soc/intel/fsp_broadwell_de/Makefile.inc
+++ b/src/soc/intel/fsp_broadwell_de/Makefile.inc
@@ -24,6 +24,7 @@
 ramstage-y += smbus_common.c
 ramstage-y += smbus.c
 romstage-y += tsc_freq.c
+postcar-y += tsc_freq.c
 ramstage-y += smi.c
 ramstage-y += gpio.c
 ramstage-y += iou_complto.c
diff --git a/src/soc/mediatek/mt8183/include/soc/memlayout.ld b/src/soc/mediatek/mt8183/include/soc/memlayout.ld
index a547083..e01dd1c 100644
--- a/src/soc/mediatek/mt8183/include/soc/memlayout.ld
+++ b/src/soc/mediatek/mt8183/include/soc/memlayout.ld
@@ -39,7 +39,7 @@
 	SRAM_END(0x00120000)
 
 	SRAM_L2C_START(0x00200000)
-	OVERLAP_DECOMPRESSOR_ROMSTAGE(0x000201000, 110K)
+	OVERLAP_DECOMPRESSOR_ROMSTAGE(0x000201000, 152K)
 	BOOTBLOCK(0x00227000, 89K)
 	VERSTAGE(0x0023E000, 114K)
 	SRAM_L2C_END(0x00280000)
diff --git a/util/abuild/abuild b/util/abuild/abuild
index 9afd364..d32b16d 100755
--- a/util/abuild/abuild
+++ b/util/abuild/abuild
@@ -717,7 +717,7 @@
 			chromeos=true
 			testclass=chromeos
 			customizing="${customizing}, chrome os"
-			configoptions="${configoptions}CONFIG_CHROMEOS=y\n"
+			configoptions="${configoptions}CONFIG_CHROMEOS=y\nCONFIG_VBOOT_MEASURED_BOOT=y\n"
 			;;
 		-X|--xmlfile)	shift; XMLFILE=$1; REAL_XMLFILE=$1; shift;;
 		-I|--recursive) shift; recursive=true;;