blob: 1ace632aff53c1fbd702542f83194cd75f64ec16 [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>
Randall Spangler144c2282014-12-03 17:35:53 -080036#include <stdlib.h>
37#include <string.h>
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010038#include <security/tpm/tspi.h>
Randall Spangler144c2282014-12-03 17:35:53 -080039#include <vb2_api.h>
Vadim Bendebury10ea1042016-06-06 12:12:34 -070040#include <console/console.h>
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070041
42#ifndef offsetof
43#define offsetof(A,B) __builtin_offsetof(A,B)
44#endif
45
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070046#ifdef FOR_TEST
Daisuke Nojiri57990972014-07-15 19:47:32 -070047#include <stdio.h>
48#define VBDEBUG(format, args...) printf(format, ## args)
49#else
Daisuke Nojiri57990972014-07-15 19:47:32 -070050#define VBDEBUG(format, args...) \
51 printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070052#endif
53
Daisuke Nojiri57990972014-07-15 19:47:32 -070054#define RETURN_ON_FAILURE(tpm_cmd) do { \
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070055 uint32_t result_; \
Daisuke Nojiri57990972014-07-15 19:47:32 -070056 if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
57 VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
58 "\n", (int)result_); \
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070059 return result_; \
60 } \
61 } while (0)
62
Philipp Deppenwiesef8499722018-07-30 01:27:47 +020063#define TPM_PCR_GBB_FLAGS_NAME "GBB flags"
64#define TPM_PCR_GBB_HWID_NAME "GBB HWID"
Julius Werner76e33032015-01-30 18:45:27 -080065
Vadim Bendebury10ea1042016-06-06 12:12:34 -070066static uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
67
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010068uint32_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
Philipp Deppenwiesef8499722018-07-30 01:27:47 +020069 enum vb2_pcr_digest which_digest)
Julius Werner76e33032015-01-30 18:45:27 -080070{
71 uint8_t buffer[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
72 uint32_t size = sizeof(buffer);
73 int rv;
74
75 rv = vb2api_get_pcr_digest(ctx, which_digest, buffer, &size);
76 if (rv != VB2_SUCCESS)
77 return rv;
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010078 if (size < TPM_PCR_MINIMUM_DIGEST_SIZE)
Julius Werner76e33032015-01-30 18:45:27 -080079 return VB2_ERROR_UNKNOWN;
80
Philipp Deppenwiesef8499722018-07-30 01:27:47 +020081 switch (which_digest) {
82 case BOOT_MODE_PCR:
Philipp Deppenwiesec9b7d1f2018-11-10 00:35:02 +010083 return tpm_extend_pcr(pcr, VB2_HASH_SHA1, buffer, size,
Philipp Deppenwiesef8499722018-07-30 01:27:47 +020084 TPM_PCR_GBB_FLAGS_NAME);
85 case HWID_DIGEST_PCR:
Philipp Deppenwiesec9b7d1f2018-11-10 00:35:02 +010086 return tpm_extend_pcr(pcr, VB2_HASH_SHA256, buffer,
87 size, TPM_PCR_GBB_HWID_NAME);
Philipp Deppenwiesef8499722018-07-30 01:27:47 +020088 default:
89 return VB2_ERROR_UNKNOWN;
90 }
Julius Werner76e33032015-01-30 18:45:27 -080091}
92
Daisuke Nojiri57990972014-07-15 19:47:32 -070093static uint32_t read_space_firmware(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070094{
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -070095 int attempts = 3;
96
97 while (attempts--) {
Daisuke Nojiri57990972014-07-15 19:47:32 -070098 RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
99 VB2_SECDATA_SIZE));
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700100
Daisuke Nojiri57990972014-07-15 19:47:32 -0700101 if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700102 return TPM_SUCCESS;
103
Daisuke Nojiri57990972014-07-15 19:47:32 -0700104 VBDEBUG("TPM: %s() - bad CRC\n", __func__);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700105 }
106
Daisuke Nojiri57990972014-07-15 19:47:32 -0700107 VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700108 return TPM_E_CORRUPTED_STATE;
109}
110
Furquan Shaikhb038f412016-11-07 23:47:11 -0800111static uint32_t read_space_rec_hash(uint8_t *data)
112{
113 RETURN_ON_FAILURE(tlcl_read(REC_HASH_NV_INDEX, data,
114 REC_HASH_NV_SIZE));
115 return TPM_SUCCESS;
116}
117
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700118static uint32_t write_secdata(uint32_t index,
119 const uint8_t *secdata,
120 uint32_t len)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700121{
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700122 uint8_t sd[32];
123 uint32_t rv;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700124 int attempts = 3;
125
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700126 if (len > sizeof(sd)) {
127 VBDEBUG("TPM: %s() - data is too large\n", __func__);
128 return TPM_E_WRITE_FAILURE;
129 }
130
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700131 while (attempts--) {
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700132 rv = safe_write(index, secdata, len);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700133 /* Can't write, not gonna try again */
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700134 if (rv != TPM_SUCCESS)
135 return rv;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700136
137 /* Read it back to be sure it got the right values. */
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700138 rv = tlcl_read(index, sd, len);
139 if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
140 return rv;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700141
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700142 VBDEBUG("TPM: %s() failed. trying again\n", __func__);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700143 /* Try writing it again. Maybe it was garbled on the way out. */
144 }
145
Daisuke Nojiri57990972014-07-15 19:47:32 -0700146 VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700147
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700148 return TPM_E_CORRUPTED_STATE;
149}
150
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700151/*
152 * This is derived from rollback_index.h of vboot_reference. see struct
153 * RollbackSpaceKernel for details.
154 */
155static const uint8_t secdata_kernel[] = {
156 0x02,
157 0x4C, 0x57, 0x52, 0x47,
158 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00,
160 0xE8,
161};
162
Furquan Shaikhb038f412016-11-07 23:47:11 -0800163/*
164 * This is used to initialize the TPM space for recovery hash after defining
165 * it. Since there is no data available to calculate hash at the point where TPM
166 * space is defined, initialize it to all 0s.
167 */
168static const uint8_t rec_hash_data[REC_HASH_NV_SIZE] = { };
169
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700170#if IS_ENABLED(CONFIG_TPM2)
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100171/*
172 * Different sets of NVRAM space attributes apply to the "ro" spaces,
173 * i.e. those which should not be possible to delete or modify once
174 * the RO exits, and the rest of the NVRAM spaces.
175 */
176const static TPMA_NV ro_space_attributes = {
177 .TPMA_NV_PPWRITE = 1,
178 .TPMA_NV_AUTHREAD = 1,
179 .TPMA_NV_PPREAD = 1,
180 .TPMA_NV_PLATFORMCREATE = 1,
181 .TPMA_NV_WRITE_STCLEAR = 1,
182 .TPMA_NV_POLICY_DELETE = 1,
183};
184
185const static TPMA_NV rw_space_attributes = {
186 .TPMA_NV_PPWRITE = 1,
187 .TPMA_NV_AUTHREAD = 1,
188 .TPMA_NV_PPREAD = 1,
189 .TPMA_NV_PLATFORMCREATE = 1,
190};
191
192/*
193 * This policy digest was obtained using TPM2_PolicyPCR
194 * selecting only PCR_0 with a value of all zeros.
195 */
196const static uint8_t pcr0_unchanged_policy[] = {
197 0x09, 0x93, 0x3C, 0xCE, 0xEB, 0xB4, 0x41, 0x11, 0x18, 0x81, 0x1D,
198 0xD4, 0x47, 0x78, 0x80, 0x08, 0x88, 0x86, 0x62, 0x2D, 0xD7, 0x79,
199 0x94, 0x46, 0x62, 0x26, 0x68, 0x8E, 0xEE, 0xE6, 0x6A, 0xA1};
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700200
201/* Nothing special in the TPM2 path yet. */
202static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
203{
204 return tlcl_write(index, data, length);
205}
206
Andrey Pronin278a5062018-01-26 12:47:51 -0800207static uint32_t set_space(const char *name, uint32_t index, const void *data,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100208 uint32_t length, const TPMA_NV nv_attributes,
209 const uint8_t *nv_policy, size_t nv_policy_size)
Andrey Pronin278a5062018-01-26 12:47:51 -0800210{
211 uint32_t rv;
212
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100213 rv = tlcl_define_space(index, length, nv_attributes, nv_policy,
214 nv_policy_size);
Andrey Pronin278a5062018-01-26 12:47:51 -0800215 if (rv == TPM_E_NV_DEFINED) {
216 /*
217 * Continue with writing: it may be defined, but not written
218 * to. In that case a subsequent tlcl_read() would still return
219 * TPM_E_BADINDEX on TPM 2.0. The cases when some non-firmware
220 * space is defined while the firmware space is not there
221 * should be rare (interrupted initialization), so no big harm
222 * in writing once again even if it was written already.
223 */
224 VBDEBUG("%s: %s space already exists\n", __func__, name);
225 rv = TPM_SUCCESS;
226 }
227
228 if (rv != TPM_SUCCESS)
229 return rv;
230
231 return safe_write(index, data, length);
232}
233
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700234static uint32_t set_firmware_space(const void *firmware_blob)
235{
Andrey Pronin278a5062018-01-26 12:47:51 -0800236 return set_space("firmware", FIRMWARE_NV_INDEX, firmware_blob,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100237 VB2_SECDATA_SIZE, ro_space_attributes,
238 pcr0_unchanged_policy, sizeof(pcr0_unchanged_policy));
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700239}
240
241static uint32_t set_kernel_space(const void *kernel_blob)
242{
Andrey Pronin278a5062018-01-26 12:47:51 -0800243 return set_space("kernel", KERNEL_NV_INDEX, kernel_blob,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100244 sizeof(secdata_kernel), rw_space_attributes, NULL, 0);
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700245}
246
Furquan Shaikhb038f412016-11-07 23:47:11 -0800247static uint32_t set_rec_hash_space(const uint8_t *data)
248{
Andrey Pronin278a5062018-01-26 12:47:51 -0800249 return set_space("MRC Hash", REC_HASH_NV_INDEX, data,
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100250 REC_HASH_NV_SIZE,
251 ro_space_attributes, pcr0_unchanged_policy,
252 sizeof(pcr0_unchanged_policy));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800253}
254
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700255static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
256{
Vadim Bendeburyadfbbde2016-07-03 15:56:41 -0700257 RETURN_ON_FAILURE(tlcl_force_clear());
Vadim Bendebury38837012016-11-14 16:36:26 -0800258
259 /*
260 * Of all NVRAM spaces defined by this function the firmware space
261 * must be defined last, because its existence is considered an
262 * indication that TPM factory initialization was successfully
263 * completed.
264 */
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700265 RETURN_ON_FAILURE(set_kernel_space(secdata_kernel));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800266
267 if (IS_ENABLED(CONFIG_VBOOT_HAS_REC_HASH_SPACE))
268 RETURN_ON_FAILURE(set_rec_hash_space(rec_hash_data));
269
Vadim Bendebury38837012016-11-14 16:36:26 -0800270 RETURN_ON_FAILURE(set_firmware_space(ctx->secdata));
271
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700272 return TPM_SUCCESS;
273}
274
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700275uint32_t antirollback_lock_space_firmware(void)
276{
277 return tlcl_lock_nv_write(FIRMWARE_NV_INDEX);
278}
279
Furquan Shaikhb038f412016-11-07 23:47:11 -0800280uint32_t antirollback_lock_space_rec_hash(void)
281{
282 return tlcl_lock_nv_write(REC_HASH_NV_INDEX);
283}
284
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700285#else
286
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700287/**
288 * Like tlcl_write(), but checks for write errors due to hitting the 64-write
289 * limit and clears the TPM when that happens. This can only happen when the
290 * TPM is unowned, so it is OK to clear it (and we really have no choice).
291 * This is not expected to happen frequently, but it could happen.
292 */
293
294static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
295{
296 uint32_t result = tlcl_write(index, data, length);
297 if (result == TPM_E_MAXNVWRITES) {
298 RETURN_ON_FAILURE(tpm_clear_and_reenable());
299 return tlcl_write(index, data, length);
300 } else {
301 return result;
302 }
303}
304
305/**
306 * Similarly to safe_write(), this ensures we don't fail a DefineSpace because
307 * we hit the TPM write limit. This is even less likely to happen than with
308 * writes because we only define spaces once at initialization, but we'd
309 * rather be paranoid about this.
310 */
311static uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
312{
313 uint32_t result = tlcl_define_space(index, perm, size);
314 if (result == TPM_E_MAXNVWRITES) {
315 RETURN_ON_FAILURE(tpm_clear_and_reenable());
316 return tlcl_define_space(index, perm, size);
317 } else {
318 return result;
319 }
320}
321
Furquan Shaikhb038f412016-11-07 23:47:11 -0800322static uint32_t set_rec_hash_space(const uint8_t *data)
323{
324 RETURN_ON_FAILURE(safe_define_space(REC_HASH_NV_INDEX,
325 TPM_NV_PER_GLOBALLOCK |
326 TPM_NV_PER_PPWRITE,
327 REC_HASH_NV_SIZE));
328 RETURN_ON_FAILURE(write_secdata(REC_HASH_NV_INDEX, data,
329 REC_HASH_NV_SIZE));
330
331 return TPM_SUCCESS;
332}
333
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700334static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700335{
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700336 TPM_PERMANENT_FLAGS pflags;
337 uint32_t result;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700338
Daisuke Nojiri57990972014-07-15 19:47:32 -0700339 result = tlcl_get_permanent_flags(&pflags);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700340 if (result != TPM_SUCCESS)
341 return result;
342
343 /*
344 * TPM may come from the factory without physical presence finalized.
345 * Fix if necessary.
346 */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700347 VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
348 pflags.physicalPresenceLifetimeLock);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700349 if (!pflags.physicalPresenceLifetimeLock) {
Daisuke Nojiri57990972014-07-15 19:47:32 -0700350 VBDEBUG("TPM: Finalizing physical presence\n");
351 RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700352 }
353
354 /*
355 * The TPM will not enforce the NV authorization restrictions until the
356 * execution of a TPM_NV_DefineSpace with the handle of
357 * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
358 * exist. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700359 VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700360 if (!pflags.nvLocked) {
Daisuke Nojiri57990972014-07-15 19:47:32 -0700361 VBDEBUG("TPM: Enabling NV locking\n");
362 RETURN_ON_FAILURE(tlcl_set_nv_locked());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700363 }
364
365 /* Clear TPM owner, in case the TPM is already owned for some reason. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700366 VBDEBUG("TPM: Clearing owner\n");
367 RETURN_ON_FAILURE(tpm_clear_and_reenable());
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700368
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700369 /* Define and initialize the kernel space */
370 RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
371 TPM_NV_PER_PPWRITE,
372 sizeof(secdata_kernel)));
373 RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX,
374 secdata_kernel,
375 sizeof(secdata_kernel)));
376
Daisuke Nojiri57990972014-07-15 19:47:32 -0700377 /* Defines and sets vb2 secdata space */
378 vb2api_secdata_create(ctx);
379 RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
380 TPM_NV_PER_GLOBALLOCK |
381 TPM_NV_PER_PPWRITE,
382 VB2_SECDATA_SIZE));
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700383 RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
384 ctx->secdata,
385 VB2_SECDATA_SIZE));
Furquan Shaikhb038f412016-11-07 23:47:11 -0800386
387 /* Define and set rec hash space, if available. */
388 if (IS_ENABLED(CONFIG_VBOOT_HAS_REC_HASH_SPACE))
389 RETURN_ON_FAILURE(set_rec_hash_space(rec_hash_data));
390
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700391 return TPM_SUCCESS;
392}
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700393
394uint32_t antirollback_lock_space_firmware(void)
395{
396 return tlcl_set_global_lock();
397}
Furquan Shaikhb038f412016-11-07 23:47:11 -0800398
399uint32_t antirollback_lock_space_rec_hash(void)
400{
401 /*
402 * Nothing needs to be done here, since global lock is already set while
403 * locking firmware space.
404 */
405 return TPM_SUCCESS;
406}
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700407#endif
408
Vadim Bendebury673a2662016-11-11 09:33:43 -0800409/**
410 * Perform one-time initializations.
411 *
412 * Create the NVRAM spaces, and set their initial values as needed. Sets the
413 * nvLocked bit and ensures the physical presence command is enabled and
414 * locked.
415 */
416static uint32_t factory_initialize_tpm(struct vb2_context *ctx)
Vadim Bendebury10ea1042016-06-06 12:12:34 -0700417{
418 uint32_t result;
419
420 /* Defines and sets vb2 secdata space */
421 vb2api_secdata_create(ctx);
422
423 VBDEBUG("TPM: factory initialization\n");
424
425 /*
426 * Do a full test. This only happens the first time the device is
427 * turned on in the factory, so performance is not an issue. This is
428 * almost certainly not necessary, but it gives us more confidence
429 * about some code paths below that are difficult to
430 * test---specifically the ones that set lifetime flags, and are only
431 * executed once per physical TPM.
432 */
433 result = tlcl_self_test_full();
434 if (result != TPM_SUCCESS)
435 return result;
436
437 result = _factory_initialize_tpm(ctx);
438 if (result != TPM_SUCCESS)
439 return result;
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700440
441 VBDEBUG("TPM: factory initialization successful\n");
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700442
443 return TPM_SUCCESS;
444}
445
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100446uint32_t vboot_setup_tpm(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700447{
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700448 uint32_t result;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700449
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100450 result = tpm_setup(ctx->flags & VB2_CONTEXT_S3_RESUME);
451 if (result == TPM_E_MUST_REBOOT)
Furquan Shaikh6fecb712015-09-17 12:40:23 -0700452 ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700453
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100454 return result;
Daisuke Nojiri57990972014-07-15 19:47:32 -0700455}
456
457uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
458{
459 uint32_t rv;
460
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100461 rv = vboot_setup_tpm(ctx);
Daisuke Nojiri57990972014-07-15 19:47:32 -0700462 if (rv)
463 return rv;
464
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700465 /* Read the firmware space. */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700466 rv = read_space_firmware(ctx);
467 if (rv == TPM_E_BADINDEX) {
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700468 /*
Daisuke Nojiri57990972014-07-15 19:47:32 -0700469 * This seems the first time we've run. Initialize the TPM.
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700470 */
Daisuke Nojiri57990972014-07-15 19:47:32 -0700471 VBDEBUG("TPM: Not initialized yet.\n");
472 RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
473 } else if (rv != TPM_SUCCESS) {
474 VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
475 //RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700476 return TPM_E_CORRUPTED_STATE;
477 }
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700478
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700479 return TPM_SUCCESS;
480}
481
Daisuke Nojiri57990972014-07-15 19:47:32 -0700482uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700483{
Aaron Durbineeb77372017-03-08 11:23:11 -0600484 if (IS_ENABLED(CONFIG_CR50_IMMEDIATELY_COMMIT_FW_SECDATA))
485 tlcl_cr50_enable_nvcommits();
Daisuke Nojiri97ea9c02014-09-29 13:02:29 -0700486 return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE);
Daisuke Nojiriefb5cde2014-07-02 08:37:23 -0700487}
Furquan Shaikhb038f412016-11-07 23:47:11 -0800488
489uint32_t antirollback_read_space_rec_hash(uint8_t *data, uint32_t size)
490{
491 if (size != REC_HASH_NV_SIZE) {
492 VBDEBUG("TPM: Incorrect buffer size for rec hash. "
493 "(Expected=0x%x Actual=0x%x).\n", REC_HASH_NV_SIZE,
494 size);
495 return TPM_E_READ_FAILURE;
496 }
497 return read_space_rec_hash(data);
498}
499
500uint32_t antirollback_write_space_rec_hash(const uint8_t *data, uint32_t size)
501{
502 uint8_t spc_data[REC_HASH_NV_SIZE];
503 uint32_t rv;
504
505 if (size != REC_HASH_NV_SIZE) {
506 VBDEBUG("TPM: Incorrect buffer size for rec hash. "
507 "(Expected=0x%x Actual=0x%x).\n", REC_HASH_NV_SIZE,
508 size);
509 return TPM_E_WRITE_FAILURE;
510 }
511
512 rv = read_space_rec_hash(spc_data);
513 if (rv == TPM_E_BADINDEX) {
514 /*
515 * If space is not defined already for recovery hash, define
516 * new space.
517 */
518 VBDEBUG("TPM: Initializing recovery hash space.\n");
519 return set_rec_hash_space(data);
520 }
521
522 if (rv != TPM_SUCCESS)
523 return rv;
524
525 return write_secdata(REC_HASH_NV_INDEX, data, size);
526}
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100527
528int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
529{
530 uint32_t rv;
531 printk(BIOS_INFO, "Clearing TPM owner\n");
532 rv = tpm_clear_and_reenable();
533 if (rv)
534 return VB2_ERROR_EX_TPM_CLEAR_OWNER;
535 return VB2_SUCCESS;
536}