From 5f9f77672d096a013094f3cad63cb138167dbf1b Mon Sep 17 00:00:00 2001 From: Philipp Deppenwiese Date: Tue, 20 Nov 2018 14:22:15 +0100 Subject: security/intel/txt: Add Intel TXT support Add TXT ramstage driver: * Show startup errors * Check for TXT reset * Check for Secrets-in-memory * Add assembly for GETSEC instruction * Check platform state if GETSEC instruction is supported * Configure TXT memory regions * Lock TXT * Protect TSEG using DMA protected regions * Place SINIT ACM * Print information about ACMs Extend the `security_clear_dram_request()` function: * Clear all DRAM if secrets are in memory Add a config so that the code gets build-tested. Since BIOS and SINIT ACM binaries are not available, use the STM binary as a placeholder. Tested on OCP Wedge100s and Facebook Watson * Able to enter a Measured Launch Environment using SINIT ACM and TBOOT * Secrets in Memory bit is set on ungraceful shutdown * Memory is cleared after ungraceful shutdown Change-Id: Iaf4be7f016cc12d3971e1e1fe171e6665e44c284 Signed-off-by: Philipp Deppenwiese Reviewed-on: https://review.coreboot.org/c/coreboot/+/37016 Tested-by: build bot (Jenkins) Reviewed-by: Christian Walter --- src/security/intel/txt/getsec.c | 117 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/security/intel/txt/getsec.c (limited to 'src/security/intel/txt/getsec.c') diff --git a/src/security/intel/txt/getsec.c b/src/security/intel/txt/getsec.c new file mode 100644 index 0000000000..a42607dccc --- /dev/null +++ b/src/security/intel/txt/getsec.c @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#include "txt_register.h" +#include "txt_getsec.h" + +/** + * Check for SMX support and enable it if possible. + * + * Returns false on error, true on success. + */ +static bool getsec_enabled(void) +{ + unsigned int ecx = cpuid_ecx(1); + /* + * Check if SMX and VMX is supported by CPU. + */ + if (!(ecx & CPUID_SMX) || !(ecx & CPUID_VMX)) + return false; + + /* + * Check if SMX, VMX and GetSec instructions haven't been disabled. + */ + msr_t msr = rdmsr(IA32_FEATURE_CONTROL); + if ((msr.lo & 0xff07) != 0xff07) + return false; + + /* + * Enable SMX. Required to execute GetSec instruction. + * Chapter 2.2.4.3 + * Intel TXT Software Development Guide (Document: 315168-015) + */ + write_cr4(read_cr4() | CR4_SMXE); + + return true; +} + +/** + * Get information as returned by getsec[PARAMETER]. + * Arguments can be set to NULL if not needed. + * + * Returns false on error, true on success. + */ +bool getsec_parameter(uint32_t *version_mask, + uint32_t *version_numbers_supported, + uint32_t *max_size_acm_area, + uint32_t *memory_type_mask, + uint32_t *senter_function_disable, + uint32_t *txt_feature_flags) +{ + uint32_t i, eax, ebx, ecx; + + if (!getsec_enabled()) + return false; + + /* + * SAFER MODE EXTENSIONS REFERENCE. + * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D + */ + for (i = 0; i < 0x1f; i++) { + /* Getsec[PARAMETERS] */ + asm volatile ("getsec\n" + : "=a" (eax), "=b" (ebx), "=c" (ecx) + : "a" (IA32_GETSEC_PARAMETERS), "b" (i) :); + switch (eax & 0x1f) { + case 0: /* NULL - Exit marker */ + return true; + case 1: /* Supported AC module versions */ + if (version_mask) + *version_mask = ebx; + if (version_numbers_supported) + *version_numbers_supported = ecx; + break; + case 2: /* Max size of authenticated code execution area */ + if (max_size_acm_area) + *max_size_acm_area = eax & ~0x1f; + break; + case 3: /* External memory types supported during AC mode */ + if (memory_type_mask) + *memory_type_mask = eax; + break; + case 4: /* Selective SENTER functionality control */ + if (senter_function_disable) + *senter_function_disable = eax & (0x3f00); + break; + case 5: /* TXT extensions support */ + if (txt_feature_flags) + *txt_feature_flags = eax & (0x60); + break; + } + } + + return true; +} + +/** + * Get capabilities as returned by getsec[CAPABILITIES]. + * + * Returns false on error, true on success. + */ + +bool getsec_capabilities(uint32_t *eax) +{ + if (!getsec_enabled()) + return false; + + asm volatile ("getsec\n" + : "=a" (*eax) + : "a" (IA32_GETSEC_CAPABILITIES), "b" (0) :); + + return true; +} -- cgit v1.2.3