Files
OpenCellular/include/rwsig.h
Nicolas Boichat 68a537e466 rwsig: Make it possible to run as a task
(Optionally) split rwsig verification into a separate task. This
allows us to initialize other components (e.g. USB) while the
verification is in progress, speeding up the boot process to active
USB in RO case.

After CONFIG_RWSIG_JUMP_TIMEOUT, the EC will jump to the RW section
if no action is taken by the AP (such as a forced request to jump
to RW, or starting an update).

Note: This comes with a ~36ms boot time regression, as other code
gets to run before verification starts.

BRANCH=none
BUG=b:35587171
TEST=Flash, board boots to RW after 1s
TEST=Change jump timeout to 5s, add 5s delay in check_signature,
     add console command to manually abort/continue rwsig verification.
     'rwsig continue' works => Board jumps to RW after check_signature
     is completed (or immediately while waiting for timeout)
     'rwsig abort' works => Board does not jump to RW.

Change-Id: Ica5732b9298bb4d3b743cae2ba78df259db915ef
Reviewed-on: https://chromium-review.googlesource.com/468709
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
2017-04-11 20:22:32 -07:00

116 lines
3.3 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
/* The pubkey goes at the end of the RO region */
#define CONFIG_RO_PUBKEY_ADDR (CONFIG_PROGRAM_MEMORY_BASE \
+ CONFIG_RO_MEM_OFF \
+ CONFIG_RO_SIZE \
- CONFIG_RO_PUBKEY_SIZE)
#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 */
#ifndef CONFIG_RW_SIG_ADDR
/* The signature goes at the end of the RW region */
#define CONFIG_RW_SIG_ADDR (CONFIG_PROGRAM_MEMORY_BASE \
+ CONFIG_RW_MEM_OFF \
+ CONFIG_RW_SIZE \
- CONFIG_RW_SIG_SIZE)
#endif /* !CONFIG_RW_SIG_ADDR */
#endif /* __CROS_EC_RWSIG_H */