ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_dotf.c
Go to the documentation of this file.
1
30
31#include "ra8_dotf.h"
32
33#include <stdint.h>
34
35#include "ra8_attributes.h"
36#include "ra8_check.h"
37#include "ra8_dotf_regs.h"
38#include "ra8_err.h"
39#include "ra8_hw_err.h"
40#include "ra8_log.h"
41#include "ra8_mstp.h"
42
47typedef enum : uint8_t {
51
62typedef enum : uint32_t {
64 k_ra8_dotf_bswap_byte0 = 0x000000FFUL,
65 k_ra8_dotf_bswap_byte1 = 0x0000FF00UL,
66 k_ra8_dotf_bswap_byte2 = 0x00FF0000UL,
67 k_ra8_dotf_bswap_byte3 = 0xFF000000UL,
69
78
95
111
116static const char* s_tag = "DOTF";
117
125
130static void* s_dotf_ctx;
131
137
154
155/* =============================================================================
156 * Internal helpers
157 * =============================================================================
158 */
159
176static inline bool internal_channel_in_range(uint8_t channel)
177{
178 return (uint16_t)channel < (uint16_t)k_ra8_dotf_channel_count;
179}
180
196static inline uint32_t internal_window_lo(uint8_t channel)
197{
198 return (channel == 0U) ? k_ra8_dotf0_window_lo : k_ra8_dotf1_window_lo;
199}
200
216static inline uint32_t internal_window_hi(uint8_t channel)
217{
218 return (channel == 0U) ? k_ra8_dotf0_window_hi : k_ra8_dotf1_window_hi;
219}
220
236static inline uint8_t internal_key_words(ra8_dotf_key_size_t size)
237{
238 if (size == k_ra8_dotf_key_size_192) {
240 }
241 if (size == k_ra8_dotf_key_size_256) {
243 }
245}
246
262static inline uint32_t internal_sca_bits(ra8_dotf_sca_level_t level)
263{
264 if (level == k_ra8_dotf_sca_max) {
266 }
267 if (level == k_ra8_dotf_sca_standard) {
269 }
270 return 0U;
271}
272
293static inline uint32_t internal_bswap32(uint32_t v)
294{
295 return ((v & k_ra8_dotf_bswap_byte0) << (uint32_t)k_ra8_dotf_bswap_shift_word) |
299}
300
317static ra8_err_t internal_validate_region(uint8_t channel, const ra8_dotf_region_t* region)
318{
319 if ((region->start_addr & k_ra8_dotf_addr_low_mask) != 0U) {
321 }
322 if ((region->end_addr & k_ra8_dotf_addr_low_mask) != 0U) {
324 }
325 if (region->start_addr > region->end_addr) {
326 /* HUM Ch 45.3.1 p 3049: "Setting CONVAREAST[31:12] >
327 * CONVAREAED[31:12] is prohibited." */
329 }
330 if (region->region_id >= k_ra8_dotf_max_regions) {
332 }
333 const uint32_t lo = internal_window_lo(channel);
334 const uint32_t hi = internal_window_hi(channel);
335 if ((region->start_addr < lo) || (region->end_addr > hi)) {
336 /* HUM Ch 45.3 p 3049 ("Image of decryption area setting"):
337 * conversion area must lie inside the matching XSPI window. */
339 }
340 return k_ra8_ok;
341}
342
359static ra8_err_t internal_check_overlap(uint8_t channel, const ra8_dotf_region_t* region)
360{
361 for (uint8_t other = 0U; other < k_ra8_dotf_channel_count; ++other) {
362 if (other == channel) {
363 continue;
364 }
365 const ra8_dotf_chan_state_t* st = &s_dotf_state[other];
367 continue;
368 }
369 const ra8_dotf_region_t* live = &st->regions[st->active_region_id];
370 /* Ranges overlap if: start_a <= end_b && start_b <= end_a. */
371 /* mcdc-deactivated: ra8_dotf overlap-detection AND; the four DOTF channels are bound to disjoint XSPI windows by HUM 45.1, and ra8_dotf_set_region rejects regions outside the per-channel window upstream. As a result the cross-channel overlap helper is only entered for region pairs that the HUM windows make non-overlapping by construction -- the AND's two inequalities are co-dependent and cannot independently flip on any reachable input. */
372 if ((region->start_addr <= live->end_addr) && (live->start_addr <= region->end_addr)) {
373 return k_ra8_err_conflict;
374 }
375 }
376 return k_ra8_ok;
377}
378
395static uint32_t internal_assemble_reg00(const ra8_dotf_chan_state_t* st, bool enable)
396{
397 uint32_t v = k_ra8_dotf_reg00_mode_ctr; /* HUM 45.1 mode = CTR. */
398 v |= (uint32_t)st->cached_key_size; /* Key size bits. */
399 v |= internal_sca_bits(st->cached_sca); /* SCA bits. */
400 if (enable) {
402 }
403 return v;
404}
405
420static void internal_stage_key(volatile ra8_dotf_regs_t* reg, const ra8_dotf_key_handle_t* h)
421{
422 const uint8_t words = internal_key_words(h->size);
423 for (uint8_t i = 0U; i < words; ++i) {
424 /* HUM Ch 45.3 "Register Descriptions" p 3049: REG03 is the AES
425 * IV staging window; the FSP reference re-uses it for wrapped-key
426 * delivery via the OutputKeyForDotf adaptor. Big-endian per
427 * ``r_ospi_b.c``. */
428 reg->REG03 = internal_bswap32(h->words[i]);
429 }
430}
431
446static void internal_stage_iv(volatile ra8_dotf_regs_t* reg, const uint32_t* iv)
447{
448 for (uint8_t i = 0U; i < k_ra8_dotf_iv_word_count; ++i) {
449 /* HUM Ch 45.1 p 3048 -- counter = {IV[127:28], Address[31:4]}.
450 * REG03 is the AES IV staging window per HUM Ch 45.3 "Register
451 * Descriptions" p 3049. */
452 reg->REG03 = internal_bswap32(iv[i]);
453 }
454}
455
469static inline void internal_channel_reset(volatile ra8_dotf_regs_t* reg)
470{
471 /* HUM Ch 45.3.1 "CONVAREAST : DOTF Conversion Area Start Address Register" p 3049 */
472 reg->CONVAREAST = 0U;
473 /* HUM Ch 45.3.2 "CONVAREAD : DOTF Conversion Area End Address Register" p 3049 */
474 reg->CONVAREAD = 0U;
475 /* REG00 holds the AES core enable + mode select.
476 * HUM Ch 45.3 "Register Descriptions" p 3049 */
478}
479
493static void internal_state_reset(uint8_t channel)
494{
495 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
496 for (uint8_t i = 0U; i < k_ra8_dotf_max_regions; ++i) {
497 st->region_valid[i] = 0U;
498 st->regions[i].start_addr = 0U;
499 st->regions[i].end_addr = 0U;
500 st->regions[i].key_index = 0U;
501 st->regions[i].region_id = 0U;
502 }
505 st->key.key_index = 0U;
506 st->key.valid = 0U;
507 for (uint8_t i = 0U; i < 8U; ++i) {
508 st->key.words[i] = 0U;
509 }
510 for (uint8_t i = 0U; i < k_ra8_dotf_iv_word_count; ++i) {
511 st->iv_cache[i] = 0U;
512 }
513 st->iv_valid = 0U;
516 st->enabled = 0U;
517}
518
519/* =============================================================================
520 * Lifecycle
521 * =============================================================================
522 */
523
524[[nodiscard]] ra8_err_t ra8_dotf_init(void)
525{
526 for (uint8_t ch = 0U; ch < k_ra8_dotf_channel_count; ++ch) {
527 /* DOTF clock gating: shared MSTPB16/17 with the matching XSPI.
528 * HUM Ch 45.6.1 "Module-stop Function" p 3050 */
529 const ra8_err_t mst_err = ra8_mstp_enable(s_dotf_mstp_table[ch]);
530 RA8_RETURN_ON_ERROR(mst_err, s_tag, "dotf_init: mstp enable failed");
531
532 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(ch);
533 if (reg == nullptr) { /* GCOVR_EXCL_BR_LINE -- loop proves ch<2; accessor nulls only ch>=2 */
534 return k_ra8_err_hw_init_failed; /* GCOVR_EXCL_LINE -- same bounded-channel accessor invariant */
535 }
538 }
539 s_dotf_fn = nullptr;
540 s_dotf_ctx = nullptr;
541 ra8_log_info(s_tag, "dotf_init");
542 return k_ra8_ok;
543}
544
545[[nodiscard]] ra8_err_t ra8_dotf_deinit(void)
546{
547 for (uint8_t ch = 0U; ch < k_ra8_dotf_channel_count; ++ch) {
548 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(ch);
549 if (reg != nullptr) {
550 /* Force bypass on teardown.
551 * HUM Ch 45.3 "Register Descriptions" p 3049 */
553 }
555 /* Gate the shared OSPI/DOTF clock.
556 * HUM Ch 45.6.1 "Module-stop Function" p 3050 */
558 }
559 s_dotf_fn = nullptr;
560 s_dotf_ctx = nullptr;
561 return k_ra8_ok;
562}
563
564/* =============================================================================
565 * Region staging
566 * =============================================================================
567 */
568
569[[nodiscard]] ra8_err_t ra8_dotf_set_region(uint8_t channel, const ra8_dotf_region_t* region)
570{
571 RA8_CHECK_NULL_PTR(region, s_tag, "region must not be nullptr");
572 if (!internal_channel_in_range(channel)) {
574 }
575 const ra8_err_t verr = internal_validate_region(channel, region);
576 if (verr != k_ra8_ok) {
577 return verr;
578 }
579 const ra8_err_t cerr = internal_check_overlap(channel, region);
580 if (cerr != k_ra8_ok) {
581 ra8_log_warn_val(s_tag, "set_region overlaps other channel", (uint32_t)channel);
582 return cerr;
583 }
584 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
585 st->regions[region->region_id] = *region;
586 st->region_valid[region->region_id] = 1U;
587 ra8_log_info_val(s_tag, "set_region staged channel", (uint32_t)channel);
588 return k_ra8_ok;
589}
590
591[[nodiscard]] ra8_err_t ra8_dotf_select_region(uint8_t channel, uint8_t region_id)
592{
593 if (!internal_channel_in_range(channel)) {
595 }
596 if (region_id >= k_ra8_dotf_max_regions) {
598 }
599 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
600 if (st->region_valid[region_id] == 0U) {
602 }
603 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
604 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
605
606 const ra8_dotf_region_t* r = &st->regions[region_id];
607 /* FSP r_ospi_b.c "Set the end and start area for DOTF
608 * conversion in that order to ensure that end address is always
609 * higher than start address."
610 * HUM Ch 45.3.2 "CONVAREAD : DOTF Conversion Area End Address Register" p 3049 */
612 /* HUM Ch 45.3.1 "CONVAREAST : DOTF Conversion Area Start Address Register" p 3049 */
614 st->active_region_id = region_id;
615 return k_ra8_ok;
616}
617
618[[nodiscard]] ra8_err_t ra8_dotf_get_active_region(uint8_t channel, ra8_dotf_region_t* region)
619{
620 RA8_CHECK_NULL_PTR(region, s_tag, "region must not be nullptr");
621 if (!internal_channel_in_range(channel)) {
623 }
624 const ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
627 }
628 *region = st->regions[st->active_region_id];
629 return k_ra8_ok;
630}
631
632/* =============================================================================
633 * Key + IV staging
634 * =============================================================================
635 */
636
637[[nodiscard]] ra8_err_t ra8_dotf_install_key(uint8_t channel, const ra8_dotf_key_handle_t* handle)
638{
639 RA8_CHECK_NULL_PTR(handle, s_tag, "handle must not be nullptr");
640 if (!internal_channel_in_range(channel)) {
642 }
643 if (handle->valid == 0U) {
645 }
646 if ((handle->size != k_ra8_dotf_key_size_128) && (handle->size != k_ra8_dotf_key_size_192) &&
647 (handle->size != k_ra8_dotf_key_size_256)) {
649 }
650 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
651 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
652
653 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
654 st->key = *handle;
655 st->cached_key_size = handle->size;
656 internal_stage_key(reg, handle);
657 ra8_log_info_val(s_tag, "install_key channel", (uint32_t)channel);
658 return k_ra8_ok;
659}
660
661[[nodiscard]] ra8_err_t ra8_dotf_set_iv(uint8_t channel, const uint32_t* iv_words)
662{
663 RA8_CHECK_NULL_PTR(iv_words, s_tag, "iv_words must not be nullptr");
664 if (!internal_channel_in_range(channel)) {
666 }
667 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
668 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
669
670 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
671 for (uint8_t i = 0U; i < k_ra8_dotf_iv_word_count; ++i) {
672 st->iv_cache[i] = iv_words[i];
673 }
674 st->iv_valid = 1U;
675 internal_stage_iv(reg, iv_words);
676 return k_ra8_ok;
677}
678
703 volatile ra8_dotf_regs_t* reg,
704 const uint32_t* iv_words)
705{
706 if (iv_words != nullptr) {
707 for (uint8_t i = 0U; i < k_ra8_dotf_iv_word_count; ++i) {
708 st->iv_cache[i] = iv_words[i];
709 }
710 st->iv_valid = 1U;
711 internal_stage_iv(reg, iv_words);
712 } else if (st->iv_valid != 0U) {
713 internal_stage_iv(reg, st->iv_cache);
714 } else {
715 /* No IV ever installed, no IV to re-stage. */
716 }
717}
718
745 const ra8_dotf_key_handle_t* new_handle)
746{
747 if (!internal_channel_in_range(channel)) {
749 }
750 if (new_handle->valid == 0U) {
752 }
753 if ((new_handle->size != k_ra8_dotf_key_size_128) &&
754 (new_handle->size != k_ra8_dotf_key_size_192) &&
755 (new_handle->size != k_ra8_dotf_key_size_256)) {
757 }
758 if (s_dotf_state[channel].active_region_id == k_ra8_dotf_no_region) {
760 }
761 return k_ra8_ok;
762}
763
764[[nodiscard]] ra8_err_t ra8_dotf_rotate_key(uint8_t channel,
765 const ra8_dotf_key_handle_t* new_handle,
766 const uint32_t* iv_words)
767{
768 RA8_CHECK_NULL_PTR(new_handle, s_tag, "new_handle must not be nullptr");
769 const ra8_err_t val_err = internal_validate_rotate_inputs(channel, new_handle);
770 RA8_RETURN_ON_ERROR(val_err, s_tag, "rotate_key: validation failed");
771
772 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
773 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
774
775 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
776 const uint8_t was_enabled = st->enabled;
777
778 /* Step 1: quiesce the AES core.
779 * HUM Ch 45.3 "Register Descriptions" p 3049 */
781 st->enabled = 0U;
782
783 /* Step 2: replace key + (optionally) IV. */
784 st->key = *new_handle;
785 st->cached_key_size = new_handle->size;
786 internal_stage_key(reg, new_handle);
787 internal_rotate_iv(st, reg, iv_words);
788
789 /* Step 3: re-arm if previously enabled. */
790 if (was_enabled != 0U) {
791 /* HUM Ch 45.3 "Register Descriptions" p 3049 */
792 reg->REG00 = internal_assemble_reg00(st, true);
793 st->enabled = 1U;
794 }
795 ra8_log_info_val(s_tag, "rotate_key channel", (uint32_t)channel);
796 return k_ra8_ok;
797}
798
799/* =============================================================================
800 * Enable / disable
801 * =============================================================================
802 */
803
804[[nodiscard]] ra8_err_t ra8_dotf_enable(uint8_t channel)
805{
806 if (!internal_channel_in_range(channel)) {
808 }
809 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
810 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
811
812 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
813 /* REG00 enables AES; pattern is (mode=CTR | key_size | sca | enable).
814 * The reset-default ``0x2200_0000`` matches mode=CTR + key_size=128
815 * with SCA off; the cached state may override every field.
816 * HUM Ch 45.3 "Register Descriptions" p 3049 */
817 reg->REG00 = internal_assemble_reg00(st, true);
818 st->enabled = 1U;
819 ra8_log_info_val(s_tag, "enable channel", (uint32_t)channel);
820 return k_ra8_ok;
821}
822
823[[nodiscard]] ra8_err_t ra8_dotf_disable(uint8_t channel)
824{
825 if (!internal_channel_in_range(channel)) {
827 }
828 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
829 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
830
831 /* Writing 0 to REG00 puts the channel in bypass.
832 * HUM Ch 45.3 "Register Descriptions" p 3049 */
834 s_dotf_state[channel].enabled = 0U;
835 return k_ra8_ok;
836}
837
838/* =============================================================================
839 * REG00 sub-field tuning
840 * =============================================================================
841 */
842
843[[nodiscard]] ra8_err_t ra8_dotf_set_sca_level(uint8_t channel, ra8_dotf_sca_level_t level)
844{
845 if (!internal_channel_in_range(channel)) {
847 }
848 if ((level != k_ra8_dotf_sca_off) && (level != k_ra8_dotf_sca_standard) &&
849 (level != k_ra8_dotf_sca_max)) {
851 }
852 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
853 st->cached_sca = level;
854 if (st->enabled != 0U) {
855 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
856 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
857 /* HUM Ch 45.3 "Register Descriptions" p 3049 */
858 reg->REG00 = internal_assemble_reg00(st, true);
859 }
860 return k_ra8_ok;
861}
862
863[[nodiscard]] ra8_err_t ra8_dotf_set_key_size(uint8_t channel, ra8_dotf_key_size_t size)
864{
865 if (!internal_channel_in_range(channel)) {
867 }
868 if ((size != k_ra8_dotf_key_size_128) && (size != k_ra8_dotf_key_size_192) &&
869 (size != k_ra8_dotf_key_size_256)) {
871 }
872 ra8_dotf_chan_state_t* st = &s_dotf_state[channel];
873 st->cached_key_size = size;
874 if (st->enabled != 0U) {
875 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
876 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
877 /* HUM Ch 45.3 "Register Descriptions" p 3049 */
878 reg->REG00 = internal_assemble_reg00(st, true);
879 }
880 return k_ra8_ok;
881}
882
883[[nodiscard]] ra8_err_t ra8_dotf_run_self_test(uint8_t channel, uint32_t* out_status)
884{
885 RA8_CHECK_NULL_PTR(out_status, s_tag, "out_status must not be nullptr");
886 if (!internal_channel_in_range(channel)) {
888 }
889 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
890 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
891
892 /* Save current REG00 so the function is observably side-effect-free
893 * once the self-test completes. */
894 const uint32_t saved = reg->REG00;
895 /* HUM Ch 45.1 p 3048 ("Supports self-test function").
896 * REG00 bit 20 triggers BIST; the bit auto-clears in real silicon.
897 * HUM Ch 45.3 "Register Descriptions" p 3049 */
898 reg->REG00 = saved | k_ra8_dotf_reg00_self_test;
899 const ra8_err_t wait_err = ra8_hw_wait_flag_clear32(&reg->REG00,
901 (uint32_t)k_ra8_dotf_self_test_spin);
902 *out_status = reg->REG00;
903 /* HUM Ch 45.3 "Register Descriptions" p 3049 */
904 reg->REG00 = saved;
905 return wait_err;
906}
907
908/* =============================================================================
909 * Status
910 * =============================================================================
911 */
912
913[[nodiscard]] ra8_err_t ra8_dotf_get_status(uint8_t channel, uint32_t* out_mask)
914{
915 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
916 if (!internal_channel_in_range(channel)) {
918 }
919 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
920 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
921
922 /* Raw REG00 read for diagnostics.
923 * HUM Ch 45.3 "Register Descriptions" p 3049 */
924 *out_mask = reg->REG00;
925 return k_ra8_ok;
926}
927
928[[nodiscard]] ra8_err_t ra8_dotf_clear_status(uint8_t channel)
929{
930 if (!internal_channel_in_range(channel)) {
932 }
933 volatile ra8_dotf_regs_t* reg = ra8_dotf_regs(channel);
934 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
935
936 /* Clearing REG00 wipes the AES enable + status bits.
937 * HUM Ch 45.3 "Register Descriptions" p 3049 */
939 s_dotf_state[channel].enabled = 0U;
940 return k_ra8_ok;
941}
942
943/* =============================================================================
944 * IRQ glue
945 * =============================================================================
946 */
947
949{
950 s_dotf_fn = fn;
951 s_dotf_ctx = ctx;
952 return k_ra8_ok;
953}
954
956void ra8_dotf_dispatch(uint8_t channel)
957{
958 if (!internal_channel_in_range(channel)) {
959 return;
960 }
962 void* const ctx = s_dotf_ctx;
963 if (fn != nullptr) {
964 fn(ctx, channel);
965 }
966}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
ra8_err_t ra8_dotf_deinit(void)
Disable DOTF and gate the OSPI clock.
Definition ra8_dotf.c:545
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.
Definition ra8_dotf.c:744
static uint32_t internal_sca_bits(ra8_dotf_sca_level_t level)
Map an SCA level enum into REG00 SCA bits.
Definition ra8_dotf.c:262
static void internal_state_reset(uint8_t channel)
Wipe all software state for one channel.
Definition ra8_dotf.c:493
ra8_err_t ra8_dotf_clear_status(uint8_t channel)
Clear REG00 (force the channel into bypass).
Definition ra8_dotf.c:928
ra8_dotf_misc_t
Internal small constants (no magic numbers).
Definition ra8_dotf.c:47
@ k_ra8_dotf_no_region
Sentinel for "no region active".
Definition ra8_dotf.c:48
@ k_ra8_dotf_self_test_spin
Bounded poll budget for self-test bit.
Definition ra8_dotf.c:49
static ra8_err_t internal_validate_region(uint8_t channel, const ra8_dotf_region_t *region)
Validate region range / alignment / window.
Definition ra8_dotf.c:317
ra8_dotf_key_word_count_t
Wrapped-key word counts per AES key size.
Definition ra8_dotf.c:90
@ k_ra8_dotf_key_words_128
RA8 dotf key words 128.
Definition ra8_dotf.c:91
@ k_ra8_dotf_key_words_192
RA8 dotf key words 192.
Definition ra8_dotf.c:92
@ k_ra8_dotf_key_words_256
RA8 dotf key words 256.
Definition ra8_dotf.c:93
static void internal_channel_reset(volatile ra8_dotf_regs_t *reg)
Reset one channel's hardware to power-on state.
Definition ra8_dotf.c:469
static uint8_t internal_key_words(ra8_dotf_key_size_t size)
Word count for a given AES key size.
Definition ra8_dotf.c:236
void ra8_dotf_dispatch(uint8_t channel)
Dispatch a DOTF event from the IRQ glue.
Definition ra8_dotf.c:956
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.
Definition ra8_dotf.c:395
ra8_dotf_bswap_const_t
Byte-extraction masks and shift counts for internal_bswap32.
Definition ra8_dotf.c:62
@ k_ra8_dotf_bswap_byte0
Selects bits [7:0] (byte 0).
Definition ra8_dotf.c:64
@ k_ra8_dotf_bswap_byte3
Selects bits [31:24] (byte 3).
Definition ra8_dotf.c:67
@ k_ra8_dotf_bswap_byte2
Selects bits [23:16] (byte 2).
Definition ra8_dotf.c:66
@ k_ra8_dotf_bswap_byte_mask
Per-byte mask used by all 4 lanes.
Definition ra8_dotf.c:63
@ k_ra8_dotf_bswap_byte1
Selects bits [15:8] (byte 1).
Definition ra8_dotf.c:65
static uint32_t internal_window_lo(uint8_t channel)
XSPI window low bound for a given DOTF channel.
Definition ra8_dotf.c:196
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.
Definition ra8_dotf.c:843
ra8_err_t ra8_dotf_enable(uint8_t channel)
Enable AES decryption for one channel.
Definition ra8_dotf.c:804
ra8_err_t ra8_dotf_attach_handler(ra8_dotf_event_fn_t fn, void *ctx)
Register a fault / event callback (shared across both channels).
Definition ra8_dotf.c:948
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.
Definition ra8_dotf.c:420
ra8_err_t ra8_dotf_get_status(uint8_t channel, uint32_t *out_mask)
Read REG00 (raw control / status snapshot).
Definition ra8_dotf.c:913
static ra8_dotf_event_fn_t s_dotf_fn
Active fault / event callback.
Definition ra8_dotf.c:124
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.
Definition ra8_dotf.c:359
ra8_err_t ra8_dotf_disable(uint8_t channel)
Disable AES decryption for one channel (transparent bypass).
Definition ra8_dotf.c:823
static uint32_t internal_bswap32(uint32_t v)
Big-endian byte-swap of a 32-bit word.
Definition ra8_dotf.c:293
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.
Definition ra8_dotf.c:637
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.
Definition ra8_dotf.c:764
ra8_err_t ra8_dotf_select_region(uint8_t channel, uint8_t region_id)
Promote a staged region into the live CONVAREAST / CONVAREAD pair.
Definition ra8_dotf.c:591
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.
Definition ra8_dotf.c:661
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.
Definition ra8_dotf.c:446
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.
Definition ra8_dotf.c:863
ra8_err_t ra8_dotf_init(void)
Power on the DOTF block and reset both channels.
Definition ra8_dotf.c:524
static const ra8_mstp_t s_dotf_mstp_table[k_ra8_dotf_channel_count]
Channel-index -> MSTP id lookup.
Definition ra8_dotf.c:150
static void * s_dotf_ctx
Caller-supplied context handed to s_dotf_fn.
Definition ra8_dotf.c:130
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.
Definition ra8_dotf.c:702
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.
Definition ra8_dotf.c:883
ra8_err_t ra8_dotf_get_active_region(uint8_t channel, ra8_dotf_region_t *region)
Read back the active region for a channel.
Definition ra8_dotf.c:618
ra8_dotf_bswap_shift_t
Shift counts used by internal_bswap32.
Definition ra8_dotf.c:74
@ k_ra8_dotf_bswap_shift_word
Shift for byte0 <-> byte3.
Definition ra8_dotf.c:76
@ k_ra8_dotf_bswap_shift_byte
Shift for one-byte slide.
Definition ra8_dotf.c:75
static bool internal_channel_in_range(uint8_t channel)
Bound-check a channel index.
Definition ra8_dotf.c:176
static ra8_dotf_chan_state_t s_dotf_state[k_ra8_dotf_channel_count]
Per-channel state table.
Definition ra8_dotf.c:136
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.
Definition ra8_dotf.c:569
static uint32_t internal_window_hi(uint8_t channel)
XSPI window high bound for a given DOTF channel.
Definition ra8_dotf.c:216
Decryption On The Fly (DOTF) HAL driver public API.
ra8_dotf_key_size_t
AES key sizes supported by the DOTF AES core.
Definition ra8_dotf.h:128
@ k_ra8_dotf_key_size_128
128-bit AES.
Definition ra8_dotf.h:129
@ k_ra8_dotf_key_size_192
192-bit AES.
Definition ra8_dotf.h:130
@ k_ra8_dotf_key_size_256
256-bit AES.
Definition ra8_dotf.h:131
void(* ra8_dotf_event_fn_t)(void *ctx, uint8_t channel)
DOTF fault / status event callback.
Definition ra8_dotf.h:214
ra8_dotf_sca_level_t
Side-channel countermeasure tuning levels.
Definition ra8_dotf.h:148
@ k_ra8_dotf_sca_max
Maximum level, bits 16 + 17 set.
Definition ra8_dotf.h:151
@ k_ra8_dotf_sca_standard
Default level, bit 16 set.
Definition ra8_dotf.h:150
@ k_ra8_dotf_sca_off
Side-channel countermeasures disabled.
Definition ra8_dotf.h:149
Decryption On The Fly (DOTF) register layout for the Renesas RA8D2.
@ k_ra8_dotf_channel_count
DOTF0 + DOTF1.
@ k_ra8_dotf_max_regions
Max staged regions per channel.
@ k_ra8_dotf_iv_word_count
IV is 128-bit = 4 x 32-bit words.
@ k_ra8_dotf_addr_low_mask
Low 12 bits read as 0/1 (HUM).
@ k_ra8_dotf_addr_mask
High 20 bits are the value.
@ k_ra8_dotf_reg00_self_test
Bit 20 – self-test trigger.
@ k_ra8_dotf_reg00_mode_ctr
CTR mode (HUM 45.1 p 3048).
@ k_ra8_dotf_reg00_aes_enable
Bit 9 – enable AES core.
@ k_ra8_dotf_reg00_sca_mode
Bit 17 – side-channel mode.
@ k_ra8_dotf_reg00_sca_en
Bit 16 – side-channel enable.
@ k_ra8_dotf_reg00_disable_value
Disable – AES bypassed.
@ k_ra8_dotf0_window_hi
Last byte covered by DOTF0.
@ k_ra8_dotf0_window_lo
First byte covered by DOTF0.
@ k_ra8_dotf1_window_lo
First byte covered by DOTF1.
@ k_ra8_dotf1_window_hi
Last byte covered by DOTF1.
static volatile ra8_dotf_regs_t * ra8_dotf_regs(uint8_t channel)
Get pointer to DOTF channel channel.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
Definition ra8_err.h:290
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_conflict
Conflict with concurrent access detected.
Definition ra8_err.h:441
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Bounded wait-flag primitives for RA8D2 HAL drivers.
static ra8_err_t ra8_hw_wait_flag_clear32(volatile const uint32_t *reg, uint32_t mask, uint32_t budget)
Spin until (*reg & mask) == 0 or budget runs out.
Definition ra8_hw_err.h:351
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_warn_val(tag, message, value)
RA8 log warn val.
Definition ra8_log.h:349
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_ospi0
MSTPB16 OSPI0+DOTF0.
@ k_ra8_mstp_ospi1
MSTPB17 OSPI1+DOTF1.
Per-channel software state.
Definition ra8_dotf.c:100
uint8_t enabled
Enabled.
Definition ra8_dotf.c:109
ra8_dotf_key_handle_t key
Key.
Definition ra8_dotf.c:104
ra8_dotf_sca_level_t cached_sca
Cached sca.
Definition ra8_dotf.c:108
uint32_t iv_cache[k_ra8_dotf_iv_word_count]
Iv cache.
Definition ra8_dotf.c:105
ra8_dotf_region_t regions[k_ra8_dotf_max_regions]
Regions.
Definition ra8_dotf.c:101
uint8_t iv_valid
Iv valid.
Definition ra8_dotf.c:106
uint8_t active_region_id
or k_ra8_dotf_no_region.
Definition ra8_dotf.c:103
ra8_dotf_key_size_t cached_key_size
Cached key size.
Definition ra8_dotf.c:107
uint8_t region_valid[k_ra8_dotf_max_regions]
1 if slot armed.
Definition ra8_dotf.c:102
Wrapped-key handle handed to DOTF by ra8_rsip.
Definition ra8_dotf.h:201
ra8_dotf_key_size_t size
128 / 192 / 256 selector for REG00.
Definition ra8_dotf.h:202
uint32_t words[8]
Wrapped-key payload (up to 256 bits).
Definition ra8_dotf.h:205
uint8_t valid
Non-zero if the wrapped key is real.
Definition ra8_dotf.h:204
uint8_t key_index
RSIP key slot this handle came from.
Definition ra8_dotf.h:203
Conversion-area descriptor for ra8_dotf_set_region.
Definition ra8_dotf.h:172
uint8_t region_id
0..k_ra8_dotf_max_regions-1 staging slot.
Definition ra8_dotf.h:176
uint32_t start_addr
First byte of the encrypted region (incl).
Definition ra8_dotf.h:173
uint8_t key_index
RSIP key index (forwarded to install_key flow).
Definition ra8_dotf.h:175
uint32_t end_addr
Last byte of the encrypted region (incl).
Definition ra8_dotf.h:174
Per-channel DOTF register window.
volatile uint32_t CONVAREAD
+0x004 Conversion area end address.
volatile uint32_t REG03
+0x08C AES IV staging window.
volatile uint32_t REG00
+0x080 AES enable / mode select.
volatile uint32_t CONVAREAST
+0x000 Conversion area start address.