blob: 71371cdb75ca8905e1e0999b2d5062b46709e561 [file] [log] [blame]
Aaron Durbin588ad7b2015-09-29 17:56:59 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2014 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Aaron Durbin588ad7b2015-09-29 17:56:59 -050014 */
15
Aaron Durbin588ad7b2015-09-29 17:56:59 -050016#include <arch/exception.h>
17#include <assert.h>
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -070018#include <bootmode.h>
Joel Kitching532e0c72019-06-16 17:23:03 +080019#include <cbmem.h>
Aaron Durbin588ad7b2015-09-29 17:56:59 -050020#include <console/console.h>
21#include <console/vtxprintf.h>
Yu-Ping Wu29c8fa42019-11-18 11:25:47 +080022#include <fmap.h>
Aaron Durbin588ad7b2015-09-29 17:56:59 -050023#include <string.h>
24#include <timestamp.h>
25#include <vb2_api.h>
Philipp Deppenwiesefea24292017-10-17 17:02:29 +020026#include <security/vboot/misc.h>
27#include <security/vboot/vbnv.h>
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +010028#include <security/vboot/vboot_crtm.h>
Christian Walter0bd84ed2019-07-23 10:26:30 +020029#include <security/vboot/tpm_common.h>
Aaron Durbin588ad7b2015-09-29 17:56:59 -050030
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +010031#include "antirollback.h"
32
Aaron Durbin87c9fae2016-01-22 15:26:04 -060033/* The max hash size to expect is for SHA512. */
34#define VBOOT_MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE
35
Aaron Durbin588ad7b2015-09-29 17:56:59 -050036#define TODO_BLOCK_SIZE 1024
37
38static int is_slot_a(struct vb2_context *ctx)
39{
40 return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
41}
42
43/* exports */
44
45void vb2ex_printf(const char *func, const char *fmt, ...)
46{
47 va_list args;
48
Randall Spanglere80c6f62017-01-20 14:48:53 -080049 if (func)
50 printk(BIOS_INFO, "VB2:%s() ", func);
51
Aaron Durbin588ad7b2015-09-29 17:56:59 -050052 va_start(args, fmt);
Kyösti Mälkki7132f252019-02-14 23:08:29 +020053 vprintk(BIOS_INFO, fmt, args);
Aaron Durbin588ad7b2015-09-29 17:56:59 -050054 va_end(args);
55
56 return;
57}
58
Joel Kitching220ac042019-07-31 14:19:00 +080059vb2_error_t vb2ex_read_resource(struct vb2_context *ctx,
60 enum vb2_resource_index index,
61 uint32_t offset,
62 void *buf,
63 uint32_t size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -050064{
65 struct region_device rdev;
66 const char *name;
67
68 switch (index) {
69 case VB2_RES_GBB:
70 name = "GBB";
71 break;
72 case VB2_RES_FW_VBLOCK:
73 if (is_slot_a(ctx))
74 name = "VBLOCK_A";
75 else
76 name = "VBLOCK_B";
77 break;
78 default:
79 return VB2_ERROR_EX_READ_RESOURCE_INDEX;
80 }
81
Yu-Ping Wu29c8fa42019-11-18 11:25:47 +080082 if (fmap_locate_area_as_rdev(name, &rdev))
Aaron Durbin588ad7b2015-09-29 17:56:59 -050083 return VB2_ERROR_EX_READ_RESOURCE_SIZE;
84
85 if (rdev_readat(&rdev, buf, offset, size) != size)
86 return VB2_ERROR_EX_READ_RESOURCE_SIZE;
87
88 return VB2_SUCCESS;
89}
90
Joel Kitchingf3507682019-10-15 01:04:35 +080091void vb2ex_abort(void)
92{
93 die("vboot has aborted execution; exit\n");
94}
95
Aaron Durbin588ad7b2015-09-29 17:56:59 -050096/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
Joel Kitching220ac042019-07-31 14:19:00 +080097__weak vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
98 uint32_t data_size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -050099{
100 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
101}
102
Joel Kitching220ac042019-07-31 14:19:00 +0800103__weak vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
104 uint32_t size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500105{
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100106 BUG(); /* Should never get called if init() returned an error. */
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500107 return VB2_ERROR_UNKNOWN;
108}
109
Joel Kitching220ac042019-07-31 14:19:00 +0800110__weak vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
111 uint32_t digest_size)
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500112{
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100113 BUG(); /* Should never get called if init() returned an error. */
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500114 return VB2_ERROR_UNKNOWN;
115}
116
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600117static int handle_digest_result(void *slot_hash, size_t slot_hash_sz)
118{
119 int is_resume;
120
121 /*
Naresh G Solanki1d04d162016-11-08 00:27:41 +0530122 * Chrome EC is the only support for vboot_save_hash() &
123 * vboot_retrieve_hash(), if Chrome EC is not enabled then return.
Naresh G Solanki3d44d692016-11-06 12:51:14 +0530124 */
Julius Wernercd49cce2019-03-05 16:53:33 -0800125 if (!CONFIG(EC_GOOGLE_CHROMEEC))
Naresh G Solanki3d44d692016-11-06 12:51:14 +0530126 return 0;
127
128 /*
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600129 * Nothing to do since resuming on the platform doesn't require
130 * vboot verification again.
131 */
Julius Wernercd49cce2019-03-05 16:53:33 -0800132 if (!CONFIG(RESUME_PATH_SAME_AS_BOOT))
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600133 return 0;
134
135 /*
136 * Assume that if vboot doesn't start in bootblock verified
137 * RW memory init code is not employed. i.e. memory init code
138 * lives in RO CBFS.
139 */
Julius Wernercd49cce2019-03-05 16:53:33 -0800140 if (!CONFIG(VBOOT_STARTS_IN_BOOTBLOCK))
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600141 return 0;
142
143 is_resume = vboot_platform_is_resuming();
144
145 if (is_resume > 0) {
146 uint8_t saved_hash[VBOOT_MAX_HASH_SIZE];
147 const size_t saved_hash_sz = sizeof(saved_hash);
148
149 assert(slot_hash_sz == saved_hash_sz);
150
151 printk(BIOS_DEBUG, "Platform is resuming.\n");
152
153 if (vboot_retrieve_hash(saved_hash, saved_hash_sz)) {
154 printk(BIOS_ERR, "Couldn't retrieve saved hash.\n");
155 return -1;
156 }
157
158 if (memcmp(saved_hash, slot_hash, slot_hash_sz)) {
159 printk(BIOS_ERR, "Hash mismatch on resume.\n");
160 return -1;
161 }
162 } else if (is_resume < 0)
163 printk(BIOS_ERR, "Unable to determine if platform resuming.\n");
164
165 printk(BIOS_DEBUG, "Saving vboot hash.\n");
166
167 /* Always save the hash for the current boot. */
168 if (vboot_save_hash(slot_hash, slot_hash_sz)) {
169 printk(BIOS_ERR, "Error saving vboot hash.\n");
170 /* Though this is an error don't report it up since it could
171 * lead to a reboot loop. The consequence of this is that
172 * we will most likely fail resuming because of EC issues or
173 * the hash digest not matching. */
174 return 0;
175 }
176
177 return 0;
178}
179
Joel Kitching220ac042019-07-31 14:19:00 +0800180static vb2_error_t hash_body(struct vb2_context *ctx,
181 struct region_device *fw_main)
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500182{
183 uint64_t load_ts;
184 uint32_t expected_size;
185 uint8_t block[TODO_BLOCK_SIZE];
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600186 uint8_t hash_digest[VBOOT_MAX_HASH_SIZE];
187 const size_t hash_digest_sz = sizeof(hash_digest);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500188 size_t block_size = sizeof(block);
189 size_t offset;
Joel Kitching220ac042019-07-31 14:19:00 +0800190 vb2_error_t rv;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500191
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600192 /* Clear the full digest so that any hash digests less than the
193 * max have trailing zeros. */
194 memset(hash_digest, 0, hash_digest_sz);
195
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500196 /*
197 * Since loading the firmware and calculating its hash is intertwined,
198 * we use this little trick to measure them separately and pretend it
199 * was first loaded and then hashed in one piece with the timestamps.
200 * (This split won't make sense with memory-mapped media like on x86.)
201 */
202 load_ts = timestamp_get();
203 timestamp_add(TS_START_HASH_BODY, load_ts);
204
205 expected_size = region_device_sz(fw_main);
206 offset = 0;
207
208 /* Start the body hash */
209 rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
210 if (rv)
211 return rv;
212
Aaron Durbin4121f9e2016-01-27 14:23:17 -0600213 /*
214 * Honor vboot's RW slot size. The expected size is pulled out of
215 * the preamble and obtained through vb2api_init_hash() above. By
216 * creating sub region the RW slot portion of the boot media is
217 * limited.
218 */
219 if (rdev_chain(fw_main, fw_main, 0, expected_size)) {
220 printk(BIOS_ERR, "Unable to restrict CBFS size.\n");
221 return VB2_ERROR_UNKNOWN;
222 }
223
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500224 /* Extend over the body */
225 while (expected_size) {
226 uint64_t temp_ts;
227 if (block_size > expected_size)
228 block_size = expected_size;
229
230 temp_ts = timestamp_get();
231 if (rdev_readat(fw_main, block, offset, block_size) < 0)
232 return VB2_ERROR_UNKNOWN;
233 load_ts += timestamp_get() - temp_ts;
234
235 rv = vb2api_extend_hash(ctx, block, block_size);
236 if (rv)
237 return rv;
238
239 expected_size -= block_size;
240 offset += block_size;
241 }
242
243 timestamp_add(TS_DONE_LOADING, load_ts);
244 timestamp_add_now(TS_DONE_HASHING);
245
246 /* Check the result (with RSA signature verification) */
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600247 rv = vb2api_check_hash_get_digest(ctx, hash_digest, hash_digest_sz);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500248 if (rv)
249 return rv;
250
251 timestamp_add_now(TS_END_HASH_BODY);
252
Aaron Durbin87c9fae2016-01-22 15:26:04 -0600253 if (handle_digest_result(hash_digest, hash_digest_sz))
254 return VB2_ERROR_UNKNOWN;
255
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500256 return VB2_SUCCESS;
257}
258
259static int locate_firmware(struct vb2_context *ctx,
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100260 struct region_device *fw_main)
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500261{
262 const char *name;
263
264 if (is_slot_a(ctx))
265 name = "FW_MAIN_A";
266 else
267 name = "FW_MAIN_B";
268
Yu-Ping Wu29c8fa42019-11-18 11:25:47 +0800269 return fmap_locate_area_as_rdev(name, fw_main);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500270}
271
272/**
273 * Save non-volatile and/or secure data if needed.
274 */
275static void save_if_needed(struct vb2_context *ctx)
276{
277 if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
278 printk(BIOS_INFO, "Saving nvdata\n");
279 save_vbnv(ctx->nvdata);
280 ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
281 }
282 if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
283 printk(BIOS_INFO, "Saving secdata\n");
284 antirollback_write_space_firmware(ctx);
285 ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
286 }
287}
288
289static uint32_t extend_pcrs(struct vb2_context *ctx)
290{
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +0100291 return vboot_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100292 vboot_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500293}
294
Joel Kitching532e0c72019-06-16 17:23:03 +0800295static void vboot_log_and_clear_recovery_mode_switch(int unused)
296{
297 /* Log the recovery mode switches if required, before clearing them. */
298 log_recovery_mode_switch();
299
300 /*
301 * The recovery mode switch is cleared (typically backed by EC) here
302 * to allow multiple queries to get_recovery_mode_switch() and have
303 * them return consistent results during the verified boot path as well
304 * as dram initialization. x86 systems ignore the saved dram settings
305 * in the recovery path in order to start from a clean slate. Therefore
306 * clear the state here since this function is called when memory
307 * is known to be up.
308 */
309 clear_recovery_mode_switch();
310}
311#if !CONFIG(VBOOT_STARTS_IN_ROMSTAGE)
312ROMSTAGE_CBMEM_INIT_HOOK(vboot_log_and_clear_recovery_mode_switch)
313#endif
314
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500315/**
316 * Verify and select the firmware in the RW image
317 *
318 * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
319 * when per-stage verification is ready.
320 */
321void verstage_main(void)
322{
Joel Kitching2332c742019-10-23 15:01:37 +0800323 struct vb2_context *ctx;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500324 struct region_device fw_main;
Joel Kitching220ac042019-07-31 14:19:00 +0800325 vb2_error_t rv;
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500326
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500327 timestamp_add_now(TS_START_VBOOT);
328
329 /* Set up context and work buffer */
Joel Kitching2332c742019-10-23 15:01:37 +0800330 ctx = vboot_get_context();
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500331
Aaron Durbin118a84f2017-09-15 11:15:07 -0600332 /* Initialize and read nvdata from non-volatile storage. */
Joel Kitching2332c742019-10-23 15:01:37 +0800333 vbnv_init(ctx->nvdata);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500334
Duncan Laurie1cdacca2016-02-19 20:26:07 -0800335 /* Set S3 resume flag if vboot should behave differently when selecting
336 * which slot to boot. This is only relevant to vboot if the platform
337 * does verification of memory init and thus must ensure it resumes with
338 * the same slot that it booted from. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800339 if (CONFIG(RESUME_PATH_SAME_AS_BOOT) &&
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100340 vboot_platform_is_resuming())
Joel Kitching2332c742019-10-23 15:01:37 +0800341 ctx->flags |= VB2_CONTEXT_S3_RESUME;
Duncan Laurie1cdacca2016-02-19 20:26:07 -0800342
Duncan Lauriea613a312016-03-14 09:32:08 -0700343 /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
344 * check the return value here because vb2api_fw_phase1 will catch
345 * invalid secdata and tell us what to do (=reboot). */
346 timestamp_add_now(TS_START_TPMINIT);
Joel Kitching2332c742019-10-23 15:01:37 +0800347 if (vboot_setup_tpm(ctx) == TPM_SUCCESS)
348 antirollback_read_space_firmware(ctx);
Duncan Lauriea613a312016-03-14 09:32:08 -0700349 timestamp_add_now(TS_END_TPMINIT);
350
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100351 /* Enable measured boot mode */
Julius Wernercd49cce2019-03-05 16:53:33 -0800352 if (CONFIG(VBOOT_MEASURED_BOOT) &&
Joel Kitching2332c742019-10-23 15:01:37 +0800353 !(ctx->flags & VB2_CONTEXT_S3_RESUME)) {
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100354 if (vboot_init_crtm() != VB2_SUCCESS)
Keith Short70064582019-05-06 16:12:57 -0600355 die_with_post_code(POST_INVALID_ROM,
356 "Initializing measured boot mode failed!");
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100357 }
358
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500359 if (get_recovery_mode_switch()) {
Joel Kitching2332c742019-10-23 15:01:37 +0800360 ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
Julius Wernercd49cce2019-03-05 16:53:33 -0800361 if (CONFIG(VBOOT_DISABLE_DEV_ON_RECOVERY))
Joel Kitching2332c742019-10-23 15:01:37 +0800362 ctx->flags |= VB2_CONTEXT_DISABLE_DEVELOPER_MODE;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500363 }
364
Julius Wernercd49cce2019-03-05 16:53:33 -0800365 if (CONFIG(VBOOT_WIPEOUT_SUPPORTED) &&
Philipp Deppenwiese66f9a092018-11-08 10:59:40 +0100366 get_wipeout_mode_switch())
Joel Kitching2332c742019-10-23 15:01:37 +0800367 ctx->flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500368
Julius Wernercd49cce2019-03-05 16:53:33 -0800369 if (CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch())
Joel Kitching2332c742019-10-23 15:01:37 +0800370 ctx->flags |= VB2_CONTEXT_NOFAIL_BOOT;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500371
Joel Kitching5923d672019-04-12 15:57:43 +0800372 /* Mainboard/SoC always initializes display. */
Wim Vervoorne7087a12019-11-15 14:02:02 +0100373 if (!CONFIG(VBOOT_MUST_REQUEST_DISPLAY) || CONFIG(VBOOT_ALWAYS_ENABLE_DISPLAY))
Joel Kitching2332c742019-10-23 15:01:37 +0800374 ctx->flags |= VB2_CONTEXT_DISPLAY_INIT;
Joel Kitching5923d672019-04-12 15:57:43 +0800375
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500376 /* Do early init (set up secdata and NVRAM, load GBB) */
377 printk(BIOS_INFO, "Phase 1\n");
Joel Kitching2332c742019-10-23 15:01:37 +0800378 rv = vb2api_fw_phase1(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500379
380 if (rv) {
381 /*
382 * If vb2api_fw_phase1 fails, check for return value.
383 * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
384 * into recovery mode.
385 * For any other error code, save context if needed and reboot.
386 */
387 if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
388 printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800389 save_if_needed(ctx);
390 extend_pcrs(ctx); /* ignore failures */
Joel Kitchingba50e482019-06-10 17:37:37 +0800391 goto verstage_main_exit;
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500392 }
393
Raul E Rangel3a591742018-07-17 14:44:43 -0600394 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800395 save_if_needed(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500396 vboot_reboot();
397 }
398
399 /* Determine which firmware slot to boot (based on NVRAM) */
400 printk(BIOS_INFO, "Phase 2\n");
Joel Kitching2332c742019-10-23 15:01:37 +0800401 rv = vb2api_fw_phase2(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500402 if (rv) {
403 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800404 save_if_needed(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500405 vboot_reboot();
406 }
407
408 /* Try that slot (verify its keyblock and preamble) */
409 printk(BIOS_INFO, "Phase 3\n");
410 timestamp_add_now(TS_START_VERIFY_SLOT);
Joel Kitching2332c742019-10-23 15:01:37 +0800411 rv = vb2api_fw_phase3(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500412 timestamp_add_now(TS_END_VERIFY_SLOT);
413 if (rv) {
414 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800415 save_if_needed(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500416 vboot_reboot();
417 }
418
419 printk(BIOS_INFO, "Phase 4\n");
Joel Kitching2332c742019-10-23 15:01:37 +0800420 rv = locate_firmware(ctx, &fw_main);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500421 if (rv)
Keith Short70064582019-05-06 16:12:57 -0600422 die_with_post_code(POST_INVALID_ROM,
423 "Failed to read FMAP to locate firmware");
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500424
Joel Kitching2332c742019-10-23 15:01:37 +0800425 rv = hash_body(ctx, &fw_main);
426 save_if_needed(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500427 if (rv) {
428 printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
429 vboot_reboot();
430 }
431
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800432 /* Only extend PCRs once on boot. */
Joel Kitching2332c742019-10-23 15:01:37 +0800433 if (!(ctx->flags & VB2_CONTEXT_S3_RESUME)) {
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800434 timestamp_add_now(TS_START_TPMPCR);
Joel Kitching2332c742019-10-23 15:01:37 +0800435 rv = extend_pcrs(ctx);
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800436 if (rv) {
437 printk(BIOS_WARNING,
438 "Failed to extend TPM PCRs (%#x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800439 vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
440 save_if_needed(ctx);
Joel Kitching6d88a5d2018-10-12 15:23:31 +0800441 vboot_reboot();
442 }
443 timestamp_add_now(TS_END_TPMPCR);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500444 }
445
446 /* Lock TPM */
Raul E Rangel4c518e12018-05-11 11:08:07 -0600447
448 timestamp_add_now(TS_START_TPMLOCK);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500449 rv = antirollback_lock_space_firmware();
450 if (rv) {
451 printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800452 vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
453 save_if_needed(ctx);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500454 vboot_reboot();
455 }
Raul E Rangel4c518e12018-05-11 11:08:07 -0600456 timestamp_add_now(TS_END_TPMLOCK);
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500457
Furquan Shaikhb038f412016-11-07 23:47:11 -0800458 /* Lock rec hash space if available. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800459 if (CONFIG(VBOOT_HAS_REC_HASH_SPACE)) {
Furquan Shaikhb038f412016-11-07 23:47:11 -0800460 rv = antirollback_lock_space_rec_hash();
461 if (rv) {
462 printk(BIOS_INFO, "Failed to lock rec hash space(%x)\n",
463 rv);
Joel Kitching2332c742019-10-23 15:01:37 +0800464 vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR,
Furquan Shaikhb038f412016-11-07 23:47:11 -0800465 0);
Joel Kitching2332c742019-10-23 15:01:37 +0800466 save_if_needed(ctx);
Furquan Shaikhb038f412016-11-07 23:47:11 -0800467 vboot_reboot();
468 }
469 }
470
Joel Kitching2332c742019-10-23 15:01:37 +0800471 printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(ctx) ? 'A' : 'B');
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800472 vboot_set_selected_region(region_device_region(&fw_main));
Joel Kitchingba50e482019-06-10 17:37:37 +0800473
474 verstage_main_exit:
Joel Kitching532e0c72019-06-16 17:23:03 +0800475 /* If CBMEM is not up yet, let the ROMSTAGE_CBMEM_INIT_HOOK take care
476 of running this function. */
477 if (ENV_ROMSTAGE && CONFIG(VBOOT_STARTS_IN_ROMSTAGE))
478 vboot_log_and_clear_recovery_mode_switch(0);
479
Joel Kitching7b10deb2019-06-17 15:22:28 +0800480 /* Save recovery reason in case of unexpected reboots on x86. */
481 vboot_save_recovery_reason_vbnv();
482
Aaron Durbin588ad7b2015-09-29 17:56:59 -0500483 timestamp_add_now(TS_END_VBOOT);
484}