ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
key_import_internal.h File Reference

Secure-side sealed key import + opaque handle vending. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_err.h"
Include dependency graph for key_import_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ra8_key_import_limits_t : uint16_t {
  k_ra8_key_import_blob_bytes = 48U ,
  k_ra8_key_import_mac_bytes = 16U ,
  k_ra8_key_import_key_bytes = 32U ,
  k_ra8_key_import_handle_zero = 0U
}
 Sizing constants exposed to NS callers via the veneer. More...

Functions

ra8_err_t priv_ra8_key_import_reset (void)
 Reset the import table (drops every handle) and re-seed the salt.
ra8_err_t priv_ra8_key_import_seal (const uint8_t *blob, uint32_t blob_len, uint32_t *out_handle)
 Validate a sealed blob and import the key into a free slot.
ra8_err_t priv_ra8_key_import_resolve (uint32_t handle, uint16_t *out_slot)
 Resolve a handle to the underlying slot index.
ra8_err_t priv_ra8_key_import_build_blob (const uint8_t *material, uint8_t *out_blob)
 Build a sealed blob from a raw key (provisioning + test helper).

Detailed Description

Secure-side sealed key import + opaque handle vending.

Tag
[Ring 5 / SECAPP] {World: S}

Layered on top of key_vault.h. Where ra8_key_vault_store is a privileged secure-only API for one-time provisioning of a 32-byte symmetric key into an in-memory slot, the ra8_key_import_* API is the bridge that lets Non-Secure code request a sealed import and then refer to the key only by an opaque handle whose value has no relation to the slot index or the key bytes.

The model:

  • NS code holds a "sealed" blob (key bytes plus a 128-bit CMAC).
  • It hands the blob to the secure side via the ra8_nsc_key_import veneer.
  • The secure side validates the CMAC, picks the next free slot, stores the key, and returns a 32-bit handle derived from the slot index and a per-boot salt.
  • Subsequent NS calls (challenge/response) reference the handle; the secure side translates handle->slot internally.

