|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Decryption On The Fly (DOTF) HAL driver public API. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_dotf_region_t |
| Conversion-area descriptor for ra8_dotf_set_region. More... | |
| struct | ra8_dotf_key_handle_t |
| Wrapped-key handle handed to DOTF by ra8_rsip. More... | |
| struct | ra8_dotf_open_cfg_t |
| One-shot DOTF bring-up descriptor consumed by ra8_dotf_open. More... | |
Typedefs | |
| typedef void(* | ra8_dotf_event_fn_t) (void *ctx, uint8_t channel) |
| DOTF fault / status event callback. | |
Enumerations | |
| enum | ra8_dotf_key_size_t : uint32_t { k_ra8_dotf_key_size_128 = k_ra8_dotf_reg00_key_size_128 , k_ra8_dotf_key_size_192 = k_ra8_dotf_reg00_key_size_192 , k_ra8_dotf_key_size_256 = k_ra8_dotf_reg00_key_size_256 } |
| AES key sizes supported by the DOTF AES core. More... | |
| enum | ra8_dotf_sca_level_t : uint8_t { k_ra8_dotf_sca_off = 0U , k_ra8_dotf_sca_standard = 1U , k_ra8_dotf_sca_max = 2U } |
| Side-channel countermeasure tuning levels. More... | |
Functions | |
| 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_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_set_iv (uint8_t channel, const uint32_t *iv_words) |
| Stage the AES counter-mode IV for a channel via REG03. | |
| 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. | |
| ra8_err_t | ra8_dotf_open (const ra8_dotf_open_cfg_t *cfg) |
| One-shot DOTF bring-up: init + install_key + set_iv + set_region (+ enable). | |
| ra8_err_t | ra8_dotf_close (void) |
| Tear down DOTF and release all hardware state. | |
| ra8_err_t | ra8_dotf_set_region_window (uint8_t channel, uint32_t start, uint32_t len) |
| Stage a region from a (start, length) pair instead of a struct. | |
| ra8_err_t | ra8_dotf_enter_stop (void) |
| Park the DOTF block prior to entering a low-power mode. | |
| ra8_err_t | ra8_dotf_exit_stop (void) |
| Bring the DOTF block back from low-power mode. | |
Decryption On The Fly (DOTF) HAL driver public API.
Driver for the RA8D2 DOTF block (HUM Ch 45 p 3048..3050). DOTF transparently decrypts read traffic on the AXI side of the OSPI / xSPI controller using an AES core configured in CTR mode, allowing encrypted code stored in external flash to execute in place from the XiP window.
The driver covers every register documented in HUM Ch 45 plus the REG00 sub-fields cross-referenced from the FSP r_ospi_b driver (key size, AES mode, side-channel countermeasure, self-test trigger, IV staging via REG03). It also implements:
Definition in file ra8_dotf.h.
| typedef void(* ra8_dotf_event_fn_t) (void *ctx, uint8_t channel) |
DOTF fault / status event callback.
| [in] | ctx | Caller context. |
| [in] | channel | Channel index 0..1 that raised the event. |
Definition at line 214 of file ra8_dotf.h.
| enum ra8_dotf_key_size_t : uint32_t |
AES key sizes supported by the DOTF AES core.
HUM Ch 45.1 p 3048 ("AES core function: Block size 128-bit; Key size: 128-bit, 192-bit, 256-bit"). The encoded values are the raw REG00 patterns that select each size; the driver simply ORs them into the assembled REG00 word.
| Enumerator | |
|---|---|
| k_ra8_dotf_key_size_128 | 128-bit AES. |
| k_ra8_dotf_key_size_192 | 192-bit AES. |
| k_ra8_dotf_key_size_256 | 256-bit AES. |
Definition at line 128 of file ra8_dotf.h.
| enum ra8_dotf_sca_level_t : uint8_t |
Side-channel countermeasure tuning levels.
HUM Ch 45.1 p 3048 ("Tamper Resistance: Countermeasures available for side-channel attacks, including SPA/DPA and timing attacks"). The HUM does not expose the raw bit names; the driver maps three coarse levels onto REG00 bits 17:16 per the FSP reference:
| Enumerator | |
|---|---|
| k_ra8_dotf_sca_off | Side-channel countermeasures disabled. |
| k_ra8_dotf_sca_standard | Default level, bit 16 set. |
| k_ra8_dotf_sca_max | Maximum level, bits 16 + 17 set. |
Definition at line 148 of file ra8_dotf.h.
|
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.
| [in] | fn | Callback fired on dispatch. |
| [in] | ctx | Context forwarded to the callback. |
Definition at line 948 of file ra8_dotf.c.
References k_ra8_ok, s_dotf_ctx, and s_dotf_fn.
|
nodiscard |
Clear REG00 (force the channel into bypass).
| [in] | channel | Channel index 0..1. |
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.
|
nodiscard |
Tear down DOTF and release all hardware state.
Companion to ra8_dotf_open: disables both channels and gates the shared OSPI MSTP bits via ra8_dotf_deinit. Provided as a thin symmetric helper so callers do not have to mix open / deinit vocabulary.
Definition at line 221 of file ra8_dotf_power.c.
References ra8_dotf_deinit().
|
nodiscard |
Disable DOTF and gate the OSPI clock.
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().
|
nodiscard |
Disable AES decryption for one channel (transparent bypass).
| [in] | channel | Channel index 0..1. |
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.
| void ra8_dotf_dispatch | ( | uint8_t | channel | ) |
Dispatch a DOTF event from the IRQ glue.
| [in] | channel | Channel index 0..1 that raised the event. Out of range channels are dropped silently. |
See implementation.
Definition at line 956 of file ra8_dotf.c.
References internal_channel_in_range(), s_dotf_ctx, and s_dotf_fn.
|
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.
| [in] | channel | Channel index 0..1. |
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().
|
nodiscard |
Park the DOTF block prior to entering a low-power mode.
Definition at line 253 of file ra8_dotf_power.c.
References k_ra8_dotf_channel_count, k_ra8_ok, ra8_mstp_disable(), and s_dotf_mstp_table.
|
nodiscard |
Bring the DOTF block back from low-power mode.
Definition at line 262 of file ra8_dotf_power.c.
References k_ra8_dotf_channel_count, k_ra8_ok, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, s_dotf_mstp_table, and s_tag.
|
nodiscard |
Read back the active region for a channel.
| [in] | channel | Channel index 0..1. |
| [out] | region | Receives a copy of the active descriptor. |
| k_ra8_ok | Descriptor returned. |
| k_ra8_err_null_ptr | region is NULL. |
| k_ra8_err_invalid_arg | Channel out of range. |
| k_ra8_err_invalid_state | No region active on channel. |
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.
|
nodiscard |
Read REG00 (raw control / status snapshot).
| [in] | channel | Channel index 0..1. |
| [out] | out_mask | Receives REG00 contents. |
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().
|
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.
| k_ra8_ok | DOTF clocked and zeroed. |
| k_ra8_err_hw_init_failed | MSTP enable failed for either id. |
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().
|
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.
| [in] | channel | Channel index 0..1. |
| [in] | handle | Non-NULL handle. handle->valid must be non-0. |
| k_ra8_ok | Key staged. |
| k_ra8_err_null_ptr | handle is NULL. |
| k_ra8_err_invalid_arg | Channel out of range or handle invalid. |
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().
|
nodiscard |
One-shot DOTF bring-up: init + install_key + set_iv + set_region (+ enable).
Convenience entry point for the bootloader: drives ra8_dotf_init (idempotent re-init is allowed), ra8_dotf_install_key, ra8_dotf_set_iv, ra8_dotf_set_region, ra8_dotf_select_region, ra8_dotf_set_sca_level and (optionally) ra8_dotf_enable from a single descriptor. Used during cold boot when XiP code lives behind the AES core and must be armed before the first instruction fetch into the encrypted window.
| [in] | cfg | Non-NULL bring-up descriptor. |
| k_ra8_ok | Channel armed (or staged + idle). |
| k_ra8_err_null_ptr | cfg was NULL. |
| k_ra8_err_invalid_arg | Channel out of range or descriptor bad. |
| k_ra8_err_hw_init_failed | MSTP enable failed. |
Definition at line 206 of file ra8_dotf_power.c.
References internal_open_finalise(), internal_open_stage_key_iv_region(), internal_open_validate_init(), k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
|
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:
| [in] | channel | Channel index 0..1. |
| [in] | new_handle | Non-NULL replacement key. |
| [in] | iv_words | k_ra8_dotf_iv_word_count words of new IV (or NULL to reuse the current IV). |
| k_ra8_ok | Rotation complete. |
| k_ra8_err_null_ptr | new_handle is NULL. |
| k_ra8_err_invalid_arg | Channel out of range or handle invalid. |
| k_ra8_err_invalid_state | No region active on the channel. |
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.
|
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.
| [in] | channel | Channel index 0..1. |
| [out] | out_status | Non-NULL diagnostic snapshot. |
| k_ra8_ok | Self-test triggered. |
| k_ra8_err_null_ptr | out_status is NULL. |
| k_ra8_err_invalid_arg | Channel out of range. |
| k_ra8_err_hw_timeout | SELF_TEST did not clear within the bounded wait. |
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().
|
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.
| [in] | channel | Channel index 0..1. |
| [in] | region_id | Slot index in the channel's region table. |
| k_ra8_ok | Region promoted. |
| k_ra8_err_invalid_arg | Out-of-range channel or region_id. |
| k_ra8_err_invalid_state | The slot has not been staged. |
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().
|
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).
| [in] | channel | Channel index 0..1. |
| [in] | iv_words | Pointer to k_ra8_dotf_iv_word_count words. |
| k_ra8_ok | Words written. |
| k_ra8_err_null_ptr | iv_words is NULL. |
| k_ra8_err_invalid_arg | Channel out of range. |
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().
|
nodiscard |
Update the cached AES key size for a channel.
| [in] | channel | Channel index 0..1. |
| [in] | size | k_ra8_dotf_key_size_*. |
| k_ra8_ok | Size cached; if armed, REG00 updated. |
| k_ra8_err_invalid_arg | Channel out of range or unknown size. |
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.
|
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.
| [in] | channel | Channel index 0..1. |
| [in] | region | Non-NULL region descriptor. |
| k_ra8_ok | Region staged. |
| k_ra8_err_null_ptr | region is NULL. |
| k_ra8_err_invalid_arg | channel or region_id out of range, addresses not 4 KB aligned, start > end, or region escapes the matching XSPI window. |
| k_ra8_err_conflict | Region overlaps the other channel's currently-armed region. |
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().
|
nodiscard |
Stage a region from a (start, length) pair instead of a struct.
Thin convenience wrapper around ra8_dotf_set_region for callers that have a base + len pair handy. Internally constructs a ra8_dotf_region_t with region_id = 0, key_index = 0 and forwards. The end address is derived as start + len - 1 and is subject to the same 4 KB alignment constraints as the struct API.
| [in] | channel | Channel index 0..1. |
| [in] | start | First byte of the encrypted region. |
| [in] | len | Length of the region in bytes (must be > 0 and 4 KB aligned). |
| k_ra8_ok | Region staged in slot 0. |
| k_ra8_err_invalid_arg | Channel out of range or alignment bad. |
Definition at line 227 of file ra8_dotf_power.c.
References internal_ra8_dotf_internal_channel_in_range(), k_ra8_dotf_addr_low_mask, k_ra8_err_invalid_arg, and ra8_dotf_set_region().
|
nodiscard |
Update the side-channel countermeasure level for a channel.
| [in] | channel | Channel index 0..1. |
| [in] | level | k_ra8_dotf_sca_off / standard / max. |
| k_ra8_ok | Cached and (if armed) written through. |
| k_ra8_err_invalid_arg | Channel out of range or unknown level. |
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().