1 /* Copyright 2019 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Secure non-volatile storage data structure definitions
6 */
7
8 #ifndef VBOOT_REFERENCE_2SECDATA_STRUCT_H_
9 #define VBOOT_REFERENCE_2SECDATA_STRUCT_H_
10
11 #include "2constants.h"
12 #include "2crc8.h"
13 #include "2sha.h"
14 #include "2sysincludes.h"
15
16 /*****************************************************************************/
17 /* Firmware secure storage space */
18
19 #define VB2_SECDATA_FIRMWARE_VERSION 2
20
21 struct vb2_secdata_firmware {
22 /* Struct version, for backwards compatibility */
23 uint8_t struct_version;
24
25 /* Flags; see vb2_secdata_firmware_flags */
26 uint8_t flags;
27
28 /* Firmware versions */
29 uint32_t fw_versions;
30
31 /* Reserved for future expansion */
32 uint8_t reserved[3];
33
34 /* CRC; must be last field in struct */
35 uint8_t crc8;
36 } __attribute__((packed));
37
38 /*****************************************************************************/
39 /* Kernel secure storage space
40 *
41 * We'll never convert v0.2 to v1.* or the other way. v0.2 or v1.* data will be
42 * passed around between AP and TPM without upgrade or downgrade.
43 *
44 * 1. Old BIOS on old device will read/write v0.2 data from/to TPM.
45 * 2. New BIOS on old device will read/write v0.2 data from/to TPM.
46 * 3. Old BIOS on new device will read/write v0.2 data from/to TPM.
47 * 4. New BIOS on new device will read/write v1.0 data from/to TPM.
48 */
49
50 /* Kernel space - KERNEL_NV_INDEX, locked with physical presence. */
51 #define VB2_SECDATA_KERNEL_VERSION_V02 (0 << 4 | 2 << 0) /* 0.2 */
52 #define VB2_SECDATA_KERNEL_VERSION_V10 (1 << 4 | 0 << 0) /* 1.0 */
53 #define VB2_SECDATA_KERNEL_VERSION_LATEST VB2_SECDATA_KERNEL_VERSION_V10
54 #define VB2_SECDATA_KERNEL_UID 0x4752574c /* 'LWRG' */
55
56 struct vb2_secdata_kernel_v0 {
57 /* Struct version, for backwards compatibility */
58 uint8_t struct_version; /* 0.2 (or 0x02 in v0 format) */
59
60 /* Unique ID to detect space redefinition */
61 uint32_t uid;
62
63 /* Kernel versions */
64 uint32_t kernel_versions;
65
66 /* Reserved for future expansion */
67 uint8_t reserved[3];
68
69 /* CRC; must be last field in struct */
70 uint8_t crc8;
71 } __attribute__((packed));
72 _Static_assert(sizeof(struct vb2_secdata_kernel_v0)
73 == VB2_SECDATA_KERNEL_SIZE_V02,
74 "VB2_SECDATA_KERNEL_SIZE_V02 incorrect");
75 _Static_assert(sizeof(struct vb2_secdata_kernel_v0)
76 < VB2_SECDATA_KERNEL_MAX_SIZE,
77 "VB2_SECDATA_KERNEL_SIZE_V02 exceeds max size");
78
79 /*
80 * Secdata kernel v1.* series.
81 */
82 struct vb2_secdata_kernel_v1 {
83 /* Struct version, for backwards compatibility */
84 uint8_t struct_version; /* 1.0 (or 0x10 in v0 format) */
85
86 /* Size of the struct */
87 uint8_t struct_size;
88
89 /* 8-bit CRC for everything below */
90 uint8_t crc8;
91
92 /* Flags; see vb2_secdata_kernel_flags */
93 uint8_t flags;
94
95 /* Kernel versions */
96 uint32_t kernel_versions;
97
98 /* EC hash used for EFS2 */
99 uint8_t ec_hash[VB2_SHA256_DIGEST_SIZE];
100 };
101 _Static_assert(sizeof(struct vb2_secdata_kernel_v1)
102 == VB2_SECDATA_KERNEL_SIZE_V10,
103 "VB2_SECDATA_KERNEL_SIZE_V10 incorrect");
104 _Static_assert(sizeof(struct vb2_secdata_kernel_v1)
105 < VB2_SECDATA_KERNEL_MAX_SIZE,
106 "VB2_SECDATA_KERNEL_SIZE_V10 exceeds max size");
107
108 /*****************************************************************************/
109 /* Firmware management parameters (FWMP) space */
110
111 #define VB2_SECDATA_FWMP_VERSION 0x10 /* 1.0 */
112 #define VB2_SECDATA_FWMP_HASH_SIZE 32 /* enough for SHA-256 */
113
114 struct vb2_secdata_fwmp {
115 /* CRC-8 of fields following struct_size */
116 uint8_t crc8;
117
118 /* Structure size in bytes */
119 uint8_t struct_size;
120
121 /* Structure version (4 bits major, 4 bits minor) */
122 uint8_t struct_version;
123
124 /* Reserved; ignored by current reader */
125 uint8_t reserved0;
126
127 /* Flags; see enum vb2_secdata_fwmp_flags */
128 uint32_t flags;
129
130 /* Hash of developer kernel key */
131 uint8_t dev_key_hash[VB2_SECDATA_FWMP_HASH_SIZE];
132 };
133
134 /**
135 * Generate CRC for FWMP secure storage space.
136 *
137 * Calculate CRC hash from struct_version onward. In valid FWMP data, this CRC
138 * value should match the crc8 field.
139 *
140 * @param sec Pointer to FWMP struct
141 * @return 32-bit CRC hash of FWMP data
142 */
vb2_secdata_fwmp_crc(struct vb2_secdata_fwmp * sec)143 static inline uint32_t vb2_secdata_fwmp_crc(struct vb2_secdata_fwmp *sec)
144 {
145 int version_offset = offsetof(struct vb2_secdata_fwmp, struct_version);
146 return vb2_crc8((void *)sec + version_offset,
147 sec->struct_size - version_offset);
148 }
149
150 #endif /* VBOOT_REFERENCE_2SECDATA_STRUCT_H_ */
151