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

Decryption On The Fly (DOTF) HAL driver implementation. More...

#include "ra8_dotf.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_dotf_regs.h"
#include "ra8_err.h"
#include "ra8_hw_err.h"
#include "ra8_log.h"
#include "ra8_mstp.h"
Include dependency graph for ra8_dotf.c:

Go to the source code of this file.

Data Structures

struct  ra8_dotf_chan_state_t
 Per-channel software state. More...

Enumerations

enum  ra8_dotf_misc_t : uint8_t {
  k_ra8_dotf_no_region = 0xFFU ,
  k_ra8_dotf_self_test_spin = 8U
}
 Internal small constants (no magic numbers). More...
enum  ra8_dotf_bswap_const_t : uint32_t {
  k_ra8_dotf_bswap_byte_mask = 0xFFUL ,
  k_ra8_dotf_bswap_byte0 = 0x000000FFUL ,
  k_ra8_dotf_bswap_byte1 = 0x0000FF00UL ,
  k_ra8_dotf_bswap_byte2 = 0x00FF0000UL ,
  k_ra8_dotf_bswap_byte3 = 0xFF000000UL
}
 Byte-extraction masks and shift counts for internal_bswap32. More...
enum  ra8_dotf_bswap_shift_t : uint8_t {
  k_ra8_dotf_bswap_shift_byte = 8U ,
  k_ra8_dotf_bswap_shift_word = 24U
}
 Shift counts used by internal_bswap32. More...
enum  ra8_dotf_key_word_count_t : uint8_t {
  k_ra8_dotf_key_words_128 = 4U ,
  k_ra8_dotf_key_words_192 = 6U ,
  k_ra8_dotf_key_words_256 = 8U
}
 Wrapped-key word counts per AES key size. More...

Functions

static bool internal_channel_in_range (uint8_t channel)
 Bound-check a channel index.
static uint32_t internal_window_lo (uint8_t channel)
 XSPI window low bound for a given DOTF channel.
static uint32_t internal_window_hi (uint8_t channel)
 XSPI window high bound for a given DOTF channel.
static uint8_t internal_key_words (ra8_dotf_key_size_t size)
 Word count for a given AES key size.
static uint32_t internal_sca_bits (ra8_dotf_sca_level_t level)
 Map an SCA level enum into REG00 SCA bits.
static uint32_t internal_bswap32 (uint32_t v)
 Big-endian byte-swap of a 32-bit word.
static ra8_err_t internal_validate_region (uint8_t channel, const ra8_dotf_region_t *region)
 Validate region range / alignment / window.
static ra8_err_t internal_check_overlap (uint8_t channel, const ra8_dotf_region_t *region)
 Reject a region that overlaps the live region of the OTHER channel.
static uint32_t internal_assemble_reg00 (const ra8_dotf_chan_state_t *st, bool enable)
 Assemble the REG00 word for the channel's cached state.
static void internal_stage_key (volatile ra8_dotf_regs_t *reg, const ra8_dotf_key_handle_t *h)
 Stage a wrapped-key payload into REG03.
static void internal_stage_iv (volatile ra8_dotf_regs_t *reg, const uint32_t *iv)
 Stage 4 IV words into REG03 in big-endian order.
static void internal_channel_reset (volatile ra8_dotf_regs_t *reg)
 Reset one channel's hardware to power-on state.
static void internal_state_reset (uint8_t channel)
 Wipe all software state for one channel.
ra8_err_t ra8_dotf_init (void)
 Power on the DOTF block and reset both channels.
ra8_err_t ra8_dotf_deinit (void)
 Disable DOTF and gate the OSPI clock.
ra8_err_t ra8_dotf_set_region (uint8_t channel, const ra8_dotf_region_t *region)
 Stage one DOTF region in the channel's region table.
ra8_err_t ra8_dotf_select_region (uint8_t channel, uint8_t region_id)
 Promote a staged region into the live CONVAREAST / CONVAREAD pair.
ra8_err_t ra8_dotf_get_active_region (uint8_t channel, ra8_dotf_region_t *region)
 Read back the active region for a channel.
ra8_err_t ra8_dotf_install_key (uint8_t channel, const ra8_dotf_key_handle_t *handle)
 Bind a wrapped AES key handle to a DOTF channel.
ra8_err_t ra8_dotf_set_iv (uint8_t channel, const uint32_t *iv_words)
 Stage the AES counter-mode IV for a channel via REG03.
static void internal_rotate_iv (ra8_dotf_chan_state_t *st, volatile ra8_dotf_regs_t *reg, const uint32_t *iv_words)
 Re-stage the IV for a rotate-key call.
static ra8_err_t internal_validate_rotate_inputs (uint8_t channel, const ra8_dotf_key_handle_t *new_handle)
 Validate the inputs to ra8_dotf_rotate_key.
ra8_err_t ra8_dotf_rotate_key (uint8_t channel, const ra8_dotf_key_handle_t *new_handle, const uint32_t *iv_words)
 Atomically rotate the key bound to a channel.
ra8_err_t ra8_dotf_enable (uint8_t channel)
 Enable AES decryption for one channel.
ra8_err_t ra8_dotf_disable (uint8_t channel)
 Disable AES decryption for one channel (transparent bypass).
ra8_err_t ra8_dotf_set_sca_level (uint8_t channel, ra8_dotf_sca_level_t level)
 Update the side-channel countermeasure level for a channel.
