soc/intel: Remove blank lines before '}' and after '{'
[coreboot2.git] / src / security / vboot / secdata_tpm2.c
blob075e4814358f519e8ba78445540c6bcec1bbc5a8
1 /* SPDX-License-Identifier: BSD-3-Clause */
3 #include <security/vboot/antirollback.h>
4 #include <security/tpm/tss.h>
5 #include <vb2_api.h>
7 #include "secdata_tpm_private.h"
9 static tpm_result_t read_space_mrc_hash(uint32_t index, uint8_t *data)
11 RETURN_ON_FAILURE(tlcl_read(index, data,
12 HASH_NV_SIZE));
13 return TPM_SUCCESS;
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.
21 static const uint8_t mrc_hash_data[HASH_NV_SIZE] = { };
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.
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,
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,
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,
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,
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,
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,
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,
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.
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};
136 static const uint8_t unsatisfiable_policy[VB2_SHA256_DIGEST_SIZE] =
137 "hmwhat if RBR beat merc in 2021";
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)
143 tpm_result_t rc;
145 rc = tlcl2_define_space(index, length, nv_attributes, nv_policy, nv_policy_size);
146 if (rc == TPM_CB_NV_DEFINED) {
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.
155 VBDEBUG("%s: %s space already exists\n", __func__, name);
156 rc = TPM_SUCCESS;
159 return rc;
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)
166 tpm_result_t rc;
168 rc = define_space(name, index, length, nv_attributes, nv_policy,
169 nv_policy_size);
170 if (rc != TPM_SUCCESS)
171 return rc;
173 return safe_write(index, data, length);
176 static tpm_result_t setup_firmware_space(struct vb2_context *ctx)
178 uint32_t firmware_space_size = vb2api_secdata_firmware_create(ctx);
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));
186 static tpm_result_t setup_fwmp_space(struct vb2_context *ctx)
188 uint32_t fwmp_space_size = vb2api_secdata_fwmp_create(ctx);
190 return setup_space("FWMP", FWMP_NV_INDEX, ctx->secdata_fwmp, fwmp_space_size,
191 fwmp_attr, NULL, 0);
194 static tpm_result_t setup_kernel_space(struct vb2_context *ctx)
196 uint32_t kernel_space_size = vb2api_secdata_kernel_create(ctx);
198 return setup_space("kernel", KERNEL_NV_INDEX, ctx->secdata_kernel,
199 kernel_space_size, rw_space_attributes, NULL, 0);
202 static tpm_result_t set_mrc_hash_space(uint32_t index, const uint8_t *data)
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);
215 * Set up the Zero-Touch Enrollment(ZTE) related spaces.
217 * These spaces are not used by firmware, but we do need to initialize them.
219 static tpm_result_t setup_zte_spaces(void)
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];
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));
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;
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;
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;
261 * Since the RMA counter has the BITS attribute, we need to call
262 * TPM2_NV_SetBits() in order to initialize it.
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;
271 return rc;
275 * Set up enterprise rollback space.
277 * This space is not used by firmware but needs to survive owner clear. Thus, it
278 * needs to be created here.
280 static tpm_result_t enterprise_rollback_create_space(void)
282 uint8_t rollback_space_default[32] = {0};
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));
290 static tpm_result_t setup_widevine_counter_spaces(void)
292 uint32_t index;
293 tpm_result_t rc;
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,
302 if (rc != TPM_SUCCESS)
303 return rc;
305 return rc;
308 tpm_result_t factory_initialize_tpm2(struct vb2_context *ctx)
310 RETURN_ON_FAILURE(tlcl_force_clear());
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.
318 RETURN_ON_FAILURE(setup_kernel_space(ctx));
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.
327 if (CONFIG(VBOOT_HAS_REC_HASH_SPACE))
328 RETURN_ON_FAILURE(set_mrc_hash_space(MRC_REC_HASH_NV_INDEX, mrc_hash_data));
330 /* Define and write firmware management parameters space. */
331 RETURN_ON_FAILURE(setup_fwmp_space(ctx));
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.
337 if (CONFIG(CHROMEOS) && !(CONFIG(TPM_GOOGLE)))
338 RETURN_ON_FAILURE(setup_zte_spaces());
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.
345 if (CONFIG(CHROMEOS))
346 RETURN_ON_FAILURE(enterprise_rollback_create_space());
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());
353 RETURN_ON_FAILURE(setup_firmware_space(ctx));
355 return TPM_SUCCESS;
358 tpm_result_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size)
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;
366 return read_space_mrc_hash(index, data);
369 tpm_result_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, uint32_t size)
371 uint8_t spc_data[HASH_NV_SIZE];
372 tpm_result_t rc;
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;
381 rc = read_space_mrc_hash(index, spc_data);
382 if (rc == TPM_BADINDEX) {
384 * If space is not defined already for hash, define
385 * new space.
387 VBDEBUG("TPM: Initializing hash space.\n");
388 return set_mrc_hash_space(index, data);
391 if (rc != TPM_SUCCESS)
392 return rc;
394 return safe_write(index, data, size);
397 tpm_result_t antirollback_lock_space_mrc_hash(uint32_t index)
399 return tlcl2_lock_nv_write(index);
402 static tpm_result_t read_space_vbios_hash(uint8_t *data)
404 RETURN_ON_FAILURE(tlcl_read(VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE));
405 return TPM_SUCCESS;
408 tpm_result_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
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;
416 return read_space_vbios_hash(data);
419 tpm_result_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
421 uint8_t spc_data[HASH_NV_SIZE];
422 tpm_result_t rc;
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;
431 rc = read_space_vbios_hash(spc_data);
432 if (rc == TPM_BADINDEX) {
434 * If space is not defined already for hash, define
435 * new space.
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);
442 if (rc != TPM_SUCCESS)
443 return rc;
445 return safe_write(VBIOS_CACHE_NV_INDEX, data, size);