nRF Connect SDK API 2.8.99
Loading...
Searching...
No Matches
bl_storage.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5 */
6
7#ifndef BL_STORAGE_H_
8#define BL_STORAGE_H_
9
10#include <string.h>
11#include <zephyr/types.h>
12#include <zephyr/autoconf.h>
13#include <drivers/nrfx_common.h>
14#if defined(CONFIG_NRFX_NVMC)
15#include <nrfx_nvmc.h>
16#elif defined(CONFIG_NRFX_RRAMC)
17#include <nrfx_rramc.h>
18#else
19#error "No NRFX storage technology supported backend selected"
20#endif
21#include <errno.h>
22#include <pm_config.h>
23
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#if defined(CONFIG_NRFX_NVMC)
30typedef uint16_t counter_t;
31typedef uint16_t lcs_data_t;
32typedef uint16_t lcs_reserved_t;
33#elif defined(CONFIG_NRFX_RRAMC)
34/* nRF54L15 only supports word writes */
35typedef uint32_t counter_t;
36typedef uint32_t lcs_data_t;
37typedef uint32_t lcs_reserved_t;
38#endif
39
40#define EHASHFF 113 /* A hash contains too many 0xFs. */
41#define EREADLCS 114 /* LCS field of OTP is in an invalid state */
42#define EINVALIDLCS 115 /* Invalid LCS*/
43
44/* We truncate the 32 byte sha256 down to 16 bytes before storing it */
45#define SB_PUBLIC_KEY_HASH_LEN 16
46
47/* Counter used by NSIB to check the firmware version */
48#define BL_MONOTONIC_COUNTERS_DESC_NSIB 0x1
49
50/* Counter used by MCUBOOT to check the firmware version. Suffixed
51 * with ID0 as we might support checking the version of multiple
52 * images in the future.
53 */
54#define BL_MONOTONIC_COUNTERS_DESC_MCUBOOT_ID0 0x2
55
67 lcs_data_t provisioning;
68 lcs_data_t secure;
69 /* Pad to end the alignment at a 4-byte boundary as some devices
70 * are only supporting 4-byte UICR->OTP reads. We place the reserved
71 * padding in the middle of the struct in case we ever need to support
72 * another state.
73 */
74 lcs_reserved_t reserved_for_padding;
75 lcs_data_t decommissioned;
76};
77
85 /* Counter description. What the counter is used for. See
86 * BL_MONOTONIC_COUNTERS_DESC_x.
87 */
88 uint16_t description;
89 /* Number of entries in 'counter_slots' list. */
91 counter_t counter_slots[1];
92};
93
100 uint16_t type; /* Must be "monotonic counter". */
101 uint16_t num_counters; /* Number of entries in 'counters' list. */
103};
104
105NRFX_STATIC_INLINE uint32_t bl_storage_word_read(uint32_t address);
106NRFX_STATIC_INLINE uint32_t bl_storage_word_write(uint32_t address, uint32_t value);
107NRFX_STATIC_INLINE counter_t bl_storage_counter_get(uint32_t address);
108NRFX_STATIC_INLINE void bl_storage_counter_set(uint32_t address, counter_t value);
109
111int get_counter(uint16_t counter_desc, counter_t *counter_value, const counter_t **free_slot);
112
118 /* NB: When placed in OTP, reads must be 4 bytes and 4 byte aligned */
120 uint8_t implementation_id[32];
121 uint32_t s0_address;
122 uint32_t s1_address;
123 uint32_t num_public_keys; /* Number of entries in 'key_data' list. */
124 struct {
125 uint32_t valid;
128};
129
130#define BL_STORAGE ((const volatile struct bl_storage_data *)(PM_PROVISION_ADDRESS))
131
132/* This must be 32 bytes according to the IETF PSA token specification */
133#define BL_STORAGE_IMPLEMENTATION_ID_SIZE 32
134
144uint32_t s0_address_read(void);
145
151uint32_t s1_address_read(void);
152
158uint32_t num_public_keys_read(void);
159
167
178int public_key_data_read(uint32_t key_idx, uint8_t *p_buf);
179
187void invalidate_public_key(uint32_t key_idx);
188
199int num_monotonic_counter_slots(uint16_t counter_desc, uint16_t *counter_slots);
200
211int get_monotonic_counter(uint16_t counter_desc, counter_t *counter_value);
212
230int set_monotonic_counter(uint16_t counter_desc, counter_t new_counter);
231
244
253NRFX_STATIC_INLINE void otp_copy32(uint8_t *restrict dst, uint32_t volatile * restrict src,
254 size_t size)
255{
256 for (int i = 0; i < size / 4; i++) {
257 /* OTP is in UICR */
258 uint32_t val = bl_storage_word_read((uint32_t)(src + i));
259
260 for (int j = 0; j < 4; j++) {
261 dst[i * 4 + j] = (val >> 8 * j) & 0xFF;
262 }
263 }
264}
270NRFX_STATIC_INLINE void read_implementation_id_from_otp(uint8_t *buf)
271{
272 if (buf == NULL) {
273 return;
274 }
275
276 otp_copy32(buf, (uint32_t *)&BL_STORAGE->implementation_id,
278}
279
280/* The OTP is 0xFFFF when erased and, like all flash, can only flip
281 * bits from 0 to 1 when erasing. By setting all bits to zero we
282 * enforce the correct transitioning of LCS until a full erase of the
283 * device.
284 */
285#define STATE_ENTERED 0x0000
286#define STATE_NOT_ENTERED 0xFFFF
287
288/* The bl_storage functions below are static inline in the header file
289 * so that TF-M (that does not include bl_storage.c) can also have
290 * access to them.
291 * This is a temporary solution until TF-M has access to NSIB functions.
292 */
293
294#if defined(CONFIG_NRFX_RRAMC)
295NRFX_STATIC_INLINE uint32_t index_from_address(uint32_t address)
296{
297 return ((address - (uint32_t)BL_STORAGE)/sizeof(uint32_t));
298}
299#endif
300
301NRFX_STATIC_INLINE counter_t bl_storage_counter_get(uint32_t address)
302{
303#if defined(CONFIG_NRFX_NVMC)
304 return ~nrfx_nvmc_otp_halfword_read(address);
305#elif defined(CONFIG_NRFX_RRAMC)
306 return ~nrfx_rramc_otp_word_read(index_from_address(address));
307#endif
308}
309
310NRFX_STATIC_INLINE void bl_storage_counter_set(uint32_t address, counter_t value)
311{
312#if defined(CONFIG_NRFX_NVMC)
313 nrfx_nvmc_halfword_write((uint32_t)address, ~value);
314#elif defined(CONFIG_NRFX_RRAMC)
315 nrfx_rramc_otp_word_write(index_from_address((uint32_t)address), ~value);
316#endif
317}
318
319NRFX_STATIC_INLINE uint32_t bl_storage_word_read(uint32_t address)
320{
321#if defined(CONFIG_NRFX_NVMC)
322 return nrfx_nvmc_uicr_word_read((uint32_t *)address);
323#elif defined(CONFIG_NRFX_RRAMC)
324 return nrfx_rramc_word_read(address);
325#endif
326}
327
328NRFX_STATIC_INLINE uint32_t bl_storage_word_write(uint32_t address, uint32_t value)
329{
330#if defined(CONFIG_NRFX_NVMC)
331 nrfx_nvmc_word_write(address, value);
332 return 0;
333#elif defined(CONFIG_NRFX_RRAMC)
334 nrfx_rramc_word_write(address, value);
335 return 0;
336#endif
337}
338
339NRFX_STATIC_INLINE uint16_t bl_storage_otp_halfword_read(uint32_t address)
340{
341 uint16_t halfword;
342#if defined(CONFIG_NRFX_NVMC)
343 halfword = nrfx_nvmc_otp_halfword_read(address);
344#elif defined(CONFIG_NRFX_RRAMC)
345 uint32_t word = nrfx_rramc_otp_word_read(index_from_address(address));
346
347 if (!(address & 0x3)) {
348 halfword = (uint16_t)(word & 0x0000FFFF); /* C truncates the upper bits */
349 } else {
350 halfword = (uint16_t)(word >> 16); /* Shift the upper half down */
351 }
352#endif
353 return halfword;
354}
355
356NRFX_STATIC_INLINE lcs_data_t bl_storage_lcs_get(uint32_t address)
357{
358#if defined(CONFIG_NRFX_NVMC)
359 return nrfx_nvmc_otp_halfword_read(address);
360#elif defined(CONFIG_NRFX_RRAMC)
361 return nrfx_rramc_otp_word_read(index_from_address(address));
362#endif
363}
364
365NRFX_STATIC_INLINE int bl_storage_lcs_set(uint32_t address, lcs_data_t state)
366{
367#if defined(CONFIG_NRFX_NVMC)
368 nrfx_nvmc_halfword_write(address, state);
369#elif defined(CONFIG_NRFX_RRAMC)
371#endif
372 return 0;
373}
374
383NRFX_STATIC_INLINE int read_life_cycle_state(enum lcs *lcs)
384{
385 if (lcs == NULL) {
386 return -EINVAL;
387 }
388
389 lcs_data_t provisioning = bl_storage_lcs_get(
390 (uint32_t) &BL_STORAGE->lcs.provisioning);
391 lcs_data_t secure = bl_storage_lcs_get((uint32_t) &BL_STORAGE->lcs.secure);
392 lcs_data_t decommissioned = bl_storage_lcs_get(
393 (uint32_t) &BL_STORAGE->lcs.decommissioned);
394
395 if (provisioning == STATE_NOT_ENTERED
396 && secure == STATE_NOT_ENTERED
397 && decommissioned == STATE_NOT_ENTERED) {
399 } else if (provisioning == STATE_ENTERED
400 && secure == STATE_NOT_ENTERED
401 && decommissioned == STATE_NOT_ENTERED) {
403 } else if (provisioning == STATE_ENTERED
404 && secure == STATE_ENTERED
405 && decommissioned == STATE_NOT_ENTERED) {
407 } else if (provisioning == STATE_ENTERED
408 && secure == STATE_ENTERED
409 && decommissioned == STATE_ENTERED) {
411 } else {
412 /* To reach this the OTP must be corrupted or reading failed */
413 return -EREADLCS;
414 }
415
416 return 0;
417}
418
429NRFX_STATIC_INLINE int update_life_cycle_state(enum lcs next_lcs)
430{
431 int err;
432 enum lcs current_lcs = 0;
433
434 if (next_lcs == BL_STORAGE_LCS_UNKNOWN) {
435 return -EINVALIDLCS;
436 }
437
438 err = read_life_cycle_state(&current_lcs);
439 if (err != 0) {
440 return err;
441 }
442
443 if (next_lcs < current_lcs) {
444 /* Is is only possible to transition into a higher state */
445 return -EINVALIDLCS;
446 }
447
448 if (next_lcs == current_lcs) {
449 /* The same LCS is a valid argument, but nothing to do so return success */
450 return 0;
451 }
452
453 /* As the device starts in ASSEMBLY, it is not possible to write it */
454 if (current_lcs == BL_STORAGE_LCS_ASSEMBLY && next_lcs == BL_STORAGE_LCS_PROVISIONING) {
455 return bl_storage_lcs_set((uint32_t)&BL_STORAGE->lcs.provisioning, STATE_ENTERED);
456 }
457
458 if (current_lcs == BL_STORAGE_LCS_PROVISIONING && next_lcs == BL_STORAGE_LCS_SECURED) {
459 return bl_storage_lcs_set((uint32_t)&BL_STORAGE->lcs.secure, STATE_ENTERED);
460 }
461
462 if (current_lcs == BL_STORAGE_LCS_SECURED && next_lcs == BL_STORAGE_LCS_DECOMMISSIONED) {
463 return bl_storage_lcs_set((uint32_t)&BL_STORAGE->lcs.decommissioned, STATE_ENTERED);
464 }
465
466 /* This will be the case if any invalid transition is tried */
467 return -EINVALIDLCS;
468}
469
472#ifdef __cplusplus
473}
474#endif
475
476#endif /* BL_STORAGE_H_ */
#define SB_PUBLIC_KEY_HASH_LEN
Definition bl_storage.h:45
#define EREADLCS
Definition bl_storage.h:41
#define BL_STORAGE
Definition bl_storage.h:130
#define EINVALIDLCS
Definition bl_storage.h:42
int get_counter(uint16_t counter_desc, counter_t *counter_value, const counter_t **free_slot)
const struct monotonic_counter * get_counter_struct(uint16_t description)
#define BL_STORAGE_IMPLEMENTATION_ID_SIZE
Definition bl_storage.h:133
void bl_storage_counter_set(uint32_t address, counter_t value)
Definition bl_storage.h:310
int set_monotonic_counter(uint16_t counter_desc, counter_t new_counter)
Set the current HW monotonic counter.
lcs_data_t bl_storage_lcs_get(uint32_t address)
Definition bl_storage.h:356
uint32_t bl_storage_word_read(uint32_t address)
Definition bl_storage.h:319
#define STATE_ENTERED
Definition bl_storage.h:285
int get_monotonic_counter(uint16_t counter_desc, counter_t *counter_value)
Get the current HW monotonic counter.
int verify_public_keys(void)
Function for reading number of public key data slots.
uint32_t s0_address_read(void)
Function for reading address of slot 0.
uint32_t num_public_keys_read(void)
Function for reading number of public key data slots.
#define STATE_NOT_ENTERED
Definition bl_storage.h:286
void otp_copy32(uint8_t *restrict dst, uint32_t volatile *restrict src, size_t size)
Definition bl_storage.h:253
int read_life_cycle_state(enum lcs *lcs)
Read the current life cycle state the device is in from OTP,.
Definition bl_storage.h:383
void invalidate_public_key(uint32_t key_idx)
Function for invalidating a public key.
uint32_t bl_storage_word_write(uint32_t address, uint32_t value)
Definition bl_storage.h:328
int num_monotonic_counter_slots(uint16_t counter_desc, uint16_t *counter_slots)
Get the number of monotonic counter slots.
int update_life_cycle_state(enum lcs next_lcs)
Update the life cycle state in OTP.
Definition bl_storage.h:429
int public_key_data_read(uint32_t key_idx, uint8_t *p_buf)
Function for reading public key hashes.
int bl_storage_lcs_set(uint32_t address, lcs_data_t state)
Definition bl_storage.h:365
uint32_t s1_address_read(void)
Function for reading address of slot 1.
uint16_t bl_storage_otp_halfword_read(uint32_t address)
Definition bl_storage.h:339
void read_implementation_id_from_otp(uint8_t *buf)
Definition bl_storage.h:270
lcs
The PSA life cycle states a device can be in.
Definition bl_storage.h:237
@ BL_STORAGE_LCS_DECOMMISSIONED
Definition bl_storage.h:242
@ BL_STORAGE_LCS_UNKNOWN
Definition bl_storage.h:238
@ BL_STORAGE_LCS_ASSEMBLY
Definition bl_storage.h:239
@ BL_STORAGE_LCS_PROVISIONING
Definition bl_storage.h:240
@ BL_STORAGE_LCS_SECURED
Definition bl_storage.h:241
counter_t bl_storage_counter_get(uint32_t address)
Definition bl_storage.h:301
uint32_t num_public_keys
Definition bl_storage.h:123
struct bl_storage_data::@151 key_data[1]
uint8_t implementation_id[32]
Definition bl_storage.h:120
uint32_t valid
Definition bl_storage.h:125
uint32_t s0_address
Definition bl_storage.h:121
uint32_t s1_address
Definition bl_storage.h:122
Definition bl_storage.h:117
uint16_t num_counters
Definition bl_storage.h:101
uint16_t type
Definition bl_storage.h:100
struct monotonic_counter counters[1]
Definition bl_storage.h:102
Definition bl_storage.h:99
lcs_reserved_t reserved_for_padding
Definition bl_storage.h:74
lcs_data_t secure
Definition bl_storage.h:68
lcs_data_t provisioning
Definition bl_storage.h:67
lcs_data_t decommissioned
Definition bl_storage.h:75
Definition bl_storage.h:66
counter_t counter_slots[1]
Definition bl_storage.h:91
uint16_t num_counter_slots
Definition bl_storage.h:90
uint16_t description
Definition bl_storage.h:88
Definition bl_storage.h:84
enum state_type state