ra8_err_t ra8_dotf_set_key_size (uint8_t channel, ra8_dotf_key_size_t size)
 Update the cached AES key size for a channel.
ra8_err_t ra8_dotf_run_self_test (uint8_t channel, uint32_t *out_status)
 Trigger the built-in self-test (REG00 bit 20) for a channel.
ra8_err_t ra8_dotf_get_status (uint8_t channel, uint32_t *out_mask)
 Read REG00 (raw control / status snapshot).
ra8_err_t ra8_dotf_clear_status (uint8_t channel)
 Clear REG00 (force the channel into bypass).
ra8_err_t ra8_dotf_attach_handler (ra8_dotf_event_fn_t fn, void *ctx)
 Register a fault / event callback (shared across both channels).
void ra8_dotf_dispatch (uint8_t channel)
 Dispatch a DOTF event from the IRQ glue.

Variables

static const char * s_tag = "DOTF"
 Logging tag for ra8_log_* calls.
static ra8_dotf_event_fn_t s_dotf_fn
 Active fault / event callback.
static void * s_dotf_ctx
 Caller-supplied context handed to s_dotf_fn.
static ra8_dotf_chan_state_t s_dotf_state [k_ra8_dotf_channel_count]
 Per-channel state table.
static const ra8_mstp_t s_dotf_mstp_table [k_ra8_dotf_channel_count]
 Channel-index -> MSTP id lookup.

Detailed Description

Decryption On The Fly (DOTF) HAL driver implementation.

Tag
[Ring 3 / HAL] {World: S}

Full HUM Ch 45 (p 3048..3050) coverage of the RA8D2 DOTF block. Layered on top of the OSPI MSTP gating; every register access carries a HUM Ch 45 citation. See ra8_dotf.h for the public surface.

Driver-side state:

  • per-channel staging table of up to k_ra8_dotf_max_regions region descriptors (multi-region support);
  • per-channel cache of the active region id (or "none");
  • per-channel REG00 cache (key size, SCA level, enable bit) so that ra8_dotf_set_sca_level / ra8_dotf_set_key_size can update the live AES core in a single REG00 write;
  • per-channel bound key handle (RSIP-key-injection wiring);
  • per-channel IV cache so ra8_dotf_rotate_key can re-stage the same IV without forcing the caller to remember it;
  • shared callback slot for IRQ glue.

Definition in file ra8_dotf.c.

Enumeration Type Documentation

◆ ra8_dotf_bswap_const_t

enum ra8_dotf_bswap_const_t : uint32_t

Byte-extraction masks and shift counts for internal_bswap32.

REG03 of the OSPI / DOTF FIFO is big-endian; both the host build and the RA8D2 are little-endian, so we always swap. These named constants replace the magic numbers flagged by clang-tidy (readability-magic-numbers) and document each byte position.

Enumerator
k_ra8_dotf_bswap_byte_mask 

Per-byte mask used by all 4 lanes.

k_ra8_dotf_bswap_byte0 

Selects bits [7:0] (byte 0).

k_ra8_dotf_bswap_byte1 

Selects bits [15:8] (byte 1).

k_ra8_dotf_bswap_byte2 

Selects bits [23:16] (byte 2).

k_ra8_dotf_bswap_byte3 

Selects bits [31:24] (byte 3).

Definition at line 62 of file ra8_dotf.c.

◆ ra8_dotf_bswap_shift_t

enum ra8_dotf_bswap_shift_t : uint8_t

Shift counts used by internal_bswap32.

Enumerator
k_ra8_dotf_bswap_shift_byte 

Shift for one-byte slide.

k_ra8_dotf_bswap_shift_word 

Shift for byte0 <-> byte3.

Definition at line 74 of file ra8_dotf.c.

◆ ra8_dotf_key_word_count_t

enum ra8_dotf_key_word_count_t : uint8_t

Wrapped-key word counts per AES key size.

The wrapped-key payload bytes are a vendor-defined RSIP envelope; the FSP reference uses HW_SCE_AES{128,192,256}_KEY_INDEX_WORD_SIZE for the ratio. RA8D2 uses 4-word / 6-word / 8-word envelopes for the 128 / 192 / 256-bit keys respectively when staged through the OutputKeyForDotf paths (r_ospi_b.c).

Enumerator
k_ra8_dotf_key_words_128 

RA8 dotf key words 128.

k_ra8_dotf_key_words_192 

RA8 dotf key words 192.

k_ra8_dotf_key_words_256 

RA8 dotf key words 256.

Definition at line 90 of file ra8_dotf.c.

◆ ra8_dotf_misc_t

enum ra8_dotf_misc_t : uint8_t

Internal small constants (no magic numbers).

Enumerator
k_ra8_dotf_no_region 

Sentinel for "no region active".

k_ra8_dotf_self_test_spin 

Bounded poll budget for self-test bit.

Definition at line 47 of file ra8_dotf.c.

Function Documentation

◆ internal_assemble_reg00()

uint32_t internal_assemble_reg00 ( const ra8_dotf_chan_state_t * st,
bool enable )
static

Assemble the REG00 word for the channel's cached state.

See implementation.

Parameters
[in]stSee implementation.
[in]enableSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 395 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::cached_key_size, ra8_dotf_chan_state_t::cached_sca, internal_sca_bits(), k_ra8_dotf_reg00_aes_enable, and k_ra8_dotf_reg00_mode_ctr.

