xref: /aosp_15_r20/external/coreboot/src/security/vboot/secdata_tpm2.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 
3 #include <security/vboot/antirollback.h>
4 #include <security/tpm/tss.h>
5 #include <vb2_api.h>
6 
7 #include "secdata_tpm_private.h"
8 
read_space_mrc_hash(uint32_t index,uint8_t * data)9 static tpm_result_t read_space_mrc_hash(uint32_t index, uint8_t *data)
10 {
11 	RETURN_ON_FAILURE(tlcl_read(index, data,
12 				    HASH_NV_SIZE));
13 	return TPM_SUCCESS;
14 }
15 
16 /*
17  * This is used to initialize the TPM space for recovery hash after defining
18  * it. Since there is no data available to calculate hash at the point where TPM
19  * space is defined, initialize it to all 0s.
20  */
21 static const uint8_t mrc_hash_data[HASH_NV_SIZE] = { };
22 
23 /*
24  * Different sets of NVRAM space attributes apply to the "ro" spaces,
25  * i.e. those which should not be possible to delete or modify once
26  * the RO exits, and the rest of the NVRAM spaces.
27  */
28 static const TPMA_NV ro_space_attributes = {
29 	.TPMA_NV_PPWRITE = 1,
30 	.TPMA_NV_AUTHREAD = 1,
31 	.TPMA_NV_PPREAD = 1,
32 	.TPMA_NV_PLATFORMCREATE = 1,
33 	.TPMA_NV_WRITE_STCLEAR = 1,
34 	.TPMA_NV_POLICY_DELETE = 1,
35 };
36 
37 static const TPMA_NV rw_space_attributes = {
38 	.TPMA_NV_PPWRITE = 1,
39 	.TPMA_NV_AUTHREAD = 1,
40 	.TPMA_NV_PPREAD = 1,
41 	.TPMA_NV_PLATFORMCREATE = 1,
42 	.TPMA_NV_WRITE_STCLEAR = 1,
43 };
44 
45 static const TPMA_NV rw_auth_space_attributes = {
46 	.TPMA_NV_AUTHWRITE = 1,
47 	.TPMA_NV_AUTHREAD = 1,
48 	.TPMA_NV_NO_DA = 1,
49 	.TPMA_NV_PPREAD = 1,
50 	.TPMA_NV_PPWRITE = 1,
51 	.TPMA_NV_PLATFORMCREATE = 1,
52 	.TPMA_NV_WRITE_STCLEAR = 1,
53 	.TPMA_NV_POLICY_DELETE = 1,
54 };
55 
56 static const TPMA_NV fwmp_attr = {
57 	.TPMA_NV_PLATFORMCREATE = 1,
58 	.TPMA_NV_OWNERWRITE = 1,
59 	.TPMA_NV_AUTHREAD = 1,
60 	.TPMA_NV_PPREAD = 1,
61 	.TPMA_NV_PPWRITE = 1,
62 };
63 
64 /* Attributes for spaces that enable zero-touch enrollment (ZTE) */
65 static const TPMA_NV zte_attr = {
66 	.TPMA_NV_PLATFORMCREATE = 1,
67 	.TPMA_NV_WRITEDEFINE = 1,
68 	.TPMA_NV_AUTHWRITE = 1,
69 	.TPMA_NV_AUTHREAD = 1,
70 	.TPMA_NV_PPWRITE = 1,
71 	.TPMA_NV_PPREAD = 1,
72 	.TPMA_NV_NO_DA = 1,
73 	.TPMA_NV_POLICY_DELETE = 1,
74 };
75 
76 static const TPMA_NV zte_rma_bytes_attr = {
77 	.TPMA_NV_PLATFORMCREATE = 1,
78 	.TPMA_NV_BITS = 1,
79 	.TPMA_NV_AUTHWRITE = 1,
80 	.TPMA_NV_AUTHREAD = 1,
81 	.TPMA_NV_PPWRITE = 1,
82 	.TPMA_NV_PPREAD = 1,
83 	.TPMA_NV_NO_DA = 1,
84 	.TPMA_NV_POLICY_DELETE = 1,
85 };
86 
87 static const TPMA_NV rw_orderly_counter_attributes = {
88 	.TPMA_NV_COUNTER = 1,
89 	.TPMA_NV_ORDERLY = 1,
90 	.TPMA_NV_AUTHREAD = 1,
91 	.TPMA_NV_AUTHWRITE = 1,
92 	.TPMA_NV_PLATFORMCREATE = 1,
93 	.TPMA_NV_WRITE_STCLEAR = 1,
94 	.TPMA_NV_PPREAD = 1,
95 	.TPMA_NV_PPWRITE = 1,
96 	.TPMA_NV_NO_DA = 1,
97 };
98 
99 /*
100  * This policy digest was obtained using TPM2_PolicyOR on 3 digests
101  * corresponding to a sequence of
102  *   -) TPM2_PolicyCommandCode(TPM_CC_NV_UndefineSpaceSpecial),
103  *   -) TPM2_PolicyPCR(PCR0, <extended_value>).
104  * where <extended value> is
105  *   1) all zeros = initial, unextended state:
106  *      - Value to extend to initial PCR0:
107  *        <none>
108  *      - Resulting PCR0:
109  *        0000000000000000000000000000000000000000000000000000000000000000
110  *      - Policy digest for PolicyCommandCode + PolicyPCR:
111  *        4B44FC4192DB5AD7167E0135708FD374890A06BFB56317DF01F24F2226542A3F
112  *   2) result of extending (SHA1(0x00|0x01|0x00) | 00s to SHA256 size)
113  *      - Value to extend to initial PCR0:
114  *        62571891215b4efc1ceab744ce59dd0b66ea6f73000000000000000000000000
115  *      - Resulting PCR0:
116  *        9F9EA866D3F34FE3A3112AE9CB1FBABC6FFE8CD261D42493BC6842A9E4F93B3D
117  *      - Policy digest for PolicyCommandCode + PolicyPCR:
118  *        CB5C8014E27A5F7586AAE42DB4F9776A977BCBC952CA61E33609DA2B2C329418
119  *   3) result of extending (SHA1(0x01|0x01|0x00) | 00s to SHA256 size)
120  *      - Value to extend to initial PCR0:
121  *        47ec8d98366433dc002e7721c9e37d5067547937000000000000000000000000
122  *      - Resulting PCR0:
123  *        2A7580E5DA289546F4D2E0509CC6DE155EA131818954D36D49E027FD42B8C8F8
124  *      - Policy digest for PolicyCommandCode + PolicyPCR:
125  *        E6EF4F0296AC3EF0F53906480985B1BE8058E0E517E5F74A5B8A415EFE339D87
126  * Values #2 and #3 correspond to two forms of recovery mode as extended by
127  * vb2api_get_pcr_digest().
128  * As a result, the digest allows deleting the space with UndefineSpaceSpecial
129  * at early RO stages (before extending PCR0) or from recovery mode.
130  */
131 static const uint8_t pcr0_allowed_policy[] = {
132 	0x44, 0x44, 0x79, 0x00, 0xCB, 0xB8, 0x3F, 0x5B, 0x15, 0x76, 0x56,
133 	0x50, 0xEF, 0x96, 0x98, 0x0A, 0x2B, 0x96, 0x6E, 0xA9, 0x09, 0x04,
134 	0x4A, 0x01, 0xB8, 0x5F, 0xA5, 0x4A, 0x96, 0xFC, 0x59, 0x84};
135 
136 static const uint8_t unsatisfiable_policy[VB2_SHA256_DIGEST_SIZE] =
137 	"hmwhat if RBR beat merc in 2021";
138 
define_space(const char * name,uint32_t index,uint32_t length,const TPMA_NV nv_attributes,const uint8_t * nv_policy,size_t nv_policy_size)139 static uint32_t define_space(const char *name, uint32_t index, uint32_t length,
140 			     const TPMA_NV nv_attributes,
141 			     const uint8_t *nv_policy, size_t nv_policy_size)
142 {
143 	tpm_result_t rc;
144 
145 	rc = tlcl2_define_space(index, length, nv_attributes, nv_policy, nv_policy_size);
146 	if (rc == TPM_CB_NV_DEFINED) {
147 		/*
148 		 * Continue with writing: it may be defined, but not written
149 		 * to. In that case a subsequent tlcl_read() would still return
150 		 * TPM_BADINDEX on TPM 2.0. The cases when some non-firmware
151 		 * space is defined while the firmware space is not there
152 		 * should be rare (interrupted initialization), so no big harm
153 		 * in writing once again even if it was written already.
154 		 */
155 		VBDEBUG("%s: %s space already exists\n", __func__, name);
156 		rc = TPM_SUCCESS;
157 	}
158 
159 	return rc;
160 }
161 
setup_space(const char * name,uint32_t index,const void * data,uint32_t length,const TPMA_NV nv_attributes,const uint8_t * nv_policy,size_t nv_policy_size)162 static tpm_result_t setup_space(const char *name, uint32_t index, const void *data,
163 				uint32_t length, const TPMA_NV nv_attributes,
164 				const uint8_t *nv_policy, size_t nv_policy_size)
165 {
166 	tpm_result_t rc;
167 
168 	rc = define_space(name, index, length, nv_attributes, nv_policy,
169 			  nv_policy_size);
170 	if (rc != TPM_SUCCESS)
171 		return rc;
172 
173 	return safe_write(index, data, length);
174 }
175 
setup_firmware_space(struct vb2_context * ctx)176 static tpm_result_t setup_firmware_space(struct vb2_context *ctx)
177 {
178 	uint32_t firmware_space_size = vb2api_secdata_firmware_create(ctx);
179 
180 	return setup_space("firmware", FIRMWARE_NV_INDEX,
181 			   ctx->secdata_firmware, firmware_space_size,
182 			   ro_space_attributes, pcr0_allowed_policy,
183 			   sizeof(pcr0_allowed_policy));
184 }
185 
setup_fwmp_space(struct vb2_context * ctx)186 static tpm_result_t setup_fwmp_space(struct vb2_context *ctx)
187 {
188 	uint32_t fwmp_space_size = vb2api_secdata_fwmp_create(ctx);
189 
190 	return setup_space("FWMP", FWMP_NV_INDEX, ctx->secdata_fwmp, fwmp_space_size,
191 			   fwmp_attr, NULL, 0);
192 }
193 
setup_kernel_space(struct vb2_context * ctx)194 static tpm_result_t setup_kernel_space(struct vb2_context *ctx)
195 {
196 	uint32_t kernel_space_size = vb2api_secdata_kernel_create(ctx);
197 
198 	return setup_space("kernel", KERNEL_NV_INDEX, ctx->secdata_kernel,
199 			    kernel_space_size, rw_space_attributes, NULL, 0);
200 }
201 
set_mrc_hash_space(uint32_t index,const uint8_t * data)202 static tpm_result_t set_mrc_hash_space(uint32_t index, const uint8_t *data)
203 {
204 	if (index == MRC_REC_HASH_NV_INDEX) {
205 		return setup_space("RO MRC Hash", index, data, HASH_NV_SIZE,
206 				   ro_space_attributes, pcr0_allowed_policy,
207 				 sizeof(pcr0_allowed_policy));
208 	} else {
209 		return setup_space("RW MRC Hash", index, data, HASH_NV_SIZE,
210 				   rw_space_attributes, NULL, 0);
211 	}
212 }
213 
214 /**
215  * Set up the Zero-Touch Enrollment(ZTE) related spaces.
216  *
217  * These spaces are not used by firmware, but we do need to initialize them.
218  */
setup_zte_spaces(void)219 static tpm_result_t setup_zte_spaces(void)
220 {
221 	tpm_result_t rc;
222 	uint64_t rma_bytes_counter_default = 0;
223 	uint8_t rma_sn_bits_default[16];
224 	uint8_t board_id_default[12];
225 
226 	/* Initialize defaults:  Board ID and RMA+SN Bits must be initialized
227 	 to all 0xFFs. */
228 	memset(rma_sn_bits_default, 0xFF, ARRAY_SIZE(rma_sn_bits_default));
229 	memset(board_id_default, 0xFF, ARRAY_SIZE(board_id_default));
230 
231 	/* Set up RMA + SN Bits */
232 	rc = setup_space("RMA + SN Bits", ZTE_RMA_SN_BITS_INDEX,
233 			 rma_sn_bits_default, sizeof(rma_sn_bits_default),
234 			 zte_attr,
235 			 unsatisfiable_policy, sizeof(unsatisfiable_policy));
236 	if (rc != TPM_SUCCESS) {
237 		VBDEBUG("%s: Failed to set up RMA + SN Bits space with error %#x\n", __func__, rc);
238 		return rc;
239 	}
240 
241 	rc = setup_space("Board ID", ZTE_BOARD_ID_NV_INDEX,
242 			 board_id_default, sizeof(board_id_default),
243 			 zte_attr,
244 			 unsatisfiable_policy, sizeof(unsatisfiable_policy));
245 	if (rc != TPM_SUCCESS) {
246 		VBDEBUG("%s: Failed to set up Board ID space with error %#x\n", __func__, rc);
247 		return rc;
248 	}
249 
250 	/* Set up RMA Bytes counter */
251 	rc = define_space("RMA Bytes Counter", ZTE_RMA_BYTES_COUNTER_INDEX,
252 			  sizeof(rma_bytes_counter_default),
253 			  zte_rma_bytes_attr,
254 			  unsatisfiable_policy, sizeof(unsatisfiable_policy));
255 	if (rc != TPM_SUCCESS) {
256 		VBDEBUG("%s: Failed to define RMA Bytes space with error %#x\n", __func__, rc);
257 		return rc;
258 	}
259 
260 	/*
261 	 * Since the RMA counter has the BITS attribute, we need to call
262 	 * TPM2_NV_SetBits() in order to initialize it.
263 	 */
264 	rc = tlcl2_set_bits(ZTE_RMA_BYTES_COUNTER_INDEX, rma_bytes_counter_default);
265 	if (rc != TPM_SUCCESS) {
266 		VBDEBUG("%s: Failed to init RMA Bytes counter space wit error %#x\n",
267 			__func__, rc);
268 		return rc;
269 	}
270 
271 	return rc;
272 }
273 
274 /*
275  * Set up enterprise rollback space.
276  *
277  * This space is not used by firmware but needs to survive owner clear. Thus, it
278  * needs to be created here.
279  */
enterprise_rollback_create_space(void)280 static tpm_result_t enterprise_rollback_create_space(void)
281 {
282 	uint8_t rollback_space_default[32] = {0};
283 
284 	return setup_space("Enterprise Rollback Space",
285 			   ENT_ROLLBACK_SPACE_INDEX, rollback_space_default,
286 			   sizeof(rollback_space_default), rw_auth_space_attributes,
287 			   unsatisfiable_policy, sizeof(unsatisfiable_policy));
288 }
289 
setup_widevine_counter_spaces(void)290 static tpm_result_t setup_widevine_counter_spaces(void)
291 {
292 	uint32_t index;
293 	tpm_result_t rc;
294 
295 	for (index = 0; index < NUM_WIDEVINE_COUNTERS; index++) {
296 		rc = define_space(WIDEVINE_COUNTER_NAME,
297 				WIDEVINE_COUNTER_NV_INDEX(index),
298 				WIDEVINE_COUNTER_SIZE,
299 				rw_orderly_counter_attributes,
300 				NULL,
301 				0);
302 		if (rc != TPM_SUCCESS)
303 			return rc;
304 	}
305 	return rc;
306 }
307 
factory_initialize_tpm2(struct vb2_context * ctx)308 tpm_result_t factory_initialize_tpm2(struct vb2_context *ctx)
309 {
310 	RETURN_ON_FAILURE(tlcl_force_clear());
311 
312 	/*
313 	 * Of all NVRAM spaces defined by this function the firmware space
314 	 * must be defined last, because its existence is considered an
315 	 * indication that TPM factory initialization was successfully
316 	 * completed.
317 	 */
318 	RETURN_ON_FAILURE(setup_kernel_space(ctx));
319 
320 	/*
321 	 * Define and set rec hash space, if available.  No need to
322 	 * create the RW hash space because we will definitely boot
323 	 * once in normal mode before shipping, meaning that the space
324 	 * will get created with correct permissions while still in
325 	 * our hands.
326 	 */
327 	if (CONFIG(VBOOT_HAS_REC_HASH_SPACE))
328 		RETURN_ON_FAILURE(set_mrc_hash_space(MRC_REC_HASH_NV_INDEX, mrc_hash_data));
329 
330 	/* Define and write firmware management parameters space. */
331 	RETURN_ON_FAILURE(setup_fwmp_space(ctx));
332 
333 	/*
334 	 * Define and write zero-touch enrollment (ZTE) spaces.  For ChromeOS devices with
335 	 * Google TPM, these are set up elsewhere via TPM vendor commands.
336 	 */
337 	if (CONFIG(CHROMEOS) && !(CONFIG(TPM_GOOGLE)))
338 		RETURN_ON_FAILURE(setup_zte_spaces());
339 
340 	/*
341 	 * On TPM 2.0, create a space that survives TPM clear. This allows to
342 	 * securely lock data during enterprise rollback by binding to this
343 	 * space's value.
344 	 */
345 	if (CONFIG(CHROMEOS))
346 		RETURN_ON_FAILURE(enterprise_rollback_create_space());
347 
348 	/* Define widevine counter space. No need to increment/write to the secure counters
349 	   and are expected to be incremented during the first use. */
350 	if (CONFIG(VBOOT_DEFINE_WIDEVINE_COUNTERS))
351 		RETURN_ON_FAILURE(setup_widevine_counter_spaces());
352 
353 	RETURN_ON_FAILURE(setup_firmware_space(ctx));
354 
355 	return TPM_SUCCESS;
356 }
357 
antirollback_read_space_mrc_hash(uint32_t index,uint8_t * data,uint32_t size)358 tpm_result_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size)
359 {
360 	if (size != HASH_NV_SIZE) {
361 		VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
362 			"(Expected=%#x Actual=%#x).\n", index, HASH_NV_SIZE,
363 			size);
364 		return TPM_CB_READ_FAILURE;
365 	}
366 	return read_space_mrc_hash(index, data);
367 }
368 
antirollback_write_space_mrc_hash(uint32_t index,const uint8_t * data,uint32_t size)369 tpm_result_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, uint32_t size)
370 {
371 	uint8_t spc_data[HASH_NV_SIZE];
372 	tpm_result_t rc;
373 
374 	if (size != HASH_NV_SIZE) {
375 		VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
376 			"(Expected=%#x Actual=%#x).\n", index, HASH_NV_SIZE,
377 			size);
378 		return TPM_CB_WRITE_FAILURE;
379 	}
380 
381 	rc = read_space_mrc_hash(index, spc_data);
382 	if (rc == TPM_BADINDEX) {
383 		/*
384 		 * If space is not defined already for hash, define
385 		 * new space.
386 		 */
387 		VBDEBUG("TPM: Initializing hash space.\n");
388 		return set_mrc_hash_space(index, data);
389 	}
390 
391 	if (rc != TPM_SUCCESS)
392 		return rc;
393 
394 	return safe_write(index, data, size);
395 }
396 
antirollback_lock_space_mrc_hash(uint32_t index)397 tpm_result_t antirollback_lock_space_mrc_hash(uint32_t index)
398 {
399 	return tlcl2_lock_nv_write(index);
400 }
401 
read_space_vbios_hash(uint8_t * data)402 static tpm_result_t read_space_vbios_hash(uint8_t *data)
403 {
404 	RETURN_ON_FAILURE(tlcl_read(VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE));
405 	return TPM_SUCCESS;
406 }
407 
antirollback_read_space_vbios_hash(uint8_t * data,uint32_t size)408 tpm_result_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
409 {
410 	if (size != HASH_NV_SIZE) {
411 		VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
412 			"(Expected=%#x Actual=%#x).\n", VBIOS_CACHE_NV_INDEX, HASH_NV_SIZE,
413 			size);
414 		return TPM_CB_READ_FAILURE;
415 	}
416 	return read_space_vbios_hash(data);
417 }
418 
antirollback_write_space_vbios_hash(const uint8_t * data,uint32_t size)419 tpm_result_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
420 {
421 	uint8_t spc_data[HASH_NV_SIZE];
422 	tpm_result_t rc;
423 
424 	if (size != HASH_NV_SIZE) {
425 		VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
426 			"(Expected=%#x Actual=%#x).\n", VBIOS_CACHE_NV_INDEX, HASH_NV_SIZE,
427 			size);
428 		return TPM_CB_WRITE_FAILURE;
429 	}
430 
431 	rc = read_space_vbios_hash(spc_data);
432 	if (rc == TPM_BADINDEX) {
433 		/*
434 		 * If space is not defined already for hash, define
435 		 * new space.
436 		 */
437 		VBDEBUG("TPM: Initializing hash space.\n");
438 		return setup_space("VBIOS Cache Hash", VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE,
439 				   rw_space_attributes, NULL, 0);
440 	}
441 
442 	if (rc != TPM_SUCCESS)
443 		return rc;
444 
445 	return safe_write(VBIOS_CACHE_NV_INDEX, data, size);
446 }
447