@@ -44,6 +44,12 @@ typedef uint32_t lcs_reserved_t;
4444/* We truncate the 32 byte sha256 down to 16 bytes before storing it */
4545#define SB_PUBLIC_KEY_HASH_LEN 16
4646
47+ /* Supported collection types. */
48+ enum collection_type {
49+ BL_COLLECTION_TYPE_MONOTONIC_COUNTERS = 1 ,
50+ BL_COLLECTION_TYPE_VARIABLE_DATA = 0x9312 ,
51+ };
52+
4753/* Counter used by NSIB to check the firmware version */
4854#define BL_MONOTONIC_COUNTERS_DESC_NSIB 0x1
4955
@@ -88,23 +94,50 @@ struct monotonic_counter {
8894 uint16_t description ;
8995 /* Number of entries in 'counter_slots' list. */
9096 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 ;
92104};
93105
94106/** The second data structure in the provision page. It has unknown length since
95107 * 'counters' is repeated. Note that each entry in counters also has unknown
96108 * 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.
98110 */
99111struct 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 [];
103136};
104137
105138/** The first data structure in the bootloader storage. It has unknown length
106139 * 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 .
108141 */
109142struct bl_storage_data {
110143 /* NB: When placed in OTP, reads must be 4 bytes and 4 byte aligned */
@@ -116,7 +149,28 @@ struct bl_storage_data {
116149 struct {
117150 uint32_t valid ;
118151 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+ */
120174};
121175
122176#define BL_STORAGE ((const volatile struct bl_storage_data *)(PM_PROVISION_ADDRESS))
@@ -150,7 +204,7 @@ uint32_t s1_address_read(void);
150204uint32_t num_public_keys_read (void );
151205
152206/**
153- * @brief Function for reading number of public key data slots .
207+ * @brief Function for verifying public keys .
154208 *
155209 * @retval 0 if all keys are ok.
156210 * @retval -EHASHFF if one or more keys contains an aligned 0xFFFF.
@@ -257,12 +311,32 @@ int read_life_cycle_state(enum lcs *lcs);
257311int update_life_cycle_state (enum lcs next_lcs );
258312
259313/**
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.
261315 *
262316 * @param[out] buf Buffer that has at least BL_STORAGE_IMPLEMENTATION_ID_SIZE bytes
263317 */
264318void read_implementation_id_from_otp (uint8_t * buf );
265319
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+
266340 /** @} */
267341
268342#ifdef __cplusplus
0 commit comments