Referenced by ra8_dotf_enable(), ra8_dotf_rotate_key(), ra8_dotf_set_key_size(), and ra8_dotf_set_sca_level().

◆ internal_bswap32()

uint32_t internal_bswap32 ( uint32_t v)
inlinestatic

Big-endian byte-swap of a 32-bit word.

REG03 is a big-endian FIFO per the FSP reference (r_ospi_b.c uses bswap_32big / change_endian_long). The host build runs little-endian and the target Cortex-M85 also runs little- endian, so an explicit byte-swap is required either way.

Parameters
[in]vSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 293 of file ra8_dotf.c.

References k_ra8_dotf_bswap_byte0, k_ra8_dotf_bswap_byte1, k_ra8_dotf_bswap_byte2, k_ra8_dotf_bswap_byte3, k_ra8_dotf_bswap_shift_byte, and k_ra8_dotf_bswap_shift_word.

Referenced by internal_stage_iv(), and internal_stage_key().

◆ internal_channel_in_range()

bool internal_channel_in_range ( uint8_t channel)
inlinestatic

Bound-check a channel index.

Parameters
[in]channelCaller-provided channel value.
Returns
true if channel is in [0, k_ra8_dotf_channel_count).

See implementation.

Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 176 of file ra8_dotf.c.

References k_ra8_dotf_channel_count.

Referenced by internal_validate_rotate_inputs(), ra8_dotf_clear_status(), ra8_dotf_disable(), ra8_dotf_dispatch(), ra8_dotf_enable(), ra8_dotf_get_active_region(), ra8_dotf_get_status(), ra8_dotf_install_key(), ra8_dotf_run_self_test(), ra8_dotf_select_region(), ra8_dotf_set_iv(), ra8_dotf_set_key_size(), ra8_dotf_set_region(), and ra8_dotf_set_sca_level().

◆ internal_channel_reset()

void internal_channel_reset ( volatile ra8_dotf_regs_t * reg)
inlinestatic

Reset one channel's hardware to power-on state.

See implementation.

Parameters
[in]regSee implementation.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 469 of file ra8_dotf.c.

References ra8_dotf_regs_t::CONVAREAD, ra8_dotf_regs_t::CONVAREAST, k_ra8_dotf_reg00_disable_value, and ra8_dotf_regs_t::REG00.

Referenced by ra8_dotf_init().

◆ internal_check_overlap()

ra8_err_t internal_check_overlap ( uint8_t channel,
const ra8_dotf_region_t * region )
static

Reject a region that overlaps the live region of the OTHER channel.

See implementation.

Parameters
[in]channelSee implementation.
[in]regionSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 359 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::active_region_id, ra8_dotf_region_t::end_addr, k_ra8_dotf_channel_count, k_ra8_dotf_no_region, k_ra8_err_conflict, k_ra8_ok, ra8_dotf_chan_state_t::regions, s_dotf_state, and ra8_dotf_region_t::start_addr.

Referenced by ra8_dotf_set_region().

◆ internal_key_words()

uint8_t internal_key_words ( ra8_dotf_key_size_t size)
inlinestatic

Word count for a given AES key size.

See implementation.

Parameters
[in]sizeSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 236 of file ra8_dotf.c.

References k_ra8_dotf_key_size_192, k_ra8_dotf_key_size_256, k_ra8_dotf_key_words_128, k_ra8_dotf_key_words_192, and k_ra8_dotf_key_words_256.

Referenced by internal_stage_key().

◆ internal_rotate_iv()

void internal_rotate_iv ( ra8_dotf_chan_state_t * st,
volatile ra8_dotf_regs_t * reg,
const uint32_t * iv_words )
static

Re-stage the IV for a rotate-key call.

If the caller provided iv_words we cache them and push them through internal_stage_iv. If the caller passed nullptr but a previous IV is cached, re-stage that one. Otherwise leave the IV registers untouched. HUM Ch 45.3 "Register Descriptions" p 3049.

Parameters
[in,out]stChannel state slot.
[in]regMMIO base for the channel.
[in]iv_wordsOptional new IV word array.
Precondition
st and reg are non-null and refer to the same channel.
Postcondition
IV registers reflect the new IV when one was supplied or cached.
Note
Internal helper, not thread-safe.
Precondition
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Since
0.1.0

Definition at line 702 of file ra8_dotf.c.

References internal_stage_iv(), ra8_dotf_chan_state_t::iv_cache, ra8_dotf_chan_state_t::iv_valid, and k_ra8_dotf_iv_word_count.

Referenced by ra8_dotf_rotate_key().

◆ internal_sca_bits()

uint32_t internal_sca_bits ( ra8_dotf_sca_level_t level)
inlinestatic

Map an SCA level enum into REG00 SCA bits.

See implementation.

Parameters
[in]levelSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 262 of file ra8_dotf.c.

References k_ra8_dotf_reg00_sca_en, k_ra8_dotf_reg00_sca_mode, k_ra8_dotf_sca_max, and k_ra8_dotf_sca_standard.

Referenced by internal_assemble_reg00().

◆ internal_stage_iv()

void internal_stage_iv ( volatile ra8_dotf_regs_t * reg,
const uint32_t * iv )
static

Stage 4 IV words into REG03 in big-endian order.

See implementation.

Parameters
[in]regSee implementation.
[in]ivSee implementation.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 446 of file ra8_dotf.c.

