Files
OpenCellular/include/rwsig.h
Daisuke Nojiri 7630636a0f vboot: Verify and jump to RW_A or RW_B
This patch gives EC the capability of verifying and jumping to
RW_A or RW_B. EC tries the slot stored in a persistent storage
(e.g. BBRAM). If verification fails due to invalid contents, EC
tries the other slot. AP's expectation and its reaction to the
state of the slots and the currently running image are summarized
below.

Since the system is still unlocked (CONFIG_SYSTEM_UNLOCKED), EC
won't try to verify or jump to RW yet.

          |       AP expects X
----------+---------------------------
SLOT_A=X  |         proceed
SLOT_B=X  |         proceed
----------+---------------------------
SLOT_A=X' |       reboot to B
SLOT_B=X  |         proceed
----------+---------------------------
SLOT_A=X  |         proceed
SLOT_B=X' |       reboot to A
----------+---------------------------
SLOT_A=X' | write X to B, reboot to B
SLOT_B=X' | write X to A, reboot to A

BUG=b:38462249
BRANCH=none
TEST=Lock the system and boot Fizz on barrel-jack and type-c.

Change-Id: I51e3abd4d9af44ab3d531561cb9bfa2e8d775f6a
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/556286
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2017-07-13 19:45:57 -07:00

127 lines
3.8 KiB
C

/* 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.
*/
#ifndef __CROS_EC_RWSIG_H
#define __CROS_EC_RWSIG_H
#include "config.h"
#include "rsa.h"
#ifndef __ASSEMBLER__
#ifdef HAS_TASK_RWSIG
/* The functions below only make sense if RWSIG task is defined. */
/* Current status of RW signature verification */
enum rwsig_status {
RWSIG_UNKNOWN = 0, /* Unknown/not started */
RWSIG_IN_PROGRESS,
RWSIG_VALID,
RWSIG_INVALID,
RWSIG_ABORTED,
};
/* Returns current rwsig verification status. */
enum rwsig_status rwsig_get_status(void);
/*
* Aborts current verification, also prevents RWSIG task from automatically
* jumping to RW.
* This is used by usb_updater when a RW update is required, giving it enough
* time to actually perform the update.
*/
void rwsig_abort(void);
/*
* Tells RWSIG task to jump to RW immediately, if the signature is correct.
* This is used by usb_updater when no RW update is required, to speed up
* boot time.
*/
void rwsig_continue(void);
#else /* !HAS_TASK_RWSIG */
/* These functions can only be called directly if RWSIG task is not defined. */
/* Checks RW signature. Returns a boolean indicating success. */
int rwsig_check_signature(void);
/* Jumps to RW, if signature is fine, returns on error (otherwise, jumps). */
void rwsig_jump_now(void);
#endif
#endif /* !__ASSEMBLER__ */
/*
* The signer puts the public key and signature into the RO and RW images
* (respectively) at known locations after the complete image is assembled. But
* since we compile the RO & RW images separately, the other image's addresses
* can't be computed by the linker. So we just hardcode the addresses here.
* These can be overridden in board.h files if desired.
*/
#ifndef CONFIG_RO_PUBKEY_SIZE
#ifdef CONFIG_RWSIG_TYPE_RWSIG
/*
* rwsig type: 1024 bytes is enough to fit RSA-3072 public key.
*
* TODO(crosbug.com/p/62321): This still wastes space. We could pack the key at
* any arbitrary location, but we need proper signer support to make sure it
* can overwrite the key correctly.
*/
#define CONFIG_RO_PUBKEY_SIZE 1024
#else
#define CONFIG_RO_PUBKEY_SIZE RSA_PUBLIC_KEY_SIZE
#endif
#endif /* ! CONFIG_RO_PUBKEY_SIZE */
#ifndef CONFIG_RO_PUBKEY_ADDR
#ifdef CONFIG_RWSIG_TYPE_RWSIG
#define CONFIG_RO_PUBKEY_STORAGE_OFF (CONFIG_RO_STORAGE_OFF \
+ CONFIG_RO_SIZE \
- CONFIG_RO_PUBKEY_SIZE)
/* The pubkey resides at the end of the RO image */
#define CONFIG_RO_PUBKEY_ADDR (CONFIG_PROGRAM_MEMORY_BASE \
+ CONFIG_EC_PROTECTED_STORAGE_OFF \
+ CONFIG_RO_PUBKEY_STORAGE_OFF)
#else
/*
* usbpd1 type assumes pubkey location at the end of first half of flash,
* which might actually be in the PSTATE region.
*/
#define CONFIG_RO_PUBKEY_ADDR (CONFIG_PROGRAM_MEMORY_BASE \
+ (CONFIG_FLASH_SIZE / 2) \
- CONFIG_RO_PUBKEY_SIZE)
#endif
#endif /* CONFIG_RO_PUBKEY_ADDR */
#ifndef CONFIG_RW_SIG_SIZE
#ifdef CONFIG_RWSIG_TYPE_RWSIG
/*
* rwsig type: futility expects signature to be 1024 bytes from the end of
* the file.
*/
#define CONFIG_RW_SIG_SIZE 1024
#else
#define CONFIG_RW_SIG_SIZE RSANUMBYTES
#endif
#endif /* ! CONFIG_RW_SIG_SIZE */
/* The signature resides at the end of each RW copy */
#define RW_SIG_OFFSET (CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
#define RW_A_ADDR (CONFIG_PROGRAM_MEMORY_BASE + \
CONFIG_EC_WRITABLE_STORAGE_OFF + \
CONFIG_RW_STORAGE_OFF)
/* Assume the layout is same as RW_A and it sits right after RW_A */
#define RW_B_ADDR (CONFIG_PROGRAM_MEMORY_BASE + \
CONFIG_EC_WRITABLE_STORAGE_OFF + \
CONFIG_RW_B_STORAGE_OFF)
#ifndef CONFIG_RW_SIG_ADDR
#define CONFIG_RW_SIG_ADDR (RW_A_ADDR + RW_SIG_OFFSET)
#endif
#ifndef CONFIG_RW_B_SIG_ADDR
#define CONFIG_RW_B_SIG_ADDR (RW_B_ADDR + RW_SIG_OFFSET)
#endif
#endif /* __CROS_EC_RWSIG_H */