blob: 38a1810d7fb5dc9b5536649b846384286e5abe9d [file] [log] [blame]
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -07001/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -07002 *
Martin Roth08d808f2017-02-09 18:06:16 -08003 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following disclaimer
11 * in the documentation and/or other materials provided with the
12 * distribution.
13 * * Neither the name of Google Inc. nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070031 * Functions for querying, manipulating and locking rollback indices
32 * stored in the TPM NVRAM.
33 */
34
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010035#include <security/vboot/antirollback.h>
Christian Walter0bd84ed2019-07-23 10:26:30 +020036#include <security/vboot/tpm_common.h>
Randall Spangler144c2282014-12-03 17:35:53 -080037#include <stdlib.h>
38#include <string.h>
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010039#include <security/tpm/tspi.h>
Randall Spangler144c2282014-12-03 17:35:53 -080040#include <vb2_api.h>
Vadim Bendebury10ea1042016-06-06 12:12:34 -070041#include <console/console.h>
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070042
43#ifndef offsetof
44#define offsetof(A,B) __builtin_offsetof(A,B)
45#endif
46
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070047#ifdef FOR_TEST
Daisuke Nojiri57990972014-07-15 19:47:32 -070048#include <stdio.h>
49#define VBDEBUG(format, args...) printf(format, ## args)
50#else
Daisuke Nojiri57990972014-07-15 19:47:32 -070051#define VBDEBUG(format, args...) \
52 printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070053#endif
54
Daisuke Nojiri57990972014-07-15 19:47:32 -070055#define RETURN_ON_FAILURE(tpm_cmd) do { \
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070056 uint32_t result_; \
Daisuke Nojiri57990972014-07-15 19:47:32 -070057 if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
58 VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
59 "\n", (int)result_); \
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070060 return result_; \
61 } \
62 } while (0)
63
Philipp Deppenwiesef8499722018-07-30 01:27:47 +020064#define TPM_PCR_GBB_FLAGS_NAME "GBB flags"
65#define TPM_PCR_GBB_HWID_NAME "GBB HWID"
Julius Werner76e33032015-01-30 18:45:27 -080066
Vadim Bendebury10ea1042016-06-06 12:12:34 -070067static uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
68
Daisuke Nojiri57990972014-07-15 19:47:32 -070069static uint32_t read_space_firmware(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070070{
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070071 int attempts = 3;
72
73 while (attempts--) {
Daisuke Nojiri57990972014-07-15 19:47:32 -070074 RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
75 VB2_SECDATA_SIZE));
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070076
Daisuke Nojiri57990972014-07-15 19:47:32 -070077 if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070078 return TPM_SUCCESS;
79
Daisuke Nojiri57990972014-07-15 19:47:32 -070080 VBDEBUG("TPM: %s() - bad CRC\n", __func__);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070081 }
82
Daisuke Nojiri57990972014-07-15 19:47:32 -070083 VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070084 return TPM_E_CORRUPTED_STATE;
85}
86
Furquan Shaikhb038f412016-11-07 23:47:11 -080087static uint32_t read_space_rec_hash(uint8_t *data)
88{
89 RETURN_ON_FAILURE(tlcl_read(REC_HASH_NV_INDEX, data,
90 REC_HASH_NV_SIZE));
91 return TPM_SUCCESS;
92}
93
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -070094static uint32_t write_secdata(uint32_t index,
95 const uint8_t *secdata,
96 uint32_t len)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070097{
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -070098 uint8_t sd[32];
99 uint32_t rv;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700100 int attempts = 3;
101
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700102 if (len > sizeof(sd)) {
103 VBDEBUG("TPM: %s() - data is too large\n", __func__);
104 return TPM_E_WRITE_FAILURE;
105 }
106
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700107 while (attempts--) {
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700108 rv = safe_write(index, secdata, len);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700109 /* Can't write, not gonna try again */
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700110 if (rv != TPM_SUCCESS)
111 return rv;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700112
113 /* Read it back to be sure it got the right values. */
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700114 rv = tlcl_read(index, sd, len);
115 if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
116 return rv;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700117
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700118 VBDEBUG("TPM: %s() failed. trying again\n", __func__);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700119 /* Try writing it again. Maybe it was garbled on the way out. */
120 }
121
Daisuke Nojiri57990972014-07-15 19:47:32 -0700122 VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700123
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700124 return TPM_E_CORRUPTED_STATE;
125}
126
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700127/*
Furquan Shaikhb038f412016-11-07 23:47:11 -0800128 * This is used to initialize the TPM space for recovery hash after defining
129 * it. Since there is no data available to calculate hash at the point where TPM
130 * space is defined, initialize it to all 0s.
131 */
132static const uint8_t rec_hash_data[REC_HASH_NV_SIZE] = { };
133
Julius Wernercd49cce2019-03-05 16:53:33 -0800134#if CONFIG(TPM2)
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100135/*
136 * Different sets of NVRAM space attributes apply to the "ro" spaces,
137 * i.e. those which should not be possible to delete or modify once
138 * the RO exits, and the rest of the NVRAM spaces.
139 */
140const static TPMA_NV ro_space_attributes = {
141 .TPMA_NV_PPWRITE = 1,
142 .TPMA_NV_AUTHREAD = 1,
143 .TPMA_NV_PPREAD = 1,
144 .TPMA_NV_PLATFORMCREATE = 1,
145 .TPMA_NV_WRITE_STCLEAR = 1,
146 .TPMA_NV_POLICY_DELETE = 1,
147};
148
149const static TPMA_NV rw_space_attributes = {
150 .TPMA_NV_PPWRITE = 1,
151 .TPMA_NV_AUTHREAD = 1,
152 .TPMA_NV_PPREAD = 1,
153 .TPMA_NV_PLATFORMCREATE = 1,
154};
155
156/*
157 * This policy digest was obtained using TPM2_PolicyPCR
158 * selecting only PCR_0 with a value of all zeros.
159 */
160const static uint8_t pcr0_unchanged_policy[] = {
161 0x09, 0x93, 0x3C, 0xCE, 0xEB, 0xB4, 0x41, 0x11, 0x18, 0x81, 0x1D,
162 0xD4, 0x47, 0x78, 0x80, 0x08, 0x88, 0x86, 0x62, 0x2D, 0xD7, 0x79,
163 0x94, 0x46, 0x62, 0x26, 0x68, 0x8E, 0xEE, 0xE6, 0x6A, 0xA1};
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700164
165/* Nothing special in the TPM2 path yet. */
166static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
167{
168 return tlcl_write(index, data, length);
169}
170
Andrey Pronin278a5062018-01-26 12:47:51 -0800171static uint32_t set_space(const char *name, uint32_t index, const void *data,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100172 uint32_t length, const TPMA_NV nv_attributes,
173 const uint8_t *nv_policy, size_t nv_policy_size)
Andrey Pronin278a5062018-01-26 12:47:51 -0800174{
175 uint32_t rv;
176
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100177 rv = tlcl_define_space(index, length, nv_attributes, nv_policy,
178 nv_policy_size);
Andrey Pronin278a5062018-01-26 12:47:51 -0800179 if (rv == TPM_E_NV_DEFINED) {
180 /*
181 * Continue with writing: it may be defined, but not written
182 * to. In that case a subsequent tlcl_read() would still return
183 * TPM_E_BADINDEX on TPM 2.0. The cases when some non-firmware
184 * space is defined while the firmware space is not there
185 * should be rare (interrupted initialization), so no big harm
186 * in writing once again even if it was written already.
187 */
188 VBDEBUG("%s: %s space already exists\n", __func__, name);
189 rv = TPM_SUCCESS;
190 }
191
192 if (rv != TPM_SUCCESS)
193 return rv;
194
195 return safe_write(index, data, length);
196}
197
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700198static uint32_t set_firmware_space(const void *firmware_blob)
199{
Andrey Pronin278a5062018-01-26 12:47:51 -0800200 return set_space("firmware", FIRMWARE_NV_INDEX, firmware_blob,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100201 VB2_SECDATA_SIZE, ro_space_attributes,
202 pcr0_unchanged_policy, sizeof(pcr0_unchanged_policy));
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700203}
204
205static uint32_t set_kernel_space(const void *kernel_blob)
206{
Andrey Pronin278a5062018-01-26 12:47:51 -0800207 return set_space("kernel", KERNEL_NV_INDEX, kernel_blob,
Joel Kitching544b5722019-06-11 13:54:51 +0800208 VB2_SECDATAK_SIZE, rw_space_attributes, NULL, 0);
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700209}
210
Furquan Shaikhb038f412016-11-07 23:47:11 -0800211static uint32_t set_rec_hash_space(const uint8_t *data)
212{
Andrey Pronin278a5062018-01-26 12:47:51 -0800213 return set_space("MRC Hash", REC_HASH_NV_INDEX, data,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100214 REC_HASH_NV_SIZE,
215 ro_space_attributes, pcr0_unchanged_policy,
216 sizeof(pcr0_unchanged_policy));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800217}
218
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700219static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
220{
Vadim Bendeburyadfbbde2016-07-03 15:56:41 -0700221 RETURN_ON_FAILURE(tlcl_force_clear());
Vadim Bendebury38837012016-11-14 16:36:26 -0800222
223 /*
224 * Of all NVRAM spaces defined by this function the firmware space
225 * must be defined last, because its existence is considered an
226 * indication that TPM factory initialization was successfully
227 * completed.
228 */
Joel Kitching544b5722019-06-11 13:54:51 +0800229 RETURN_ON_FAILURE(set_kernel_space(ctx->secdatak));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800230
Julius Wernercd49cce2019-03-05 16:53:33 -0800231 if (CONFIG(VBOOT_HAS_REC_HASH_SPACE))
Furquan Shaikhb038f412016-11-07 23:47:11 -0800232 RETURN_ON_FAILURE(set_rec_hash_space(rec_hash_data));
233
Vadim Bendebury38837012016-11-14 16:36:26 -0800234 RETURN_ON_FAILURE(set_firmware_space(ctx->secdata));
235
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700236 return TPM_SUCCESS;
237}
238
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700239uint32_t antirollback_lock_space_firmware(void)
240{
241 return tlcl_lock_nv_write(FIRMWARE_NV_INDEX);
242}
243
Furquan Shaikhb038f412016-11-07 23:47:11 -0800244uint32_t antirollback_lock_space_rec_hash(void)
245{
246 return tlcl_lock_nv_write(REC_HASH_NV_INDEX);
247}
248
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700249#else
250
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700251/**
252 * Like tlcl_write(), but checks for write errors due to hitting the 64-write
253 * limit and clears the TPM when that happens. This can only happen when the
254 * TPM is unowned, so it is OK to clear it (and we really have no choice).
255 * This is not expected to happen frequently, but it could happen.
256 */
257
258static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
259{
260 uint32_t result = tlcl_write(index, data, length);
261 if (result == TPM_E_MAXNVWRITES) {
262 RETURN_ON_FAILURE(tpm_clear_and_reenable());
263 return tlcl_write(index, data, length);
264 } else {
265 return result;
266 }
267}
268
269/**
270 * Similarly to safe_write(), this ensures we don't fail a DefineSpace because
271 * we hit the TPM write limit. This is even less likely to happen than with
272 * writes because we only define spaces once at initialization, but we'd
273 * rather be paranoid about this.
274 */
275static uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
276{
277 uint32_t result = tlcl_define_space(index, perm, size);
278 if (result == TPM_E_MAXNVWRITES) {
279 RETURN_ON_FAILURE(tpm_clear_and_reenable());
280 return tlcl_define_space(index, perm, size);
281 } else {
282 return result;
283 }
284}
285
Furquan Shaikhb038f412016-11-07 23:47:11 -0800286static uint32_t set_rec_hash_space(const uint8_t *data)
287{
288 RETURN_ON_FAILURE(safe_define_space(REC_HASH_NV_INDEX,
289 TPM_NV_PER_GLOBALLOCK |
290 TPM_NV_PER_PPWRITE,
291 REC_HASH_NV_SIZE));
292 RETURN_ON_FAILURE(write_secdata(REC_HASH_NV_INDEX, data,
293 REC_HASH_NV_SIZE));
294
295 return TPM_SUCCESS;
296}
297
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700298static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700299{
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700300 TPM_PERMANENT_FLAGS pflags;
301 uint32_t result;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700302
Daisuke Nojiri57990972014-07-15 19:47:32 -0700303 result = tlcl_get_permanent_flags(&pflags);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700304 if (result != TPM_SUCCESS)
305 return result;
306
307 /*
308 * TPM may come from the factory without physical presence finalized.
309 * Fix if necessary.
310 */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700311 VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
312 pflags.physicalPresenceLifetimeLock);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700313 if (!pflags.physicalPresenceLifetimeLock) {
Daisuke Nojiri57990972014-07-15 19:47:32 -0700314 VBDEBUG("TPM: Finalizing physical presence\n");
315 RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700316 }
317
318 /*
319 * The TPM will not enforce the NV authorization restrictions until the
320 * execution of a TPM_NV_DefineSpace with the handle of
321 * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
322 * exist. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700323 VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700324 if (!pflags.nvLocked) {
Daisuke Nojiri57990972014-07-15 19:47:32 -0700325 VBDEBUG("TPM: Enabling NV locking\n");
326 RETURN_ON_FAILURE(tlcl_set_nv_locked());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700327 }
328
329 /* Clear TPM owner, in case the TPM is already owned for some reason. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700330 VBDEBUG("TPM: Clearing owner\n");
331 RETURN_ON_FAILURE(tpm_clear_and_reenable());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700332
Joel Kitching544b5722019-06-11 13:54:51 +0800333 /* Define and write secdatak kernel space. */
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700334 RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
335 TPM_NV_PER_PPWRITE,
Joel Kitching544b5722019-06-11 13:54:51 +0800336 VB2_SECDATAK_SIZE));
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700337 RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX,
Joel Kitching544b5722019-06-11 13:54:51 +0800338 ctx->secdatak,
339 VB2_SECDATAK_SIZE));
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700340
Joel Kitching544b5722019-06-11 13:54:51 +0800341 /* Define and write secdata firmware space. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700342 RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
343 TPM_NV_PER_GLOBALLOCK |
344 TPM_NV_PER_PPWRITE,
345 VB2_SECDATA_SIZE));
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700346 RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
347 ctx->secdata,
348 VB2_SECDATA_SIZE));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800349
350 /* Define and set rec hash space, if available. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800351 if (CONFIG(VBOOT_HAS_REC_HASH_SPACE))
Furquan Shaikhb038f412016-11-07 23:47:11 -0800352 RETURN_ON_FAILURE(set_rec_hash_space(rec_hash_data));
353
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700354 return TPM_SUCCESS;
355}
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700356
357uint32_t antirollback_lock_space_firmware(void)
358{
359 return tlcl_set_global_lock();
360}
Furquan Shaikhb038f412016-11-07 23:47:11 -0800361
362uint32_t antirollback_lock_space_rec_hash(void)
363{
364 /*
365 * Nothing needs to be done here, since global lock is already set while
366 * locking firmware space.
367 */
368 return TPM_SUCCESS;
369}
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700370#endif
371
Vadim Bendebury673a2662016-11-11 09:33:43 -0800372/**
373 * Perform one-time initializations.
374 *
375 * Create the NVRAM spaces, and set their initial values as needed. Sets the
376 * nvLocked bit and ensures the physical presence command is enabled and
377 * locked.
378 */
379static uint32_t factory_initialize_tpm(struct vb2_context *ctx)
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700380{
381 uint32_t result;
382
Joel Kitching544b5722019-06-11 13:54:51 +0800383 /* Set initial values of secdata and secdatak spaces. */
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700384 vb2api_secdata_create(ctx);
Joel Kitching544b5722019-06-11 13:54:51 +0800385 vb2api_secdatak_create(ctx);
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700386
387 VBDEBUG("TPM: factory initialization\n");
388
389 /*
390 * Do a full test. This only happens the first time the device is
391 * turned on in the factory, so performance is not an issue. This is
392 * almost certainly not necessary, but it gives us more confidence
393 * about some code paths below that are difficult to
394 * test---specifically the ones that set lifetime flags, and are only
395 * executed once per physical TPM.
396 */
397 result = tlcl_self_test_full();
398 if (result != TPM_SUCCESS)
399 return result;
400
401 result = _factory_initialize_tpm(ctx);
402 if (result != TPM_SUCCESS)
403 return result;
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700404
405 VBDEBUG("TPM: factory initialization successful\n");
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700406
407 return TPM_SUCCESS;
408}
409
Daisuke Nojiri57990972014-07-15 19:47:32 -0700410uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
411{
412 uint32_t rv;
413
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700414 /* Read the firmware space. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700415 rv = read_space_firmware(ctx);
416 if (rv == TPM_E_BADINDEX) {
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700417 /*
Daisuke Nojiri57990972014-07-15 19:47:32 -0700418 * This seems the first time we've run. Initialize the TPM.
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700419 */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700420 VBDEBUG("TPM: Not initialized yet.\n");
421 RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
422 } else if (rv != TPM_SUCCESS) {
423 VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
424 //RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700425 return TPM_E_CORRUPTED_STATE;
426 }
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700427
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700428 return TPM_SUCCESS;
429}
430
Daisuke Nojiri57990972014-07-15 19:47:32 -0700431uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700432{
Julius Wernercd49cce2019-03-05 16:53:33 -0800433 if (CONFIG(CR50_IMMEDIATELY_COMMIT_FW_SECDATA))
Aaron Durbineeb77372017-03-08 11:23:11 -0600434 tlcl_cr50_enable_nvcommits();
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700435 return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700436}
Furquan Shaikhb038f412016-11-07 23:47:11 -0800437
438uint32_t antirollback_read_space_rec_hash(uint8_t *data, uint32_t size)
439{
440 if (size != REC_HASH_NV_SIZE) {
441 VBDEBUG("TPM: Incorrect buffer size for rec hash. "
442 "(Expected=0x%x Actual=0x%x).\n", REC_HASH_NV_SIZE,
443 size);
444 return TPM_E_READ_FAILURE;
445 }
446 return read_space_rec_hash(data);
447}
448
449uint32_t antirollback_write_space_rec_hash(const uint8_t *data, uint32_t size)
450{
451 uint8_t spc_data[REC_HASH_NV_SIZE];
452 uint32_t rv;
453
454 if (size != REC_HASH_NV_SIZE) {
455 VBDEBUG("TPM: Incorrect buffer size for rec hash. "
456 "(Expected=0x%x Actual=0x%x).\n", REC_HASH_NV_SIZE,
457 size);
458 return TPM_E_WRITE_FAILURE;
459 }
460
461 rv = read_space_rec_hash(spc_data);
462 if (rv == TPM_E_BADINDEX) {
463 /*
464 * If space is not defined already for recovery hash, define
465 * new space.
466 */
467 VBDEBUG("TPM: Initializing recovery hash space.\n");
468 return set_rec_hash_space(data);
469 }
470
471 if (rv != TPM_SUCCESS)
472 return rv;
473
474 return write_secdata(REC_HASH_NV_INDEX, data, size);
475}
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100476
Joel Kitching220ac042019-07-31 14:19:00 +0800477vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *ctx)
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100478{
479 uint32_t rv;
480 printk(BIOS_INFO, "Clearing TPM owner\n");
481 rv = tpm_clear_and_reenable();
482 if (rv)
483 return VB2_ERROR_EX_TPM_CLEAR_OWNER;
484 return VB2_SUCCESS;
485}