References internal_bswap32(), k_ra8_dotf_iv_word_count, and ra8_dotf_regs_t::REG03.

Referenced by internal_rotate_iv(), and ra8_dotf_set_iv().

◆ internal_stage_key()

void internal_stage_key ( volatile ra8_dotf_regs_t * reg,
const ra8_dotf_key_handle_t * h )
static

Stage a wrapped-key payload into REG03.

See implementation.

Parameters
[in]regSee implementation.
[in]hSee implementation.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 420 of file ra8_dotf.c.

References internal_bswap32(), internal_key_words(), ra8_dotf_regs_t::REG03, ra8_dotf_key_handle_t::size, and ra8_dotf_key_handle_t::words.

Referenced by ra8_dotf_install_key(), and ra8_dotf_rotate_key().

◆ internal_state_reset()

void internal_state_reset ( uint8_t channel)
static

Wipe all software state for one channel.

See implementation.

Parameters
[in]channelSee implementation.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 493 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::active_region_id, ra8_dotf_chan_state_t::cached_key_size, ra8_dotf_chan_state_t::cached_sca, ra8_dotf_chan_state_t::enabled, ra8_dotf_region_t::end_addr, ra8_dotf_chan_state_t::iv_cache, ra8_dotf_chan_state_t::iv_valid, k_ra8_dotf_iv_word_count, k_ra8_dotf_key_size_128, k_ra8_dotf_max_regions, k_ra8_dotf_no_region, k_ra8_dotf_sca_standard, ra8_dotf_chan_state_t::key, ra8_dotf_key_handle_t::key_index, ra8_dotf_region_t::key_index, ra8_dotf_region_t::region_id, ra8_dotf_chan_state_t::region_valid, ra8_dotf_chan_state_t::regions, s_dotf_state, ra8_dotf_key_handle_t::size, ra8_dotf_region_t::start_addr, ra8_dotf_key_handle_t::valid, and ra8_dotf_key_handle_t::words.

Referenced by ra8_dotf_deinit(), and ra8_dotf_init().

◆ internal_validate_region()

ra8_err_t internal_validate_region ( uint8_t channel,
const ra8_dotf_region_t * region )
static

Validate region range / alignment / window.

See implementation.

Parameters
[in]channelSee implementation.
[in]regionSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 317 of file ra8_dotf.c.

References ra8_dotf_region_t::end_addr, internal_window_hi(), internal_window_lo(), k_ra8_dotf_addr_low_mask, k_ra8_dotf_max_regions, k_ra8_err_invalid_arg, k_ra8_ok, ra8_dotf_region_t::region_id, and ra8_dotf_region_t::start_addr.

Referenced by ra8_dotf_set_region().

◆ internal_validate_rotate_inputs()

ra8_err_t internal_validate_rotate_inputs ( uint8_t channel,
const ra8_dotf_key_handle_t * new_handle )
static

Validate the inputs to ra8_dotf_rotate_key.

Range-checks channel and the wrapped-key fields, and rejects calls that try to rotate before any region was activated. The check for new_handle != nullptr is the caller's responsibility.

Parameters
[in]channelChannel index.
[in]new_handleCaller-supplied wrapped key.
Returns
k_ra8_ok if all preconditions pass.
Return values
k_ra8_err_invalid_argchannel out of range or handle malformed.
k_ra8_err_invalid_statera8_dotf_install_region not yet called.
Precondition
new_handle is non-null.
Postcondition
No side effects.
Note
Internal helper, not thread-safe.
Precondition
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Since
0.1.0

Definition at line 744 of file ra8_dotf.c.

References internal_channel_in_range(), k_ra8_dotf_key_size_128, k_ra8_dotf_key_size_192, k_ra8_dotf_key_size_256, k_ra8_dotf_no_region, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, s_dotf_state, ra8_dotf_key_handle_t::size, and ra8_dotf_key_handle_t::valid.

Referenced by ra8_dotf_rotate_key().

◆ internal_window_hi()

uint32_t internal_window_hi ( uint8_t channel)
inlinestatic

XSPI window high bound for a given DOTF channel.

See implementation.

Parameters
[in]channelSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 216 of file ra8_dotf.c.

References k_ra8_dotf0_window_hi, and k_ra8_dotf1_window_hi.

Referenced by internal_validate_region().

◆ internal_window_lo()

uint32_t internal_window_lo ( uint8_t channel)
inlinestatic

XSPI window low bound for a given DOTF channel.

See implementation.

Parameters
[in]channelSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 196 of file ra8_dotf.c.

References k_ra8_dotf0_window_lo, and k_ra8_dotf1_window_lo.

Referenced by internal_validate_region().

◆ ra8_dotf_attach_handler()

ra8_err_t ra8_dotf_attach_handler ( ra8_dotf_event_fn_t fn,
void * ctx )
nodiscard

Register a fault / event callback (shared across both channels).

DOTF on its own does not raise an IRQ – faults surface through the matching xSPI controller's INTS register. The platform IRQ glue forwards the channel index to ra8_dotf_dispatch which fires this callback. Useful for telemetry on key-mismatch / illegal-region hits during bring-up.

Parameters
[in]fnCallback fired on dispatch.
[in]ctxContext forwarded to the callback.
Returns
ra8_err_t error code.
Precondition
Called with IRQs masked or before dispatch ever fires.
Postcondition
Subsequent dispatches will fire fn(ctx, channel).
Since
0.1.0

