xref: /aosp_15_r20/external/coreboot/src/security/intel/txt/common.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cbfs.h>
4 #include <console/console.h>
5 #include <cpu/x86/cr.h>
6 #include <cpu/x86/mp.h>
7 #include <cpu/x86/msr.h>
8 #include <cpu/x86/mtrr.h>
9 #include <device/mmio.h>
10 #include <lib.h>
11 #include <smp/node.h>
12 #include <string.h>
13 #include <types.h>
14 
15 #if CONFIG(SOC_INTEL_COMMON_BLOCK_SA)
16 #include <soc/intel/common/reset.h>
17 #else
18 #if CONFIG(SOUTHBRIDGE_INTEL_COMMON_ME)
19 #include <southbridge/intel/common/me.h>
20 #endif
21 #include <cf9_reset.h>
22 #endif
23 
24 #include "txt.h"
25 #include "txt_register.h"
26 #include "txt_getsec.h"
27 
28 /* Usual security practice: if an unexpected error happens, reboot */
txt_reset_platform(void)29 void __noreturn txt_reset_platform(void)
30 {
31 #if CONFIG(SOC_INTEL_COMMON_BLOCK_SA)
32 	global_reset();
33 #else
34 #if CONFIG(SOUTHBRIDGE_INTEL_COMMON_ME)
35 	set_global_reset(1);
36 #endif
37 	full_reset();
38 #endif
39 }
40 
41 /**
42  * Dump the ACM error status bits.
43  *
44  * @param  acm_error The status register to dump
45  * @return -1 on error (register is not valid)
46  *	  0 on error (Class > 0 and Major > 0)
47  *	  1 on success (Class == 0 and Major == 0 and progress > 0)
48  */
intel_txt_log_acm_error(const uint32_t acm_error)49 int intel_txt_log_acm_error(const uint32_t acm_error)
50 {
51 	if (!(acm_error & ACMERROR_TXT_VALID))
52 		return -1;
53 
54 	const uint8_t type = (acm_error & ACMERROR_TXT_TYPE_CODE)
55 			      >> ACMERROR_TXT_TYPE_SHIFT;
56 
57 	switch (type) {
58 	case ACMERROR_TXT_AC_MODULE_TYPE_BIOS:
59 		printk(BIOS_ERR, "BIOSACM");
60 		break;
61 	case ACMERROR_TXT_AC_MODULE_TYPE_SINIT:
62 		printk(BIOS_ERR, "SINIT");
63 		break;
64 	default:
65 		printk(BIOS_ERR, "ACM");
66 		break;
67 	}
68 	printk(BIOS_ERR, ": Error code valid\n");
69 
70 	if (acm_error & ACMERROR_TXT_EXTERNAL)
71 		printk(BIOS_ERR, " Caused by: External\n");
72 	else
73 		printk(BIOS_ERR, " Caused by: Processor\n");
74 
75 	const uint32_t class = (acm_error & ACMERROR_TXT_CLASS_CODE)
76 							>> ACMERROR_TXT_CLASS_SHIFT;
77 	const uint32_t major = (acm_error & ACMERROR_TXT_MAJOR_CODE)
78 							>> ACMERROR_TXT_MAJOR_SHIFT;
79 	const uint32_t minor = (acm_error & ACMERROR_TXT_MINOR_CODE)
80 							>> ACMERROR_TXT_MINOR_SHIFT;
81 	const uint32_t progress = (acm_error & ACMERROR_TXT_PROGRESS_CODE)
82 							>> ACMERROR_TXT_PROGRESS_SHIFT;
83 
84 	if (!minor) {
85 		if (class == 0 && major == 0 && progress > 0) {
86 			printk(BIOS_ERR, " Execution successful\n");
87 			printk(BIOS_ERR, " Progress code 0x%x\n", progress);
88 		} else {
89 			printk(BIOS_ERR, " Error Class: %x\n", class);
90 			printk(BIOS_ERR, " Error: %x.%x\n", major, progress);
91 		}
92 	} else {
93 		printk(BIOS_ERR, " ACM didn't start\n");
94 		printk(BIOS_ERR, " Error Type: 0x%x\n", acm_error & 0xffffff);
95 		return -1;
96 	}
97 
98 	return (acm_error & ACMERROR_TXT_EXTERNAL) && class == 0 && major == 0 && progress > 0;
99 }
100 
intel_txt_log_spad(void)101 void intel_txt_log_spad(void)
102 {
103 	const uint64_t acm_status = read64p(TXT_SPAD);
104 
105 	printk(BIOS_INFO, "TXT-STS: ACM verification ");
106 
107 	if (acm_status & ACMSTS_VERIFICATION_ERROR)
108 		printk(BIOS_INFO, "error\n");
109 	else
110 		printk(BIOS_INFO, "successful\n");
111 
112 	printk(BIOS_INFO, "TXT-STS: IBB ");
113 
114 	if (acm_status & ACMSTS_IBB_MEASURED)
115 		printk(BIOS_INFO, "measured\n");
116 	else
117 		printk(BIOS_INFO, "not measured\n");
118 
119 	printk(BIOS_INFO, "TXT-STS: TXT is ");
120 
121 	if (acm_status & ACMSTS_TXT_DISABLED)
122 		printk(BIOS_INFO, "disabled\n");
123 	else
124 		printk(BIOS_INFO, "not disabled\n");
125 
126 	printk(BIOS_INFO, "TXT-STS: BIOS is ");
127 
128 	if (acm_status & ACMSTS_BIOS_TRUSTED)
129 		printk(BIOS_INFO, "trusted\n");
130 	else
131 		printk(BIOS_INFO, "not trusted\n");
132 }
133 
134 /* Returns true if secrets might be in memory */
intel_txt_memory_has_secrets(void)135 bool intel_txt_memory_has_secrets(void)
136 {
137 	bool ret;
138 	if (!CONFIG(INTEL_TXT))
139 		return false;
140 
141 	ret = (read8p(TXT_ESTS) & TXT_ESTS_WAKE_ERROR_STS) ||
142 	      (read64p(TXT_E2STS) & TXT_E2STS_SECRET_STS);
143 
144 	if (ret)
145 		printk(BIOS_CRIT, "TXT-STS: Secrets in memory!\n");
146 	return ret;
147 }
148 
intel_txt_chipset_is_production_fused(void)149 bool intel_txt_chipset_is_production_fused(void)
150 {
151 	/*
152 	 * Certain chipsets report production fused information in either
153 	 * TXT.VER.FSBIF or TXT.VER.EMIF/TXT.VER.QPIIF.
154 	 * Chapter B.1.7 and B.1.9
155 	 * Intel TXT Software Development Guide (Document: 315168-015)
156 	 */
157 	uint32_t reg = read32p(TXT_VER_FSBIF);
158 
159 	if (reg == 0 || reg == UINT32_MAX)
160 		reg = read32p(TXT_VER_QPIIF);
161 
162 	return (reg & TXT_VER_PRODUCTION_FUSED) ? true : false;
163 }
164 
find_info_table(const void * ptr)165 static struct acm_info_table *find_info_table(const void *ptr)
166 {
167 	const struct acm_header_v0 *acm_header = (struct acm_header_v0 *)ptr;
168 
169 	return (struct acm_info_table *)(ptr +
170 		(acm_header->header_len + acm_header->scratch_size) * sizeof(uint32_t));
171 }
172 
173 /**
174  * Validate that the provided ACM is usable on this platform.
175  */
validate_acm(const void * ptr)176 static int validate_acm(const void *ptr)
177 {
178 	const struct acm_header_v0 *acm_header = (struct acm_header_v0 *)ptr;
179 	uint32_t max_size_acm_area = 0;
180 
181 	if (acm_header->module_type != CHIPSET_ACM)
182 		return ACM_E_TYPE_NOT_MATCH;
183 
184 	/* Seems inconsistent across generations. */
185 	if (acm_header->module_sub_type != 0 && acm_header->module_sub_type != 1)
186 		return ACM_E_MODULE_SUB_TYPE_WRONG;
187 
188 	if (acm_header->module_vendor != INTEL_ACM_VENDOR)
189 		return ACM_E_MODULE_VENDOR_NOT_INTEL;
190 
191 	if (acm_header->size == 0)
192 		return ACM_E_SIZE_INCORRECT;
193 
194 	if (((acm_header->header_len + acm_header->scratch_size) * sizeof(uint32_t) +
195 	    sizeof(struct acm_info_table)) > (acm_header->size & 0xffffff) * sizeof(uint32_t)) {
196 		return ACM_E_SIZE_INCORRECT;
197 	}
198 
199 	if (!getsec_parameter(NULL, NULL, &max_size_acm_area, NULL, NULL, NULL))
200 		return ACM_E_CANT_CALL_GETSEC;
201 
202 	/*
203 	 * Causes #GP if acm_header->size > processor internal authenticated
204 	 * code area capacity.
205 	 * SAFER MODE EXTENSIONS REFERENCE.
206 	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
207 	 */
208 	const size_t acm_len = 1UL << log2_ceil((acm_header->size & 0xffffff) << 2);
209 	if (max_size_acm_area < acm_len) {
210 		printk(BIOS_ERR, "TEE-TXT: BIOS ACM doesn't fit into AC execution region\n");
211 		return ACM_E_NOT_FIT_INTO_CPU_ACM_MEM;
212 	}
213 
214 	struct acm_info_table *info = find_info_table(ptr);
215 	if (!info)
216 		return ACM_E_NO_INFO_TABLE;
217 	if (info->chipset_acm_type != BIOS)
218 		return ACM_E_NOT_BIOS_ACM;
219 
220 	static const u8 acm_uuid[] = {
221 		0xaa, 0x3a, 0xc0, 0x7f, 0xa7, 0x46, 0xdb, 0x18,
222 		0x2e, 0xac, 0x69, 0x8f, 0x8d, 0x41, 0x7f, 0x5a,
223 	};
224 	if (memcmp(acm_uuid, info->uuid, sizeof(acm_uuid)) != 0)
225 		return ACM_E_UUID_NOT_MATCH;
226 
227 	const bool production_acm = !(acm_header->flags & ACM_FORMAT_FLAGS_DEBUG);
228 	if (production_acm != intel_txt_chipset_is_production_fused())
229 		return ACM_E_PLATFORM_IS_NOT_PROD;
230 
231 	return 0;
232 }
233 
234 /*
235  * Prepare to run the BIOS ACM: mmap it from the CBFS and verify that it
236  * can be launched. Returns pointer to ACM on success, NULL on failure.
237  */
intel_txt_prepare_bios_acm(size_t * acm_len)238 static void *intel_txt_prepare_bios_acm(size_t *acm_len)
239 {
240 	void *acm_data = NULL;
241 
242 	if (!acm_len)
243 		return NULL;
244 
245 	acm_data = cbfs_map(CONFIG_INTEL_TXT_CBFS_BIOS_ACM, acm_len);
246 	if (!acm_data) {
247 		printk(BIOS_ERR, "TEE-TXT: Couldn't locate BIOS ACM in CBFS.\n");
248 		return NULL;
249 	}
250 
251 	/*
252 	 * CPU enforces only 4KiB alignment.
253 	 * Chapter A.1.1
254 	 * Intel TXT Software Development Guide (Document: 315168-015)
255 	 */
256 	if (!IS_ALIGNED((uintptr_t)acm_data, 4096)) {
257 		printk(BIOS_ERR, "TEE-TXT: BIOS ACM isn't mapped at page boundary.\n");
258 		cbfs_unmap(acm_data);
259 		return NULL;
260 	}
261 
262 	/*
263 	 * Causes #GP if not multiple of 64.
264 	 * SAFER MODE EXTENSIONS REFERENCE.
265 	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
266 	 */
267 	if (!IS_ALIGNED(*acm_len, 64)) {
268 		printk(BIOS_ERR, "TEE-TXT: BIOS ACM size isn't multiple of 64.\n");
269 		cbfs_unmap(acm_data);
270 		return NULL;
271 	}
272 
273 	/*
274 	 * The ACM should be aligned to it's size, but that's not possible, as
275 	 * some ACMs are not power of two. Use the next power of two for verification.
276 	 */
277 	if (!IS_ALIGNED((uintptr_t)acm_data, (1UL << log2_ceil(*acm_len)))) {
278 		printk(BIOS_ERR, "TEE-TXT: BIOS ACM isn't aligned to its size.\n");
279 		cbfs_unmap(acm_data);
280 		return NULL;
281 	}
282 
283 	/*
284 	 * When setting up the MTRRs to cache the BIOS ACM, one must cache less than
285 	 * a page (4 KiB) of unused memory after the BIOS ACM. On Haswell, failure
286 	 * to do so will cause a TXT reset with Class Code 5, Major Error Code 2.
287 	 */
288 	if (popcnt(ALIGN_UP(*acm_len, 4096)) > get_var_mtrr_count()) {
289 		printk(BIOS_ERR, "TEE-TXT: Not enough MTRRs to cache this BIOS ACM's size.\n");
290 		cbfs_unmap(acm_data);
291 		return NULL;
292 	}
293 
294 	if (CONFIG(INTEL_TXT_LOGGING))
295 		txt_dump_acm_info(acm_data);
296 
297 	const int ret = validate_acm(acm_data);
298 	if (ret < 0) {
299 		printk(BIOS_ERR, "TEE-TXT: Validation of ACM failed with: %d\n", ret);
300 		cbfs_unmap(acm_data);
301 		return NULL;
302 	}
303 
304 	return acm_data;
305 }
306 
307 #define MCU_BASE_ADDR	(TXT_BASE + 0x278)
308 #define BIOACM_ADDR	(TXT_BASE + 0x27c)
309 #define APINIT_ADDR	(TXT_BASE + 0x290)
310 #define SEMAPHORE	(TXT_BASE + 0x294)
311 
312 /* Returns on failure, resets the computer on success */
intel_txt_run_sclean(void)313 void intel_txt_run_sclean(void)
314 {
315 	size_t acm_len;
316 
317 	void *acm_data = intel_txt_prepare_bios_acm(&acm_len);
318 
319 	if (!acm_data)
320 		return;
321 
322 	/* FIXME: Do we need to program these two? */
323 	//write32p(MCU_BASE_ADDR, 0xffe1a990);
324 	//write32p(APINIT_ADDR, 0xfffffff0);
325 
326 	write32p(BIOACM_ADDR, (uintptr_t)acm_data);
327 	write32p(SEMAPHORE, 0);
328 
329 	/*
330 	 * The time SCLEAN will take depends on the installed RAM size.
331 	 * On Haswell with 8 GiB of DDR3, it takes five or ten minutes. (rough estimate)
332 	 */
333 	printk(BIOS_ALERT, "TEE-TXT: Invoking SCLEAN. This can take several minutes.\n");
334 
335 	/*
336 	 * Invoke the BIOS ACM. If successful, the system will reset with memory unlocked.
337 	 */
338 	getsec_sclean((uintptr_t)acm_data, acm_len);
339 
340 	/*
341 	 * However, if this function returns, the BIOS ACM could not be invoked. This is bad.
342 	 */
343 	printk(BIOS_CRIT, "TEE-TXT: getsec_sclean could not launch the BIOS ACM.\n");
344 
345 	cbfs_unmap(acm_data);
346 }
347 
348 /*
349  * Test all bits for TXT execution.
350  *
351  * @return 0 on success
352  */
intel_txt_run_bios_acm(const u8 input_params)353 int intel_txt_run_bios_acm(const u8 input_params)
354 {
355 	size_t acm_len;
356 
357 	void *acm_data = intel_txt_prepare_bios_acm(&acm_len);
358 
359 	if (!acm_data)
360 		return -1;
361 
362 	/* Call into assembly which invokes the referenced ACM */
363 	getsec_enteraccs(input_params, (uintptr_t)acm_data, acm_len);
364 
365 	cbfs_unmap(acm_data);
366 
367 	const uint64_t acm_status = read64p(TXT_SPAD);
368 	if (acm_status & ACMERROR_TXT_VALID) {
369 		printk(BIOS_ERR, "TEE-TXT: FATAL ACM launch error !\n");
370 		/*
371 		 * WARNING !
372 		 * To clear TXT.BIOSACM.ERRORCODE you must issue a cold reboot!
373 		 */
374 		intel_txt_log_acm_error(read32p(TXT_BIOSACM_ERRORCODE));
375 		return -1;
376 	}
377 
378 	return 0;
379 }
380 
381  /* Returns true if cond is not met */
check_precondition(const int cond)382 static bool check_precondition(const int cond)
383 {
384 	printk(BIOS_DEBUG, "%s\n", cond ? "true" : "false");
385 	return !cond;
386 }
387 
388 /*
389  * Test all bits that are required for Intel TXT.
390  * Enable SMX if available.
391  *
392  * @return 0 on success
393  */
intel_txt_prepare_txt_env(void)394 bool intel_txt_prepare_txt_env(void)
395 {
396 	bool failure = false;
397 	uint32_t txt_feature_flags = 0;
398 
399 	unsigned int ecx = cpuid_ecx(1);
400 
401 	printk(BIOS_DEBUG, "TEE-TXT: CPU supports SMX: ");
402 	failure |= check_precondition(ecx & CPUID_SMX);
403 
404 	printk(BIOS_DEBUG, "TEE-TXT: CPU supports VMX: ");
405 	failure |= check_precondition(ecx & CPUID_VMX);
406 
407 	msr_t msr = rdmsr(IA32_FEATURE_CONTROL);
408 	if (!(msr.lo & BIT(0))) {
409 		printk(BIOS_ERR, "TEE-TXT: IA32_FEATURE_CONTROL is not locked\n");
410 		txt_reset_platform();
411 	}
412 
413 	printk(BIOS_DEBUG, "TEE-TXT: IA32_FEATURE_CONTROL\n");
414 	printk(BIOS_DEBUG, " VMXON in SMX enable: ");
415 	failure |= check_precondition(msr.lo & BIT(1));
416 
417 	printk(BIOS_DEBUG, " VMXON outside SMX enable: ");
418 	failure |= check_precondition(msr.lo & FEATURE_ENABLE_VMX);
419 
420 	printk(BIOS_DEBUG, " register is locked: ");
421 	failure |= check_precondition(msr.lo & BIT(0));
422 
423 	/* IA32_FEATURE_CONTROL enables getsec instructions */
424 	printk(BIOS_DEBUG, " GETSEC (all instructions) is enabled: ");
425 	failure |= check_precondition((msr.lo & 0xff00) == 0xff00);
426 
427 	/* Prevent crash and opt out early */
428 	if (failure)
429 		return true;
430 
431 	uint32_t eax = 0;
432 	/*
433 	 * GetSec[CAPABILITIES]
434 	 * SAFER MODE EXTENSIONS REFERENCE.
435 	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
436 	 * Must check BIT0 of TXT chipset has been detected by CPU.
437 	 */
438 	if (!getsec_capabilities(&eax))
439 		return true;
440 
441 	printk(BIOS_DEBUG, "TEE-TXT: GETSEC[CAPABILITIES] returned:\n");
442 	printk(BIOS_DEBUG, " TXT capable chipset:  %s\n", (eax & BIT(0)) ? "true" : "false");
443 
444 	printk(BIOS_DEBUG, " ENTERACCS available:  %s\n", (eax & BIT(2)) ? "true" : "false");
445 	printk(BIOS_DEBUG, " EXITAC available:     %s\n", (eax & BIT(3)) ? "true" : "false");
446 	printk(BIOS_DEBUG, " SENTER available:     %s\n", (eax & BIT(4)) ? "true" : "false");
447 	printk(BIOS_DEBUG, " SEXIT available:      %s\n", (eax & BIT(5)) ? "true" : "false");
448 	printk(BIOS_DEBUG, " PARAMETERS available: %s\n", (eax & BIT(6)) ? "true" : "false");
449 	printk(BIOS_DEBUG, " SMCTRL available:     %s\n", (eax & BIT(7)) ? "true" : "false");
450 	printk(BIOS_DEBUG, " WAKEUP available:     %s\n", (eax & BIT(8)) ? "true" : "false");
451 
452 	txt_dump_getsec_parameters();
453 
454 	/*
455 	 * Causes #GP if function is not supported by getsec.
456 	 * SAFER MODE EXTENSIONS REFERENCE.
457 	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
458 	 * Order Number:  325383-060US
459 	 */
460 	if ((eax & 0x7d) != 0x7d)
461 		failure = true;
462 
463 	const uint64_t status = read64p(TXT_SPAD);
464 
465 	if (status & ACMSTS_TXT_DISABLED) {
466 		printk(BIOS_INFO, "TEE-TXT: TXT disabled by BIOS policy in FIT.\n");
467 		failure = true;
468 	}
469 
470 	/*
471 	 * Only the BSP must call getsec[ENTERACCS].
472 	 * SAFER MODE EXTENSIONS REFERENCE.
473 	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
474 	 * Order Number:  325383-060US
475 	 */
476 	if (!boot_cpu()) {
477 		printk(BIOS_ERR, "TEE-TXT: BSP flag not set in APICBASE_MSR.\n");
478 		failure = true;
479 	}
480 
481 	/*
482 	 * There must be no MCEs pending.
483 	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
484 	 * Order Number:  325383-060US
485 	 */
486 	msr = rdmsr(IA32_MCG_STATUS);
487 	if (msr.lo & 0x4) {
488 		printk(BIOS_ERR, "TEE-TXT: IA32_MCG_STATUS.MCIP is set.\n");
489 		failure = true;
490 	}
491 
492 	if (!getsec_parameter(NULL, NULL, NULL, NULL, NULL, &txt_feature_flags))
493 		return true;
494 
495 	printk(BIOS_DEBUG, "TEE-TXT: Machine Check Register: ");
496 	if (txt_feature_flags & GETSEC_PARAMS_TXT_EXT_MACHINE_CHECK)
497 		printk(BIOS_DEBUG, "preserved\n");
498 	else
499 		printk(BIOS_DEBUG, "must be clear\n");
500 
501 	if (!(txt_feature_flags & GETSEC_PARAMS_TXT_EXT_MACHINE_CHECK)) {
502 		/*
503 		* Make sure there are no uncorrectable MCE errors.
504 		* Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
505 		*/
506 		size_t max_mc_msr = mca_get_bank_count();
507 		for (size_t i = 0; i < max_mc_msr; i++) {
508 			msr = rdmsr(IA32_MC_STATUS(i));
509 			if (!(msr.hi & MCA_STATUS_HI_UC))
510 				continue;
511 
512 			printk(BIOS_ERR, "TEE-TXT: IA32_MC%zd_STATUS.UC is set.\n", i);
513 			failure = true;
514 			break;
515 		}
516 	}
517 
518 	/* Need to park all APs. */
519 	if (CONFIG(PARALLEL_MP_AP_WORK))
520 		mp_park_aps();
521 
522 	return failure;
523 }
524