summaryrefslogtreecommitdiff
path: root/common/vboot
diff options
context:
space:
mode:
Diffstat (limited to 'common/vboot')
-rw-r--r--common/vboot/common.c58
-rw-r--r--common/vboot/efs2.c352
-rw-r--r--common/vboot/vb21_lib.c108
-rw-r--r--common/vboot/vboot.c228
4 files changed, 0 insertions, 746 deletions
diff --git a/common/vboot/common.c b/common/vboot/common.c
deleted file mode 100644
index 39f8c193c7..0000000000
--- a/common/vboot/common.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright 2017 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "common.h"
-#include "console.h"
-#include "rsa.h"
-#include "sha256.h"
-#include "shared_mem.h"
-#include "vboot.h"
-
-#define CPRINTS(format, args...) cprints(CC_VBOOT, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
-
-int vboot_is_padding_valid(const uint8_t *data, uint32_t start, uint32_t end)
-{
- const uint32_t *data32 = (const uint32_t *)data;
- int i;
-
- if (start > end)
- return EC_ERROR_INVAL;
-
- if (start % 4 || end % 4)
- return EC_ERROR_INVAL;
-
- for (i = start / 4; i < end / 4; i++) {
- if (data32[i] != 0xffffffff)
- return EC_ERROR_INVAL;
- }
-
- return EC_SUCCESS;
-}
-
-int vboot_verify(const uint8_t *data, int len,
- const struct rsa_public_key *key, const uint8_t *sig)
-{
- struct sha256_ctx ctx;
- uint8_t *hash;
- uint32_t *workbuf;
- int err = EC_SUCCESS;
-
- if (SHARED_MEM_ACQUIRE_CHECK(3 * RSANUMBYTES, (char **)&workbuf))
- return EC_ERROR_MEMORY_ALLOCATION;
-
- /* Compute hash of the RW firmware */
- SHA256_init(&ctx);
- SHA256_update(&ctx, data, len);
- hash = SHA256_final(&ctx);
-
- /* Verify the data */
- if (rsa_verify(key, sig, hash, workbuf) != 1)
- err = EC_ERROR_VBOOT_DATA_VERIFY;
-
- shared_mem_release(workbuf);
-
- return err;
-}
diff --git a/common/vboot/efs2.c b/common/vboot/efs2.c
deleted file mode 100644
index e5c3b64f04..0000000000
--- a/common/vboot/efs2.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/*
- * Early Firmware Selection ver.2.
- *
- * Verify and jump to a RW image. Register boot mode to Cr50.
- */
-
-#include "battery.h"
-#include "chipset.h"
-#include "clock.h"
-#include "compile_time_macros.h"
-#include "console.h"
-#include "crc8.h"
-#include "flash.h"
-#include "hooks.h"
-#include "sha256.h"
-#include "system.h"
-#include "task.h"
-#include "usb_pd.h"
-#include "uart.h"
-#include "vboot.h"
-#include "vboot_hash.h"
-
-#define CPRINTS(format, args...) cprints(CC_VBOOT,"VB " format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_VBOOT,"VB " format, ## args)
-
-static const char *boot_mode_to_string(uint8_t mode)
-{
- static const char *boot_mode_str[] = {
- [BOOT_MODE_NORMAL] = "NORMAL",
- [BOOT_MODE_NO_BOOT] = "NO_BOOT",
- };
- if (mode < ARRAY_SIZE(boot_mode_str))
- return boot_mode_str[mode];
- return "UNDEF";
-}
-
-/*
- * Check whether the session has successfully ended or not. ERR_TIMEOUT is
- * excluded because it's an internal error produced by EC itself.
- */
-static bool is_valid_cr50_response(enum cr50_comm_err code)
-{
- return code != CR50_COMM_ERR_TIMEOUT
- && (code >> 8) == CR50_COMM_ERR_PREFIX;
-}
-
-__overridable void board_enable_packet_mode(bool enable)
-{
- /*
- * This can be done by set_flags(INPUT|PULL_UP). We don't need it now
- * because Cr50 never initiates communication.
- */
- gpio_set_level(GPIO_PACKET_MODE_EN, enable ? 1 : 0);
-}
-
-static enum cr50_comm_err send_to_cr50(const uint8_t *data, size_t size)
-{
- timestamp_t until;
- int i, timeout = 0;
- uint32_t lock_key;
- struct cr50_comm_response res = {};
-
- /* This will wake up (if it's sleeping) and interrupt Cr50. */
- board_enable_packet_mode(true);
-
- uart_flush_output();
- uart_clear_input();
-
- if (uart_shell_stop()) {
- /* Failed to stop the shell. */
- board_enable_packet_mode(false);
- return CR50_COMM_ERR_UNKNOWN;
- }
-
- /*
- * Send packet. No traffic control, assuming Cr50 consumes stream much
- * faster. TX buffer shouldn't overflow because it's cleared above and
- * much bigger than the max packet size.
- *
- * Disable interrupts so that the data frame will be stored in the Tx
- * buffer in one piece.
- */
- lock_key = irq_lock();
- uart_put_raw(data, size);
- irq_unlock(lock_key);
-
- uart_flush_output();
-
- until.val = get_time().val + CR50_COMM_TIMEOUT;
-
- /*
- * Make sure console task won't steal the response in case we exchange
- * packets after tasks start.
- */
-#ifndef CONFIG_ZEPHYR
- if (task_start_called())
- task_disable_task(TASK_ID_CONSOLE);
-#endif /* !CONFIG_ZEPHYR */
-
- /* Wait for response from Cr50 */
- for (i = 0; i < sizeof(res); i++) {
- while (!timeout) {
- int c = uart_getc();
- if (c != -1) {
- res.error = res.error | c << (i*8);
- break;
- }
- msleep(1);
- timeout = timestamp_expired(until, NULL);
- }
- }
-
- uart_shell_start();
-#ifndef CONFIG_ZEPHYR
- if (task_start_called())
- task_enable_task(TASK_ID_CONSOLE);
-#endif /* CONFIG_ZEPHYR */
-
- /* Exit packet mode */
- board_enable_packet_mode(false);
-
- CPRINTS("Received 0x%04x", res.error);
-
- if (timeout) {
- CPRINTS("Timeout");
- return CR50_COMM_ERR_TIMEOUT;
- }
-
- return res.error;
-}
-
-static enum cr50_comm_err cmd_to_cr50(enum cr50_comm_cmd cmd,
- const uint8_t *data, size_t size)
-{
- /*
- * This is on the stack instead of .bss because vboot_main currently is
- * called only once (from main). Keeping the space unused in .bss would
- * be wasteful.
- */
- struct {
- uint8_t preamble[CR50_UART_RX_BUFFER_SIZE];
- uint8_t packet[CR50_COMM_MAX_REQUEST_SIZE];
- } __packed s;
- struct cr50_comm_request *p = (struct cr50_comm_request *)s.packet;
- int retry = CR50_COMM_MAX_RETRY;
- enum cr50_comm_err rv;
-
- /* compose a frame = preamble + packet */
- memset(s.preamble, CR50_COMM_PREAMBLE, sizeof(s.preamble));
- p->magic = CR50_PACKET_MAGIC;
- p->struct_version = CR50_COMM_PACKET_VERSION;
- p->type = cmd;
- p->size = size;
- memcpy(p->data, data, size);
- p->crc = cros_crc8((uint8_t *)&p->type,
- sizeof(p->type) + sizeof(p->size) + size);
-
- do {
- rv = send_to_cr50((uint8_t *)&s,
- sizeof(s.preamble) + sizeof(*p) + p->size);
- if (is_valid_cr50_response(rv))
- break;
- msleep(5);
- } while (--retry);
-
- return rv;
-}
-
-static enum cr50_comm_err verify_hash(void)
-{
- const uint8_t *hash;
- int rv;
-
- /* Wake up Cr50 beforehand in case it's asleep. */
- board_enable_packet_mode(true);
- CPRINTS("Ping Cr50");
- msleep(1);
- board_enable_packet_mode(false);
-
- rv = vboot_get_rw_hash(&hash);
- if (rv)
- return rv;
-
- CPRINTS("Verifying hash");
- return cmd_to_cr50(CR50_COMM_CMD_VERIFY_HASH, hash, SHA256_DIGEST_SIZE);
-}
-
-static enum cr50_comm_err set_boot_mode(uint8_t mode)
-{
- enum cr50_comm_err rv;
-
- CPRINTS("Setting boot mode to %s(%d)", boot_mode_to_string(mode), mode);
- rv = cmd_to_cr50(CR50_COMM_CMD_SET_BOOT_MODE,
- &mode, sizeof(enum boot_mode));
- if (rv != CR50_COMM_SUCCESS)
- CPRINTS("Failed to set boot mode");
- return rv;
-}
-
-static bool pd_comm_enabled;
-
-static void enable_pd(void)
-{
- CPRINTS("Enable USB-PD");
- pd_comm_enabled = true;
-}
-
-bool vboot_allow_usb_pd(void)
-{
- return pd_comm_enabled;
-}
-
-__overridable void show_critical_error(void)
-{
- CPRINTS("%s", __func__);
-}
-
-static void verify_and_jump(void)
-{
- enum cr50_comm_err rv = verify_hash();
-
- switch (rv) {
- case CR50_COMM_ERR_BAD_PAYLOAD:
- /* Cr50 should have set NO_BOOT. */
- CPRINTS("Hash mismatch");
- enable_pd();
- break;
- case CR50_COMM_SUCCESS:
- system_set_reset_flags(EC_RESET_FLAG_EFS);
- rv = system_run_image_copy(EC_IMAGE_RW);
- CPRINTS("Failed to jump (0x%x)", rv);
- system_clear_reset_flags(EC_RESET_FLAG_EFS);
- show_critical_error();
- break;
- default:
- CPRINTS("Failed to verify RW (0x%x)", rv);
- show_critical_error();
- }
-}
-
-__overridable void show_power_shortage(void)
-{
- CPRINTS("%s", __func__);
-}
-
-static bool is_battery_ready(void)
-{
- /* TODO: Add battery check (https://crbug.com/1045216) */
- return true;
-}
-
-void vboot_main(void)
-{
- CPRINTS("Main");
-
- if (system_is_in_rw()) {
- /*
- * We come here and immediately return. LED shows power shortage
- * but it will be immediately corrected if the adapter can
- * provide enough power.
- */
- CPRINTS("Already in RW");
- show_power_shortage();
- return;
- }
-
- if (system_is_manual_recovery() ||
- (system_get_reset_flags() & EC_RESET_FLAG_STAY_IN_RO)) {
- if (system_is_manual_recovery())
- CPRINTS("In recovery mode");
- if (!IS_ENABLED(CONFIG_BATTERY)
- && !IS_ENABLED(HAS_TASK_KEYSCAN)) {
- /*
- * For Chromeboxes, we relax security by allowing PD in
- * RO. Attackers don't gain meaningful advantage on
- * built-in-keyboard-less systems.
- *
- * Alternatively, we can use NO_BOOT to show a firmware
- * screen, strictly requiring BJ adapter and keeping PD
- * disabled.
- */
- enable_pd();
- return;
- }
-
- /*
- * If battery is drained or bad, we will boot in NO_BOOT mode to
- * inform the user of the problem.
- */
- if (!is_battery_ready()) {
- CPRINTS("Battery not ready or bad");
- if (set_boot_mode(BOOT_MODE_NO_BOOT) ==
- CR50_COMM_SUCCESS)
- enable_pd();
- }
-
- /* We'll enter recovery mode immediately, later, or never. */
- return;
- }
-
- verify_and_jump();
-
- /*
- * EFS failed. EC-RO may be able to boot AP if:
- *
- * - Battery is charged or
- * - AC adapter supply in RO >= Boot threshold or
- * - BJ adapter is plugged.
- *
- * Once AP boots, software sync will fix the mismatch. If that's the
- * reason of the failure, we won't come back here next time.
- */
- CPRINTS("Exit");
-}
-
-void hook_shutdown(void)
-{
- CPRINTS("%s", __func__);
-
- /*
- * We filter the cases which can be interfered with if we execute
- * system_reset in HOOK_CHIPSET_SHUTDOWN context. Most cases are
- * filtered out by system_is_in_rw (e.g. system_common_shutdown,
- * check_pending_cutoff).
- */
- if (system_is_in_rw())
- return;
-
- /*
- * We can't reset here because it'll completely tear down the power
- * and disturb the PCH's power sequence. We instead sysjump.
- *
- * Note that this does not reduce the security. Even if it's hijacked in
- * NO_BOOT mode, an RO still needs to go through a cold reset to clear
- * NO_BOOT flag since Cr50 rejects to switch from NO_BOOT to NORMAL.
- * If a spoofed matching hash is passed to Cr50, Cr50 would reset EC.
- */
- system_set_reset_flags(EC_RESET_FLAG_AP_IDLE);
- verify_and_jump();
-}
-/*
- * There can be hooks which are needed to set external chips to a certain state
- * in S5. If the initial state (i.e. AP_OFF state) is different from what those
- * hooks realize, they need to be considered. This hook runs last (i.e.
- * HOOK_PRIO_LAST) to make our landing on S5 as mild as possible.
- */
-DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN_COMPLETE, hook_shutdown, HOOK_PRIO_LAST);
diff --git a/common/vboot/vb21_lib.c b/common/vboot/vb21_lib.c
deleted file mode 100644
index 4e215c14e5..0000000000
--- a/common/vboot/vb21_lib.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright 2017 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/*
- * Common utility APIs for vboot 2.1
- */
-
-#include "common.h"
-#include "host_command.h"
-#include "rsa.h"
-#include "rwsig.h"
-#include "system.h"
-#include "vb21_struct.h"
-#include "vboot.h"
-
-int vb21_is_packed_key_valid(const struct vb21_packed_key *key)
-{
- if (key->c.magic != VB21_MAGIC_PACKED_KEY)
- return EC_ERROR_VBOOT_KEY_MAGIC;
- if (key->key_size != sizeof(struct rsa_public_key))
- return EC_ERROR_VBOOT_KEY_SIZE;
- return EC_SUCCESS;
-}
-
-int vb21_is_signature_valid(const struct vb21_signature *sig,
- const struct vb21_packed_key *key)
-{
- if (sig->c.magic != VB21_MAGIC_SIGNATURE)
- return EC_ERROR_VBOOT_SIG_MAGIC;
- if (sig->sig_size != RSANUMBYTES)
- return EC_ERROR_VBOOT_SIG_SIZE;
- if (key->sig_alg != sig->sig_alg)
- return EC_ERROR_VBOOT_SIG_ALGORITHM;
- if (key->hash_alg != sig->hash_alg)
- return EC_ERROR_VBOOT_HASH_ALGORITHM;
- /* Validity check signature offset and data size. */
- if (sig->sig_offset < sizeof(*sig))
- return EC_ERROR_VBOOT_SIG_OFFSET;
- if (sig->sig_offset + RSANUMBYTES > CONFIG_RW_SIG_SIZE)
- return EC_ERROR_VBOOT_SIG_OFFSET;
- if (sig->data_size > CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
- return EC_ERROR_VBOOT_DATA_SIZE;
- return EC_SUCCESS;
-}
-
-const struct vb21_packed_key *vb21_get_packed_key(void)
-{
- return (const struct vb21_packed_key *)(CONFIG_RO_PUBKEY_ADDR);
-}
-
-static void read_rwsig_info(struct ec_response_rwsig_info *r)
-{
-
- const struct vb21_packed_key *vb21_key;
- int rv;
-
- vb21_key = vb21_get_packed_key();
-
- r->sig_alg = vb21_key->sig_alg;
- r->hash_alg = vb21_key->hash_alg;
- r->key_version = vb21_key->key_version;
- { BUILD_ASSERT(sizeof(r->key_id) == sizeof(vb21_key->id),
- "key ID sizes must match"); }
- { BUILD_ASSERT(sizeof(vb21_key->id) == sizeof(vb21_key->id.raw),
- "key ID sizes must match"); }
- memcpy(r->key_id, vb21_key->id.raw, sizeof(r->key_id));
-
- rv = vb21_is_packed_key_valid(vb21_key);
- r->key_is_valid = (rv == EC_SUCCESS);
-}
-
-static int command_rwsig_info(int argc, char **argv)
-{
- int i;
- struct ec_response_rwsig_info r;
-
- read_rwsig_info(&r);
-
- ccprintf("sig_alg: %d\n", r.sig_alg);
- ccprintf("key_version: %d\n", r.key_version);
- ccprintf("hash_alg: %d\n", r.hash_alg);
- ccprintf("key_is_valid: %d\n", r.key_is_valid);
-
- ccprintf("key_id: ");
- for (i = 0; i < sizeof(r.key_id); i++)
- ccprintf("%x", r.key_id[i]);
- ccprintf("\n");
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(rwsiginfo, command_rwsig_info, NULL,
- "Display rwsig info on console.");
-
-static enum ec_status
-host_command_rwsig_info(struct host_cmd_handler_args *args)
-{
- struct ec_response_rwsig_info *r = args->response;
-
- read_rwsig_info(r);
- args->response_size = sizeof(*r);
-
- return EC_RES_SUCCESS;
-}
-
-DECLARE_HOST_COMMAND(EC_CMD_RWSIG_INFO, host_command_rwsig_info,
- EC_VER_MASK(EC_VER_RWSIG_INFO));
diff --git a/common/vboot/vboot.c b/common/vboot/vboot.c
deleted file mode 100644
index 910156335d..0000000000
--- a/common/vboot/vboot.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/* Copyright 2017 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/*
- * Verify and jump to a RW image if power supply is not sufficient.
- */
-
-#include "battery.h"
-#include "charge_manager.h"
-#include "chipset.h"
-#include "clock.h"
-#include "console.h"
-#include "flash.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "rsa.h"
-#include "rwsig.h"
-#include "stdbool.h"
-#include "sha256.h"
-#include "shared_mem.h"
-#include "system.h"
-#include "usb_pd.h"
-#include "vboot.h"
-#include "vb21_struct.h"
-
-#define CPRINTS(format, args...) cprints(CC_VBOOT,"VB " format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_VBOOT,"VB " format, ## args)
-
-static int has_matrix_keyboard(void)
-{
- return 0;
-}
-
-static int verify_slot(enum ec_image slot)
-{
- const struct vb21_packed_key *vb21_key;
- const struct vb21_signature *vb21_sig;
- const struct rsa_public_key *key;
- const uint8_t *sig;
- const uint8_t *data;
- int len;
- int rv;
-
- CPRINTS("Verifying %s", ec_image_to_string(slot));
-
- vb21_key = (const struct vb21_packed_key *)(
- CONFIG_MAPPED_STORAGE_BASE +
- CONFIG_EC_PROTECTED_STORAGE_OFF +
- CONFIG_RO_PUBKEY_STORAGE_OFF);
- rv = vb21_is_packed_key_valid(vb21_key);
- if (rv) {
- CPRINTS("Invalid key (%d)", rv);
- return EC_ERROR_VBOOT_KEY;
- }
- key = (const struct rsa_public_key *)
- ((const uint8_t *)vb21_key + vb21_key->key_offset);
-
- if (slot == EC_IMAGE_RW_A) {
- data = (const uint8_t *)(CONFIG_MAPPED_STORAGE_BASE +
- CONFIG_EC_WRITABLE_STORAGE_OFF +
- CONFIG_RW_A_STORAGE_OFF);
- vb21_sig = (const struct vb21_signature *)(
- CONFIG_MAPPED_STORAGE_BASE +
- CONFIG_EC_WRITABLE_STORAGE_OFF +
- CONFIG_RW_A_SIGN_STORAGE_OFF);
- } else {
- data = (const uint8_t *)(CONFIG_MAPPED_STORAGE_BASE +
- CONFIG_EC_WRITABLE_STORAGE_OFF +
- CONFIG_RW_B_STORAGE_OFF);
- vb21_sig = (const struct vb21_signature *)(
- CONFIG_MAPPED_STORAGE_BASE +
- CONFIG_EC_WRITABLE_STORAGE_OFF +
- CONFIG_RW_B_SIGN_STORAGE_OFF);
- }
-
- rv = vb21_is_signature_valid(vb21_sig, vb21_key);
- if (rv) {
- CPRINTS("Invalid signature (%d)", rv);
- return EC_ERROR_INVAL;
- }
- sig = (const uint8_t *)vb21_sig + vb21_sig->sig_offset;
- len = vb21_sig->data_size;
-
- if (vboot_is_padding_valid(data, len,
- CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)) {
- CPRINTS("Invalid padding");
- return EC_ERROR_INVAL;
- }
-
- rv = vboot_verify(data, len, key, sig);
- if (rv) {
- CPRINTS("Invalid data (%d)", rv);
- return EC_ERROR_INVAL;
- }
-
- CPRINTS("Verified %s", ec_image_to_string(slot));
-
- return EC_SUCCESS;
-}
-
-static enum ec_status hc_verify_slot(struct host_cmd_handler_args *args)
-{
- const struct ec_params_efs_verify *p = args->params;
- enum ec_image slot;
-
- switch (p->region) {
- case EC_FLASH_REGION_ACTIVE:
- slot = system_get_active_copy();
- break;
- case EC_FLASH_REGION_UPDATE:
- slot = system_get_update_copy();
- break;
- default:
- return EC_RES_INVALID_PARAM;
- }
- return verify_slot(slot) ? EC_RES_ERROR : EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_EFS_VERIFY, hc_verify_slot, EC_VER_MASK(0));
-
-static int verify_and_jump(void)
-{
- enum ec_image slot;
- int rv;
-
- /* 1. Decide which slot to try */
- slot = system_get_active_copy();
-
- /* 2. Verify the slot */
- rv = verify_slot(slot);
- if (rv) {
- if (rv == EC_ERROR_VBOOT_KEY)
- /* Key error. The other slot isn't worth trying. */
- return rv;
- slot = system_get_update_copy();
- /* TODO(chromium:767050): Skip reading key again. */
- rv = verify_slot(slot);
- if (rv)
- /* Both slots failed */
- return rv;
-
- /* Proceed with the other slot. If this slot isn't expected, AP
- * will catch it and request recovery after a few attempts. */
- if (system_set_active_copy(slot))
- CPRINTS("Failed to activate %s",
- ec_image_to_string(slot));
- }
-
- /* 3. Jump (and reboot) */
- rv = system_run_image_copy(slot);
- CPRINTS("Failed to jump (%d)", rv);
-
- return rv;
-}
-
-/* Request more power: charging battery or more powerful AC adapter */
-__overridable void show_power_shortage(void)
-{
- CPRINTS("%s", __func__);
-}
-
-__overridable void show_critical_error(void)
-{
- CPRINTS("%s", __func__);
-}
-
-static bool pd_comm_enabled;
-
-bool vboot_allow_usb_pd(void)
-{
- return pd_comm_enabled;
-}
-
-void vboot_main(void)
-{
- CPRINTS("Main");
-
- if (system_is_in_rw()) {
- /*
- * We come here and immediately return. LED shows power shortage
- * but it will be immediately corrected if the adapter can
- * provide enough power.
- */
- CPRINTS("Already in RW. Wait for power...");
- show_power_shortage();
- return;
- }
-
- if (!(crec_flash_get_protect() & EC_FLASH_PROTECT_GPIO_ASSERTED)) {
- /*
- * If hardware WP is disabled, PD communication is enabled.
- * We can return and wait for more power.
- * Note: If software WP is disabled, we still perform EFS even
- * though PD communication is enabled.
- */
- CPRINTS("HW-WP not asserted.");
- show_power_shortage();
- return;
- }
-
- if (system_is_manual_recovery() ||
- (system_get_reset_flags() & EC_RESET_FLAG_STAY_IN_RO)) {
- if (system_is_manual_recovery())
- CPRINTS("Manual recovery");
-
- if (battery_is_present() || has_matrix_keyboard()) {
- show_power_shortage();
- return;
- }
- /* We don't request_power because we don't want to assume all
- * devices support a non type-c charger. We open up a security
- * hole by allowing EC-RO to do PD negotiation but attackers
- * don't gain meaningful advantage on devices without a matrix
- * keyboard */
- CPRINTS("Enable PD comm");
- pd_comm_enabled = true;
- return;
- }
-
- clock_enable_module(MODULE_FAST_CPU, 1);
- /* If successful, this won't return. */
- verify_and_jump();
- clock_enable_module(MODULE_FAST_CPU, 0);
-
- /* Failed to jump. Need recovery. */
- show_critical_error();
-}