blob: 8e82e40bf07012bd8f5f6d5d5729d15c9abdf42f [file] [log] [blame]
Angel Pons986d50e2020-04-02 23:48:53 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Aaron Durbin588ad7b2015-09-29 17:56:59 -05003
Aaron Durbin588ad7b2015-09-29 17:56:59 -05004#include <arch/exception.h>
5#include <assert.h>
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -07006#include <bootmode.h>
Joel Kitching532e0c72019-06-16 17:23:03 +08007#include <cbmem.h>
Yu-Ping Wu29c8fa42019-11-18 11:25:47 +08008#include <fmap.h>
Bill XIEc79e96b2019-08-22 20:28:36 +08009#include <security/tpm/tspi/crtm.h>
dnojiridff56a02020-04-03 10:56:43 -070010#include <security/tpm/tss/vendor/cr50/cr50.h>
Bill XIEc79e96b2019-08-22 20:28:36 +080011#include <security/vboot/misc.h>
12#include <security/vboot/vbnv.h>
13#include <security/vboot/tpm_common.h>
Aaron Durbin588ad7b2015-09-29 17:56:59 -050014#include <string.h>
15#include <timestamp.h>
16#include <vb2_api.h>
Aaron Durbin588ad7b2015-09-29 17:56:59 -050017
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010018#include "antirollback.h"
19
Aaron Durbin87c9fae2016-01-22 15:26:04 -060020/* The max hash size to expect is for SHA512. */
21#define VBOOT_MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE
22
Aaron Durbin588ad7b2015-09-29 17:56:59 -050023#define TODO_BLOCK_SIZE 1024
24
Aaron Durbin588ad7b2015-09-29 17:56:59 -050025/* exports */
26
Joel Kitching220ac042019-07-31 14:19:00 +080027vb2_error_t vb2ex_read_resource(struct vb2_context *ctx,
28 enum vb2_resource_index index,
29 uint32_t offset,
30 void *buf,
31 uint32_t size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -050032{
33 struct region_device rdev;
34 const char *name;
35
36 switch (index) {
37 case VB2_RES_GBB:
38 name = "GBB";
39 break;
40 case VB2_RES_FW_VBLOCK:
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080041 if (vboot_is_firmware_slot_a(ctx))
Aaron Durbin588ad7b2015-09-29 17:56:59 -050042 name = "VBLOCK_A";
43 else
44 name = "VBLOCK_B";
45 break;
46 default:
47 return VB2_ERROR_EX_READ_RESOURCE_INDEX;
48 }
49
Yu-Ping Wu29c8fa42019-11-18 11:25:47 +080050 if (fmap_locate_area_as_rdev(name, &rdev))
Aaron Durbin588ad7b2015-09-29 17:56:59 -050051 return VB2_ERROR_EX_READ_RESOURCE_SIZE;
52
53 if (rdev_readat(&rdev, buf, offset, size) != size)
54 return VB2_ERROR_EX_READ_RESOURCE_SIZE;
55
56 return VB2_SUCCESS;
57}
58
59/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
Joel Kitching220ac042019-07-31 14:19:00 +080060__weak vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
61 uint32_t data_size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -050062{
63 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
64}
65
Joel Kitching220ac042019-07-31 14:19:00 +080066__weak vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
67 uint32_t size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -050068{
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +010069 BUG(); /* Should never get called if init() returned an error. */
Aaron Durbin588ad7b2015-09-29 17:56:59 -050070 return VB2_ERROR_UNKNOWN;
71}
72
Joel Kitching220ac042019-07-31 14:19:00 +080073__weak vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
74 uint32_t digest_size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -050075{
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +010076 BUG(); /* Should never get called if init() returned an error. */
Aaron Durbin588ad7b2015-09-29 17:56:59 -050077 return VB2_ERROR_UNKNOWN;
78}
79
Aaron Durbin87c9fae2016-01-22 15:26:04 -060080static int handle_digest_result(void *slot_hash, size_t slot_hash_sz)
81{
82 int is_resume;
83
84 /*
Naresh G Solanki1d04d162016-11-08 00:27:41 +053085 * Chrome EC is the only support for vboot_save_hash() &
86 * vboot_retrieve_hash(), if Chrome EC is not enabled then return.
Naresh G Solanki3d44d692016-11-06 12:51:14 +053087 */
Julius Wernercd49cce2019-03-05 16:53:33 -080088 if (!CONFIG(EC_GOOGLE_CHROMEEC))
Naresh G Solanki3d44d692016-11-06 12:51:14 +053089 return 0;
90
91 /*
Aaron Durbin87c9fae2016-01-22 15:26:04 -060092 * Nothing to do since resuming on the platform doesn't require
93 * vboot verification again.
94 */
Julius Wernercd49cce2019-03-05 16:53:33 -080095 if (!CONFIG(RESUME_PATH_SAME_AS_BOOT))
Aaron Durbin87c9fae2016-01-22 15:26:04 -060096 return 0;
97
98 /*
99 * Assume that if vboot doesn't start in bootblock verified
100 * RW memory init code is not employed. i.e. memory init code
101 * lives in RO CBFS.
102 */
Julius Wernercd49cce2019-03-05 16:53:33 -0800103 if (!CONFIG(VBOOT_STARTS_IN_BOOTBLOCK))
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600104 return 0;
105
Bill XIE516c0a52020-02-24 23:08:35 +0800106 is_resume = platform_is_resuming();
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600107
108 if (is_resume > 0) {
109 uint8_t saved_hash[VBOOT_MAX_HASH_SIZE];
110 const size_t saved_hash_sz = sizeof(saved_hash);
111
112 assert(slot_hash_sz == saved_hash_sz);
113
114 printk(BIOS_DEBUG, "Platform is resuming.\n");
115
116 if (vboot_retrieve_hash(saved_hash, saved_hash_sz)) {
117 printk(BIOS_ERR, "Couldn't retrieve saved hash.\n");
118 return -1;
119 }
120
121 if (memcmp(saved_hash, slot_hash, slot_hash_sz)) {
122 printk(BIOS_ERR, "Hash mismatch on resume.\n");
123 return -1;
124 }
125 } else if (is_resume < 0)
126 printk(BIOS_ERR, "Unable to determine if platform resuming.\n");
127
128 printk(BIOS_DEBUG, "Saving vboot hash.\n");
129
130 /* Always save the hash for the current boot. */
131 if (vboot_save_hash(slot_hash, slot_hash_sz)) {
132 printk(BIOS_ERR, "Error saving vboot hash.\n");
133 /* Though this is an error don't report it up since it could
134 * lead to a reboot loop. The consequence of this is that
135 * we will most likely fail resuming because of EC issues or
136 * the hash digest not matching. */
137 return 0;
138 }
139
140 return 0;
141}
142
Joel Kitching220ac042019-07-31 14:19:00 +0800143static vb2_error_t hash_body(struct vb2_context *ctx,
Julius Wernerf8e17642019-12-12 13:23:06 -0800144 struct region_device *fw_body)
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500145{
146 uint64_t load_ts;
Julius Wernerf8e17642019-12-12 13:23:06 -0800147 uint32_t remaining;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500148 uint8_t block[TODO_BLOCK_SIZE];
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600149 uint8_t hash_digest[VBOOT_MAX_HASH_SIZE];
150 const size_t hash_digest_sz = sizeof(hash_digest);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500151 size_t block_size = sizeof(block);
152 size_t offset;
Joel Kitching220ac042019-07-31 14:19:00 +0800153 vb2_error_t rv;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500154
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600155 /* Clear the full digest so that any hash digests less than the
156 * max have trailing zeros. */
157 memset(hash_digest, 0, hash_digest_sz);
158
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500159 /*
160 * Since loading the firmware and calculating its hash is intertwined,
161 * we use this little trick to measure them separately and pretend it
162 * was first loaded and then hashed in one piece with the timestamps.
163 * (This split won't make sense with memory-mapped media like on x86.)
164 */
165 load_ts = timestamp_get();
166 timestamp_add(TS_START_HASH_BODY, load_ts);
167
Julius Wernerf8e17642019-12-12 13:23:06 -0800168 remaining = region_device_sz(fw_body);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500169 offset = 0;
170
171 /* Start the body hash */
Julius Wernerf8e17642019-12-12 13:23:06 -0800172 rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500173 if (rv)
174 return rv;
175
176 /* Extend over the body */
Julius Wernerf8e17642019-12-12 13:23:06 -0800177 while (remaining) {
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500178 uint64_t temp_ts;
Julius Wernerf8e17642019-12-12 13:23:06 -0800179 if (block_size > remaining)
180 block_size = remaining;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500181
182 temp_ts = timestamp_get();
Julius Wernerf8e17642019-12-12 13:23:06 -0800183 if (rdev_readat(fw_body, block, offset, block_size) < 0)
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500184 return VB2_ERROR_UNKNOWN;
185 load_ts += timestamp_get() - temp_ts;
186
187 rv = vb2api_extend_hash(ctx, block, block_size);
188 if (rv)
189 return rv;
190
Julius Wernerf8e17642019-12-12 13:23:06 -0800191 remaining -= block_size;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500192 offset += block_size;
193 }
194
195 timestamp_add(TS_DONE_LOADING, load_ts);
196 timestamp_add_now(TS_DONE_HASHING);
197
198 /* Check the result (with RSA signature verification) */
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600199 rv = vb2api_check_hash_get_digest(ctx, hash_digest, hash_digest_sz);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500200 if (rv)
201 return rv;
202
203 timestamp_add_now(TS_END_HASH_BODY);
204
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600205 if (handle_digest_result(hash_digest, hash_digest_sz))
206 return VB2_ERROR_UNKNOWN;
207
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500208 return VB2_SUCCESS;
209}
210
dnojiridff56a02020-04-03 10:56:43 -0700211void vboot_save_data(struct vb2_context *ctx)
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500212{
dnojiridff56a02020-04-03 10:56:43 -0700213 if (ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED &&
214 (CONFIG(VBOOT_MOCK_SECDATA) || tlcl_lib_init() == VB2_SUCCESS)) {
215 printk(BIOS_INFO, "Saving secdata firmware\n");
216 antirollback_write_space_firmware(ctx);
217 ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
218 }
219
220 if (ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED &&
221 (CONFIG(VBOOT_MOCK_SECDATA) || tlcl_lib_init() == VB2_SUCCESS)) {
222 printk(BIOS_INFO, "Saving secdata kernel\n");
223 antirollback_write_space_kernel(ctx);
224 ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED;
225 }
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600226
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500227 if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
228 printk(BIOS_INFO, "Saving nvdata\n");
229 save_vbnv(ctx->nvdata);
230 ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
231 }
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600232}
233
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500234static uint32_t extend_pcrs(struct vb2_context *ctx)
235{
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100236 return vboot_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100237 vboot_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500238}
239
dnojiridff56a02020-04-03 10:56:43 -0700240#define EC_EFS_BOOT_MODE_NORMAL 0x00
241#define EC_EFS_BOOT_MODE_NO_BOOT 0x01
242
243static const char *get_boot_mode_string(uint8_t boot_mode)
244{
245 if (boot_mode == EC_EFS_BOOT_MODE_NORMAL)
246 return "NORMAL";
247 else if (boot_mode == EC_EFS_BOOT_MODE_NO_BOOT)
248 return "NO_BOOT";
249 else
250 return "UNDEFINED";
251}
252
253static void check_boot_mode(struct vb2_context *ctx)
254{
255 uint8_t boot_mode;
256 int rv;
257
258 rv = tlcl_cr50_get_boot_mode(&boot_mode);
259 switch (rv) {
260 case TPM_E_NO_SUCH_COMMAND:
261 printk(BIOS_WARNING, "Cr50 does not support GET_BOOT_MODE.\n");
262 /* Proceed to legacy boot model. */
263 return;
264 case TPM_SUCCESS:
265 break;
266 default:
267 printk(BIOS_ERR,
268 "Communication error in getting Cr50 boot mode.\n");
269 if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
270 /* Continue to boot in recovery mode */
271 return;
272 vb2api_fail(ctx, VB2_RECOVERY_CR50_BOOT_MODE, rv);
273 vboot_save_data(ctx);
274 vboot_reboot();
275 return;
276 }
277
278 printk(BIOS_INFO, "Cr50 says boot_mode is %s(0x%02x).\n",
279 get_boot_mode_string(boot_mode), boot_mode);
280
281 if (boot_mode == EC_EFS_BOOT_MODE_NO_BOOT)
282 ctx->flags |= VB2_CONTEXT_NO_BOOT;
283}
284
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500285/**
286 * Verify and select the firmware in the RW image
287 *
288 * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
289 * when per-stage verification is ready.
290 */
291void verstage_main(void)
292{
Joel Kitching2332c742019-10-23 15:01:37 +0800293 struct vb2_context *ctx;
Julius Wernerf8e17642019-12-12 13:23:06 -0800294 struct region_device fw_body;
Joel Kitching220ac042019-07-31 14:19:00 +0800295 vb2_error_t rv;
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500296
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500297 timestamp_add_now(TS_START_VBOOT);
298
299 /* Set up context and work buffer */
Joel Kitching2332c742019-10-23 15:01:37 +0800300 ctx = vboot_get_context();
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500301
Aaron Durbin118a84f2017-09-15 11:15:07 -0600302 /* Initialize and read nvdata from non-volatile storage. */
Joel Kitching2332c742019-10-23 15:01:37 +0800303 vbnv_init(ctx->nvdata);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500304
Duncan Laurie1cdacca2016-02-19 20:26:07 -0800305 /* Set S3 resume flag if vboot should behave differently when selecting
306 * which slot to boot. This is only relevant to vboot if the platform
307 * does verification of memory init and thus must ensure it resumes with
308 * the same slot that it booted from. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800309 if (CONFIG(RESUME_PATH_SAME_AS_BOOT) &&
Bill XIE516c0a52020-02-24 23:08:35 +0800310 platform_is_resuming())
Joel Kitching2332c742019-10-23 15:01:37 +0800311 ctx->flags |= VB2_CONTEXT_S3_RESUME;
Duncan Laurie1cdacca2016-02-19 20:26:07 -0800312
Duncan Lauriea613a312016-03-14 09:32:08 -0700313 /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
314 * check the return value here because vb2api_fw_phase1 will catch
315 * invalid secdata and tell us what to do (=reboot). */
316 timestamp_add_now(TS_START_TPMINIT);
dnojiridff56a02020-04-03 10:56:43 -0700317 if (vboot_setup_tpm(ctx) == TPM_SUCCESS) {
Joel Kitching2332c742019-10-23 15:01:37 +0800318 antirollback_read_space_firmware(ctx);
dnojiridff56a02020-04-03 10:56:43 -0700319 antirollback_read_space_kernel(ctx);
320 }
Duncan Lauriea613a312016-03-14 09:32:08 -0700321 timestamp_add_now(TS_END_TPMINIT);
322
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500323 if (get_recovery_mode_switch()) {
Joel Kitching2332c742019-10-23 15:01:37 +0800324 ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
Julius Wernercd49cce2019-03-05 16:53:33 -0800325 if (CONFIG(VBOOT_DISABLE_DEV_ON_RECOVERY))
Joel Kitching2332c742019-10-23 15:01:37 +0800326 ctx->flags |= VB2_CONTEXT_DISABLE_DEVELOPER_MODE;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500327 }
328
Julius Wernercd49cce2019-03-05 16:53:33 -0800329 if (CONFIG(VBOOT_WIPEOUT_SUPPORTED) &&
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100330 get_wipeout_mode_switch())
Joel Kitching2332c742019-10-23 15:01:37 +0800331 ctx->flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500332
Julius Wernercd49cce2019-03-05 16:53:33 -0800333 if (CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch())
Joel Kitching2332c742019-10-23 15:01:37 +0800334 ctx->flags |= VB2_CONTEXT_NOFAIL_BOOT;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500335
Joel Kitching5923d672019-04-12 15:57:43 +0800336 /* Mainboard/SoC always initializes display. */
Wim Vervoorne7087a12019-11-15 14:02:02 +0100337 if (!CONFIG(VBOOT_MUST_REQUEST_DISPLAY) || CONFIG(VBOOT_ALWAYS_ENABLE_DISPLAY))
Joel Kitching2332c742019-10-23 15:01:37 +0800338 ctx->flags |= VB2_CONTEXT_DISPLAY_INIT;
Joel Kitching5923d672019-04-12 15:57:43 +0800339
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500340 /* Do early init (set up secdata and NVRAM, load GBB) */
341 printk(BIOS_INFO, "Phase 1\n");
Joel Kitching2332c742019-10-23 15:01:37 +0800342 rv = vb2api_fw_phase1(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500343
344 if (rv) {
345 /*
346 * If vb2api_fw_phase1 fails, check for return value.
347 * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
348 * into recovery mode.
349 * For any other error code, save context if needed and reboot.
350 */
351 if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
352 printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600353 vboot_save_data(ctx);
Joel Kitching2332c742019-10-23 15:01:37 +0800354 extend_pcrs(ctx); /* ignore failures */
Joel Kitchingba50e482019-06-10 17:37:37 +0800355 goto verstage_main_exit;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500356 }
357
Raul E Rangel3a591742018-07-17 14:44:43 -0600358 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600359 vboot_save_data(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500360 vboot_reboot();
361 }
362
363 /* Determine which firmware slot to boot (based on NVRAM) */
364 printk(BIOS_INFO, "Phase 2\n");
Joel Kitching2332c742019-10-23 15:01:37 +0800365 rv = vb2api_fw_phase2(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500366 if (rv) {
367 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600368 vboot_save_data(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500369 vboot_reboot();
370 }
371
372 /* Try that slot (verify its keyblock and preamble) */
373 printk(BIOS_INFO, "Phase 3\n");
374 timestamp_add_now(TS_START_VERIFY_SLOT);
Joel Kitching2332c742019-10-23 15:01:37 +0800375 rv = vb2api_fw_phase3(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500376 timestamp_add_now(TS_END_VERIFY_SLOT);
377 if (rv) {
378 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600379 vboot_save_data(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500380 vboot_reboot();
381 }
382
383 printk(BIOS_INFO, "Phase 4\n");
Julius Wernerf8e17642019-12-12 13:23:06 -0800384 rv = vboot_locate_firmware(ctx, &fw_body);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500385 if (rv)
Keith Short70064582019-05-06 16:12:57 -0600386 die_with_post_code(POST_INVALID_ROM,
387 "Failed to read FMAP to locate firmware");
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500388
Julius Wernerf8e17642019-12-12 13:23:06 -0800389 rv = hash_body(ctx, &fw_body);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600390 vboot_save_data(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500391 if (rv) {
392 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
393 vboot_reboot();
394 }
395
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800396 /* Only extend PCRs once on boot. */
Joel Kitching2332c742019-10-23 15:01:37 +0800397 if (!(ctx->flags & VB2_CONTEXT_S3_RESUME)) {
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800398 timestamp_add_now(TS_START_TPMPCR);
Joel Kitching2332c742019-10-23 15:01:37 +0800399 rv = extend_pcrs(ctx);
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800400 if (rv) {
401 printk(BIOS_WARNING,
402 "Failed to extend TPM PCRs (%#x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800403 vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600404 vboot_save_data(ctx);
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800405 vboot_reboot();
406 }
407 timestamp_add_now(TS_END_TPMPCR);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500408 }
409
dnojiridff56a02020-04-03 10:56:43 -0700410 if (CONFIG(TPM_CR50))
411 check_boot_mode(ctx);
412
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500413 /* Lock TPM */
Raul E Rangel4c518e12018-05-11 11:08:07 -0600414
415 timestamp_add_now(TS_START_TPMLOCK);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500416 rv = antirollback_lock_space_firmware();
417 if (rv) {
418 printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800419 vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600420 vboot_save_data(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500421 vboot_reboot();
422 }
Raul E Rangel4c518e12018-05-11 11:08:07 -0600423 timestamp_add_now(TS_END_TPMLOCK);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500424
Furquan Shaikhb038f412016-11-07 23:47:11 -0800425 /* Lock rec hash space if available. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800426 if (CONFIG(VBOOT_HAS_REC_HASH_SPACE)) {
Furquan Shaikhb038f412016-11-07 23:47:11 -0800427 rv = antirollback_lock_space_rec_hash();
428 if (rv) {
429 printk(BIOS_INFO, "Failed to lock rec hash space(%x)\n",
430 rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800431 vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR,
Furquan Shaikhb038f412016-11-07 23:47:11 -0800432 0);
Tim Wawrzynczakd6fc5572019-10-25 14:58:15 -0600433 vboot_save_data(ctx);
Furquan Shaikhb038f412016-11-07 23:47:11 -0800434 vboot_reboot();
435 }
436 }
437
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +0800438 printk(BIOS_INFO, "Slot %c is selected\n",
439 vboot_is_firmware_slot_a(ctx) ? 'A' : 'B');
Joel Kitchingba50e482019-06-10 17:37:37 +0800440
441 verstage_main_exit:
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500442 timestamp_add_now(TS_END_VBOOT);
443}