1 /* SPDX-License-Identifier: BSD-3-Clause */
3 #include <security/vboot/antirollback.h>
4 #include <security/tpm/tss.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
,
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
= {
30 .TPMA_NV_AUTHREAD
= 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
= {
39 .TPMA_NV_AUTHREAD
= 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,
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,
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,
73 .TPMA_NV_POLICY_DELETE
= 1,
76 static const TPMA_NV zte_rma_bytes_attr
= {
77 .TPMA_NV_PLATFORMCREATE
= 1,
79 .TPMA_NV_AUTHWRITE
= 1,
80 .TPMA_NV_AUTHREAD
= 1,
84 .TPMA_NV_POLICY_DELETE
= 1,
87 static const TPMA_NV rw_orderly_counter_attributes
= {
90 .TPMA_NV_AUTHREAD
= 1,
91 .TPMA_NV_AUTHWRITE
= 1,
92 .TPMA_NV_PLATFORMCREATE
= 1,
93 .TPMA_NV_WRITE_STCLEAR
= 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:
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
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
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
)
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
);
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
)
168 rc
= define_space(name
, index
, length
, nv_attributes
, nv_policy
,
170 if (rc
!= TPM_SUCCESS
)
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
,
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
));
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)
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
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
),
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
);
241 rc
= setup_space("Board ID", ZTE_BOARD_ID_NV_INDEX
,
242 board_id_default
, sizeof(board_id_default
),
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
);
250 /* Set up RMA Bytes counter */
251 rc
= define_space("RMA Bytes Counter", ZTE_RMA_BYTES_COUNTER_INDEX
,
252 sizeof(rma_bytes_counter_default
),
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
);
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",
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)
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
,
302 if (rc
!= TPM_SUCCESS
)
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
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
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
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
));
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
,
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
];
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
,
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
387 VBDEBUG("TPM: Initializing hash space.\n");
388 return set_mrc_hash_space(index
, data
);
391 if (rc
!= TPM_SUCCESS
)
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
));
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
,
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
];
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
,
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
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
)
445 return safe_write(VBIOS_CACHE_NV_INDEX
, data
, size
);