1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/exception.h>
5 #include <console/console.h>
7 #include <ec/google/chromeec/ec.h>
9 #include <security/tpm/tspi/crtm.h>
10 #include <security/tpm/tss/vendor/cr50/cr50.h>
11 #include <security/tpm/tss_errors.h>
12 #include <security/vboot/misc.h>
13 #include <security/vboot/vbnv.h>
14 #include <security/vboot/tpm_common.h>
16 #include <timestamp.h>
18 #include <boot_device.h>
20 #include "antirollback.h"
22 /* The max hash size to expect is for SHA512. */
23 #define VBOOT_MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE
27 vb2_error_t
vb2ex_read_resource(struct vb2_context
*ctx
,
28 enum vb2_resource_index index
,
33 struct region_device rdev
;
40 case VB2_RES_FW_VBLOCK
:
41 if (vboot_is_firmware_slot_a(ctx
))
47 return VB2_ERROR_EX_READ_RESOURCE_INDEX
;
50 if (fmap_locate_area_as_rdev(name
, &rdev
))
51 return VB2_ERROR_EX_READ_RESOURCE_SIZE
;
53 if (rdev_readat(&rdev
, buf
, offset
, size
) != size
)
54 return VB2_ERROR_EX_READ_RESOURCE_SIZE
;
59 static vb2_error_t
handle_digest_result(void *slot_hash
, size_t slot_hash_sz
)
64 * Chrome EC is the only support for vboot_save_hash() &
65 * vboot_retrieve_hash(), if Chrome EC is not enabled then return.
67 if (!CONFIG(EC_GOOGLE_CHROMEEC
))
71 * Nothing to do since resuming on the platform doesn't require
72 * vboot verification again.
74 if (!CONFIG(RESUME_PATH_SAME_AS_BOOT
))
78 * Assume that if vboot doesn't start in bootblock verified
79 * RW memory init code is not employed. i.e. memory init code
82 if (!CONFIG(VBOOT_STARTS_IN_BOOTBLOCK
))
85 is_resume
= platform_is_resuming();
88 uint8_t saved_hash
[VBOOT_MAX_HASH_SIZE
];
89 const size_t saved_hash_sz
= sizeof(saved_hash
);
91 assert(slot_hash_sz
<= saved_hash_sz
);
93 printk(BIOS_DEBUG
, "Platform is resuming.\n");
95 if (vboot_retrieve_hash(saved_hash
, saved_hash_sz
)) {
96 printk(BIOS_ERR
, "Couldn't retrieve saved hash.\n");
97 return VB2_ERROR_UNKNOWN
;
100 if (memcmp(saved_hash
, slot_hash
, slot_hash_sz
)) {
101 printk(BIOS_ERR
, "Hash mismatch on resume.\n");
102 return VB2_ERROR_UNKNOWN
;
104 } else if (is_resume
< 0)
105 printk(BIOS_ERR
, "Unable to determine if platform resuming.\n");
107 printk(BIOS_DEBUG
, "Saving vboot hash.\n");
109 /* Always save the hash for the current boot. */
110 if (vboot_save_hash(slot_hash
, slot_hash_sz
)) {
111 printk(BIOS_ERR
, "Error saving vboot hash.\n");
112 /* Though this is an error don't report it up since it could
113 * lead to a reboot loop. The consequence of this is that
114 * we will most likely fail resuming because of EC issues or
115 * the hash digest not matching. */
122 static vb2_error_t
hash_body(struct vb2_context
*ctx
,
123 struct region_device
*fw_body
)
127 uint8_t block
[CONFIG_VBOOT_HASH_BLOCK_SIZE
];
128 uint8_t hash_digest
[VBOOT_MAX_HASH_SIZE
];
129 const size_t hash_digest_sz
= sizeof(hash_digest
);
130 size_t block_size
= sizeof(block
);
134 /* Clear the full digest so that any hash digests less than the
135 * max have trailing zeros. */
136 memset(hash_digest
, 0, hash_digest_sz
);
139 * Since loading the firmware and calculating its hash is intertwined,
140 * we use this little trick to measure them separately and pretend it
141 * was first loaded and then hashed in one piece with the timestamps.
142 * (This split won't make sense with memory-mapped media like on x86.)
144 load_ts
= timestamp_get();
145 timestamp_add(TS_HASH_BODY_START
, load_ts
);
147 remaining
= region_device_sz(fw_body
);
150 /* Start the body hash */
151 rc
= vb2api_init_hash(ctx
, VB2_HASH_TAG_FW_BODY
);
155 /* Extend over the body */
158 if (block_size
> remaining
)
159 block_size
= remaining
;
161 temp_ts
= timestamp_get();
162 if (rdev_readat(fw_body
, block
, offset
, block_size
) < 0)
163 return VB2_ERROR_UNKNOWN
;
164 load_ts
+= timestamp_get() - temp_ts
;
166 rc
= vb2api_extend_hash(ctx
, block
, block_size
);
170 remaining
-= block_size
;
171 offset
+= block_size
;
174 timestamp_add(TS_LOADING_END
, load_ts
);
175 timestamp_add_now(TS_HASHING_END
);
177 /* Check the result (with RSA signature verification) */
178 rc
= vb2api_check_hash_get_digest(ctx
, hash_digest
, hash_digest_sz
);
182 timestamp_add_now(TS_HASH_BODY_END
);
184 return handle_digest_result(hash_digest
, hash_digest_sz
);
187 static tpm_result_t
extend_pcrs(struct vb2_context
*ctx
)
190 rc
= vboot_extend_pcr(ctx
, CONFIG_PCR_BOOT_MODE
, BOOT_MODE_PCR
);
193 rc
= vboot_extend_pcr(ctx
, CONFIG_PCR_HWID
, HWID_DIGEST_PCR
);
196 return vboot_extend_pcr(ctx
, CONFIG_PCR_FW_VER
, FIRMWARE_VERSION_PCR
);
199 #define EC_EFS_BOOT_MODE_VERIFIED_RW 0x00
200 #define EC_EFS_BOOT_MODE_UNTRUSTED_RO 0x01
201 #define EC_EFS_BOOT_MODE_TRUSTED_RO 0x02
203 static const char *get_boot_mode_string(uint8_t boot_mode
)
205 if (boot_mode
== EC_EFS_BOOT_MODE_TRUSTED_RO
)
207 else if (boot_mode
== EC_EFS_BOOT_MODE_UNTRUSTED_RO
)
208 return "UNTRUSTED_RO";
209 else if (boot_mode
== EC_EFS_BOOT_MODE_VERIFIED_RW
)
210 return "VERIFIED_RW";
215 static void check_boot_mode(struct vb2_context
*ctx
)
220 rc
= tlcl_cr50_get_boot_mode(&boot_mode
);
222 case TPM_CB_NO_SUCH_COMMAND
:
223 printk(BIOS_WARNING
, "GSC does not support GET_BOOT_MODE.\n");
224 /* Proceed to legacy boot model. */
230 "Communication error(%#x) in getting GSC boot mode.\n", rc
);
231 vb2api_fail(ctx
, VB2_RECOVERY_GSC_BOOT_MODE
, rc
);
235 printk(BIOS_INFO
, "GSC says boot_mode is %s(0x%02x).\n",
236 get_boot_mode_string(boot_mode
), boot_mode
);
238 if (boot_mode
== EC_EFS_BOOT_MODE_UNTRUSTED_RO
)
239 ctx
->flags
|= VB2_CONTEXT_NO_BOOT
;
240 else if (boot_mode
== EC_EFS_BOOT_MODE_TRUSTED_RO
)
241 ctx
->flags
|= VB2_CONTEXT_EC_TRUSTED
;
244 /* Verify and select the firmware in the RW image */
245 void verstage_main(void)
247 struct vb2_context
*ctx
;
251 timestamp_add_now(TS_VBOOT_START
);
253 /* Lockdown SPI flash controller if required */
254 if (CONFIG(BOOTMEDIA_LOCK_IN_VERSTAGE
))
255 boot_device_security_lockdown();
257 /* Set up context and work buffer */
258 ctx
= vboot_get_context();
260 /* Initialize and read nvdata from non-volatile storage. */
263 /* Set S3 resume flag if vboot should behave differently when selecting
264 * which slot to boot. This is only relevant to vboot if the platform
265 * does verification of memory init and thus must ensure it resumes with
266 * the same slot that it booted from. */
267 if (CONFIG(RESUME_PATH_SAME_AS_BOOT
) &&
268 platform_is_resuming())
269 ctx
->flags
|= VB2_CONTEXT_S3_RESUME
;
271 if (!CONFIG(VBOOT_SLOTS_RW_AB
))
272 ctx
->flags
|= VB2_CONTEXT_SLOT_A_ONLY
;
274 /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
275 * check the return value here because vb2api_fw_phase1 will catch
276 * invalid secdata and tell us what to do (=reboot). */
277 timestamp_add_now(TS_TPMINIT_START
);
278 rv
= vboot_setup_tpm(ctx
);
279 if (rv
== TPM_SUCCESS
) {
280 antirollback_read_space_firmware(ctx
);
281 antirollback_read_space_kernel(ctx
);
283 vb2api_fail(ctx
, VB2_RECOVERY_RO_TPM_S_ERROR
, rv
);
284 if (CONFIG(TPM_SETUP_HIBERNATE_ON_ERR
) &&
285 rv
== TPM_CB_COMMUNICATION_ERROR
) {
286 printk(BIOS_ERR
, "Failed to communicate with TPM\n"
287 "Next reboot will hibernate to reset TPM");
288 /* Command the EC to hibernate on next AP shutdown */
289 if (google_chromeec_reboot(
291 EC_REBOOT_FLAG_ON_AP_SHUTDOWN
)) {
292 printk(BIOS_ERR
, "Failed to get EC to schedule hibernate");
296 timestamp_add_now(TS_TPMINIT_END
);
298 if (get_recovery_mode_switch()) {
299 ctx
->flags
|= VB2_CONTEXT_FORCE_RECOVERY_MODE
;
300 if (CONFIG(VBOOT_DISABLE_DEV_ON_RECOVERY
))
301 ctx
->flags
|= VB2_CONTEXT_DISABLE_DEVELOPER_MODE
;
304 if (CONFIG(VBOOT_WIPEOUT_SUPPORTED
) &&
305 get_wipeout_mode_switch())
306 ctx
->flags
|= VB2_CONTEXT_FORCE_WIPEOUT_MODE
;
308 if (CONFIG(VBOOT_LID_SWITCH
) && !get_lid_switch())
309 ctx
->flags
|= VB2_CONTEXT_NOFAIL_BOOT
;
311 /* Mainboard/SoC always initializes display. */
312 if (!CONFIG(VBOOT_MUST_REQUEST_DISPLAY
) || CONFIG(VBOOT_ALWAYS_ENABLE_DISPLAY
))
313 ctx
->flags
|= VB2_CONTEXT_DISPLAY_INIT
;
316 * Get boot mode from GSC. This allows us to refuse to boot OS
317 * (with VB2_CONTEXT_NO_BOOT) or to switch to developer mode (with
318 * !VB2_CONTEXT_EC_TRUSTED).
320 * If there is an communication error, a recovery reason will be set and
321 * vb2api_fw_phase1 will route us to recovery mode.
323 if (CONFIG(TPM_GOOGLE
))
324 check_boot_mode(ctx
);
326 if (get_ec_is_trusted())
327 ctx
->flags
|= VB2_CONTEXT_EC_TRUSTED
;
329 /* Do early init (set up secdata and NVRAM, load GBB) */
330 printk(BIOS_INFO
, "Phase 1\n");
331 rv
= vb2api_fw_phase1(ctx
);
335 * If vb2api_fw_phase1 fails, check for return value.
336 * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
337 * into recovery mode.
338 * For any other error code, save context if needed and reboot.
340 if (rv
== VB2_ERROR_API_PHASE1_RECOVERY
) {
341 printk(BIOS_INFO
, "Recovery requested (%#x)\n", rv
);
342 vboot_save_data(ctx
);
343 extend_pcrs(ctx
); /* ignore failures */
344 goto verstage_main_exit
;
346 vboot_save_and_reboot(ctx
, rv
);
349 /* Determine which firmware slot to boot (based on NVRAM) */
350 printk(BIOS_INFO
, "Phase 2\n");
351 rv
= vb2api_fw_phase2(ctx
);
353 vboot_save_and_reboot(ctx
, rv
);
355 /* Try that slot (verify its keyblock and preamble) */
356 printk(BIOS_INFO
, "Phase 3\n");
357 timestamp_add_now(TS_VERIFY_SLOT_START
);
358 rv
= vb2api_fw_phase3(ctx
);
359 timestamp_add_now(TS_VERIFY_SLOT_END
);
361 vboot_save_and_reboot(ctx
, rv
);
363 printk(BIOS_INFO
, "Phase 4\n");
364 if (CONFIG(VBOOT_CBFS_INTEGRATION
)) {
365 struct vb2_hash
*metadata_hash
;
366 rv
= vb2api_get_metadata_hash(ctx
, &metadata_hash
);
367 if (rv
== VB2_SUCCESS
)
368 rv
= handle_digest_result(metadata_hash
->raw
,
369 vb2_digest_size(metadata_hash
->algo
));
371 struct region_device fw_body
;
372 if (vboot_locate_firmware(ctx
, &fw_body
))
373 die_with_post_code(POSTCODE_INVALID_ROM
,
374 "Failed to read FMAP to locate firmware");
376 rv
= hash_body(ctx
, &fw_body
);
380 vboot_fail_and_reboot(ctx
, VB2_RECOVERY_FW_GET_FW_BODY
, rv
);
381 vboot_save_data(ctx
);
383 /* Only extend PCRs once on boot. */
384 if (!(ctx
->flags
& VB2_CONTEXT_S3_RESUME
)) {
385 timestamp_add_now(TS_TPMPCR_START
);
386 tpm_rc
= extend_pcrs(ctx
);
388 printk(BIOS_WARNING
, "Failed to extend TPM PCRs (%#x)\n",
390 vboot_fail_and_reboot(ctx
,
391 VB2_RECOVERY_RO_TPM_U_ERROR
,
394 timestamp_add_now(TS_TPMPCR_END
);
399 timestamp_add_now(TS_TPMLOCK_START
);
400 tpm_rc
= antirollback_lock_space_firmware();
402 printk(BIOS_INFO
, "Failed to lock TPM (%#x)\n", tpm_rc
);
403 vboot_fail_and_reboot(ctx
, VB2_RECOVERY_RO_TPM_L_ERROR
, 0);
405 timestamp_add_now(TS_TPMLOCK_END
);
407 /* Lock rec hash space if available. */
408 if (CONFIG(VBOOT_HAS_REC_HASH_SPACE
)) {
409 tpm_rc
= antirollback_lock_space_mrc_hash(
410 MRC_REC_HASH_NV_INDEX
);
412 printk(BIOS_INFO
, "Failed to lock rec hash space(%#x)\n",
414 vboot_fail_and_reboot(ctx
, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR
, tpm_rc
);
418 printk(BIOS_INFO
, "Slot %c is selected\n",
419 vboot_is_firmware_slot_a(ctx
) ? 'A' : 'B');
422 timestamp_add_now(TS_VBOOT_END
);