blob: 45851a09f4e5706f5eb3099b3c7f40d3dd9f62d9 [file] [log] [blame]
Patrick Georgi593124d2020-05-10 19:44:08 +02001/* SPDX-License-Identifier: BSD-3-Clause */
Martin Roth08d808f2017-02-09 18:06:16 -08002
3/*
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -07004 * Functions for querying, manipulating and locking rollback indices
5 * stored in the TPM NVRAM.
6 */
7
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +01008#include <security/vboot/antirollback.h>
Christian Walter0bd84ed2019-07-23 10:26:30 +02009#include <security/vboot/tpm_common.h>
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010010#include <security/tpm/tspi.h>
Daisuke Nojirid9f26ed2020-04-21 15:13:07 -070011#include <security/tpm/tss.h>
12#include <security/tpm/tss/tcg-1.2/tss_structures.h>
Aseda Aboagyec8f70962021-05-04 15:50:49 -070013#include <security/tpm/tss/tcg-2.0/tss_structures.h>
Randall Spangler144c2282014-12-03 17:35:53 -080014#include <vb2_api.h>
Vadim Bendebury10ea1042016-06-06 12:12:34 -070015#include <console/console.h>
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070016
Daisuke Nojiri57990972014-07-15 19:47:32 -070017#define VBDEBUG(format, args...) \
Elyes Haouas8b8ada62022-11-22 17:36:02 +010018 printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070019
Daisuke Nojiri57990972014-07-15 19:47:32 -070020#define RETURN_ON_FAILURE(tpm_cmd) do { \
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070021 uint32_t result_; \
Daisuke Nojiri57990972014-07-15 19:47:32 -070022 if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
23 VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
24 "\n", (int)result_); \
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070025 return result_; \
26 } \
27 } while (0)
28
Vadim Bendebury10ea1042016-06-06 12:12:34 -070029static uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
30
Daisuke Nojiri57990972014-07-15 19:47:32 -070031static uint32_t read_space_firmware(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070032{
Joel Kitching38141162020-04-14 18:20:44 +080033 RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX,
34 ctx->secdata_firmware,
35 VB2_SECDATA_FIRMWARE_SIZE));
36 return TPM_SUCCESS;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070037}
38
dnojiridff56a02020-04-03 10:56:43 -070039uint32_t antirollback_read_space_kernel(struct vb2_context *ctx)
40{
Daisuke Nojirid9f26ed2020-04-21 15:13:07 -070041 if (!CONFIG(TPM2)) {
42 /*
43 * Before reading the kernel space, verify its permissions. If
44 * the kernel space has the wrong permission, we give up. This
45 * will need to be fixed by the recovery kernel. We will have
46 * to worry about this because at any time (even with PP turned
47 * off) the TPM owner can remove and redefine a PP-protected
48 * space (but not write to it).
49 */
50 uint32_t perms;
51
52 RETURN_ON_FAILURE(tlcl_get_permissions(KERNEL_NV_INDEX,
53 &perms));
54 if (perms != TPM_NV_PER_PPWRITE) {
55 printk(BIOS_ERR,
56 "TPM: invalid secdata_kernel permissions\n");
57 return TPM_E_CORRUPTED_STATE;
58 }
59 }
60
Tim Wawrzynczakf6c53c02021-10-27 14:54:54 -060061 uint8_t size = VB2_SECDATA_KERNEL_SIZE;
62 uint32_t ret;
dnojiridff56a02020-04-03 10:56:43 -070063
Tim Wawrzynczakf6c53c02021-10-27 14:54:54 -060064 /* Start with the version 1.0 size used by all modern cr50-boards. */
65 ret = tlcl_read(KERNEL_NV_INDEX, ctx->secdata_kernel, size);
66 if (ret == TPM_E_RANGE) {
67 /* Fallback to version 0.2(minimum) size and re-read. */
68 VBDEBUG("Antirollback: NV read out of range, trying min size\n");
69 size = VB2_SECDATA_KERNEL_MIN_SIZE;
70 ret = tlcl_read(KERNEL_NV_INDEX, ctx->secdata_kernel, size);
71 }
72 RETURN_ON_FAILURE(ret);
dnojiridff56a02020-04-03 10:56:43 -070073
Tim Wawrzynczakf6c53c02021-10-27 14:54:54 -060074 if (vb2api_secdata_kernel_check(ctx, &size) == VB2_ERROR_SECDATA_KERNEL_INCOMPLETE)
dnojiridff56a02020-04-03 10:56:43 -070075 /* Re-read. vboot will run the check and handle errors. */
Tim Wawrzynczakf6c53c02021-10-27 14:54:54 -060076 RETURN_ON_FAILURE(tlcl_read(KERNEL_NV_INDEX, ctx->secdata_kernel, size));
dnojiridff56a02020-04-03 10:56:43 -070077
78 return TPM_SUCCESS;
79}
80
Shelley Chen17df7d62020-10-20 23:10:55 -070081#if CONFIG(TPM2)
82
Shelley Chena79803c2020-10-16 13:15:59 -070083static uint32_t read_space_mrc_hash(uint32_t index, uint8_t *data)
Furquan Shaikhb038f412016-11-07 23:47:11 -080084{
Shelley Chena79803c2020-10-16 13:15:59 -070085 RETURN_ON_FAILURE(tlcl_read(index, data,
86 HASH_NV_SIZE));
Furquan Shaikhb038f412016-11-07 23:47:11 -080087 return TPM_SUCCESS;
88}
89
Vadim Bendebury10ea1042016-06-06 12:12:34 -070090/*
Furquan Shaikhb038f412016-11-07 23:47:11 -080091 * This is used to initialize the TPM space for recovery hash after defining
92 * it. Since there is no data available to calculate hash at the point where TPM
93 * space is defined, initialize it to all 0s.
94 */
Shelley Chena79803c2020-10-16 13:15:59 -070095static const uint8_t mrc_hash_data[HASH_NV_SIZE] = { };
Furquan Shaikhb038f412016-11-07 23:47:11 -080096
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010097/*
98 * Different sets of NVRAM space attributes apply to the "ro" spaces,
99 * i.e. those which should not be possible to delete or modify once
100 * the RO exits, and the rest of the NVRAM spaces.
101 */
Elyes HAOUAS68ec3eb2019-06-22 09:21:18 +0200102static const TPMA_NV ro_space_attributes = {
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100103 .TPMA_NV_PPWRITE = 1,
104 .TPMA_NV_AUTHREAD = 1,
105 .TPMA_NV_PPREAD = 1,
106 .TPMA_NV_PLATFORMCREATE = 1,
107 .TPMA_NV_WRITE_STCLEAR = 1,
108 .TPMA_NV_POLICY_DELETE = 1,
109};
110
Elyes HAOUAS68ec3eb2019-06-22 09:21:18 +0200111static const TPMA_NV rw_space_attributes = {
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100112 .TPMA_NV_PPWRITE = 1,
113 .TPMA_NV_AUTHREAD = 1,
114 .TPMA_NV_PPREAD = 1,
115 .TPMA_NV_PLATFORMCREATE = 1,
Aseda Aboagyeb9d94ec2021-07-15 16:19:04 -0700116 .TPMA_NV_WRITE_STCLEAR = 1,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100117};
118
Miriam Polzer2c389332022-08-11 06:38:46 +0000119static const TPMA_NV rw_auth_space_attributes = {
120 .TPMA_NV_AUTHWRITE = 1,
121 .TPMA_NV_AUTHREAD = 1,
122 .TPMA_NV_NO_DA = 1,
123 .TPMA_NV_PPREAD = 1,
124 .TPMA_NV_PPWRITE = 1,
125 .TPMA_NV_PLATFORMCREATE = 1,
126 .TPMA_NV_WRITE_STCLEAR = 1,
127 .TPMA_NV_POLICY_DELETE = 1,
128};
129
Aseda Aboagyec8f70962021-05-04 15:50:49 -0700130static const TPMA_NV fwmp_attr = {
131 .TPMA_NV_PLATFORMCREATE = 1,
132 .TPMA_NV_OWNERWRITE = 1,
133 .TPMA_NV_AUTHREAD = 1,
134 .TPMA_NV_PPREAD = 1,
135 .TPMA_NV_PPWRITE = 1,
136};
137
Aseda Aboagye08938a92021-05-24 17:04:38 -0700138/* Attributes for spaces that enable zero-touch enrollment (ZTE) */
139static const TPMA_NV zte_attr = {
140 .TPMA_NV_PLATFORMCREATE = 1,
141 .TPMA_NV_WRITEDEFINE = 1,
142 .TPMA_NV_AUTHWRITE = 1,
143 .TPMA_NV_AUTHREAD = 1,
144 .TPMA_NV_PPWRITE = 1,
145 .TPMA_NV_PPREAD = 1,
146 .TPMA_NV_NO_DA = 1,
147 .TPMA_NV_POLICY_DELETE = 1,
148};
149
150static const TPMA_NV zte_rma_bytes_attr = {
151 .TPMA_NV_PLATFORMCREATE = 1,
152 .TPMA_NV_BITS = 1,
153 .TPMA_NV_AUTHWRITE = 1,
154 .TPMA_NV_AUTHREAD = 1,
155 .TPMA_NV_PPWRITE = 1,
156 .TPMA_NV_PPREAD = 1,
157 .TPMA_NV_NO_DA = 1,
158 .TPMA_NV_POLICY_DELETE = 1,
159};
160
Karthikeyan Ramasubramanian4fcf13a2021-11-17 17:33:08 -0700161static const TPMA_NV rw_orderly_counter_attributes = {
162 .TPMA_NV_COUNTER = 1,
163 .TPMA_NV_ORDERLY = 1,
164 .TPMA_NV_AUTHREAD = 1,
165 .TPMA_NV_AUTHWRITE = 1,
166 .TPMA_NV_PLATFORMCREATE = 1,
167 .TPMA_NV_WRITE_STCLEAR = 1,
168 .TPMA_NV_PPREAD = 1,
169 .TPMA_NV_PPWRITE = 1,
170 .TPMA_NV_NO_DA = 1,
171};
172
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100173/*
Andrey Pronin441c63d2020-10-25 13:00:30 -0700174 * This policy digest was obtained using TPM2_PolicyOR on 3 digests
175 * corresponding to a sequence of
176 * -) TPM2_PolicyCommandCode(TPM_CC_NV_UndefineSpaceSpecial),
177 * -) TPM2_PolicyPCR(PCR0, <extended_value>).
178 * where <extended value> is
179 * 1) all zeros = initial, unextended state:
180 * - Value to extend to initial PCR0:
181 * <none>
182 * - Resulting PCR0:
183 * 0000000000000000000000000000000000000000000000000000000000000000
184 * - Policy digest for PolicyCommandCode + PolicyPCR:
185 * 4B44FC4192DB5AD7167E0135708FD374890A06BFB56317DF01F24F2226542A3F
186 * 2) result of extending (SHA1(0x00|0x01|0x00) | 00s to SHA256 size)
187 * - Value to extend to initial PCR0:
188 * 62571891215b4efc1ceab744ce59dd0b66ea6f73000000000000000000000000
189 * - Resulting PCR0:
190 * 9F9EA866D3F34FE3A3112AE9CB1FBABC6FFE8CD261D42493BC6842A9E4F93B3D
191 * - Policy digest for PolicyCommandCode + PolicyPCR:
192 * CB5C8014E27A5F7586AAE42DB4F9776A977BCBC952CA61E33609DA2B2C329418
193 * 3) result of extending (SHA1(0x01|0x01|0x00) | 00s to SHA256 size)
194 * - Value to extend to initial PCR0:
195 * 47ec8d98366433dc002e7721c9e37d5067547937000000000000000000000000
196 * - Resulting PCR0:
197 * 2A7580E5DA289546F4D2E0509CC6DE155EA131818954D36D49E027FD42B8C8F8
198 * - Policy digest for PolicyCommandCode + PolicyPCR:
199 * E6EF4F0296AC3EF0F53906480985B1BE8058E0E517E5F74A5B8A415EFE339D87
200 * Values #2 and #3 correspond to two forms of recovery mode as extended by
201 * vb2api_get_pcr_digest().
202 * As a result, the digest allows deleting the space with UndefineSpaceSpecial
203 * at early RO stages (before extending PCR0) or from recovery mode.
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100204 */
Andrey Pronin441c63d2020-10-25 13:00:30 -0700205static const uint8_t pcr0_allowed_policy[] = {
206 0x44, 0x44, 0x79, 0x00, 0xCB, 0xB8, 0x3F, 0x5B, 0x15, 0x76, 0x56,
207 0x50, 0xEF, 0x96, 0x98, 0x0A, 0x2B, 0x96, 0x6E, 0xA9, 0x09, 0x04,
208 0x4A, 0x01, 0xB8, 0x5F, 0xA5, 0x4A, 0x96, 0xFC, 0x59, 0x84};
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700209
Aseda Aboagye08938a92021-05-24 17:04:38 -0700210static const uint8_t unsatisfiable_policy[VB2_SHA256_DIGEST_SIZE] =
211 "hmwhat if RBR beat merc in 2021";
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700212
Aseda Aboagye08938a92021-05-24 17:04:38 -0700213static uint32_t define_space(const char *name, uint32_t index, uint32_t length,
214 const TPMA_NV nv_attributes,
215 const uint8_t *nv_policy, size_t nv_policy_size)
Andrey Pronin278a5062018-01-26 12:47:51 -0800216{
217 uint32_t rv;
218
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100219 rv = tlcl_define_space(index, length, nv_attributes, nv_policy,
220 nv_policy_size);
Andrey Pronin278a5062018-01-26 12:47:51 -0800221 if (rv == TPM_E_NV_DEFINED) {
222 /*
223 * Continue with writing: it may be defined, but not written
224 * to. In that case a subsequent tlcl_read() would still return
225 * TPM_E_BADINDEX on TPM 2.0. The cases when some non-firmware
226 * space is defined while the firmware space is not there
227 * should be rare (interrupted initialization), so no big harm
228 * in writing once again even if it was written already.
229 */
230 VBDEBUG("%s: %s space already exists\n", __func__, name);
231 rv = TPM_SUCCESS;
232 }
233
Aseda Aboagye08938a92021-05-24 17:04:38 -0700234 return rv;
235}
236
237/* Nothing special in the TPM2 path yet. */
238static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
239{
240 return tlcl_write(index, data, length);
241}
242
243static uint32_t setup_space(const char *name, uint32_t index, const void *data,
244 uint32_t length, const TPMA_NV nv_attributes,
245 const uint8_t *nv_policy, size_t nv_policy_size)
246{
247 uint32_t rv;
248
249 rv = define_space(name, index, length, nv_attributes, nv_policy,
250 nv_policy_size);
Andrey Pronin278a5062018-01-26 12:47:51 -0800251 if (rv != TPM_SUCCESS)
252 return rv;
253
Joel Kitching38141162020-04-14 18:20:44 +0800254 return safe_write(index, data, length);
Andrey Pronin278a5062018-01-26 12:47:51 -0800255}
256
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700257static uint32_t setup_firmware_space(struct vb2_context *ctx)
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700258{
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700259 uint32_t firmware_space_size = vb2api_secdata_firmware_create(ctx);
260
261 return setup_space("firmware", FIRMWARE_NV_INDEX,
262 ctx->secdata_firmware, firmware_space_size,
263 ro_space_attributes, pcr0_allowed_policy,
264 sizeof(pcr0_allowed_policy));
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700265}
266
Aseda Aboagyec8f70962021-05-04 15:50:49 -0700267static uint32_t setup_fwmp_space(struct vb2_context *ctx)
268{
269 uint32_t fwmp_space_size = vb2api_secdata_fwmp_create(ctx);
270
271 return setup_space("FWMP", FWMP_NV_INDEX, ctx->secdata_fwmp, fwmp_space_size,
272 fwmp_attr, NULL, 0);
273}
274
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700275static uint32_t setup_kernel_space(struct vb2_context *ctx)
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700276{
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700277 uint32_t kernel_space_size = vb2api_secdata_kernel_create(ctx);
278
279 return setup_space("kernel", KERNEL_NV_INDEX, ctx->secdata_kernel,
280 kernel_space_size, rw_space_attributes, NULL, 0);
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700281}
282
Shelley Chena79803c2020-10-16 13:15:59 -0700283static uint32_t set_mrc_hash_space(uint32_t index, const uint8_t *data)
Furquan Shaikhb038f412016-11-07 23:47:11 -0800284{
Shelley Chendf0481e2020-10-16 13:37:09 -0700285 if (index == MRC_REC_HASH_NV_INDEX) {
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700286 return setup_space("RO MRC Hash", index, data, HASH_NV_SIZE,
287 ro_space_attributes, pcr0_allowed_policy,
Andrey Pronin441c63d2020-10-25 13:00:30 -0700288 sizeof(pcr0_allowed_policy));
Shelley Chendf0481e2020-10-16 13:37:09 -0700289 } else {
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700290 return setup_space("RW MRC Hash", index, data, HASH_NV_SIZE,
291 rw_space_attributes, NULL, 0);
Shelley Chendf0481e2020-10-16 13:37:09 -0700292 }
Furquan Shaikhb038f412016-11-07 23:47:11 -0800293}
294
Aseda Aboagye08938a92021-05-24 17:04:38 -0700295/**
296 * Set up the Zero-Touch Enrollment(ZTE) related spaces.
297 *
298 * These spaces are not used by firmware, but we do need to initialize them.
299 */
300static uint32_t setup_zte_spaces(void)
301{
302 uint32_t rv;
303 uint64_t rma_bytes_counter_default = 0;
304 uint8_t rma_sn_bits_default[16];
305 uint8_t board_id_default[12];
306
307 /* Initialize defaults: Board ID and RMA+SN Bits must be initialized
308 to all 0xFFs. */
309 memset(rma_sn_bits_default, 0xFF, ARRAY_SIZE(rma_sn_bits_default));
310 memset(board_id_default, 0xFF, ARRAY_SIZE(board_id_default));
311
312 /* Set up RMA + SN Bits */
313 rv = setup_space("RMA + SN Bits", ZTE_RMA_SN_BITS_INDEX,
314 rma_sn_bits_default, sizeof(rma_sn_bits_default),
315 zte_attr,
316 unsatisfiable_policy, sizeof(unsatisfiable_policy));
317 if (rv != TPM_SUCCESS) {
318 VBDEBUG("%s: Failed to set up RMA + SN Bits space\n", __func__);
319 return rv;
320 }
321
322 rv = setup_space("Board ID", ZTE_BOARD_ID_NV_INDEX,
323 board_id_default, sizeof(board_id_default),
324 zte_attr,
325 unsatisfiable_policy, sizeof(unsatisfiable_policy));
326 if (rv != TPM_SUCCESS) {
327 VBDEBUG("%s: Failed to set up Board ID space\n", __func__);
328 return rv;
329 }
330
331 /* Set up RMA Bytes counter */
332 rv = define_space("RMA Bytes Counter", ZTE_RMA_BYTES_COUNTER_INDEX,
333 sizeof(rma_bytes_counter_default),
334 zte_rma_bytes_attr,
335 unsatisfiable_policy, sizeof(unsatisfiable_policy));
336 if (rv != TPM_SUCCESS) {
337 VBDEBUG("%s: Failed to define RMA Bytes space\n", __func__);
338 return rv;
339 }
340
341 /*
342 * Since the RMA counter has the BITS attribute, we need to call
343 * TPM2_NV_SetBits() in order to initialize it.
344 */
345 rv = tlcl_set_bits(ZTE_RMA_BYTES_COUNTER_INDEX,
346 rma_bytes_counter_default);
347 if (rv != TPM_SUCCESS) {
348 VBDEBUG("%s: Failed to init RMA Bytes counter space\n",
349 __func__);
350 return rv;
351 }
352
353 return rv;
354}
355
Miriam Polzer2c389332022-08-11 06:38:46 +0000356/*
357 * Set up enterprise rollback space.
358 *
359 * This space is not used by firmware but needs to survive owner clear. Thus, it
360 * needs to be created here.
361 */
362static uint32_t enterprise_rollback_create_space(void)
363{
364 uint8_t rollback_space_default[32] = {0};
365
366 return setup_space("Enterprise Rollback Space",
367 ENT_ROLLBACK_SPACE_INDEX, rollback_space_default,
368 sizeof(rollback_space_default), rw_auth_space_attributes,
369 unsatisfiable_policy, sizeof(unsatisfiable_policy));
370}
371
Karthikeyan Ramasubramanian4fcf13a2021-11-17 17:33:08 -0700372static uint32_t setup_widevine_counter_spaces(void)
373{
374 uint32_t index, rv;
375
376 for (index = 0; index < NUM_WIDEVINE_COUNTERS; index++) {
377 rv = define_space(WIDEVINE_COUNTER_NAME, WIDEVINE_COUNTER_NV_INDEX(index),
378 WIDEVINE_COUNTER_SIZE, rw_orderly_counter_attributes, NULL, 0);
379 if (rv != TPM_SUCCESS)
380 return rv;
381 }
382 return TPM_SUCCESS;
383}
384
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700385static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
386{
Vadim Bendeburyadfbbde2016-07-03 15:56:41 -0700387 RETURN_ON_FAILURE(tlcl_force_clear());
Vadim Bendebury38837012016-11-14 16:36:26 -0800388
389 /*
390 * Of all NVRAM spaces defined by this function the firmware space
391 * must be defined last, because its existence is considered an
392 * indication that TPM factory initialization was successfully
393 * completed.
394 */
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700395 RETURN_ON_FAILURE(setup_kernel_space(ctx));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800396
Shelley Chendf0481e2020-10-16 13:37:09 -0700397 /*
398 * Define and set rec hash space, if available. No need to
399 * create the RW hash space because we will definitely boot
400 * once in normal mode before shipping, meaning that the space
Elyes HAOUAS2d634c92021-01-16 15:00:02 +0100401 * will get created with correct permissions while still in
Shelley Chendf0481e2020-10-16 13:37:09 -0700402 * our hands.
403 */
Julius Wernercd49cce2019-03-05 16:53:33 -0800404 if (CONFIG(VBOOT_HAS_REC_HASH_SPACE))
Shelley Chena79803c2020-10-16 13:15:59 -0700405 RETURN_ON_FAILURE(set_mrc_hash_space(MRC_REC_HASH_NV_INDEX, mrc_hash_data));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800406
Aseda Aboagyec8f70962021-05-04 15:50:49 -0700407 /* Define and write firmware management parameters space. */
408 RETURN_ON_FAILURE(setup_fwmp_space(ctx));
409
Aseda Aboagye08938a92021-05-24 17:04:38 -0700410 /*
411 * Define and write zero-touch enrollment (ZTE) spaces. For Cr50 devices,
412 * these are set up elsewhere via TPM vendor commands.
413 */
Jes B. Klinkec6b041a12022-04-19 14:00:33 -0700414 if (CONFIG(CHROMEOS) && !(CONFIG(TPM_GOOGLE)))
Aseda Aboagye08938a92021-05-24 17:04:38 -0700415 RETURN_ON_FAILURE(setup_zte_spaces());
416
Miriam Polzer2c389332022-08-11 06:38:46 +0000417 /*
418 * On TPM 2.0, create a space that survives TPM clear. This allows to
419 * securely lock data during enterprise rollback by binding to this
420 * space's value.
421 */
422 if (CONFIG(CHROMEOS))
423 RETURN_ON_FAILURE(enterprise_rollback_create_space());
424
Karthikeyan Ramasubramanian4fcf13a2021-11-17 17:33:08 -0700425 /* Define widevine counter space. No need to increment/write to the secure counters
426 and are expected to be incremented during the first use. */
427 if (CONFIG(VBOOT_DEFINE_WIDEVINE_COUNTERS))
428 RETURN_ON_FAILURE(setup_widevine_counter_spaces());
429
Aseda Aboagyed87ed2d2021-05-14 15:35:12 -0700430 RETURN_ON_FAILURE(setup_firmware_space(ctx));
Vadim Bendebury38837012016-11-14 16:36:26 -0800431
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700432 return TPM_SUCCESS;
433}
434
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700435uint32_t antirollback_lock_space_firmware(void)
436{
437 return tlcl_lock_nv_write(FIRMWARE_NV_INDEX);
438}
439
Shelley Chen17df7d62020-10-20 23:10:55 -0700440uint32_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size)
441{
442 if (size != HASH_NV_SIZE) {
443 VBDEBUG("TPM: Incorrect buffer size for hash idx 0x%x. "
444 "(Expected=0x%x Actual=0x%x).\n", index, HASH_NV_SIZE,
445 size);
446 return TPM_E_READ_FAILURE;
447 }
448 return read_space_mrc_hash(index, data);
449}
450
451uint32_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, uint32_t size)
452{
453 uint8_t spc_data[HASH_NV_SIZE];
454 uint32_t rv;
455
456 if (size != HASH_NV_SIZE) {
457 VBDEBUG("TPM: Incorrect buffer size for hash idx 0x%x. "
458 "(Expected=0x%x Actual=0x%x).\n", index, HASH_NV_SIZE,
459 size);
460 return TPM_E_WRITE_FAILURE;
461 }
462
463 rv = read_space_mrc_hash(index, spc_data);
464 if (rv == TPM_E_BADINDEX) {
465 /*
466 * If space is not defined already for hash, define
467 * new space.
468 */
469 VBDEBUG("TPM: Initializing hash space.\n");
470 return set_mrc_hash_space(index, data);
471 }
472
473 if (rv != TPM_SUCCESS)
474 return rv;
475
476 return safe_write(index, data, size);
477}
478
Shelley Chena79803c2020-10-16 13:15:59 -0700479uint32_t antirollback_lock_space_mrc_hash(uint32_t index)
Furquan Shaikhb038f412016-11-07 23:47:11 -0800480{
Shelley Chena79803c2020-10-16 13:15:59 -0700481 return tlcl_lock_nv_write(index);
Furquan Shaikhb038f412016-11-07 23:47:11 -0800482}
483
Matt DeVillier9ce755d2023-01-23 18:31:27 -0600484static uint32_t read_space_vbios_hash(uint8_t *data)
485{
486 RETURN_ON_FAILURE(tlcl_read(VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE));
487 return TPM_SUCCESS;
488}
489
490uint32_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
491{
492 if (size != HASH_NV_SIZE) {
493 VBDEBUG("TPM: Incorrect buffer size for hash idx 0x%x. "
494 "(Expected=0x%x Actual=0x%x).\n", VBIOS_CACHE_NV_INDEX, HASH_NV_SIZE,
495 size);
496 return TPM_E_READ_FAILURE;
497 }
498 return read_space_vbios_hash(data);
499}
500
501uint32_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
502{
503 uint8_t spc_data[HASH_NV_SIZE];
504 uint32_t rv;
505
506 if (size != HASH_NV_SIZE) {
507 VBDEBUG("TPM: Incorrect buffer size for hash idx 0x%x. "
508 "(Expected=0x%x Actual=0x%x).\n", VBIOS_CACHE_NV_INDEX, HASH_NV_SIZE,
509 size);
510 return TPM_E_WRITE_FAILURE;
511 }
512
513 rv = read_space_vbios_hash(spc_data);
514 if (rv == TPM_E_BADINDEX) {
515 /*
516 * If space is not defined already for hash, define
517 * new space.
518 */
519 VBDEBUG("TPM: Initializing hash space.\n");
520 return setup_space("VBIOS Cache Hash", VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE,
521 rw_space_attributes, NULL, 0);
522 }
523
524 if (rv != TPM_SUCCESS)
525 return rv;
526
527 return safe_write(VBIOS_CACHE_NV_INDEX, data, size);
528}
529
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700530#else
531
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700532/**
533 * Like tlcl_write(), but checks for write errors due to hitting the 64-write
534 * limit and clears the TPM when that happens. This can only happen when the
535 * TPM is unowned, so it is OK to clear it (and we really have no choice).
536 * This is not expected to happen frequently, but it could happen.
537 */
538
539static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
540{
541 uint32_t result = tlcl_write(index, data, length);
542 if (result == TPM_E_MAXNVWRITES) {
543 RETURN_ON_FAILURE(tpm_clear_and_reenable());
544 return tlcl_write(index, data, length);
545 } else {
546 return result;
547 }
548}
549
550/**
551 * Similarly to safe_write(), this ensures we don't fail a DefineSpace because
552 * we hit the TPM write limit. This is even less likely to happen than with
553 * writes because we only define spaces once at initialization, but we'd
554 * rather be paranoid about this.
555 */
556static uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
557{
558 uint32_t result = tlcl_define_space(index, perm, size);
559 if (result == TPM_E_MAXNVWRITES) {
560 RETURN_ON_FAILURE(tpm_clear_and_reenable());
561 return tlcl_define_space(index, perm, size);
562 } else {
563 return result;
564 }
565}
566
567static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700568{
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700569 TPM_PERMANENT_FLAGS pflags;
570 uint32_t result;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700571
Yu-Ping Wu74a00b92022-08-31 14:52:46 +0800572 vb2api_secdata_firmware_create(ctx);
dnojiri58cf6032020-01-28 12:34:20 -0800573 vb2api_secdata_kernel_create_v0(ctx);
574
Daisuke Nojiri57990972014-07-15 19:47:32 -0700575 result = tlcl_get_permanent_flags(&pflags);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700576 if (result != TPM_SUCCESS)
577 return result;
578
579 /*
580 * TPM may come from the factory without physical presence finalized.
581 * Fix if necessary.
582 */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700583 VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
584 pflags.physicalPresenceLifetimeLock);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700585 if (!pflags.physicalPresenceLifetimeLock) {
Daisuke Nojiri57990972014-07-15 19:47:32 -0700586 VBDEBUG("TPM: Finalizing physical presence\n");
587 RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700588 }
589
590 /*
591 * The TPM will not enforce the NV authorization restrictions until the
592 * execution of a TPM_NV_DefineSpace with the handle of
593 * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
594 * exist. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700595 VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700596 if (!pflags.nvLocked) {
Daisuke Nojiri57990972014-07-15 19:47:32 -0700597 VBDEBUG("TPM: Enabling NV locking\n");
598 RETURN_ON_FAILURE(tlcl_set_nv_locked());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700599 }
600
601 /* Clear TPM owner, in case the TPM is already owned for some reason. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700602 VBDEBUG("TPM: Clearing owner\n");
603 RETURN_ON_FAILURE(tpm_clear_and_reenable());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700604
Joel Kitching928511a2019-12-11 17:25:02 +0800605 /* Define and write secdata_kernel space. */
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700606 RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
607 TPM_NV_PER_PPWRITE,
dnojiri58cf6032020-01-28 12:34:20 -0800608 VB2_SECDATA_KERNEL_SIZE_V02));
Joel Kitching38141162020-04-14 18:20:44 +0800609 RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX,
610 ctx->secdata_kernel,
611 VB2_SECDATA_KERNEL_SIZE_V02));
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700612
Joel Kitching928511a2019-12-11 17:25:02 +0800613 /* Define and write secdata_firmware space. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700614 RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
Joel Kitching928511a2019-12-11 17:25:02 +0800615 TPM_NV_PER_GLOBALLOCK |
616 TPM_NV_PER_PPWRITE,
617 VB2_SECDATA_FIRMWARE_SIZE));
Joel Kitching38141162020-04-14 18:20:44 +0800618 RETURN_ON_FAILURE(safe_write(FIRMWARE_NV_INDEX,
619 ctx->secdata_firmware,
Joel Kitching928511a2019-12-11 17:25:02 +0800620 VB2_SECDATA_FIRMWARE_SIZE));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800621
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700622 return TPM_SUCCESS;
623}
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700624
625uint32_t antirollback_lock_space_firmware(void)
626{
627 return tlcl_set_global_lock();
628}
Furquan Shaikhb038f412016-11-07 23:47:11 -0800629
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700630#endif
631
Vadim Bendebury673a2662016-11-11 09:33:43 -0800632/**
633 * Perform one-time initializations.
634 *
635 * Create the NVRAM spaces, and set their initial values as needed. Sets the
636 * nvLocked bit and ensures the physical presence command is enabled and
637 * locked.
638 */
639static uint32_t factory_initialize_tpm(struct vb2_context *ctx)
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700640{
641 uint32_t result;
642
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700643 VBDEBUG("TPM: factory initialization\n");
644
645 /*
646 * Do a full test. This only happens the first time the device is
647 * turned on in the factory, so performance is not an issue. This is
648 * almost certainly not necessary, but it gives us more confidence
649 * about some code paths below that are difficult to
650 * test---specifically the ones that set lifetime flags, and are only
651 * executed once per physical TPM.
652 */
653 result = tlcl_self_test_full();
654 if (result != TPM_SUCCESS)
655 return result;
656
657 result = _factory_initialize_tpm(ctx);
658 if (result != TPM_SUCCESS)
659 return result;
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700660
Julius Werner683657e2019-12-04 12:50:43 -0800661 /* _factory_initialize_tpm() writes initial secdata values to TPM
662 immediately, so let vboot know that it's up to date now. */
663 ctx->flags &= ~(VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED |
664 VB2_CONTEXT_SECDATA_KERNEL_CHANGED);
665
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700666 VBDEBUG("TPM: factory initialization successful\n");
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700667
668 return TPM_SUCCESS;
669}
670
Daisuke Nojiri57990972014-07-15 19:47:32 -0700671uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
672{
673 uint32_t rv;
674
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700675 /* Read the firmware space. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700676 rv = read_space_firmware(ctx);
677 if (rv == TPM_E_BADINDEX) {
Julius Werner683657e2019-12-04 12:50:43 -0800678 /* This seems the first time we've run. Initialize the TPM. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700679 VBDEBUG("TPM: Not initialized yet.\n");
680 RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
681 } else if (rv != TPM_SUCCESS) {
682 VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700683 return TPM_E_CORRUPTED_STATE;
684 }
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700685
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700686 return TPM_SUCCESS;
687}
688
Daisuke Nojiri57990972014-07-15 19:47:32 -0700689uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700690{
Jes B. Klinkec6b041a12022-04-19 14:00:33 -0700691 if (CONFIG(TPM_GOOGLE_IMMEDIATELY_COMMIT_FW_SECDATA))
Aaron Durbineeb77372017-03-08 11:23:11 -0600692 tlcl_cr50_enable_nvcommits();
Joel Kitching38141162020-04-14 18:20:44 +0800693 return safe_write(FIRMWARE_NV_INDEX, ctx->secdata_firmware,
694 VB2_SECDATA_FIRMWARE_SIZE);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700695}
Furquan Shaikhb038f412016-11-07 23:47:11 -0800696
dnojiridff56a02020-04-03 10:56:43 -0700697uint32_t antirollback_write_space_kernel(struct vb2_context *ctx)
698{
699 /* Learn the expected size. */
700 uint8_t size = VB2_SECDATA_KERNEL_MIN_SIZE;
701 vb2api_secdata_kernel_check(ctx, &size);
702
Jett Rink3f5de1c2020-07-10 12:10:35 -0600703 /*
704 * Ensure that the TPM actually commits our changes to NVMEN in case
705 * there is a power loss or other unexpected event. The AP does not
706 * write to the TPM during normal boot flow; it only writes during
707 * recovery, software sync, or other special boot flows. When the AP
708 * wants to write, it is imporant to actually commit changes.
709 */
Jes B. Klinkec6b041a12022-04-19 14:00:33 -0700710 if (CONFIG(TPM_GOOGLE_IMMEDIATELY_COMMIT_FW_SECDATA))
Jett Rink3f5de1c2020-07-10 12:10:35 -0600711 tlcl_cr50_enable_nvcommits();
712
Patrick Georgib81147c2020-04-20 09:25:51 +0200713 return safe_write(KERNEL_NV_INDEX, ctx->secdata_kernel, size);
dnojiridff56a02020-04-03 10:56:43 -0700714}
715
Joel Kitching220ac042019-07-31 14:19:00 +0800716vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *ctx)
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100717{
718 uint32_t rv;
719 printk(BIOS_INFO, "Clearing TPM owner\n");
720 rv = tpm_clear_and_reenable();
721 if (rv)
722 return VB2_ERROR_EX_TPM_CLEAR_OWNER;
723 return VB2_SUCCESS;
724}