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

Phase-5 OTA firmware-update orchestration for the RA8D2. More...

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

Go to the source code of this file.

Data Structures

struct  ra8_ota_manifest_t
 Decoded representation of the server manifest. More...
struct  ra8_ota_progress_t
 Snapshot delivered to the caller's progress callback. More...
struct  ra8_ota_net_iface_t
 Injected HTTPS-download interface (Dependency Inversion). More...
struct  ra8_ota_crypto_iface_t
 Injected hash + ECDSA verification interface. More...
struct  ra8_ota_flash_iface_t
 Injected flash backend (so tests do not need real MRAM). More...
struct  ra8_ota_cfg_t
 Initialisation descriptor for ra8_ota_init. More...

Typedefs

typedef void(* ra8_ota_progress_cb_t) (const ra8_ota_progress_t *p)
 Caller progress callback type.

Enumerations

enum  ra8_ota_constants_t : uint32_t {
  k_ra8_ota_chunk_bytes = 4096U ,
  k_ra8_ota_manifest_max_bytes = 2048U ,
  k_ra8_ota_sha256_bytes = 32U ,
  k_ra8_ota_signature_max_bytes = 96U ,
  k_ra8_ota_url_max_bytes = 256U ,
  k_ra8_ota_version_str_bytes = 32U ,
  k_ra8_ota_max_image_bytes = 0x80000U ,
  k_ra8_ota_thread_stack_bytes = 4096U
}
 Compile-time bounds for the OTA module. More...
enum  ra8_ota_state_t : uint8_t {
  k_ra8_ota_state_idle = 0U ,
  k_ra8_ota_state_checking = 1U ,
  k_ra8_ota_state_downloading = 2U ,
  k_ra8_ota_state_verifying = 3U ,
  k_ra8_ota_state_committing = 4U ,
  k_ra8_ota_state_done = 5U ,
  k_ra8_ota_state_error = 6U ,
  k_ra8_ota_state_count = 7U
}
 Cooperative state-machine states. More...

Functions

ra8_err_t ra8_ota_init (const ra8_ota_cfg_t *cfg)
 Initialise the OTA module.
ra8_err_t ra8_ota_deinit (void)
 Tear the OTA module down (mostly for tests / re-init).
ra8_err_t ra8_ota_check_for_update (ra8_ota_manifest_t *out_manifest)
 Fetch and decode the manifest JSON over HTTPS.
ra8_err_t ra8_ota_download_to_inactive_bank (const ra8_ota_manifest_t *manifest)
 Stream the firmware blob into the inactive MRAM bank.
ra8_err_t ra8_ota_verify_signature (const ra8_ota_manifest_t *manifest)
 Verify SHA-256 + ECDSA over the freshly programmed bank.
ra8_err_t ra8_ota_commit_and_reboot (void)
 Persist the bank swap and reboot.
ra8_ota_state_t ra8_ota_get_state (void)
 Return the current state-machine value.
ra8_err_t ra8_ota_run_step (void)
 Drive the OTA state machine one step forward.
ra8_err_t ra8_ota_run_full_update (void)
 Kick off an end-to-end update from idle.
void ra8_ota_system_reset_hook (void)
 Test/host hook for commit_and_reboot.

Detailed Description

Phase-5 OTA firmware-update orchestration for the RA8D2.

Tag
[Ring 4 / Service] {World: NS}

The RA8D2 has 1 MiB of code-MRAM split into two equal-size banks (HUM Ch 7.2 "BTFLG Boot-Area Swap" p 282..286 + HUM Ch 59.5 "MSUACR / MSUASMON" p 3582..3586). At any moment the part is executing out of one bank ("active"); the other bank ("inactive") is free to be erased and re-programmed. ra8_ota orchestrates the safe-update flow on top of the existing ra8_flash driver:

State machine (single thread, optionally a ThreadX worker):
IDLE -> CHECKING -> DOWNLOADING -> VERIFYING -> COMMITTING -> DONE
| | |
v v v
ERROR <-----'-----<--------'