Definition at line 948 of file ra8_dotf.c.

References k_ra8_ok, s_dotf_ctx, and s_dotf_fn.

◆ ra8_dotf_clear_status()

ra8_err_t ra8_dotf_clear_status ( uint8_t channel)
nodiscard

Clear REG00 (force the channel into bypass).

Parameters
[in]channelChannel index 0..1.
Returns
ra8_err_t error code.
Precondition
channel is in range.
Postcondition
REG00 reads 0.
Since
0.1.0

Definition at line 928 of file ra8_dotf.c.

References internal_channel_in_range(), k_ra8_dotf_reg00_disable_value, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_dotf_regs_t::REG00, s_dotf_state, and s_tag.

◆ ra8_dotf_deinit()

ra8_err_t ra8_dotf_deinit ( void )
nodiscard

Disable DOTF and gate the OSPI clock.

Returns
ra8_err_t error code.
Precondition
IRQs masked or single-threaded teardown context.
Postcondition
Both DOTF channels are disabled and MSTPB16/17 are set.
Warning
Will also gate the matching XSPI controller – callers must have stopped all XiP traffic first.
Since
0.1.0

Definition at line 545 of file ra8_dotf.c.

References internal_state_reset(), k_ra8_dotf_channel_count, k_ra8_dotf_reg00_disable_value, k_ra8_ok, ra8_dotf_regs(), ra8_mstp_disable(), ra8_dotf_regs_t::REG00, s_dotf_ctx, s_dotf_fn, and s_dotf_mstp_table.

Referenced by ra8_dotf_close().

◆ ra8_dotf_disable()

ra8_err_t ra8_dotf_disable ( uint8_t channel)
nodiscard

Disable AES decryption for one channel (transparent bypass).

Parameters
[in]channelChannel index 0..1.
Returns
ra8_err_t error code.
Precondition
ra8_dotf_init has run.
Postcondition
REG00 reads 0 and the conversion area passes through.
Since
0.1.0

Definition at line 823 of file ra8_dotf.c.

References internal_channel_in_range(), k_ra8_dotf_reg00_disable_value, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_dotf_regs_t::REG00, s_dotf_state, and s_tag.

◆ ra8_dotf_dispatch()

void ra8_dotf_dispatch ( uint8_t channel)

Dispatch a DOTF event from the IRQ glue.

Parameters
[in]channelChannel index 0..1 that raised the event. Out of range channels are dropped silently.
Since
0.1.0

See implementation.

Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.

Definition at line 956 of file ra8_dotf.c.

References internal_channel_in_range(), s_dotf_ctx, and s_dotf_fn.

◆ ra8_dotf_enable()

ra8_err_t ra8_dotf_enable ( uint8_t channel)
nodiscard

Enable AES decryption for one channel.

Writes the cached REG00 word (default 0x2200_0000 ORed with the bound key-size bits, the SCA bits, and the enable bit). The channel must have a key staged and a region selected.

Parameters
[in]channelChannel index 0..1.
Returns
ra8_err_t error code.
Precondition
ra8_dotf_set_region + ra8_dotf_select_region have been called for channel.
ra8_dotf_install_key has been called for channel.
Postcondition
REG00 reflects the assembled key-size + SCA + enable pattern.
Subsequent reads in the conversion area go through the AES core.
Warning
If the conversion region overlaps live XiP code the CPU will fault on the next instruction fetch. Callers must ensure no fetches target the encrypted window until the key is in place.
Since
0.1.0

