Software APIs
boot_data.h
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_BOOT_DATA_H_
6#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_BOOT_DATA_H_
7
9#include "sw/device/silicon_creator/lib/drivers/hmac.h"
10#include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
11#include "sw/device/silicon_creator/lib/error.h"
12#include "sw/device/silicon_creator/lib/nonce.h"
13
14#ifdef __cplusplus
15extern "C" {
16#endif // __cplusplus
17
18/**
19 * Boot data stored in the flash info partition.
20 */
21typedef struct boot_data {
22 /**
23 * SHA-256 digest of boot data.
24 *
25 * The region covered by this digest starts immediately after this field and
26 * ends at the end of the entry.
27 */
28 hmac_digest_t digest;
29 /**
30 * Invalidation field.
31 *
32 * This field is used to invalidate the previous entry after writing a new
33 * entry. When writing a new entry, the value of this field is assumed to be
34 * `kBootDataValidEntry`, which matches the value of unwritten flash words,
35 * but it is skipped so that the entry can be invalidated at a later time. An
36 * entry can be invalidated by writing `kBootDataInvalidEntry` to this field
37 * resulting in a digest mismatch.
38 */
39 uint64_t is_valid;
40 /**
41 * Boot data identifier.
42 */
43 uint32_t identifier;
44 /**
45 * Boot data format version.
46 *
47 * This field must be set to the latest version for new entries but is not
48 * enforced during reads for forward compatibility in ROM and backward
49 * compatibility in ROM_EXT.
50 */
51 uint32_t version;
52 /**
53 * Counter.
54 *
55 * This is a monotonically increasing counter that is used to determine the
56 * newest entry across both boot data pages.
57 */
58 uint32_t counter;
59 /**
60 * Minimum required security version for ROM_EXT.
61 */
63 /**
64 * Minimum required security version for BL0.
65 */
67 /**
68 * The BL0 slot that is prioritized during boot.
69 */
71 /**
72 * Next owner key (ECDSA). Only relevant in the UNLOCKED_ENDORSED ownership
73 * state.
74 */
75 uint32_t next_owner[8];
76 /**
77 * Challenge/response nonce for signed boot_svc commands.
78 */
79 nonce_t nonce;
80 /**
81 * Ownership state. One of LOCKED_OWNER, LOCKED_UPDATE, UNLOCKED_ANY,
82 * UNLOCKED_ENDORSED, LOCKED_NONE.
83 */
85 /**
86 * Number of ownership transfers this chip has had.
87 */
89
90 /**
91 * Padding for future enhancements and to make the size of `boot_data_t` a
92 * power of two.
93 */
94 uint32_t padding[4];
95} boot_data_t;
96
97OT_ASSERT_MEMBER_OFFSET(boot_data_t, digest, 0);
98OT_ASSERT_MEMBER_OFFSET(boot_data_t, is_valid, 32);
99OT_ASSERT_MEMBER_OFFSET(boot_data_t, identifier, 40);
100OT_ASSERT_MEMBER_OFFSET(boot_data_t, version, 44);
101OT_ASSERT_MEMBER_OFFSET(boot_data_t, counter, 48);
102OT_ASSERT_MEMBER_OFFSET(boot_data_t, min_security_version_rom_ext, 52);
103OT_ASSERT_MEMBER_OFFSET(boot_data_t, min_security_version_bl0, 56);
104OT_ASSERT_MEMBER_OFFSET(boot_data_t, primary_bl0_slot, 60);
105OT_ASSERT_MEMBER_OFFSET(boot_data_t, next_owner, 64);
106OT_ASSERT_MEMBER_OFFSET(boot_data_t, nonce, 96);
107OT_ASSERT_MEMBER_OFFSET(boot_data_t, ownership_state, 104);
108OT_ASSERT_MEMBER_OFFSET(boot_data_t, ownership_transfers, 108);
109OT_ASSERT_MEMBER_OFFSET(boot_data_t, padding, 112);
110OT_ASSERT_SIZE(boot_data_t, 128);
111
112enum {
113 /**
114 * Boot data identifier value (ASCII "BODA").
115 */
116 kBootDataIdentifier = 0x41444f42,
117 /**
118 * Boot data version 1 value.
119 */
120 kBootDataVersion1 = 0xd4ce468e,
121 /**
122 * Boot data version 2 value.
123 */
124 kBootDataVersion2 = 0xad51e729,
125 /**
126 * Value of the `is_valid` field for valid entries.
127 */
128 kBootDataValidEntry = UINT64_MAX,
129 /**
130 * Value of the `is_valid` field for invalidated entries.
131 *
132 * This value is used to invalidate the previous entry after writing a new
133 * entry.
134 */
135 kBootDataInvalidEntry = 0,
136 /**
137 * Value of the counter field of the default boot data entry.
138 *
139 * This starts from 5 to have a slightly less trivial value in case we need to
140 * distinguish the default entry.
141 */
142 kBootDataDefaultCounterVal = 5,
143 /**
144 * Size of `boot_data_t` in words.
145 */
146 kBootDataNumWords = sizeof(boot_data_t) / sizeof(uint32_t),
147 /**
148 * Number of boot data entries per info page.
149 *
150 * Boot data pages are used as append-only logs where new data is written to
151 * the first empty entry of the active page. If all entries of the currently
152 * active page are used when `boot_data_write()` is called, the other page
153 * will be erased and new data will be written to its first entry, making it
154 * the new active page.
155 */
156 kBootDataEntriesPerPage = 16,
157};
158static_assert(kBootDataInvalidEntry != kBootDataValidEntry,
159 "Invalidation values cannot be equal.");
160
161/**
162 * Constants referring to EFLASH slots A and B.
163 */
164typedef enum boot_slot {
165 /** Slot A: `AA__`. */
166 kBootSlotA = 0x5f5f4141,
167 /** Slot B: `__BB`. */
168 kBootSlotB = 0x42425f5f,
169 /** Slot Unspecified: `UUUU`. */
170 kBootSlotUnspecified = 0x55555555,
171} boot_slot_t;
172
173/**
174 * Reads the boot data stored in the flash info partition.
175 *
176 * The flash controller must be initialized with proper permissions for the
177 * first and second info pages of the second flash bank before calling this
178 * function.
179 *
180 * If there is no valid boot data in the flash info partition, this function
181 * returns the default boot data in non-production life cycle states
182 * (TEST_UNLOCKED, DEV, RMA).
183 *
184 * @param lc_state Life cycle state of the device.
185 * @param boot_data[out] Boot data.
186 * @return The result of the operation.
187 */
189rom_error_t boot_data_read(lifecycle_state_t lc_state, boot_data_t *boot_data);
190
191/**
192 * Writes the given boot data to the flash info partition.
193 *
194 * This function updates the `identifier`, `counter`, and `digest` fields of the
195 * given `boot_data` before writing it to the flash.
196 *
197 * @param boot_data[out] Boot data.
198 * @return The result of the operation.
199 */
201rom_error_t boot_data_write(const boot_data_t *boot_data);
202
203/**
204 * Checks whether a boot data entry is valid.
205 *
206 * This function checks the `identifier` and `digest` fields of the given
207 * `boot_data` entry.
208 *
209 * @param boot_data A buffer that holds a boot data entry.
210 * @return Whether the digest of the entry is valid.
211 */
213rom_error_t boot_data_check(const boot_data_t *boot_data);
214
215#ifdef __cplusplus
216} // extern "C"
217#endif // __cplusplus
218
219#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_BOOT_DATA_H_