diff options
author | Frans Hendriks <fhendriks@eltan.com> | 2019-08-01 15:25:19 +0200 |
---|---|---|
committer | Philipp Deppenwiese <zaolin.daisuki@gmail.com> | 2019-10-04 13:36:13 +0000 |
commit | 7c82dbcc51657806bf2117b214a490bca8eec2f8 (patch) | |
tree | 2fad8be6d18668a05e2b228758461272d3481f42 /src | |
parent | cfe08ff1976bb6a4b922810f2a16132a07e6af47 (diff) | |
download | coreboot-7c82dbcc51657806bf2117b214a490bca8eec2f8.tar.xz |
vendorcode/eltan/security/mboot: Add measured boot support
Create measured boot.
This feature uses the vendorcode/eltan/security/lib.
Measure boot can work with and without Verified boot enabled.
The function mb_measure() is starting point for the support. This
function will be called by the common Verified boot code.
BUG=N/A
TEST=Created binary and verify logging on Facebook FBG-1701
Change-Id: I7f880a17e240515dd42d57383b5ddddf576985b0
Signed-off-by: Frans Hendriks <fhendriks@eltan.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/30833
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vendorcode/eltan/security/mboot/Kconfig | 28 | ||||
-rw-r--r-- | src/vendorcode/eltan/security/mboot/Makefile.inc | 29 | ||||
-rw-r--r-- | src/vendorcode/eltan/security/mboot/mboot.c | 555 | ||||
-rw-r--r-- | src/vendorcode/eltan/security/mboot/mboot.h | 131 | ||||
-rw-r--r-- | src/vendorcode/eltan/security/mboot/mboot_func.c | 28 |
5 files changed, 771 insertions, 0 deletions
diff --git a/src/vendorcode/eltan/security/mboot/Kconfig b/src/vendorcode/eltan/security/mboot/Kconfig new file mode 100644 index 0000000000..c4e8dbabee --- /dev/null +++ b/src/vendorcode/eltan/security/mboot/Kconfig @@ -0,0 +1,28 @@ +## This file is part of the coreboot project. +## +## Copyright (C) 2018-2019 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +menu "Measured Boot (mboot)" + +config VENDORCODE_ELTAN_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 VENDORCODE_ELTAN_CRTM_VERSION_STRING + string "default CRTM version" + default "default CRTM version" + +endmenu # Measured Boot (mboot) diff --git a/src/vendorcode/eltan/security/mboot/Makefile.inc b/src/vendorcode/eltan/security/mboot/Makefile.inc new file mode 100644 index 0000000000..68b38586b1 --- /dev/null +++ b/src/vendorcode/eltan/security/mboot/Makefile.inc @@ -0,0 +1,29 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2018-2019 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +ifneq ($(filter y,$(CONFIG_VENDORCODE_ELTAN_VBOOT) $(CONFIG_VENDORCODE_ELTAN_MBOOT)),) +CPPFLAGS_common += -I$(src)/security/mboot +endif + +ifeq ($(CONFIG_VENDORCODE_ELTAN_MBOOT),y) +postcar-y += mboot.c + +ramstage-y += mboot.c +ramstage-y += mboot_func.c + +romstage-y += mboot.c +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR) + +endif # CONFIG_VENDORCODE_ELTAN_VBOOT or CONFIG_VENDORCODE_ELTAN_MBOOT diff --git a/src/vendorcode/eltan/security/mboot/mboot.c b/src/vendorcode/eltan/security/mboot/mboot.c new file mode 100644 index 0000000000..5774429329 --- /dev/null +++ b/src/vendorcode/eltan/security/mboot/mboot.c @@ -0,0 +1,555 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corporation + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <mboot.h> +#include <assert.h> +#include <build.h> +#include <vb2_api.h> +#include <board_mboot.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", __func__, + 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_get_capability 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; + int status; + int index; + + status = tlcl_get_capability(TPM_CAP_PCRS, 0, 1, &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", __func__, + (size_t)hashDataLen); + + if (invalid) { + digest = &(newEventHdr->digest.digests[digest_num]); + 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, + VB2_SHA1_DIGEST_SIZE); + } else { + status = cb_sha_endian(VB2_HASH_SHA1, hashData, + hashDataLen, + digest->digest.sha1, + NO_ENDIAN_ALGORITHM); + if ( status ) + return TPM_E_IOERROR; + } + + digest->hashAlg = TPM_ALG_SHA1; + digest_num++; + + printk(BIOS_DEBUG, "%s: SHA1 Hash Digest:\n", __func__); + mboot_print_buffer(digest->digest.sha1, + VB2_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 { + status = cb_sha_endian(VB2_HASH_SHA256, hashData, + hashDataLen, + digest->digest.sha256, + LITTLE_ENDIAN_ALGORITHM); + if (status) + return TPM_E_IOERROR; + } + digest->hashAlg = TPM_ALG_SHA256; + digest_num++; + + printk(BIOS_DEBUG, "%s: SHA256 Hash Digest:\n", + __func__); + mboot_print_buffer(digest->digest.sha256, + VB2_SHA256_DIGEST_SIZE); + } + } + + newEventHdr->digest.count = digest_num; + + status = tlcl_extend(newEventHdr->pcrIndex, (uint8_t *)&(newEventHdr->digest), + NULL); + if (status != TPM_SUCCESS) + printk(BIOS_DEBUG, "%s: returned 0x%x\n", __func__, 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", __func__, 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", __func__, 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", __func__, name); + base = cbfs_boot_map_with_leak(name, type, &size); + + if (base == NULL) { + printk(BIOS_DEBUG, "%s: CBFS locate fail: %s\n", __func__, + name); + return VB2_ERROR_READ_FILE_OPEN; + } + + printk(BIOS_DEBUG, "%s: CBFS locate success: %s\n", + __func__, 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", __func__); + if (tlcl_lib_init() != VB2_SUCCESS) { + printk(BIOS_ERR, "%s: TPM driver initialization failed.\n", + __func__); + return TPM_E_IOERROR; + } + + if (wake_from_s3) { + printk(BIOS_DEBUG, "%s: tlcl_resume\n", __func__); + status = tlcl_resume(); + } else { + printk(BIOS_DEBUG, "%s: tlcl_startup\n", __func__); + status = tlcl_startup(); + } + + if (status) + printk(BIOS_ERR, "%s: StartUp failed 0x%x!\n", __func__, + 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", __func__); + status = mb_measure_log_start(); + if (status == TPM_SUCCESS) { + printk(BIOS_DEBUG, "%s: Measuring, successful!\n", + __func__); + } else { + invalidate_pcrs(); + printk(BIOS_ERR, "%s: Measuring returned 0x%x " + "unsuccessful! PCRs invalidated.\n", + __func__, status); + } + } else { + invalidate_pcrs(); + printk(BIOS_ERR, "%s: StartUp returned 0x%x, unsuccessful!" + "PCRs invalidated.\n", __func__, 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 + * + * 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", + __func__); + return TPM_E_IOERROR; + } + + status = mb_crtm(ActivePcrs); + if (status != TPM_SUCCESS) { + printk(BIOS_DEBUG, "%s: Fail! CRTM Version can't be measured." + " ABORTING!!!\n", __func__); + return status; + } + printk(BIOS_DEBUG, "%s: Success! CRTM Version measured.\n", __func__); + + /* Log the items defined by the mainboard */ + for (i = 0; i < ARRAY_SIZE(mb_log_list); 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: Fail! %s can't be measured." + "ABORTING!!!\n", __func__, + mb_log_list[i].cbfs_name); + return status; + } + printk(BIOS_DEBUG, "%s: Success! %s measured to pcr" + "%d.\n", __func__, mb_log_list[i].cbfs_name, + mb_log_list[i].pcr); + } + return status; +} + +static const uint8_t crtm_version[] = + CONFIG_VENDORCODE_ELTAN_CRTM_VERSION_STRING\ + COREBOOT_VERSION COREBOOT_EXTRA_VERSION " " COREBOOT_BUILD; + +/* + * + * 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[VB2_SHA256_DIGEST_SIZE]; + uint8_t *msgPtr; + + /* Use FirmwareVersion string to represent CRTM version. */ + printk(BIOS_DEBUG, "%s: Measure CRTM Version\n", __func__); + 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", __func__, + 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); + return status; + } + + status = get_intel_me_hash(hash); + if (status) { + printk(BIOS_DEBUG, "get_intel_me_hash returned 0x%x\n", status); + status = TPM_E_IOERROR; + return status; + } + + /* Add the me hash */ + printk(BIOS_DEBUG, "%s: Add the hash returned by the ME\n", + __func__); + memset(&tcgEventHdr, 0, sizeof(tcgEventHdr)); + tcgEventHdr.pcrIndex = MBOOT_PCR_INDEX_0; + tcgEventHdr.eventType = EV_S_CRTM_CONTENTS; + + msgPtr = NULL; + tcgEventHdr.eventSize = 0; + status = mboot_hash_extend_log(activePcr, MBOOT_HASH_PROVIDED, hash, + sizeof(hash), &tcgEventHdr, msgPtr, 0); + if (status) + printk(BIOS_DEBUG, "Add ME hash returned 0x%x\n", status); + + return status; +} +#endif // __PRE_RAM__ diff --git a/src/vendorcode/eltan/security/mboot/mboot.h b/src/vendorcode/eltan/security/mboot/mboot.h new file mode 100644 index 0000000000..96375aba5b --- /dev/null +++ b/src/vendorcode/eltan/security/mboot/mboot.h @@ -0,0 +1,131 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corporation + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MBOOT_H +#define MBOOT_H + +#include <arch/io.h> +#include <arch/acpi.h> +#include <string.h> +#include <cb_sha.h> +#include <console/console.h> +#include <cbfs.h> +#include <lib.h> +#include <boot/coreboot_tables.h> +#include <security/tpm/tss/tcg-2.0/tss_structures.h> +#include <security/tpm/tss.h> +#include <swab.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 */ + +/* Index to a PCR register */ +typedef uint32_t TPM_PCRINDEX; +typedef uint32_t TCG_EVENTTYPE; +typedef TPM_PCRINDEX TCG_PCRINDEX; +typedef int8_t TCG_DIGEST; + +/* TCG_PCR_EVENT_HDR */ +typedef struct { + TCG_PCRINDEX pcrIndex; + TCG_EVENTTYPE eventType; + TCG_DIGEST digest[TPM_SHA1_160_HASH_LEN]; + uint32_t eventSize; +} __packed TCG_PCR_EVENT_HDR; + +/* TCG_PCR_EVENT2_HDR */ +typedef struct { + 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 *buffer, unsigned int size); + +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); + +int mb_measure(int wake_from_s3); +int mb_entry(int wake_from_s3); + +int log_efi_specid_event(EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrs); +int log_event_tcg_20_format(TCG_PCR_EVENT2_HDR *EventHdr, uint8_t *EventLog); +int log_event_tcg_12_format(TCG_PCR_EVENT2_HDR *EventHdr, uint8_t *EventLog); + +int get_intel_me_hash(uint8_t *hash); + +#endif /* MBOOT_H */ diff --git a/src/vendorcode/eltan/security/mboot/mboot_func.c b/src/vendorcode/eltan/security/mboot/mboot_func.c new file mode 100644 index 0000000000..ec66d345d0 --- /dev/null +++ b/src/vendorcode/eltan/security/mboot/mboot_func.c @@ -0,0 +1,28 @@ +/* + * 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 <mboot.h> + +int log_efi_specid_event(EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrs) { + return TPM_SUCCESS; +} + +int log_event_tcg_12_format(TCG_PCR_EVENT2_HDR *EventHdr, uint8_t *EventLog) { + return TPM_SUCCESS; +} + +int log_event_tcg_20_format(TCG_PCR_EVENT2_HDR *EventHdr, uint8_t *EventLog) { + return TPM_SUCCESS; +} |