Each public entry point is one transition arrow. ra8_ota_run_step drives the machine cooperatively from a caller's main loop; cfg.run_as_thread = true instead spawns a single static ThreadX thread that calls ra8_ota_run_step until DONE / ERROR.

The HTTPS download and ECDSA verification are exposed through function-pointer interfaces (ra8_ota_net_iface_t, ra8_ota_crypto_iface_t) so the module compiles independently of ra8_tls / mbedtls / tf-psa-crypto and can be unit-tested with mocks. This is the Dependency-Inversion deviation called out in CLAUDE.md "NASA Rule 9 -- INTENTIONAL DEVIATION".

Memory budget:

Every buffer is a file-static in ra8_ota.c. There is zero dynamic allocation anywhere in this module (NASA Rule 3).

Definition in file ra8_ota.h.

Typedef Documentation

◆ ra8_ota_progress_cb_t

typedef void(* ra8_ota_progress_cb_t) (const ra8_ota_progress_t *p)

Caller progress callback type.

Parameters
[in]pSnapshot of OTA progress (state, bytes, last err).
Precondition
p non-NULL (guaranteed by the dispatcher).
Postcondition
Callback returns; the OTA module continues with the next state-machine step.
Note
Runs in the OTA worker context (or the caller's thread when cooperatively driven). Keep it short and non-blocking.

Definition at line 147 of file ra8_ota.h.

Enumeration Type Documentation

◆ ra8_ota_constants_t

enum ra8_ota_constants_t : uint32_t

Compile-time bounds for the OTA module.

Centralises every numeric limit so callers and unit tests can reference them by name. All values are typed (NASA Rule 8 + CLAUDE.md "C23 typed enums").

Enumerator
k_ra8_ota_chunk_bytes 

Download streaming chunk size in bytes.

k_ra8_ota_manifest_max_bytes 

Largest accepted manifest payload.

k_ra8_ota_sha256_bytes 

SHA-256 digest length.

k_ra8_ota_signature_max_bytes 

ECDSA-P256 ASN.1 sig upper bound.

k_ra8_ota_url_max_bytes 

NUL-terminated URL upper bound.

k_ra8_ota_version_str_bytes 

NUL-terminated version string.

k_ra8_ota_max_image_bytes 

512 KiB upper bound per bank.

k_ra8_ota_thread_stack_bytes 

Static ThreadX worker stack.

Definition at line 72 of file ra8_ota.h.

◆ ra8_ota_state_t

enum ra8_ota_state_t : uint8_t

Cooperative state-machine states.

Returned by ra8_ota_get_state. Values are stable across calls so callers may compare with == or use them as table indices.

Enumerator
k_ra8_ota_state_idle 

No update in progress.

k_ra8_ota_state_checking 

Manifest fetch in flight.

k_ra8_ota_state_downloading 

Streaming firmware to inactive bank.

k_ra8_ota_state_verifying 

SHA-256 + ECDSA verification.

k_ra8_ota_state_committing 

About to swap banks + reset.

k_ra8_ota_state_done 

Update applied (reset is imminent).

k_ra8_ota_state_error 

Last operation failed; see last err.

k_ra8_ota_state_count 

Sentinel.

Definition at line 91 of file ra8_ota.h.

Function Documentation

◆ ra8_ota_check_for_update()

ra8_err_t ra8_ota_check_for_update ( ra8_ota_manifest_t * out_manifest)
nodiscard

Fetch and decode the manifest JSON over HTTPS.

Drives cfg.net.open / read / close against the manifest URL, runs a small JSON parser to extract version, image URL, image size, expected SHA-256 and ECDSA signature, and returns the decoded struct in out_manifest. The bytes of the JSON itself are dropped after decoding – only the fixed-size struct is kept.

Parameters
[out]out_manifestNon-NULL destination.
Returns
ra8_err_t outcome.
Return values
k_ra8_okManifest decoded.
k_ra8_err_null_ptrout_manifest was NULL.
k_ra8_err_not_initializedra8_ota_init not called.
k_ra8_err_invalid_stateModule not in idle.
k_ra8_err_hw_errorNetwork backend reported an error.
k_ra8_err_invalid_sizeManifest exceeded k_ra8_ota_manifest_max_bytes.
k_ra8_err_invalid_argJSON malformed / missing field.
Precondition
ra8_ota_init has been called.
out_manifest non-NULL.
Postcondition
On success, every field in *out_manifest is populated.
Module returns to k_ra8_ota_state_idle on either path.
Note
Thread-safe: no.
Since
0.1.0

Fetch and decode the manifest JSON over HTTPS.

Transitions the state machine idle -> checking -> idle (success) or idle -> checking -> error (failure). On success the manifest is mirrored both into *out_manifest and into the module-private s_manifest so subsequent steps can refer to it.

Parameters
[out]out_manifestCaller-owned manifest buffer.
Returns
ra8_err_t outcome.
Return values
k_ra8_okManifest cached and returned.
k_ra8_err_not_initializedModule not initialized.
k_ra8_err_null_ptrout_manifest was NULL.
k_ra8_err_invalid_stateModule not in idle.
otherNetwork or decode error.
Precondition
ra8_ota_init succeeded.
Module is in k_ra8_ota_state_idle.
Postcondition
On success state == idle, manifest is cached.
On failure state == error with s_last_err set.
See also
ra8_ota_download_to_inactive_bank()
Note
Thread-safe: no.
Since
0.1.0

Definition at line 338 of file ra8_ota.c.

References g_ra8_ota_buf, g_ra8_ota_initialized, g_ra8_ota_state, internal_fetch_manifest_payload(), k_ra8_err_invalid_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_checking, k_ra8_ota_state_error, k_ra8_ota_state_idle, memcpy(), priv_ota_manifest_decode(), priv_ota_set_state(), RA8_CHECK_NULL_PTR, s_manifest, s_manifest_valid, and s_tag.

Referenced by internal_step_dispatch().

◆ ra8_ota_commit_and_reboot()

ra8_err_t ra8_ota_commit_and_reboot ( void )
nodiscard

Persist the bank swap and reboot.

Calls cfg.flash.set_startup with the inactive-bank index and persistent = true (so BTFLG sticks across reset), sets the state to k_ra8_ota_state_done, and – in production – triggers NVIC_SystemReset. In the host test build the system-reset call is forwarded to a weak ra8_ota_system_reset_hook symbol so the test process does not actually exit.

Returns
ra8_err_t outcome (caller usually never sees the success path on hardware – the part is already resetting).
Return values
k_ra8_okBoot bank swapped (host build only).
k_ra8_err_not_initializedModule not initialized.
k_ra8_err_invalid_stateVerification has not passed.
k_ra8_err_hw_errorset_startup failed.
Precondition
Verification has passed (state == committing).
Postcondition
On hardware, the part resets and boots from the new bank.
Note
Thread-safe: no.
Warning
Calling this without prior verification will boot unverified code on the next reset.
Since
0.1.0

Persist the bank swap and reboot.

Calls g_ra8_ota_cfg.flash.set_startup to mark the inactive bank as the boot bank, then invokes ra8_ota_system_reset_hook (which on hardware overrides to NVIC_SystemReset and on host is a no-op for testability).

Returns
ra8_err_t outcome.
Return values
k_ra8_okBank latched (the call normally doesn't return on hardware).
k_ra8_err_not_initializedModule not initialized.
k_ra8_err_invalid_stateModule not in committing.
otherBackend error from set_startup.
Precondition
ra8_ota_verify_signature succeeded.
Module is in k_ra8_ota_state_committing.
Postcondition
On success state == done and the system reset hook fired.
On failure state == error.
See also
ra8_ota_system_reset_hook()
Note
Thread-safe: no.
Since
0.1.0

Definition at line 603 of file ra8_ota.c.

References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_err_invalid_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_committing, k_ra8_ota_state_done, k_ra8_ota_state_error, priv_ota_set_state(), and ra8_ota_system_reset_hook().

Referenced by app_run_attempt(), and internal_step_dispatch().

◆ ra8_ota_deinit()

ra8_err_t ra8_ota_deinit ( void )
nodiscard

Tear the OTA module down (mostly for tests / re-init).

Aborts an in-progress download, signals the worker thread to exit, and clears the module-static state. Safe to call from idle.

Returns
ra8_err_t outcome.
Return values
k_ra8_okModule deinitialized.
Precondition
None.
Postcondition
Module is back in the uninitialized state.
Calling any other ra8_ota_* API now returns k_ra8_err_not_initialized.
Note
Thread-safe: no.
Since
0.1.0

Tear the OTA module down (mostly for tests / re-init).

Clears the cached configuration, manifest, byte-counter and last error so a future ra8_ota_init starts from a clean slate.

Returns
ra8_err_t outcome.
Return values
k_ra8_okAlways succeeds.
Precondition
None (safe to call before init).
Postcondition
g_ra8_ota_initialized is false.
g_ra8_ota_cfg is zeroed.
See also
ra8_ota_init()
Note
Thread-safe: no – intended to be called when no OTA worker is running.
Since
0.1.0
Precondition
Module has been initialized.

Definition at line 224 of file ra8_ota.c.

References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_ok, k_ra8_ota_state_idle, memset(), s_bytes_done, s_last_err, and s_manifest_valid.

Referenced by app_run_attempt().

◆ ra8_ota_download_to_inactive_bank()

ra8_err_t ra8_ota_download_to_inactive_bank ( const ra8_ota_manifest_t * manifest)
nodiscard

Stream the firmware blob into the inactive MRAM bank.

Walks the image URL one k_ra8_ota_chunk_bytes chunk at a time. Each chunk is:

  1. Fed to the running SHA-256 context.
  2. Programmed into the inactive bank via cfg.flash.erase (first chunk only) and cfg.flash.program.
  3. Reported to cfg.on_progress if registered.

Writes are page-aligned (32-byte MRAM page). The function tracks a high-water byte offset so it can resume cleanly if the caller re-invokes it after a partial download.

Parameters
[in]manifestNon-NULL, validated manifest.
Returns
ra8_err_t outcome.
Return values
k_ra8_okAll bytes programmed.
k_ra8_err_null_ptrmanifest was NULL.
k_ra8_err_not_initializedModule not initialized.
k_ra8_err_invalid_stateWrong state for download.
k_ra8_err_invalid_sizeimage_size > bank size.
k_ra8_err_hw_errorFlash or network backend failed.
Precondition
manifest non-NULL with valid fields.
ra8_ota_init has been called.
Postcondition
On success, the inactive bank holds the new image.
On any error path, the inactive bank is left in an indeterminate state and must be re-erased before retrying.
Note
Thread-safe: no.
Since
0.1.0

Stream the firmware blob into the inactive MRAM bank.

On a fresh start (s_bytes_done == 0) erases the bank and primes the SHA accumulator via internal_prepare_bank. Then opens the image URL and runs internal_download_loop. On success the state machine lands in verifying; on failure it lands in error.

Parameters
[in]manifestManifest describing the image to fetch.
Returns
ra8_err_t outcome.
Return values
k_ra8_okDownload complete; ready to verify.
k_ra8_err_not_initializedModule not initialized.
k_ra8_err_null_ptrmanifest was NULL.
k_ra8_err_invalid_stateModule not in idle or downloading.
k_ra8_err_invalid_sizeImage larger than the configured bank.
otherNetwork / crypto / flash error.
Precondition
ra8_ota_init succeeded.
manifest non-NULL.
Postcondition
On success state == verifying.
On failure state == error with s_last_err set.
See also
ra8_ota_verify_signature()
Note
Thread-safe: no.
Since
0.1.0

Definition at line 534 of file ra8_ota.c.

References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, ra8_ota_manifest_t::image_size_bytes, ra8_ota_manifest_t::image_url, internal_download_loop(), internal_prepare_bank(), k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_downloading, k_ra8_ota_state_error, k_ra8_ota_state_idle, k_ra8_ota_state_verifying, priv_ota_download_state_invalid(), priv_ota_set_state(), RA8_CHECK_NULL_PTR, s_bytes_done, and s_tag.

Referenced by app_run_attempt(), and internal_step_dispatch().

◆ ra8_ota_get_state()

ra8_ota_state_t ra8_ota_get_state ( void )

Return the current state-machine value.

Direct read of the latched state byte. s_state is a single uint8_t so a torn read is impossible on the target.

Returns
One of ra8_ota_state_t; k_ra8_ota_state_idle if the module has not been initialized.
Return values
k_ra8_ota_state_idleUninitialized, idle, or already done.
k_ra8_ota_state_checkingManifest fetch in progress.
k_ra8_ota_state_downloadingImage download in progress.
k_ra8_ota_state_verifyingVerifying signature.
k_ra8_ota_state_committingCommitting bank swap.
k_ra8_ota_state_doneUpdate complete.
k_ra8_ota_state_errorLast step failed.
Precondition
None.
Postcondition
No state change.
Note
Thread-safe: read of a single uint8_t.
Since
0.1.0
Precondition
Module has been initialized.
Postcondition
Side effects bounded to documented state.

Return the current state-machine value.

Reads the latched g_ra8_ota_state directly. g_ra8_ota_state is a single byte, so a torn read is impossible on the target.

Returns
ra8_ota_state_t outcome.
Return values
k_ra8_ota_state_idleModule not initialized, or genuinely idle.
otherWhatever state the worker last latched.
Precondition
None (safe to call before init – returns idle).
Postcondition
No state mutated.
See also
ra8_ota_run_step()
Note
Thread-safe: yes – single-byte read of a static.
Since
0.1.0
Precondition
Module has been initialized.
Postcondition
Side effects bounded to documented state.

Definition at line 257 of file ra8_ota.c.

References g_ra8_ota_state.

Referenced by app_run_attempt().

◆ ra8_ota_init()

ra8_err_t ra8_ota_init ( const ra8_ota_cfg_t * cfg)
nodiscard

Initialise the OTA module.

Validates every field of cfg, copies it into module-static storage, optionally spawns the ThreadX worker, and parks the state machine in k_ra8_ota_state_idle.

Parameters
[in]cfgNon-NULL configuration descriptor.
Returns
ra8_err_t outcome.
Return values
k_ra8_okModule ready.
k_ra8_err_null_ptrcfg was NULL or any required function pointer was NULL.
k_ra8_err_invalid_argURL string was empty or not NUL-terminated; bank size 0; etc.
k_ra8_err_invalid_stateAlready initialized.
Precondition
cfg non-NULL.
Every interface in cfg has all its function pointers set.
Postcondition
Module is in k_ra8_ota_state_idle.
Subsequent ra8_ota_* calls are valid.
Note
Thread-safe: no, single-threaded init only.
See also
ra8_ota_deinit
Since
0.1.0

Initialise the OTA module.

Verifies the module is in the un-initialized state, runs the full priv_ota_validate_cfg check on cfg, then captures the descriptor by-value into g_ra8_ota_cfg and resets the state machine to k_ra8_ota_state_idle.

Parameters
[in]cfgConfiguration descriptor (function pointers + URLs).
Returns
ra8_err_t outcome.
Return values
k_ra8_okModule initialized.
k_ra8_err_invalid_stateModule already initialized.
k_ra8_err_null_ptrcfg (or sub-pointer) was NULL.
k_ra8_err_invalid_argConfiguration field out of range.
Precondition
Module is uninitialized (or ra8_ota_deinit was called).
All function pointers in cfg are wired up.
Postcondition
On success the module is in k_ra8_ota_state_idle.
On failure no module state was mutated.
Example:
ra8_ota_cfg_t cfg = { .net = { ... }, .crypto = { ... } };
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
ra8_err_t ra8_ota_init(const ra8_ota_cfg_t *cfg)
Initialise the OTA module.
Definition ra8_ota.c:182
Initialisation descriptor for ra8_ota_init.
Definition ra8_ota.h:258
See also
ra8_ota_deinit()
ra8_ota_run_full_update()
Note
Thread-safe: no.
Since
0.1.0

Definition at line 182 of file ra8_ota.c.

References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_ota_state_idle, memcpy(), priv_ota_validate_cfg(), s_bytes_done, s_last_err, and s_manifest_valid.

Referenced by app_run_attempt().

◆ ra8_ota_run_full_update()

ra8_err_t ra8_ota_run_full_update ( void )
nodiscard

Kick off an end-to-end update from idle.

Sequences check_for_update -> download_to_inactive_bank -> verify_signature -> commit_and_reboot against the cached manifest. Used by the ThreadX worker thread; equally available to single-threaded callers that prefer one call over driving the state machine themselves.

Returns
ra8_err_t outcome (the success path on hardware normally never returns – the part resets first).
Precondition
ra8_ota_init has been called.
Postcondition
Module is in done (success) or error (failure).
Note
Thread-safe: no.
Since
0.1.0

Kick off an end-to-end update from idle.

Loops calling ra8_ota_run_step for at most k_ra8_ota_state_count iterations (NASA Rule 2 bound: idle -> checking -> downloading -> verifying -> committing -> done). Stops early on done or error.

Returns
ra8_err_t outcome.
Return values
k_ra8_okUpdate completed (or already done).
k_ra8_err_not_initializedModule not initialized.
otherWhatever the failing step returned.
Precondition
ra8_ota_init succeeded.
Postcondition
Module is in done (success) or error (failure).
See also
ra8_ota_run_step()
Note
Thread-safe: no.
Since
0.1.0
Precondition
Module has been initialized.
Postcondition
Side effects bounded to documented state.

Definition at line 740 of file ra8_ota.c.

References g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_count, k_ra8_ota_state_done, k_ra8_ota_state_error, ra8_ota_run_step(), and s_last_err.

◆ ra8_ota_run_step()

ra8_err_t ra8_ota_run_step ( void )
nodiscard

Drive the OTA state machine one step forward.

For callers that opted out of cfg.run_as_thread: invoke this from a main loop. Each call advances at most one transition. The caller may inspect ra8_ota_get_state between invocations.

Returns
k_ra8_ok on a successful step (including no-op when already idle/done) or a state-specific error code.
Return values
k_ra8_okStep completed.
k_ra8_err_not_initializedModule not initialized.
Precondition
ra8_ota_init has been called.
Postcondition
The state machine is in the next state, done, or error.
Note
Thread-safe: no (the worker thread, if any, owns the SM).
Since
0.1.0

Thin wrapper over internal_step_dispatch that gates on g_ra8_ota_initialized. Intended for callers that opted out of running the OTA worker as a background thread.

Returns
ra8_err_t outcome.
Return values
k_ra8_okStep completed.
k_ra8_err_not_initializedModule not initialized.
otherStep-specific error.
Precondition
ra8_ota_init succeeded.
Postcondition
The state machine has advanced by at most one transition.
See also
ra8_ota_get_state()
ra8_ota_run_full_update()
Note
Thread-safe: no – single owner only.
Since
0.1.0
Precondition
Module has been initialized.
Postcondition
Side effects bounded to documented state.

Definition at line 707 of file ra8_ota.c.

References g_ra8_ota_initialized, internal_step_dispatch(), and k_ra8_err_not_initialized.

Referenced by ra8_ota_run_full_update().

◆ ra8_ota_system_reset_hook()

void ra8_ota_system_reset_hook ( void )

Test/host hook for commit_and_reboot.

Called instead of NVIC_SystemReset when the implementation detects it is running outside the ARM target (RA8_OFF_TARGET defined). Default implementation is a no-op. Tests override to count invocations.

Precondition
None (safe to call any time after init).
Caller has already latched the new boot bank.
Postcondition
Default implementation: no state mutation.
Target override: function does not return – the part resets.
Note
Weak symbol; safe to leave unimplemented.
Since
0.1.0

Test/host hook for commit_and_reboot.

Called from ra8_ota_commit_and_reboot after the bank-swap is latched. The hardware build overrides this with a definition that calls NVIC_SystemReset. The host (unit-test) build keeps the weak no-op default so tests can observe post-commit state without actually exiting the process.

Precondition
Weak symbol; safe to leave unimplemented.
Postcondition
Default no-op; target override never returns.
Example:
// In target firmware:
void ra8_ota_system_reset_hook(void) { NVIC_SystemReset(); }
void ra8_ota_system_reset_hook(void)
Test/host hook for commit_and_reboot.
Definition ra8_ota.c:791
Note
Thread-safe: target override does not return, so trivially safe.
Since
0.1.0

Definition at line 791 of file ra8_ota.c.

Referenced by ra8_ota_commit_and_reboot().

◆ ra8_ota_verify_signature()

ra8_err_t ra8_ota_verify_signature ( const ra8_ota_manifest_t * manifest)
nodiscard

Verify SHA-256 + ECDSA over the freshly programmed bank.

Re-reads the inactive bank chunk-by-chunk, computes the SHA-256, and compares it against manifest->image_sha256. On a match it binds the manifest metadata (version / image_url / image_size_bytes) into the signed material – the ECDSA verify runs over SHA-256 of the version, URL, size and image digest concatenated, not over the bare image digest – so a MITM that alters the declared version (an anti-rollback bypass), redirects the URL, or changes the size cannot present a valid signature (T5-05). Then it dispatches the crypto interface's ecdsa_verify over that bound digest and manifest->signature. All checks must pass.

Parameters
[in]manifestNon-NULL, validated manifest.
Returns
ra8_err_t outcome.
Return values
k_ra8_okVerification passed.
k_ra8_err_null_ptrmanifest was NULL.
k_ra8_err_not_initializedModule not initialized.
k_ra8_err_invalid_stateWrong state for verification.
k_ra8_err_crc_mismatchSHA-256 digest mismatch.
k_ra8_err_hw_errorECDSA verification rejected the signature (bad sig or tampered metadata).
Precondition
manifest non-NULL.
Inactive bank holds the freshly downloaded image.
Postcondition
On success, the module advances to k_ra8_ota_state_committing.
On failure, the module is in k_ra8_ota_state_error.
Note
Thread-safe: no.
Since
0.1.0

Verify SHA-256 + ECDSA over the freshly programmed bank.

Re-hashes the inactive bank via internal_rehash_bank and compares the digest against manifest->image_sha256. On a match it binds the manifest metadata (version / URL / size) into the signed material via internal_bind_manifest_material and invokes the configured ECDSA verifier over that metadata-bound digest, so a MITM that alters the declared version (defeating anti-rollback), redirects the URL, or changes the size cannot ride a signature made over the bare image digest (T5-05). On success the state machine lands in committing.

Parameters
[in]manifestManifest used for the download.
Returns
ra8_err_t outcome.
Return values
k_ra8_okImage authenticated.
k_ra8_err_not_initializedModule not initialized.
k_ra8_err_null_ptrmanifest was NULL.
k_ra8_err_invalid_stateModule not in verifying.
k_ra8_err_crc_mismatchSHA-256 mismatch (image corrupt).
k_ra8_err_hw_errorECDSA verify rejected the signature.
otherCrypto / flash backend error.
Precondition
ra8_ota_download_to_inactive_bank succeeded.
manifest non-NULL.
Postcondition
On success state == committing.
On failure state == error.
See also
ra8_ota_commit_and_reboot()
Note
Thread-safe: no.
Since
0.1.0

Definition at line 227 of file ra8_ota_verify.c.

References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, ra8_ota_manifest_t::image_sha256, internal_bind_manifest_material(), internal_rehash_bank(), k_ra8_err_crc_mismatch, k_ra8_err_hw_error, k_ra8_err_invalid_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_sha256_bytes, k_ra8_ota_state_committing, k_ra8_ota_state_error, k_ra8_ota_state_verifying, priv_ota_set_state(), RA8_CHECK_NULL_PTR, ra8_ct_equal(), s_tag, ra8_ota_manifest_t::signature, and ra8_ota_manifest_t::signature_len.

Referenced by app_run_attempt(), and internal_step_dispatch().