Definition at line 804 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::enabled, internal_assemble_reg00(), internal_channel_in_range(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_log_info_val, ra8_dotf_regs_t::REG00, s_dotf_state, and s_tag.

Referenced by internal_open_finalise().

◆ ra8_dotf_get_active_region()

ra8_err_t ra8_dotf_get_active_region ( uint8_t channel,
ra8_dotf_region_t * region )
nodiscard

Read back the active region for a channel.

Parameters
[in]channelChannel index 0..1.
[out]regionReceives a copy of the active descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okDescriptor returned.
k_ra8_err_null_ptrregion is NULL.
k_ra8_err_invalid_argChannel out of range.
k_ra8_err_invalid_stateNo region active on channel.
Precondition
region is non-NULL.
channel is in range.
Postcondition
On success *region holds the live region descriptor.
Hardware state is unchanged.
Since
0.1.0

Definition at line 618 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::active_region_id, internal_channel_in_range(), k_ra8_dotf_no_region, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_chan_state_t::regions, s_dotf_state, and s_tag.

◆ ra8_dotf_get_status()

ra8_err_t ra8_dotf_get_status ( uint8_t channel,
uint32_t * out_mask )
nodiscard

Read REG00 (raw control / status snapshot).

Parameters
[in]channelChannel index 0..1.
[out]out_maskReceives REG00 contents.
Returns
ra8_err_t error code.
Precondition
out_mask is non-NULL.
channel is in range.
Postcondition
On success, *out_mask reflects the live REG00 value.
Since
0.1.0

Definition at line 913 of file ra8_dotf.c.

References internal_channel_in_range(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_dotf_regs_t::REG00, and s_tag.

Referenced by internal_dotf_demo_sample().

◆ ra8_dotf_init()

ra8_err_t ra8_dotf_init ( void )
nodiscard

Power on the DOTF block and reset both channels.

Clears MSTPB16 (DOTF0 + XSPI0) and MSTPB17 (DOTF1 + XSPI1) via ra8_mstp_enable, then writes 0 to each channel's REG00 and clears CONVAREAST / CONVAREAD to their reset values. Also scrubs every staged region slot, the IV cache, and the bound key handles.

Returns
ra8_err_t error code.
Return values
k_ra8_okDOTF clocked and zeroed.
k_ra8_err_hw_init_failedMSTP enable failed for either id.
Precondition
IRQs masked or single-threaded init context.
ra8_mstp_init has been called.
Postcondition
Both DOTF channels are reachable but disabled.
REG00 of every channel reads 0.
Note
Thread safety: not thread-safe.
See also
ra8_dotf_set_region
ra8_dotf_enable
Since
0.1.0

Definition at line 524 of file ra8_dotf.c.

References internal_channel_reset(), internal_state_reset(), k_ra8_dotf_channel_count, k_ra8_err_hw_init_failed, k_ra8_ok, ra8_dotf_regs(), ra8_log_info, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, s_dotf_ctx, s_dotf_fn, s_dotf_mstp_table, and s_tag.

Referenced by internal_open_validate_init(), and main().

◆ ra8_dotf_install_key()

ra8_err_t ra8_dotf_install_key ( uint8_t channel,
const ra8_dotf_key_handle_t * handle )
nodiscard

Bind a wrapped AES key handle to a DOTF channel.

Copies the handle into the driver's per-channel slot and stages the wrapped-key payload into REG03 in big-endian word order. The channel is left disabled; the AES core only goes hot once ra8_dotf_enable (or ra8_dotf_rotate_key) is called. The HAL does not unwrap the key – that work belongs to ra8_rsip and runs before this call. The handle's size field is mirrored into the driver's REG00 cache so subsequent ra8_dotf_enable writes the correct key-size bits.

Parameters
[in]channelChannel index 0..1.
[in]handleNon-NULL handle. handle->valid must be non-0.
Returns
ra8_err_t error code.
Return values
k_ra8_okKey staged.
k_ra8_err_null_ptrhandle is NULL.
k_ra8_err_invalid_argChannel out of range or handle invalid.
Precondition
handle is non-NULL and handle->valid != 0.
ra8_dotf_init has run.
Postcondition
The channel's bound key handle equals *handle.
REG03 has been written words_for_size(handle->size) times.
Warning
Do NOT call this while the channel is enabled. Re-keying a live channel must go through ra8_dotf_rotate_key.
Since
0.1.0

Definition at line 637 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::cached_key_size, internal_channel_in_range(), internal_stage_key(), k_ra8_dotf_key_size_128, k_ra8_dotf_key_size_192, k_ra8_dotf_key_size_256, k_ra8_err_invalid_arg, k_ra8_ok, ra8_dotf_chan_state_t::key, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_log_info_val, s_dotf_state, s_tag, ra8_dotf_key_handle_t::size, and ra8_dotf_key_handle_t::valid.

Referenced by internal_open_stage_key_iv_region().

◆ ra8_dotf_rotate_key()

ra8_err_t ra8_dotf_rotate_key ( uint8_t channel,
const ra8_dotf_key_handle_t * new_handle,
const uint32_t * iv_words )
nodiscard

Atomically rotate the key bound to a channel.

Quiesces the channel (writes 0 to REG00), re-stages the new wrapped key + IV, then re-arms the AES core with the cached key- size and SCA settings. Used by the bootloader to swap signing keys during anti-rollback handling.

Sequence:

  1. Save current REG00 enable state.
  2. Write 0 to REG00 (disable AES).
  3. Replace the bound key handle.
  4. Re-stage the IV via REG03.
  5. Re-arm REG00 with the new key-size + SCA + enable bits.
Parameters
[in]channelChannel index 0..1.
[in]new_handleNon-NULL replacement key.
[in]iv_wordsk_ra8_dotf_iv_word_count words of new IV (or NULL to reuse the current IV).
Returns
ra8_err_t error code.
Return values
k_ra8_okRotation complete.
k_ra8_err_null_ptrnew_handle is NULL.
k_ra8_err_invalid_argChannel out of range or handle invalid.
k_ra8_err_invalid_stateNo region active on the channel.
Precondition
ra8_dotf_install_key was called at least once.
A region is currently armed (select_region ran).
Postcondition
The new key is in REG03, REG00 is re-armed with enable bit.
The active key handle reflects *new_handle.
Warning
Outstanding XiP fetches between step 2 and step 5 will observe garbage. Callers must temporarily steer instruction fetches away from the encrypted window (typically by jumping into SRAM) before invoking this.
Since
0.1.0

Definition at line 764 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::cached_key_size, ra8_dotf_chan_state_t::enabled, internal_assemble_reg00(), internal_rotate_iv(), internal_stage_key(), internal_validate_rotate_inputs(), k_ra8_dotf_reg00_disable_value, k_ra8_ok, ra8_dotf_chan_state_t::key, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_log_info_val, RA8_RETURN_ON_ERROR, ra8_dotf_regs_t::REG00, s_dotf_state, s_tag, and ra8_dotf_key_handle_t::size.

◆ ra8_dotf_run_self_test()

ra8_err_t ra8_dotf_run_self_test ( uint8_t channel,
uint32_t * out_status )
nodiscard

Trigger the built-in self-test (REG00 bit 20) for a channel.

HUM Ch 45.1 p 3048 ("Supports self-test function"). Sets bit 20 of REG00, polls for completion by re-reading REG00 a bounded number of times, and returns the post-test snapshot via out_status. The bit auto-clears in real hardware; in the fake the bit remains set after the spin (the host has no way to model AES timing) – callers MUST treat out_status as opaque diagnostic data, not a pass/fail indicator on the host.

Parameters
[in]channelChannel index 0..1.
[out]out_statusNon-NULL diagnostic snapshot.
Returns
ra8_err_t error code.
Return values
k_ra8_okSelf-test triggered.
k_ra8_err_null_ptrout_status is NULL.
k_ra8_err_invalid_argChannel out of range.
k_ra8_err_hw_timeoutSELF_TEST did not clear within the bounded wait.
Precondition
ra8_dotf_init has run.
Channel is currently disabled.
Postcondition
REG00 bit 20 was set at least once.
On return, REG00 has been restored to its pre-test value.
Since
0.1.0

Definition at line 883 of file ra8_dotf.c.

References internal_channel_in_range(), k_ra8_dotf_reg00_self_test, k_ra8_dotf_self_test_spin, k_ra8_err_invalid_arg, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_hw_wait_flag_clear32(), ra8_dotf_regs_t::REG00, and s_tag.

Referenced by internal_dotf_demo_sample().

◆ ra8_dotf_select_region()

ra8_err_t ra8_dotf_select_region ( uint8_t channel,
uint8_t region_id )
nodiscard

Promote a staged region into the live CONVAREAST / CONVAREAD pair.

Atomically writes CONVAREAD then CONVAREAST (in that order per the FSP reference comment "Set the end and start area for DOTF conversion in that order to ensure that end address is always higher than start address.", r_ospi_b.c). Caller is expected to have called ra8_dotf_disable first; the function does NOT clear REG00 itself so the AES core stays primed for the subsequent ra8_dotf_enable call.

Parameters
[in]channelChannel index 0..1.
[in]region_idSlot index in the channel's region table.
Returns
ra8_err_t error code.
Return values
k_ra8_okRegion promoted.
k_ra8_err_invalid_argOut-of-range channel or region_id.
k_ra8_err_invalid_stateThe slot has not been staged.
Precondition
ra8_dotf_set_region(channel, ..., region_id=region_id) previously returned k_ra8_ok.
Channel is currently disabled (HUM 45.3.1 p 3049).
Postcondition
CONVAREAST / CONVAREAD reflect the staged region.
The "active region" cache for channel is updated.
Since
0.1.0

Definition at line 591 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::active_region_id, ra8_dotf_regs_t::CONVAREAD, ra8_dotf_regs_t::CONVAREAST, ra8_dotf_region_t::end_addr, internal_channel_in_range(), k_ra8_dotf_addr_mask, k_ra8_dotf_max_regions, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_dotf_chan_state_t::region_valid, ra8_dotf_chan_state_t::regions, s_dotf_state, s_tag, and ra8_dotf_region_t::start_addr.

Referenced by internal_open_stage_key_iv_region().

◆ ra8_dotf_set_iv()

ra8_err_t ra8_dotf_set_iv ( uint8_t channel,
const uint32_t * iv_words )
nodiscard

Stage the AES counter-mode IV for a channel via REG03.

Per HUM Ch 45.1 p 3048 the AES counter is {IV[127:28], Address[31:4]}. Software still loads a full 128-bit IV; the hardware silently overwrites the bottom 28 bits with the AXI address bits at decryption time. The four 32-bit words are written into REG03 in big-endian byte order, mirroring the FSP reference (r_ospi_b.c).

Parameters
[in]channelChannel index 0..1.
[in]iv_wordsPointer to k_ra8_dotf_iv_word_count words.
Returns
ra8_err_t error code.
Return values
k_ra8_okWords written.
k_ra8_err_null_ptriv_words is NULL.
k_ra8_err_invalid_argChannel out of range.
Precondition
iv_words is non-NULL and points to >= 4 valid words.
Channel is currently disabled.
Postcondition
The IV cache for channel mirrors the new value.
REG03 has been written 4 times in big-endian word order.
Since
0.1.0

Definition at line 661 of file ra8_dotf.c.

References internal_channel_in_range(), internal_stage_iv(), ra8_dotf_chan_state_t::iv_cache, ra8_dotf_chan_state_t::iv_valid, k_ra8_dotf_iv_word_count, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), s_dotf_state, and s_tag.

Referenced by internal_open_stage_key_iv_region().

◆ ra8_dotf_set_key_size()

ra8_err_t ra8_dotf_set_key_size ( uint8_t channel,
ra8_dotf_key_size_t size )
nodiscard

Update the cached AES key size for a channel.

Parameters
[in]channelChannel index 0..1.
[in]sizek_ra8_dotf_key_size_*.
Returns
ra8_err_t error code.
Return values
k_ra8_okSize cached; if armed, REG00 updated.
k_ra8_err_invalid_argChannel out of range or unknown size.
Precondition
ra8_dotf_init has run.
Postcondition
REG00 key-size bits reflect size (only if armed).
Subsequent ra8_dotf_enable calls write the new size.
Since
0.1.0

Definition at line 863 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::cached_key_size, ra8_dotf_chan_state_t::enabled, internal_assemble_reg00(), internal_channel_in_range(), k_ra8_dotf_key_size_128, k_ra8_dotf_key_size_192, k_ra8_dotf_key_size_256, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_dotf_regs_t::REG00, s_dotf_state, and s_tag.

◆ ra8_dotf_set_region()

ra8_err_t ra8_dotf_set_region ( uint8_t channel,
const ra8_dotf_region_t * region )
nodiscard

Stage one DOTF region in the channel's region table.

Validates 4 KB alignment, start <= end, that the region falls entirely inside the matching channel's XSPI window ([0x8000_0000..0x9FFF_FFFF] for DOTF0, [0x7000_0000.. 0x7FFF_FFFF] for DOTF1), and that the region does NOT overlap the other channel's currently-armed region. On success the descriptor is copied into slot region->region_id of the channel's staging table; the slot becomes "live" only when ra8_dotf_select_region(channel, region_id) is called.

Parameters
[in]channelChannel index 0..1.
[in]regionNon-NULL region descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okRegion staged.
k_ra8_err_null_ptrregion is NULL.
k_ra8_err_invalid_argchannel or region_id out of range, addresses not 4 KB aligned, start > end, or region escapes the matching XSPI window.
k_ra8_err_conflictRegion overlaps the other channel's currently-armed region.
Precondition
ra8_dotf_init has run.
Channel channel may be enabled or disabled (the slot table is software-only until select_region is called).
Postcondition
Slot region->region_id of channel channel mirrors *region and is marked valid.
The hardware CONVAREAST / CONVAREAD registers are NOT updated until ra8_dotf_select_region runs.
Warning
HUM 45.3.1 / 45.3.2 say: "Set before the AXI transfer request and do not make any further changes." Any change to the live region MUST go through ra8_dotf_disable -> ra8_dotf_select_region -> ra8_dotf_enable.
Since
0.1.0

Definition at line 569 of file ra8_dotf.c.

References internal_channel_in_range(), internal_check_overlap(), internal_validate_region(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_info_val, ra8_log_warn_val, ra8_dotf_region_t::region_id, ra8_dotf_chan_state_t::region_valid, ra8_dotf_chan_state_t::regions, s_dotf_state, and s_tag.

Referenced by internal_open_stage_key_iv_region(), and ra8_dotf_set_region_window().

◆ ra8_dotf_set_sca_level()

ra8_err_t ra8_dotf_set_sca_level ( uint8_t channel,
ra8_dotf_sca_level_t level )
nodiscard

Update the side-channel countermeasure level for a channel.

Parameters
[in]channelChannel index 0..1.
[in]levelk_ra8_dotf_sca_off / standard / max.
Returns
ra8_err_t error code.
Return values
k_ra8_okCached and (if armed) written through.
k_ra8_err_invalid_argChannel out of range or unknown level.
Precondition
ra8_dotf_init has run.
Postcondition
REG00 SCA bits reflect level; if the channel was already enabled, the AES core is updated in place (single REG00 write).
Since
0.1.0

Definition at line 843 of file ra8_dotf.c.

References ra8_dotf_chan_state_t::cached_sca, ra8_dotf_chan_state_t::enabled, internal_assemble_reg00(), internal_channel_in_range(), k_ra8_dotf_sca_max, k_ra8_dotf_sca_off, k_ra8_dotf_sca_standard, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dotf_regs(), ra8_dotf_regs_t::REG00, s_dotf_state, and s_tag.

Referenced by internal_open_finalise().

Variable Documentation

◆ s_dotf_ctx

void* s_dotf_ctx
static

Caller-supplied context handed to s_dotf_fn.

Definition at line 130 of file ra8_dotf.c.

Referenced by ra8_dotf_attach_handler(), ra8_dotf_deinit(), ra8_dotf_dispatch(), and ra8_dotf_init().

◆ s_dotf_fn

ra8_dotf_event_fn_t s_dotf_fn
static

Active fault / event callback.

nullptr means "no callback".

Warning
Do not modify directly; use ra8_dotf_attach_handler.

Definition at line 124 of file ra8_dotf.c.

Referenced by ra8_dotf_attach_handler(), ra8_dotf_deinit(), ra8_dotf_dispatch(), and ra8_dotf_init().

◆ s_dotf_mstp_table

const ra8_mstp_t s_dotf_mstp_table[k_ra8_dotf_channel_count]
static
Initial value:
= {
}
@ k_ra8_mstp_ospi0
MSTPB16 OSPI0+DOTF0.
@ k_ra8_mstp_ospi1
MSTPB17 OSPI1+DOTF1.

Channel-index -> MSTP id lookup.

DOTF0 + XSPI0 share MSTPB16; DOTF1 + XSPI1 share MSTPB17 (HUM Ch 11.2.7 MSTPCRB description references both peripherals). The MSTP wrapper enums in ra8_mstp_regs.h already encode this as k_ra8_mstp_ospi0 / k_ra8_mstp_ospi1 – the comments call them out as "OSPI0+DOTF0" / "OSPI1+DOTF1" so we just reuse them here rather than minting DOTF-specific aliases.

Definition at line 150 of file ra8_dotf.c.

Referenced by ra8_dotf_deinit(), ra8_dotf_enter_stop(), ra8_dotf_exit_stop(), and ra8_dotf_init().

◆ s_dotf_state

◆ s_tag

const char* s_tag = "DOTF"
static

Logging tag for ra8_log_* calls.

Definition at line 116 of file ra8_dotf.c.