@@ -44,6 +44,12 @@ typedef uint32_t lcs_reserved_t;
44
44
/* We truncate the 32 byte sha256 down to 16 bytes before storing it */
45
45
#define SB_PUBLIC_KEY_HASH_LEN 16
46
46
47
+ /* Supported collection types. */
48
+ enum collection_type {
49
+ BL_COLLECTION_TYPE_MONOTONIC_COUNTERS = 1 ,
50
+ BL_COLLECTION_TYPE_VARIABLE_DATA = 0x9312 ,
51
+ };
52
+
47
53
/* Counter used by NSIB to check the firmware version */
48
54
#define BL_MONOTONIC_COUNTERS_DESC_NSIB 0x1
49
55
@@ -88,23 +94,50 @@ struct monotonic_counter {
88
94
uint16_t description ;
89
95
/* Number of entries in 'counter_slots' list. */
90
96
uint16_t num_counter_slots ;
91
- counter_t counter_slots [1 ];
97
+ counter_t counter_slots [];
98
+ };
99
+
100
+ /** Common part for all collections. */
101
+ struct collection {
102
+ uint16_t type ;
103
+ uint16_t count ;
92
104
};
93
105
94
106
/** The second data structure in the provision page. It has unknown length since
95
107
* 'counters' is repeated. Note that each entry in counters also has unknown
96
108
* length, and each entry can have different length from the others, so the
97
- * entries beyond the first cannot be accessed via array indices.
109
+ * entries beyond the first cannot be accessed through array indices.
98
110
*/
99
111
struct counter_collection {
100
- uint16_t type ; /* Must be "monotonic counter". */
101
- uint16_t num_counters ; /* Number of entries in 'counters' list. */
102
- struct monotonic_counter counters [1 ];
112
+ struct collection collection ; /* Type must be BL_COLLECTION_TYPE_MONOTONIC_COUNTERS */
113
+ struct monotonic_counter counters [];
114
+ };
115
+
116
+ /* Variable data types. */
117
+ enum variable_data_type {
118
+ BL_VARIABLE_DATA_TYPE_PSA_CERTIFICATION_REFERENCE = 0x1
119
+ };
120
+ struct variable_data {
121
+ uint8_t type ;
122
+ uint8_t length ;
123
+ uint8_t data [];
124
+ };
125
+
126
+ /* The third data structure in the provision page. It has unknown length since
127
+ * 'variable_data' is repeated. The collection starts immediately after the
128
+ * counter collection. As the counter collection has unknown length, the start
129
+ * of the variable data collection must be calculated dynamically. Similarly,
130
+ * the entries in the variable data collection have unknown length, so they
131
+ * cannot be accessed through array indices.
132
+ */
133
+ struct variable_data_collection {
134
+ struct collection collection ; /* Type must be BL_COLLECTION_TYPE_VARIABLE_DATA */
135
+ struct variable_data variable_data [];
103
136
};
104
137
105
138
/** The first data structure in the bootloader storage. It has unknown length
106
139
* since 'key_data' is repeated. This data structure is immediately followed by
107
- * struct counter_collection.
140
+ * struct counter_collection, which is then followed by struct variable_data_collection .
108
141
*/
109
142
struct bl_storage_data {
110
143
/* NB: When placed in OTP, reads must be 4 bytes and 4 byte aligned */
@@ -116,7 +149,28 @@ struct bl_storage_data {
116
149
struct {
117
150
uint32_t valid ;
118
151
uint8_t hash [SB_PUBLIC_KEY_HASH_LEN ];
119
- } key_data [1 ];
152
+ } key_data [];
153
+
154
+ /* Monotonic counter collection:
155
+ * uint16_t type;
156
+ * uint16_t count;
157
+ * struct {
158
+ * uint16_t description;
159
+ * uint16_t num_counter_slots;
160
+ * counter_t counter_slots[];
161
+ * } counters[];
162
+ */
163
+
164
+ /* Variable data collection:
165
+ * uint16_t type;
166
+ * uint16_t count;
167
+ * struct {
168
+ * uint8_t type;
169
+ * uint8_t length;
170
+ * uint8_t data[];
171
+ * } variable_data[];
172
+ * uint8_t padding[]; // Padding to align to 4 bytes
173
+ */
120
174
};
121
175
122
176
#define BL_STORAGE ((const volatile struct bl_storage_data *)(PM_PROVISION_ADDRESS))
@@ -150,7 +204,7 @@ uint32_t s1_address_read(void);
150
204
uint32_t num_public_keys_read (void );
151
205
152
206
/**
153
- * @brief Function for reading number of public key data slots .
207
+ * @brief Function for verifying public keys .
154
208
*
155
209
* @retval 0 if all keys are ok.
156
210
* @retval -EHASHFF if one or more keys contains an aligned 0xFFFF.
@@ -257,12 +311,32 @@ int read_life_cycle_state(enum lcs *lcs);
257
311
int update_life_cycle_state (enum lcs next_lcs );
258
312
259
313
/**
260
- * Read the implementation id from OTP and copy it into a given buffer.
314
+ * Read the implementation ID from OTP and copy it into a given buffer.
261
315
*
262
316
* @param[out] buf Buffer that has at least BL_STORAGE_IMPLEMENTATION_ID_SIZE bytes
263
317
*/
264
318
void read_implementation_id_from_otp (uint8_t * buf );
265
319
320
+ /**
321
+ * @brief Read variable data from OTP.
322
+ *
323
+ * Variable data starts with variable data collection ID, followed by amount of variable data
324
+ * entries and the variable data entries themselves.
325
+ * [Collection ID][Variable count][Type][Variable data length][Variable data][Type]...
326
+ * 2 bytes 2 bytes 1 byte 1 byte 0-255 bytes
327
+ *
328
+ * @note If data is not found, function does not fail. Instead, 0 length is returned.
329
+ *
330
+ * @param[in] data_type Type of the variable data to read.
331
+ * @param[out] buf Buffer to store the variable data.
332
+ * @param[in,out] buf_len On input, the size of the buffer. On output, the length of the data.
333
+ *
334
+ * @retval 0 Variable data read successfully, or not found.
335
+ * @retval -EINVAL No buffer provided.
336
+ * @retval -ENOMEM Buffer too small.
337
+ */
338
+ int read_variable_data (enum variable_data_type data_type , uint8_t * buf , uint32_t * buf_len );
339
+
266
340
/** @} */
267
341
268
342
#ifdef __cplusplus
0 commit comments