The sealing MAC is AES-CMAC (NIST SP 800-38B) over the 32 key bytes, keyed by the key-authentication key (KAK) the vault holds (ra8_key_vault_load_mac_key) – a secret the Non-Secure world can never reach. The CMAC itself is computed through the ra8_sec_cmac_* seam. That seam resolves to the KAT-pinned in-tree AES-CMAC reference in EVERY build, firmware and host alike; its TF-PSA-Crypto psa_mac_* backend is compiled by nothing (#619). A forged blob therefore requires recovering the KAK, not merely replaying a trivial fold.

Definition in file key_import_internal.h.

Enumeration Type Documentation

◆ ra8_key_import_limits_t

enum ra8_key_import_limits_t : uint16_t

Sizing constants exposed to NS callers via the veneer.

Enumerator
k_ra8_key_import_blob_bytes 

32-byte key + 16-byte CMAC.

k_ra8_key_import_mac_bytes 

Trailing AES-CMAC tag length.

k_ra8_key_import_key_bytes 

Key portion length.

k_ra8_key_import_handle_zero 

Reserved invalid-handle sentinel.

Definition at line 57 of file key_import_internal.h.

Function Documentation

◆ priv_ra8_key_import_build_blob()

ra8_err_t priv_ra8_key_import_build_blob ( const uint8_t * material,
uint8_t * out_blob )
nodiscard

Build a sealed blob from a raw key (provisioning + test helper).

Computes the AES-CMAC over material using the vault KAK and writes [key | cmac] to out_blob. Secure-side provisioning code uses this to package a key just before passing it through the import API. Tests use it to drive the happy path.

Parameters
[in]material32-byte key material to seal.
[out]out_blobDestination of k_ra8_key_import_blob_bytes.
Returns
ra8_err_t error code.
Return values
k_ra8_okBlob built.
k_ra8_err_null_ptrmaterial or out_blob was NULL.
k_ra8_err_not_foundNo KAK provisioned in the vault.
Precondition
Both pointers non-NULL.
A KAK was provisioned via ra8_key_vault_set_mac_key.
Postcondition
out_blob carries a blob that priv_ra8_key_import_seal will accept while the KAK is unchanged.
Note
Thread safety: not thread-safe.
Since
0.1.0

Build a sealed blob from a raw key (provisioning + test helper).

Copies the key bytes verbatim, computes the AES-CMAC over them with the vault KAK via priv_ra8_sec_cmac_compute, and writes the trailing k_ra8_key_import_mac_bytes of the blob. Provided so provisioning and unit tests can package a key the import path will accept.

Parameters
[in]materialRaw 32-byte key material.
[out]out_blobReceives k_ra8_key_import_blob_bytes of output.
Returns
ra8_err_t error code.
Return values
k_ra8_okBlob written.
k_ra8_err_null_ptrmaterial or out_blob was NULL.
k_ra8_err_not_foundNo KAK provisioned in the vault.
Precondition
material and out_blob are non-NULL.
A KAK was provisioned via ra8_key_vault_set_mac_key.
Postcondition
On success out_blob is accepted by internal_verify_cmac under the current KAK.
No global state is mutated.
Note
Not thread-safe.
See also
priv_ra8_key_import_seal
Since
0.1.0

Definition at line 369 of file key_import.c.

References k_ra8_key_import_key_bytes, k_ra8_key_vault_mac_key_bytes, k_ra8_ok, priv_ra8_sec_cmac_compute(), RA8_CHECK_NULL_PTR, ra8_key_vault_load_mac_key(), ra8_secure_memzero(), and s_tag.

◆ priv_ra8_key_import_reset()

ra8_err_t priv_ra8_key_import_reset ( void )
nodiscard

Reset the import table (drops every handle) and re-seed the salt.

Returns
ra8_err_t error code (currently always k_ra8_ok).
Precondition
Called from the secure boot path before any veneer can fire.
Postcondition
Every previously vended handle now resolves to no slot.
The per-boot salt has been refreshed.
Note
Thread safety: secure-world only, single-threaded init.
Since
0.1.0

Reset the import table (drops every handle) and re-seed the salt.

Clears every s_slot_used bit and rotates the salt with a fixed mixing constant so successive resets vend different handles for the same slot index. Falls back to the boot seed if the rerolled salt happens to be zero.

Returns
ra8_err_t error code.
Return values
k_ra8_okAlways; the operation cannot fail.
Precondition
Caller is in the secure-side init context.
No NS-side handle issued before the call may be considered live afterwards.
Postcondition
All slots are marked free.
s_salt is non-zero.
Note
Not thread-safe; reset belongs to the boot/test path.
Since
0.1.0

Definition at line 224 of file key_import.c.

References internal_rotate_left_32(), k_initial_salt, k_ra8_ok, k_salt_reroll_rot, k_salt_reroll_xor, s_salt, and s_slot_used.

◆ priv_ra8_key_import_resolve()

ra8_err_t priv_ra8_key_import_resolve ( uint32_t handle,
uint16_t * out_slot )
nodiscard

Resolve a handle to the underlying slot index.

Parameters
[in]handleHandle previously returned from priv_ra8_key_import_seal.
[out]out_slotSlot index 0..k_ra8_key_vault_slots-1 on success.
Returns
ra8_err_t error code.
Return values
k_ra8_okSlot returned.
k_ra8_err_null_ptrout_slot was NULL.
k_ra8_err_not_foundHandle does not refer to a live import.
Precondition
out_slot non-NULL.
Postcondition
On success *out_slot < k_ra8_key_vault_slots.
Note
Thread safety: not thread-safe.
Since
0.1.0

Resolve a handle to the underlying slot index.

Walks the live slot bitmap and recomputes the per-slot handle until a match is found. The slot index never leaves the secure world via the handle itself; this function is the only place that performs the inverse mapping.

Parameters
[in]handleOpaque handle previously returned by priv_ra8_key_import_seal.
[out]out_slotReceives the resolved slot index on success.
Returns
ra8_err_t error code.
Return values
k_ra8_okHandle matched a live slot.
k_ra8_err_null_ptrout_slot was NULL.
k_ra8_err_not_foundHandle does not match any live slot.
Precondition
out_slot is non-NULL.
Caller has previously issued the handle through priv_ra8_key_import_seal.
Postcondition
On success, *out_slot is in [0, k_ra8_key_vault_slots).
No vault state is mutated.
Note
Not thread-safe.
See also
priv_ra8_key_import_seal
Since
0.1.0

Definition at line 329 of file key_import.c.

References internal_handle_for_slot(), k_ra8_err_not_found, k_ra8_key_vault_slots, k_ra8_ok, RA8_CHECK_NULL_PTR, s_slot_used, and s_tag.

◆ priv_ra8_key_import_seal()

ra8_err_t priv_ra8_key_import_seal ( const uint8_t * blob,
uint32_t blob_len,
uint32_t * out_handle )
nodiscard

Validate a sealed blob and import the key into a free slot.

Walks the sealed blob [key (32B) | cmac (16B)], verifies the AES-CMAC keyed by the vault KAK, and copies the key bytes into the next free slot via ra8_key_vault_store. The returned handle is an obfuscated form of the slot index that NS callers can use as the slot argument to subsequent veneer calls.

Parameters
[in]blobSealed blob (caller-owned secure copy).
[in]blob_lenMust equal k_ra8_key_import_blob_bytes.
[out]out_handleOpaque handle (non-zero on success).
Returns
ra8_err_t error code.
Return values
k_ra8_okKey imported, handle written.
k_ra8_err_null_ptrblob or out_handle was NULL.
k_ra8_err_invalid_sizeblob_len mismatched.
k_ra8_err_invalid_argCMAC verification failed.
k_ra8_err_not_foundNo KAK provisioned in the vault.
k_ra8_err_no_memEvery slot already occupied.
Precondition
Called from secure world (or via the NSC veneer).
A KAK was provisioned via ra8_key_vault_set_mac_key.
blob points to blob_len bytes of secure scratch (the veneer copies from NS before calling this function).
Postcondition
On success *out_handle != k_ra8_key_import_handle_zero.
On failure the import table is unchanged.
Note
Thread safety: not thread-safe; the slot bitmap is a single static.
Since
0.1.0

Validate a sealed blob and import the key into a free slot.

Validates the blob length, checks the AES-CMAC, allocates the lowest free vault slot, copies the key into the vault, and returns an opaque handle that the NS world can later present to the SHA-256 challenge primitive without ever learning the slot index.

Parameters
[in]blobSealed key blob.
[in]blob_lenLength of blob; must equal k_ra8_key_import_blob_bytes.
[out]out_handleReceives the opaque handle on success.
Returns
ra8_err_t error code.
Return values
k_ra8_okKey sealed and handle issued.
k_ra8_err_null_ptrblob or out_handle was NULL.
k_ra8_err_invalid_sizeblob_len did not match expected size.
k_ra8_err_invalid_argCMAC verification failed.
k_ra8_err_not_foundNo KAK provisioned in the vault.
k_ra8_err_no_memAll vault slots are in use.
Precondition
blob and out_handle are non-NULL.
A KAK was provisioned via ra8_key_vault_set_mac_key.
Postcondition
On success, the chosen slot bit is set in s_slot_used.
On error, no vault slot is mutated.
Note
Not thread-safe; secure-side serial dispatch only.
See also
priv_ra8_key_import_resolve
Since
0.1.0

Definition at line 268 of file key_import.c.

References internal_handle_for_slot(), internal_verify_cmac(), k_ra8_err_invalid_size, k_ra8_err_no_mem, k_ra8_key_import_blob_bytes, k_ra8_key_vault_slots, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_key_vault_store(), s_slot_used, and s_tag.