blob: 9a3013ebbc8fef7fb293dab6c4c22d31abb6c039 [file] [log] [blame]
/* Copyright 2017 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef __CROS_EC_INCLUDE_VBOOT_H
#define __CROS_EC_INCLUDE_VBOOT_H
#include "common.h"
#include "rsa.h"
#include "sha256.h"
#include "stdbool.h"
#include "timer.h"
#include "vb21_struct.h"
/**
* Validate key contents.
*
* @param key
* @return EC_SUCCESS or EC_ERROR_*
*/
int vb21_is_packed_key_valid(const struct vb21_packed_key *key);
/**
* Validate signature contents.
*
* @param sig Signature to be validated.
* @param key Key to be used for validating <sig>.
* @return EC_SUCCESS or EC_ERROR_*
*/
int vb21_is_signature_valid(const struct vb21_signature *sig,
const struct vb21_packed_key *key);
/**
* Returns the public key in RO that was used to sign RW.
*
* @return pointer to key, never NULL
*/
const struct vb21_packed_key *vb21_get_packed_key(void);
/**
* Check data region is filled with ones
*
* @param data Data to be validated.
* @param start Offset where validation starts.
* @param end Offset where validation ends. data[end] won't be checked.
* @return EC_SUCCESS or EC_ERROR_*
*/
int vboot_is_padding_valid(const uint8_t *data, uint32_t start, uint32_t end);
/**
* Verify data by RSA signature
*
* @param data Data to be verified.
* @param len Number of bytes in <data>.
* @param key Key to be used for verification.
* @param sig Signature of <data>
* @return EC_SUCCESS or EC_ERROR_*
*/
int vboot_verify(const uint8_t *data, int len, const struct rsa_public_key *key,
const uint8_t *sig);
/**
* Entry point of EC EFS
*/
void vboot_main(void);
/**
* Get if vboot requires PD comm to be enabled or not
*
* @return 1: need PD communication. 0: PD communication is not needed.
*/
int vboot_need_pd_comm(void);
/**
* Callback for boards to notify users of vboot error when no display is
* available.
*
* Typically this happens when a Chromebox is booting on a Type-C adapter and
* EFS failed.
*/
__override_proto void show_critical_error(void);
/**
* Callback for boards to notify the user of power shortage.
*/
__override_proto void show_power_shortage(void);
/*
* Board level packet mode enable function.
*/
__override_proto void board_enable_packet_mode(bool enable);
/**
* Interrupt handler for packet mode entry.
*
* @param signal GPIO id for packet mode interrupt pin.
*/
void packet_mode_interrupt(enum gpio_signal signal);
/* Maximum number of times EC retries packet transmission before giving up. */
#define CR50_COMM_MAX_RETRY 5
/* EC's timeout for packet transmission to Cr50. */
#define CR50_COMM_TIMEOUT (50 * MSEC)
/* Preamble character repeated before the packet header starts. */
#define CR50_COMM_PREAMBLE 0xec
/* Magic characters used to identify ec-cr50-comm packets */
#define CR50_PACKET_MAGIC 0x4345 /* 'EC' in little endian */
/* version of struct cr50_comm_request */
#define CR50_COMM_PACKET_VERSION (0 << 4 | 0 << 0) /* 0.0 */
/**
* EC-Cr50 data frame looks like the following:
*
* [preamble][header][payload]
*
* preamble: 0xec ...
* header: struct cr50_comm_request
* payload: data[]
*/
struct cr50_comm_request {
/* Header */
uint16_t magic; /* CR50_PACKET_MAGIC */
uint8_t struct_version; /* version of this struct msb:lsb=major:minor */
uint8_t crc; /* checksum computed from all bytes after crc */
uint16_t type; /* CR50_CMD_* */
uint8_t size; /* Payload size. Be easy on Cr50 buffer. */
/* Payload */
uint8_t data[];
} __packed;
struct cr50_comm_response {
uint16_t error;
} __packed;
#define CR50_COMM_MAX_REQUEST_SIZE \
(sizeof(struct cr50_comm_request) + UINT8_MAX)
#define CR50_UART_RX_BUFFER_SIZE 32 /* TODO: Get from Cr50 header */
/* commands */
enum cr50_comm_cmd {
CR50_COMM_CMD_HELLO = 0x0000,
CR50_COMM_CMD_SET_BOOT_MODE = 0x0001,
CR50_COMM_CMD_VERIFY_HASH = 0x0002,
CR50_COMM_CMD_LIMIT = 0xffff,
} __packed;
BUILD_ASSERT(sizeof(enum cr50_comm_cmd) == sizeof(uint16_t));
#define CR50_COMM_ERR_PREFIX 0xec
/* return code */
enum cr50_comm_err {
CR50_COMM_SUCCESS = 0xec00,
CR50_COMM_ERR_UNKNOWN = 0xec01,
CR50_COMM_ERR_MAGIC = 0xec02,
CR50_COMM_ERR_CRC = 0xec03,
CR50_COMM_ERR_SIZE = 0xec04,
CR50_COMM_ERR_TIMEOUT = 0xec05, /* Generated by EC */
CR50_COMM_ERR_UNDEFINED_CMD = 0xec06,
CR50_COMM_ERR_BAD_PAYLOAD = 0xec07,
CR50_COMM_ERR_STRUCT_VERSION = 0xec08,
CR50_COMM_ERR_NVMEM = 0xec09,
} __packed;
BUILD_ASSERT(sizeof(enum cr50_comm_err) == sizeof(uint16_t));
/*
* BIT(1) : NO_BOOT flag
* BIT(0) : RECOVERY flag
*/
enum boot_mode {
BOOT_MODE_NORMAL = 0x00,
BOOT_MODE_NO_BOOT = 0x01,
} __packed;
BUILD_ASSERT(sizeof(enum boot_mode) == sizeof(uint8_t));
/**
* Indicate PD is allowed (in RO) by vboot or not.
*
* Overridden by each EFS implementation (EFS1 and EFS2) not by boards.
*
* @return true - allowed. false - disallowed.
*/
__override_proto bool vboot_allow_usb_pd(void);
#ifdef TEST_BUILD
/**
* Set the vboot_allow_usb_pd flag to false.
*/
__test_only void vboot_disable_pd(void);
#endif
#endif /* __CROS_EC_INCLUDE_VBOOT_H */