Bootloader storage
The bootloader storage library is used to read and write both one-time programmable (OTP) data and a non-volatile counter.
If the nRF Secure Immutable Bootloader (NSIB) is enabled, it should be the only user of this library. The application image can only include this library when the NSIB is disabled.
The library has the following functions for either reading or writing, or in some cases both reading and writing:
The lifecycle state of the device, used to deny certain operations when in wrong lifecycle state.
A 32-byte user-defined implementation ID, used to identify the immutable bootloader.
Image slot addresses.
A monotonic counter, used to enforce anti-rollback protection.
Hashes of public keys.
Invalidation tokens, used to revoke public keys.
Additional public key metadata.
The library uses either the OTP region of the user information configuration registers (UICR), when present on nRF91 Series or nRF5340 devices, or the internal flash memory. When the library uses the internal flash memory, the bootloader blocks the write access before booting the next image.
See Provisioning for more information about the provisioned data and how the bootloader uses it.
See tests/subsys/bootloader/bl_storage/
for tests of the library.
API documentation
include/bl_storage.h
subsys/bootloader/bl_storage/
- group bl_storage
-
Enums
-
enum lcs
The PSA life cycle states a device can be in.
The LCS can be only transitioned in the order they are defined here.
Values:
-
enumerator BL_STORAGE_LCS_UNKNOWN
-
enumerator BL_STORAGE_LCS_ASSEMBLY
-
enumerator BL_STORAGE_LCS_PROVISIONING
-
enumerator BL_STORAGE_LCS_SECURED
-
enumerator BL_STORAGE_LCS_DECOMMISSIONED
-
enumerator BL_STORAGE_LCS_UNKNOWN
Functions
-
uint32_t s0_address_read(void)
Function for reading address of slot 0.
- Returns:
Address of slot 0.
-
uint32_t s1_address_read(void)
Function for reading address of slot 1.
- Returns:
Address of slot 1.
-
uint32_t num_public_keys_read(void)
Function for reading number of public key data slots.
- Returns:
Number of public key data slots.
-
int verify_public_keys(void)
Function for reading number of public key data slots.
- Return values:
0 – if all keys are ok.
-EHASHFF – if one or more keys contains an aligned 0xFFFF.
-
int public_key_data_read(uint32_t key_idx, uint8_t *p_buf)
Function for reading public key hashes.
- Parameters:
key_idx – [in] Index of key.
p_buf – [out] Pointer to where the hash will be written. The buffer must be at least SB_PUBLIC_KEY_HASH_LEN bytes large.
- Return values:
-EINVAL – Key has been invalidated.
-EFAULT – key_idx is too large. There is no key with that index.
- Returns:
Number of successfully written bytes to p_buf.
-
void invalidate_public_key(uint32_t key_idx)
Function for invalidating a public key.
The public key will no longer be returned by public_key_data_read.
- Parameters:
key_idx – [in] Index of key.
-
int num_monotonic_counter_slots(uint16_t counter_desc, uint16_t *counter_slots)
Get the number of monotonic counter slots.
- Parameters:
counter_desc – [in] Counter description.
counter_slots – [out] Number of slots occupied by the counter.
- Return values:
0 – Success
-EINVAL – Cannot find counters with description
counter_desc
or the pointer tocounter_slots
is NULL.
-
int get_monotonic_counter(uint16_t counter_desc, uint16_t *counter_value)
Get the current HW monotonic counter.
- Parameters:
counter_desc – [in] Counter description.
counter_value – [out] The value of the current counter.
- Return values:
0 – Success
-EINVAL – Cannot find counters with description
counter_desc
or the pointer tocounter_value
is NULL.
-
int set_monotonic_counter(uint16_t counter_desc, uint16_t new_counter)
Set the current HW monotonic counter.
Note
FYI for users looking at the values directly in flash: Values are stored with their bits flipped. This is to squeeze one more value out of the counter.
- Parameters:
counter_desc – [in] Counter description.
new_counter – [in] The new counter value. Must be larger than the current value.
- Return values:
0 – The counter was updated successfully.
-EINVAL –
new_counter
is invalid (must be larger than current counter, and cannot be 0xFFFF).-ENOMEM – There are no more free counter slots (see
CONFIG_SB_NUM_VER_COUNTER_SLOTS
).
-
void otp_copy32(uint8_t *restrict dst, uint32_t volatile *restrict src, size_t size)
Copies
src
intodst
. Reads fromsrc
are done 32 bits at a time. Writes todst
are done a byte at a time.- Parameters:
dst – [out] destination buffer.
src – [in] source buffer in OTP. Must be 4-byte-aligned.
size – [in] number of bytes in src to copy into dst. Must be divisible by 4.
-
void read_implementation_id_from_otp(uint8_t *buf)
Read the implementation id from OTP and copy it into a given buffer.
- Parameters:
buf – [out] Buffer that has at least BL_STORAGE_IMPLEMENTATION_ID_SIZE bytes
-
enum lcs