Bootloader crypto
The bootloader crypto library is the cryptography library that is used by the nRF Secure Immutable Bootloader.
The API is public because applications that are booted by the immutable bootloader can call functions from this library using the bootloader’s code, through external APIs. See External APIs for more information.
The library provides the following functionality:
SHA256 hashing
SECP256R1 signature validation
Root-of-trust firmware validation, which is the function the bootloader uses to validate a firmware’s signature and digest, using the SHA256 and SECP256R1 algorithms
These functions are available as separate external APIs. The API can be used the same way regardless of which backend is used.
Backends
When using the library, you can choose between the following backends:
Hardware backend nrf_cc310_bl crypto library (can only be used if Arm CryptoCell CC310 is available)
Software backend nrf_oberon crypto library
Another image’s instance of the bootloader crypto library, called through external APIs. The other image chooses its own backend.
To configure which backend is used for hashing, set one of the following configuration options:
To configure which backend is used for firmware verification, set one of the following configuration options:
API documentation
include/bl_crypto.h
subsys/bootloader/bl_crypto/
and subsys/bootloader/bl_crypto_client/
- group bl_crypto
-
Typedefs
-
typedef uint32_t bl_sha256_ctx_t[256 / 4]
-
typedef int (*bl_root_of_trust_verify_t)(const uint8_t *public_key, const uint8_t *public_key_hash, const uint8_t *signature, const uint8_t *firmware, const uint32_t firmware_len)
-
typedef int (*bl_sha256_init_t)(bl_sha256_ctx_t *ctx)
-
typedef int (*bl_sha256_update_t)(bl_sha256_ctx_t *ctx, const uint8_t *data, uint32_t data_len)
-
typedef int (*bl_sha256_finalize_t)(bl_sha256_ctx_t *ctx, uint8_t *output)
-
typedef int (*bl_sha256_verify_t)(const uint8_t *data, uint32_t data_len, const uint8_t *expected)
-
typedef int (*bl_secp256r1_validate_t)(const uint8_t *hash, uint32_t hash_len, const uint8_t *signature, const uint8_t *public_key)
Functions
-
int bl_crypto_init(void)
Initialize bootloader crypto module.
- Return values:
0 – On success.
-EFAULT – If crypto module reported an error.
-
int bl_root_of_trust_verify(const uint8_t *public_key, const uint8_t *public_key_hash, const uint8_t *signature, const uint8_t *firmware, const uint32_t firmware_len)
Verify a signature using configured signature and SHA-256.
Verifies the public key against the public key hash, then verifies the hash of the signed data against the signature using the public key.
Remark
No parameter can be NULL.
- Parameters:
public_key – [in] Public key.
public_key_hash – [in] Expected hash of the public key. This is the root of trust.
signature – [in] Firmware signature.
firmware – [in] Firmware.
firmware_len – [in] Length of firmware.
- Return values:
0 – On success.
-EHASHINV – If public_key_hash didn’t match public_key.
-ESIGINV – If signature validation failed.
- Returns:
Any error code from bl_sha256_init, bl_sha256_update, bl_sha256_finalize, or bl_secp256r1_validate if something else went wrong.
-
int bl_root_of_trust_verify_external(const uint8_t *public_key, const uint8_t *public_key_hash, const uint8_t *signature, const uint8_t *firmware, const uint32_t firmware_len)
Implementation of rot_verify that is safe to be called from EXT_API.
See bl_root_of_trust_verify for docs.
-
int bl_sha256_init(bl_sha256_ctx_t *ctx)
Initialize a sha256 operation context variable.
- Parameters:
ctx – [out] Context to be initialized.
- Return values:
0 – On success.
-EINVAL – If
ctx
was NULL.
-
int bl_sha256_update(bl_sha256_ctx_t *ctx, const uint8_t *data, uint32_t data_len)
Hash a portion of data.
Note
ctx
must be initialized before being used in this function. An uninitializedctx
might not be reported as an error. Also,ctx
must not be used if it has been finalized, though this might also not be reported as an error.- Parameters:
ctx – [in] Context variable. Must have been initialized.
data – [in] Data to hash.
data_len – [in] Length of
data
.
- Return values:
0 – On success.
-EINVAL – If
ctx
was NULL, uninitialized, or corrupted.-ENOSYS – If the context has already been finalized.
-
int bl_sha256_finalize(bl_sha256_ctx_t *ctx, uint8_t *output)
Finalize a hash result.
- Parameters:
ctx – [in] Context variable.
output – [out] Where to put the resulting digest. Must be at least 32 bytes long.
- Return values:
0 – On success.
-EINVAL – If
ctx
was NULL or corrupted, oroutput
was NULL.
-
int bl_sha256_verify(const uint8_t *data, uint32_t data_len, const uint8_t *expected)
Calculate a digest and verify it directly.
- Parameters:
data – [in] The data to hash.
data_len – [in] The length of
data
.expected – [in] The expected digest over
data
.
- Return values:
0 – If the procedure succeeded and the resulting digest is identical to
expected
.-EHASHINV – If the procedure succeeded, but the digests don’t match.
- Returns:
Any error code from bl_sha256_init, bl_sha256_update, or bl_sha256_finalize if something else went wrong.
-
int bl_secp256r1_validate(const uint8_t *hash, uint32_t hash_len, const uint8_t *signature, const uint8_t *public_key)
Validate a secp256r1 signature.
- Parameters:
hash – [in] The hash to validate against.
hash_len – [in] The length of the hash.
signature – [in] The signature to validate.
public_key – [in] The public key to validate with.
- Return values:
0 – The operation succeeded and the signature is valid for the hash.
-EINVAL – A parameter was NULL, or the
hash_len
was not 32 bytes.-ESIGINV – The signature validation failed.
-
struct bl_rot_verify_ext_api
- #include <bl_crypto.h>
Structure describing the BL_ROT_VERIFY EXT_API.
-
struct bl_sha256_ext_api
- #include <bl_crypto.h>
Structure describing the BL_SHA256 EXT_API.
-
struct bl_secp256r1_ext_api
- #include <bl_crypto.h>
Structure describing the BL_SECP256R1 EXT_API.
-
typedef uint32_t bl_sha256_ctx_t[256 / 4]