summaryrefslogtreecommitdiff
path: root/include/vboot.h
blob: ba924508c7cd6274d4dcd2da4e9597a2e82cf27f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* 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_INCLUDE_VBOOT_H
#define __CROS_EC_INCLUDE_VBOOT_H

#include "common.h"
#include "vb21_struct.h"
#include "rsa.h"
#include "sha256.h"

#define CR50_COMM_VERSION               0x00
#define CR50_COMM_PREAMBLE              0xec
#define MIN_LENGTH_PREAMBLE             4
#define CR50_COMM_MAGIC_CHAR0           'E'
#define CR50_COMM_MAGIC_CHAR1           'C'
#define CR50_COMM_MAGIC_WORD            ((CR50_COMM_MAGIC_CHAR1 << 8) | \
					 CR50_COMM_MAGIC_CHAR0)

/*
 * EC-Cr50 data stream looks like as follows:
 *
 *   [preamble][header][payload]
 *
 * preamble: CR50_COMM_PREAMBLE (at least MIN_LENGTH_PREAMBLE times)
 * header: struct cr50_comm_packet
 * payload: data[]
 */
struct cr50_comm_packet {
	/* Header */
	uint16_t magic;	/* CR50_COMM_MAGIC_WORD */
	uint8_t version;/* Struct version. 4MSB=Major. 4LSB=Minor. */
	uint8_t crc;	/* checksum computed from all bytes after crc */
	uint16_t cmd;	/* CR50_COMM_CMD_* if EC sends */
			/* CR50_COMM_RESPONSE(X) if CR50 sends. */
	uint8_t size;	/* Size of 'data[]' member. */
	uint8_t data[];	/* Payload */
} __packed;

#define CR50_COMM_MAX_DATA_SIZE         32
#define CR50_COMM_MAX_PACKET_SIZE       (sizeof(struct cr50_comm_packet) + \
					 CR50_COMM_MAX_DATA_SIZE)

/* EC-CR50 commands (2 bytes) for cr50_comm_packet.cmd */
#define CR50_COMM_CMD_SET_BOOT_MODE     0x0001
#define CR50_COMM_CMD_VERIFY_HASH       0x0002

/* EC-CR50 response codes (2 bytes) for cr50_comm_packet.cmd */
#define CR50_COMM_RESPONSE(X)           ((CR50_COMM_PREAMBLE << 8) | \
					 ((X) & 0xff))
#define CR50_COMM_SUCCESS               CR50_COMM_RESPONSE(0x00)
#define CR50_COMM_ERROR_UNKNOWN         CR50_COMM_RESPONSE(0x01)
#define CR50_COMM_ERROR_MAGIC           CR50_COMM_RESPONSE(0x02)
#define CR50_COMM_ERROR_CRC             CR50_COMM_RESPONSE(0x03)
#define CR50_COMM_ERROR_SIZE            CR50_COMM_RESPONSE(0x04)
#define CR50_COMM_ERROR_TIMEOUT         CR50_COMM_RESPONSE(0x05)
#define CR50_COMM_ERROR_UNDEFINED_CMD   CR50_COMM_RESPONSE(0x06)
#define CR50_COMM_ERROR_BAD_PAYLOAD     CR50_COMM_RESPONSE(0x07)
#define CR50_COMM_ERROR_STRUCT_VERSION  CR50_COMM_RESPONSE(0x08)
#define CR50_COMM_ERROR_NVMEM           CR50_COMM_RESPONSE(0x09)

/*
 * BIT(0) : NO_BOOT flag
 * BIT(1) : RECOVERY flag
 */
enum ec_efs_boot_mode {
	EC_EFS_BOOT_MODE_NORMAL           = 0x00,
	EC_EFS_BOOT_MODE_NO_BOOT          = 0x01,

	/* boot_mode is uint8_t */
	EC_EFS_BOOT_MODE_LIMIT            = 255,
};

/****************************************************************************
 * This is quoted from 2secdata_struct.h in the directory,
 * src/platform/vboot_reference/firmware/2lib/include/.
 ****************************************************************************/

/* Kernel secure storage space */
#define VB2_SECDATA_KERNEL_STRUCT_VERSION_MIN  0x10
#define VB2_SECDATA_KERNEL_UID          0x4752574c  /* 'LWRG' */
struct vb2_secdata_kernel {
	uint8_t struct_version;		/* top-half:major. bottom-half:minor. */
	uint8_t struct_size;		/* Whole structure size */
	uint8_t crc8;			/* CRC for everything below */
	uint8_t reserved0;

	uint32_t kernel_versions;	/* Kernel versions */
	uint8_t ec_hash[SHA256_DIGEST_SIZE];
} __packed;

/**
 * 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);

/**
 * 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);

#endif  /* __CROS_EC_INCLUDE_VBOOT_H */