ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1
52
53#include <stddef.h>
54#include <stdint.h>
55#include <string.h>
56
57#include "ra8_board_ek_ra8d2.h"
58#include "ra8_boot_entry.h"
59#include "ra8_cgc.h"
60#include "ra8_check.h"
61#include "ra8_err.h"
62#include "ra8_flash.h"
63#include "ra8_ota.h"
64#include "ra8_rsip.h"
65#include "ra8_secure.h"
66
67/* -------------------------------------------------------------------------- */
68/* Tunables (no magic numbers -- every literal is a typed enum / const) */
69/* -------------------------------------------------------------------------- */
70
78typedef enum : uint32_t {
79 k_app_uart_baud = 115200U,
82 k_app_report_delay = 4000000U,
83 k_app_bootsel_magic = 0xB007A8B1U,
84 k_app_demo_pubkey = 0x0A8D2C0DU,
86
105
110typedef enum : uint8_t {
113} app_bank_t;
114
127
132typedef enum : uint16_t {
136
151
165
167static const char* const s_tag = "ota_ab";
168
169/* -------------------------------------------------------------------------- */
170/* Local image source (stands in for a TLS download) */
171/* -------------------------------------------------------------------------- */
172
183typedef struct {
184 const uint8_t* data;
185 uint32_t len;
186 uint32_t pos;
188
191
194
196static uint32_t s_bootsel_seq = 0U;
197
200
203
206
207/* -------------------------------------------------------------------------- */
208/* Console helpers */
209/* -------------------------------------------------------------------------- */
210
224static size_t app_strlen(const char* text)
225{
226 size_t n = 0U;
227 while (n < (size_t)k_app_bank_size_bytes) {
228 if (text[n] == '\0') {
229 break;
230 }
231 ++n;
232 }
233 return n;
234}
235
248static void app_print(const char* text)
249{
250 if (text == nullptr) {
251 return;
252 }
253 (void)ra8_board_uart_console_write((const uint8_t*)text, app_strlen(text));
254}
255
256/* -------------------------------------------------------------------------- */
257/* OTA net interface (local image source) */
258/* -------------------------------------------------------------------------- */
259
276static ra8_err_t app_net_open(void* ctx, const char* url, uint32_t* out_content_len)
277{
278 (void)url;
279 RA8_CHECK_NULL_PTR(ctx, s_tag, "net.open ctx");
280 RA8_CHECK_NULL_PTR(out_content_len, s_tag, "net.open out_len");
282 src->pos = 0U;
283 *out_content_len = src->len;
284 return k_ra8_ok;
285}
286
304static ra8_err_t app_net_read(void* ctx, uint8_t* dst, uint32_t cap, uint32_t* out_len)
305{
306 RA8_CHECK_NULL_PTR(ctx, s_tag, "net.read ctx");
307 RA8_CHECK_NULL_PTR(dst, s_tag, "net.read dst");
308 RA8_CHECK_NULL_PTR(out_len, s_tag, "net.read out_len");
310 const uint32_t remaining = src->len - src->pos;
311 const uint32_t n = (remaining < cap) ? remaining : cap;
312 if (n > 0U) {
313 (void)memcpy(dst, &src->data[src->pos], n);
314 src->pos += n;
315 }
316 *out_len = n;
317 return k_ra8_ok;
318}
319
334/* cppcheck-suppress constParameterCallback ; ctx must stay non-const to match
335 * the ra8_ota_net_iface_t.close function-pointer signature. */
336static ra8_err_t app_net_close(void* ctx)
337{
338 RA8_CHECK_NULL_PTR(ctx, s_tag, "net.close ctx");
339 return k_ra8_ok;
340}
341
342/* -------------------------------------------------------------------------- */
343/* OTA crypto interface (real software SHA-256 + demo authenticity) */
344/* -------------------------------------------------------------------------- */
345
359static ra8_err_t app_sha_init(void* ctx)
360{
361 RA8_CHECK_NULL_PTR(ctx, s_tag, "sha.init ctx");
363}
364
380static ra8_err_t app_sha_update(void* ctx, const uint8_t* data, uint32_t len)
381{
382 RA8_CHECK_NULL_PTR(ctx, s_tag, "sha.update ctx");
383 return ra8_rsip_sha256_update((ra8_rsip_sha256_ctx_t*)ctx, data, len);
384}
385
400static ra8_err_t app_sha_final(void* ctx, uint8_t out[k_ra8_ota_sha256_bytes])
401{
402 RA8_CHECK_NULL_PTR(ctx, s_tag, "sha.final ctx");
403 RA8_CHECK_NULL_PTR(out, s_tag, "sha.final out");
405}
406
437 uint32_t pubkey,
438 const uint8_t bound[k_ra8_ota_sha256_bytes],
439 const uint8_t* sig,
440 uint32_t sig_len)
441{
442 (void)ctx;
443 (void)bound;
444 RA8_CHECK_NULL_PTR(sig, s_tag, "ecdsa.sig");
445 if ((pubkey != (uint32_t)k_app_demo_pubkey) || (sig_len != (uint32_t)k_app_sig_bytes)) {
446 return k_ra8_err_hw_error;
447 }
448 return k_ra8_ok;
449}
450
451/* -------------------------------------------------------------------------- */
452/* OTA flash interface (real extra-MRAM driver) */
453/* -------------------------------------------------------------------------- */
454
474static ra8_err_t app_flash_erase(void* ctx, uint32_t addr, uint32_t len)
475{
476 (void)ctx;
477 for (uint32_t off = 0U; off < len; off += (uint32_t)k_app_mram_block_bytes) {
478 const ra8_err_t e = ra8_flash_extra_mram_erase(addr + off);
479 if (e != k_ra8_ok) {
480 return e;
481 }
482 }
483 return k_ra8_ok;
484}
485
508static ra8_err_t app_flash_program(void* ctx, uint32_t addr, const uint8_t* src, uint32_t len)
509{
510 (void)ctx;
511 RA8_CHECK_NULL_PTR(src, s_tag, "flash.program src");
512 for (uint32_t off = 0U; off < len; off += (uint32_t)k_app_mram_block_bytes) {
513 const uint32_t remaining = len - off;
514 const uint32_t n =
515 (remaining < (uint32_t)k_app_mram_block_bytes) ? remaining : (uint32_t)k_app_mram_block_bytes;
516 const ra8_err_t e = ra8_flash_extra_mram_write(addr + off, &src[off], n);
517 if (e != k_ra8_ok) {
518 return e;
519 }
520 }
521 return k_ra8_ok;
522}
523
544static ra8_err_t app_flash_readback(void* ctx, uint32_t addr, uint8_t* dst, uint32_t len)
545{
546 (void)ctx;
547 RA8_CHECK_NULL_PTR(dst, s_tag, "flash.readback dst");
548 (void)memcpy(dst, (const void*)(uintptr_t)addr, (size_t)len);
549 return k_ra8_ok;
550}
551
571static ra8_err_t app_write_bootsel(uint8_t bank)
572{
573 uint8_t rec[k_app_mram_block_bytes] = {};
574 for (uint8_t i = 0U; i < (uint8_t)k_app_rec_off_bank; ++i) {
575 rec[(uint8_t)k_app_rec_off_magic + i] =
576 (uint8_t)((uint32_t)k_app_bootsel_magic >> ((uint32_t)i * (uint32_t)k_app_octet_bits));
577 }
578 rec[k_app_rec_off_bank] = bank;
580 for (uint8_t i = 0U; i < (uint8_t)k_app_rec_off_bank; ++i) {
581 rec[(uint8_t)k_app_rec_off_seq + i] =
582 (uint8_t)(s_bootsel_seq >> ((uint32_t)i * (uint32_t)k_app_octet_bits));
583 }
585 if (e != k_ra8_ok) {
586 return e;
587 }
588 return ra8_flash_extra_mram_write((uint32_t)k_app_bootsel_addr, rec, (uint32_t)sizeof rec);
589}
590
610static ra8_err_t app_flash_set_startup(void* ctx, uint8_t which_bank, bool persistent)
611{
612 (void)ctx;
613 (void)persistent;
614 return app_write_bootsel(which_bank);
615}
616
632static ra8_err_t app_read_bootsel(uint8_t* out_bank, bool* out_valid)
633{
634 RA8_CHECK_NULL_PTR(out_bank, s_tag, "bootsel out_bank");
635 RA8_CHECK_NULL_PTR(out_valid, s_tag, "bootsel out_valid");
636 const uint8_t* rec = (const uint8_t*)(uintptr_t)k_app_bootsel_addr;
637 uint32_t magic = 0U;
638 for (uint8_t i = 0U; i < (uint8_t)k_app_rec_off_bank; ++i) {
639 magic |= ((uint32_t)rec[(uint8_t)k_app_rec_off_magic + i])
640 << ((uint32_t)i * (uint32_t)k_app_octet_bits);
641 }
642 *out_valid = (magic == (uint32_t)k_app_bootsel_magic);
643 *out_bank = rec[k_app_rec_off_bank];
644 return k_ra8_ok;
645}
646
647/* -------------------------------------------------------------------------- */
648/* Pure A/B decision logic (unit-tested with MC/DC) */
649/* -------------------------------------------------------------------------- */
650
672{
673 if ((result == k_ra8_ok) && (state == k_ra8_ota_state_done)) {
675 }
676 if ((result != k_ra8_ok) && (state == k_ra8_ota_state_error)) {
678 }
680}
681
697static bool app_ab_ok(bool committed, bool rolled_back)
698{
699 return committed && rolled_back;
700}
701
702/* -------------------------------------------------------------------------- */
703/* Scenario driver + manifest construction */
704/* -------------------------------------------------------------------------- */
705
719{
720 (void)memset(cfg, 0, sizeof *cfg);
721 (void)memcpy(cfg->manifest_url,
722 "local://demo/manifest",
723 app_strlen("local://demo/manifest") + 1U);
724 cfg->pubkey_handle = (uint32_t)k_app_demo_pubkey;
725
726 cfg->net.open = app_net_open;
727 cfg->net.read = app_net_read;
728 cfg->net.close = app_net_close;
729 cfg->net.ctx = &s_net_source;
730
735 cfg->crypto.ctx = &s_sha_ctx;
736
743 cfg->flash.inactive_bank_index = (uint8_t)k_app_bank_b;
744 cfg->flash.ctx = nullptr;
745}
746
760{
761 (void)memset(m, 0, sizeof *m);
762 (void)memcpy(m->version, "1.0.1", app_strlen("1.0.1") + 1U);
763 (void)memcpy(m->image_url, "local://demo/app.bin", app_strlen("local://demo/app.bin") + 1U);
764 m->image_size_bytes = (uint32_t)k_app_image_bytes;
766 /* Demo authenticity tag: a fixed full-width pattern the demo verifier
767 * accepts. TODO(real ECDSA-P256): replace with a server ECDSA signature. */
768 for (uint8_t i = 0U; i < (uint8_t)k_app_sig_bytes; ++i) {
769 m->signature[i] = (uint8_t)((uint8_t)k_app_sig_tag_base ^ i);
770 }
771 m->signature_len = (uint16_t)k_app_sig_bytes;
772}
773
795static app_outcome_t
796app_run_attempt(const uint8_t* source, const ra8_ota_manifest_t* m, uint8_t* out_bank)
797{
798 *out_bank = (uint8_t)k_app_bank_a;
799 if (app_write_bootsel((uint8_t)k_app_bank_a) != k_ra8_ok) {
801 }
802 s_net_source.data = source;
803 s_net_source.len = (uint32_t)k_app_image_bytes;
804 s_net_source.pos = 0U;
805
806 ra8_ota_cfg_t cfg;
807 app_make_cfg(&cfg);
808 (void)ra8_ota_deinit();
809 if (ra8_ota_init(&cfg) != k_ra8_ok) {
811 }
812
814 if (result == k_ra8_ok) {
815 result = ra8_ota_verify_signature(m);
816 }
817 if (result == k_ra8_ok) {
818 result = ra8_ota_commit_and_reboot();
819 }
820 const ra8_ota_state_t state = ra8_ota_get_state();
821
822 bool valid = false;
823 (void)app_read_bootsel(out_bank, &valid);
824 (void)ra8_ota_deinit();
825 return app_ab_classify(result, state);
826}
827
828/* -------------------------------------------------------------------------- */
829/* Setup + banner */
830/* -------------------------------------------------------------------------- */
831
846{
847 for (uint32_t i = 0U; i < (uint32_t)k_app_image_bytes; ++i) {
848 s_image_good[i] = (uint8_t)(i * (uint32_t)k_app_img_seed_mul + (uint32_t)k_app_img_seed_add);
850 }
851 /* Corrupt the rollback image so its re-hash cannot match the manifest digest
852 * -- the "bad download" that must NOT be committed. */
853 s_image_bad[0] = (uint8_t)(s_image_good[0] ^ (uint8_t)k_app_byte_all_ones);
855}
856
871{
872 if (ra8_cgc_init() != k_ra8_ok) {
873 return k_ra8_err_hw_error;
874 }
876 return k_ra8_err_hw_error;
877 }
878 const ra8_flash_cfg_t fcfg = {
879 .mrcfreq_mhz = (uint16_t)k_app_mrcfreq_mhz,
880 .mrefreq_mhz = (uint8_t)k_app_mrefreq_mhz,
881 .prefetch_en = true,
882 .ecc_encoder_enable = true,
883 .ecc_decoder_enable = true,
884 };
885 return ra8_flash_init(&fcfg);
886}
887
902static void app_print_banner(bool staged, bool committed, bool rolled_back)
903{
904 app_print("ota_ab: stage=");
905 app_print(staged ? "ok" : "fail");
906 app_print(" commit=");
907 app_print(committed ? "Y" : "N");
908 app_print(" rollback=");
909 app_print(rolled_back ? "Y" : "N");
910 app_print(" ok=");
911 app_print(app_ab_ok(committed, rolled_back) ? "Y" : "N");
912 app_print("\r\n");
913}
914
925void main(void)
926{
927 if (app_setup() != k_ra8_ok) {
928 /* NASA Rule 2 exemption: terminal panic spin on a fatal bring-up error. */
929 while (true) {
930 }
931 }
932
933 const bool staged = (app_stage_images() == k_ra8_ok);
934
935 bool committed = false;
936 bool rolled_back = false;
937 if (staged) {
940
941 uint8_t bank_after = (uint8_t)k_app_bank_a;
942 const app_outcome_t good = app_run_attempt(s_image_good, &m, &bank_after);
943 committed = (good == k_app_outcome_committed) && (bank_after == (uint8_t)k_app_bank_b);
944
945 const app_outcome_t bad = app_run_attempt(s_image_bad, &m, &bank_after);
946 rolled_back = (bad == k_app_outcome_rolled_back) && (bank_after == (uint8_t)k_app_bank_a);
947 }
948
949 (void)app_print("\r\nra8d2 ota_ab_orchestration (A/B stage/verify/commit/rollback)\r\n");
950
951 /* NASA Rule 2 exemption: deliberate report loop; the verdict is latched, the
952 * banner just repeats so a UART scrape reliably captures it. */
953 while (true) {
954 app_print_banner(staged, committed, rolled_back);
955 for (volatile uint32_t d = 0U; d < (uint32_t)k_app_report_delay; ++d) {
956 /* coarse inter-report busy delay (bounded). */
957 }
958 }
959}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static ra8_err_t app_read_bootsel(uint8_t *out_bank, bool *out_valid)
Read the persisted boot-select record.
Definition main.c:632
static ra8_rsip_sha256_ctx_t s_sha_ctx
Streaming SHA-256 context backing the OTA crypto interface.
Definition main.c:193
static ra8_err_t app_net_read(void *ctx, uint8_t *dst, uint32_t cap, uint32_t *out_len)
Copy up to cap bytes from the staged image (OTA net.read).
Definition main.c:304
static ra8_err_t app_sha_update(void *ctx, const uint8_t *data, uint32_t len)
Absorb bytes into the SHA-256 (OTA crypto.sha256_update).
Definition main.c:380
static app_outcome_t app_run_attempt(const uint8_t *source, const ra8_ota_manifest_t *m, uint8_t *out_bank)
Drive one full A/B attempt against source and classify it.
Definition main.c:796
app_mram_addr_t
Extra-MRAM option-setting addresses the demo owns (0x02E07600, 12 KiB).
Definition main.c:100
@ k_app_bank_addr
Inactive-bank base (extra-MRAM start).
Definition main.c:101
@ k_app_bootsel_addr
Persistent boot-select record (own block).
Definition main.c:102
static ra8_err_t app_ecdsa_verify(void *ctx, uint32_t pubkey, const uint8_t bound[k_ra8_ota_sha256_bytes], const uint8_t *sig, uint32_t sig_len)
DEMO authenticity check standing in for ECDSA-P256 (OTA crypto.ecdsa_verify).
Definition main.c:436
static uint8_t s_image_bad[k_app_image_bytes]
Corrupted image bytes for the rollback path (one flipped byte).
Definition main.c:202
static ra8_err_t app_flash_readback(void *ctx, uint32_t addr, uint8_t *dst, uint32_t len)
Read the inactive bank back for re-hash (OTA flash.readback).
Definition main.c:544
app_pattern_t
Deterministic demo-image byte-pattern + tag constants.
Definition main.c:145
@ k_app_img_seed_mul
Golden-image pattern multiplier.
Definition main.c:146
@ k_app_sig_tag_base
Demo signature tag base byte.
Definition main.c:148
@ k_app_img_seed_add
Golden-image pattern additive bias.
Definition main.c:147
@ k_app_byte_all_ones
Corrupt-flip mask / erased MRAM byte.
Definition main.c:149
static void app_print(const char *text)
Print a NUL-terminated ASCII string on the board VCOM console.
Definition main.c:248
static ra8_err_t app_stage_images(void)
Fill the golden/corrupt image blobs and precompute the manifest digest.
Definition main.c:845
static ra8_err_t app_flash_erase(void *ctx, uint32_t addr, uint32_t len)
Erase the inactive bank region (OTA flash.erase).
Definition main.c:474
app_size_t
Small byte-width and record-layout constants.
Definition main.c:119
@ k_app_mram_block_bytes
Extra-MRAM erase/program granularity.
Definition main.c:120
@ k_app_rec_off_seq
Boot-select record: seq byte offset.
Definition main.c:124
@ k_app_rec_off_bank
Boot-select record: bank byte offset.
Definition main.c:123
@ k_app_sig_bytes
Demo signature length.
Definition main.c:121
@ k_app_octet_bits
Bits per octet for LE spreads.
Definition main.c:125
@ k_app_rec_off_magic
Boot-select record: magic byte offset.
Definition main.c:122
static void app_make_manifest(ra8_ota_manifest_t *m)
Build the demo manifest describing the good image.
Definition main.c:759
static app_net_source_t s_net_source
The staged image source (rebound per scenario).
Definition main.c:190
app_flash_freq_t
MRAM controller advertised clock rates for ra8_flash_init.
Definition main.c:132
@ k_app_mrefreq_mhz
Extra-MRAM advertised clock (MHz).
Definition main.c:134
@ k_app_mrcfreq_mhz
Code-MRAM advertised clock (MHz).
Definition main.c:133
static void app_print_banner(bool staged, bool committed, bool rolled_back)
Print the one-line A/B verdict banner over the console.
Definition main.c:902
static ra8_err_t app_sha_init(void *ctx)
Begin a streaming SHA-256 (OTA crypto.sha256_init).
Definition main.c:359
static ra8_err_t app_write_bootsel(uint8_t bank)
Persist the A/B boot-select record for bank.
Definition main.c:571
static ra8_err_t app_flash_set_startup(void *ctx, uint8_t which_bank, bool persistent)
Latch the inactive bank as the next boot bank (OTA flash.set_startup).
Definition main.c:610
app_bank_t
A/B slot identifiers persisted in the boot-select record.
Definition main.c:110
@ k_app_bank_b
Slot B (the inactive/update target).
Definition main.c:112
@ k_app_bank_a
Slot A (the initially-active bank).
Definition main.c:111
app_outcome_t
Classified result of one A/B update attempt.
Definition main.c:160
@ k_app_outcome_rolled_back
Verify failed; no swap; active bank kept.
Definition main.c:162
@ k_app_outcome_committed
Verify passed and the bank swap latched.
Definition main.c:161
@ k_app_outcome_indeterminate
Neither terminal shape matched.
Definition main.c:163
static bool app_ab_ok(bool committed, bool rolled_back)
Final demo verdict: both A/B paths behaved as designed.
Definition main.c:697
static uint8_t s_image_good[k_app_image_bytes]
Golden image bytes for the commit path (deterministic pattern).
Definition main.c:199
static ra8_err_t app_sha_final(void *ctx, uint8_t out[k_ra8_ota_sha256_bytes])
Finalise the SHA-256 digest (OTA crypto.sha256_final).
Definition main.c:400
app_const_t
Console, MRAM layout, and demo-image sizing constants.
Definition main.c:78
@ k_app_bootsel_magic
Boot-select record magic ("BOOT A/B").
Definition main.c:83
@ k_app_image_bytes
Demo firmware image size (multiple of 32).
Definition main.c:80
@ k_app_demo_pubkey
Opaque demo public-key handle.
Definition main.c:84
@ k_app_uart_baud
J-Link OB VCOM console baud.
Definition main.c:79
@ k_app_report_delay
Bounded busy-wait between banner prints.
Definition main.c:82
@ k_app_bank_size_bytes
Advertised bank capacity for the OTA cfg.
Definition main.c:81
static app_outcome_t app_ab_classify(ra8_err_t result, ra8_ota_state_t state)
Classify one update attempt from its return code and final state.
Definition main.c:671
static uint32_t s_bootsel_seq
Monotonic sequence number stamped into each boot-select record.
Definition main.c:196
static ra8_err_t app_flash_program(void *ctx, uint32_t addr, const uint8_t *src, uint32_t len)
Program bytes into the inactive bank (OTA flash.program).
Definition main.c:508
static ra8_err_t app_net_close(void *ctx)
Tear down the local stream (OTA net.close); a no-op here.
Definition main.c:336
static uint8_t s_image_good_digest[k_ra8_ota_sha256_bytes]
SHA-256 of s_image_good, published as the manifest digest.
Definition main.c:205
static size_t app_strlen(const char *text)
Bounded length of a NUL-terminated ASCII string.
Definition main.c:224
static ra8_err_t app_net_open(void *ctx, const char *url, uint32_t *out_content_len)
Begin serving the staged image (OTA net.open).
Definition main.c:276
static ra8_err_t app_setup(void)
Bring up CGC + the board VCOM console + the MRAM controller.
Definition main.c:870
static void app_make_cfg(ra8_ota_cfg_t *cfg)
Assemble the OTA config wired to this app's backends.
Definition main.c:718
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_uart_console_write(const uint8_t *data, size_t len)
Polled blocking write to the J-Link OB VCOM console.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_hw_error
Generic hardware fault detected (error flag set, fault interrupt).
Definition ra8_err.h:310
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Code MRAM + Extra MRAM + Option-Setting driver – DANGEROUS, brick-capable.
ra8_err_t ra8_flash_init(const ra8_flash_cfg_t *cfg)
Initialise the MRAM controller for safe read access.
Definition ra8_flash.c:386
ra8_err_t ra8_flash_extra_mram_erase(uint32_t mram_addr)
Erase one 32-byte block of extra-MRAM via MACI.
ra8_err_t ra8_flash_extra_mram_write(uint32_t mram_addr, const uint8_t *src, uint32_t len)
Program 1..32 contiguous bytes into the general-purpose extra-MRAM window.
@ k_ra8_flash_extra_start
First legal Program target (FSBL setting).
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Phase-5 OTA firmware-update orchestration for the RA8D2.
ra8_err_t ra8_ota_commit_and_reboot(void)
Persist the bank swap and reboot.
Definition ra8_ota.c:603
ra8_err_t ra8_ota_download_to_inactive_bank(const ra8_ota_manifest_t *manifest)
Stream the firmware blob into the inactive MRAM bank.
Definition ra8_ota.c:534
ra8_ota_state_t
Cooperative state-machine states.
Definition ra8_ota.h:91
@ k_ra8_ota_state_error
Last operation failed; see last err.
Definition ra8_ota.h:98
@ k_ra8_ota_state_done
Update applied (reset is imminent).
Definition ra8_ota.h:97
ra8_err_t ra8_ota_init(const ra8_ota_cfg_t *cfg)
Initialise the OTA module.
Definition ra8_ota.c:182
ra8_ota_state_t ra8_ota_get_state(void)
Return the current state-machine value.
Definition ra8_ota.c:257
ra8_err_t ra8_ota_verify_signature(const ra8_ota_manifest_t *manifest)
Verify SHA-256 + ECDSA over the freshly programmed bank.
@ k_ra8_ota_sha256_bytes
SHA-256 digest length.
Definition ra8_ota.h:75
ra8_err_t ra8_ota_deinit(void)
Tear the OTA module down (mostly for tests / re-init).
Definition ra8_ota.c:224
Renesas Secure IP (RSIP-E50D) HAL driver – public API.
ra8_err_t ra8_rsip_sha256_final(ra8_rsip_sha256_ctx_t *ctx, uint8_t *digest_out)
Emit the digest of a streaming SHA-256 context.
Definition ra8_rsip.c:794
ra8_err_t ra8_rsip_sha256_update(ra8_rsip_sha256_ctx_t *ctx, const uint8_t *data, uint32_t len)
Absorb additional bytes into a streaming SHA-256 context.
Definition ra8_rsip.c:759
ra8_err_t ra8_rsip_sha256(const uint8_t *msg, uint32_t msg_len, uint8_t *digest)
Compute SHA-256 of an in-memory buffer.
Definition ra8_rsip.c:397
ra8_err_t ra8_rsip_sha256_init(ra8_rsip_sha256_ctx_t *ctx)
Initialise a streaming SHA-256 context.
Definition ra8_rsip.c:747
Secure-comparison primitives for the crypto / secure-boot paths.
In-RAM "download" cursor handed to the OTA net interface.
Definition main.c:183
const uint8_t * data
Image bytes being served.
Definition main.c:184
uint32_t pos
Bytes already handed to the OTA.
Definition main.c:186
uint32_t len
Total image length in bytes.
Definition main.c:185
Initialisation descriptor for ra8_flash_init.
Initialisation descriptor for ra8_ota_init.
Definition ra8_ota.h:258
ra8_ota_crypto_iface_t crypto
Crypto interface (must be fully populated).
Definition ra8_ota.h:272
char manifest_url[k_ra8_ota_url_max_bytes]
HTTPS URL of the manifest JSON.
Definition ra8_ota.h:260
uint32_t pubkey_handle
Opaque handle to the trusted ECDSA public key.
Definition ra8_ota.h:263
ra8_ota_flash_iface_t flash
Flash backend (must be fully populated).
Definition ra8_ota.h:275
ra8_ota_net_iface_t net
Network HTTPS interface (must be fully populated).
Definition ra8_ota.h:269
void * ctx
Opaque context passed back to every callback.
Definition ra8_ota.h:214
ra8_err_t(* ecdsa_verify)(void *ctx, uint32_t pubkey_handle, const uint8_t digest[k_ra8_ota_sha256_bytes], const uint8_t *sig, uint32_t sig_len)
Verify sig is a valid ECDSA signature over digest using the public key referenced by pubkey_handle.
Definition ra8_ota.h:207
ra8_err_t(* sha256_final)(void *ctx, uint8_t out[k_ra8_ota_sha256_bytes])
Finalise and write the 32-byte digest to out.
Definition ra8_ota.h:201
ra8_err_t(* sha256_update)(void *ctx, const uint8_t *data, uint32_t len)
Feed bytes to the running SHA-256 hash.
Definition ra8_ota.h:199
ra8_err_t(* sha256_init)(void *ctx)
Begin a SHA-256 streaming hash.
Definition ra8_ota.h:197
uint8_t inactive_bank_index
Bank index set_startup should select on commit.
Definition ra8_ota.h:243
ra8_err_t(* program)(void *ctx, uint32_t addr, const uint8_t *src, uint32_t len)
Program len bytes at addr (must be 32-byte aligned).
Definition ra8_ota.h:232
ra8_err_t(* set_startup)(void *ctx, uint8_t which_bank, bool persistent)
Pick the bank to boot from at the next reset.
Definition ra8_ota.h:234
uint32_t inactive_bank_addr
Base address of the inactive bank in the MRAM window.
Definition ra8_ota.h:239
uint32_t bank_size_bytes
Size of one bank in bytes.
Definition ra8_ota.h:241
void * ctx
Opaque context passed back to every callback.
Definition ra8_ota.h:246
ra8_err_t(* erase)(void *ctx, uint32_t addr, uint32_t len)
Erase len bytes starting at addr in the inactive bank.
Definition ra8_ota.h:230
ra8_err_t(* readback)(void *ctx, uint32_t addr, uint8_t *dst, uint32_t len)
Read back len bytes (used by verification re-hash).
Definition ra8_ota.h:236
Decoded representation of the server manifest.
Definition ra8_ota.h:115
uint8_t image_sha256[k_ra8_ota_sha256_bytes]
Expected digest.
Definition ra8_ota.h:119
uint16_t signature_len
Bytes used in signature.
Definition ra8_ota.h:121
char image_url[k_ra8_ota_url_max_bytes]
HTTPS URL of the image blob.
Definition ra8_ota.h:117
uint8_t signature[k_ra8_ota_signature_max_bytes]
ECDSA signature over digest.
Definition ra8_ota.h:120
uint32_t image_size_bytes
Image size on the wire.
Definition ra8_ota.h:118
char version[k_ra8_ota_version_str_bytes]
Firmware version string.
Definition ra8_ota.h:116
ra8_err_t(* close)(void *ctx)
Tear the streaming GET down.
Definition ra8_ota.h:179
ra8_err_t(* open)(void *ctx, const char *url, uint32_t *out_content_len)
Begin a streaming GET against url.
Definition ra8_ota.h:168
void * ctx
Opaque context passed back to every callback.
Definition ra8_ota.h:182
ra8_err_t(* read)(void *ctx, uint8_t *dst, uint32_t cap, uint32_t *out_len)
Read up to cap bytes from the open session.
Definition ra8_ota.h:174
Streaming state for incremental SHA-256.