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

Phase-5 OTA signature-verification cluster – implementation. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_ota.h"
#include "ra8_ota_internal.h"
#include "ra8_secure.h"
Include dependency graph for ra8_ota_verify.c:

Go to the source code of this file.

Enumerations

enum  ra8_ota_bind_field_t : uint8_t {
  k_ra8_ota_size_field_bytes = 4U ,
  k_ra8_ota_octet_bits = 8U
}
 Fixed byte-widths bound into the OTA signature material (T5-05). More...

Functions

static ra8_err_t internal_rehash_bank (const ra8_ota_manifest_t *m, uint8_t out_digest[32])
 Re-hash the inactive bank to re-derive the digest after program.
static ra8_err_t internal_bind_manifest_material (const ra8_ota_manifest_t *manifest, const uint8_t *image_digest, uint8_t out_bound[k_ra8_ota_sha256_bytes])
 Bind manifest metadata (version/url/size) into the signed digest.
ra8_err_t ra8_ota_verify_signature (const ra8_ota_manifest_t *manifest)
 Verify the freshly-programmed bank against the manifest signature.

Variables

static const char *const s_tag = "ra8_ota"
 Module log tag (private copy; immutable literal).

Detailed Description

Phase-5 OTA signature-verification cluster – implementation.

Companion translation unit to ra8_ota.c. Holds the cohesive signature-verification responsibility so the orchestration TU stays under the per-file line budget:

  • internal_rehash_bank re-derives the inactive-bank SHA-256 after the streamed program pass.
  • internal_bind_manifest_material binds the manifest metadata (version / URL / size) plus the image digest into the canonical material the server ECDSA signature authenticates (T5-05).
  • ra8_ota_verify_signature (public API) compares the re-derived digest under a constant-time equality (T5-12) and then runs the injected ECDSA verifier over that bound material.

The verify path reads the module-static state defined in ra8_ota.c (configuration, state byte, init flag, streaming buffer) through the extern declarations in ra8_ota_internal.h and drives state transitions through priv_ota_set_state. The read-only log tag is duplicated locally (cheap, correct for an immutable literal). No malloc anywhere (NASA Rule 3); every loop has a static upper bound (NASA Rule 2).

Since
0.1.0

Definition in file ra8_ota_verify.c.

Enumeration Type Documentation

◆ ra8_ota_bind_field_t

enum ra8_ota_bind_field_t : uint8_t

Fixed byte-widths bound into the OTA signature material (T5-05).

The manifest metadata is bound into the signed digest with a fixed-width canonical layout: the NUL-padded version / image_url char arrays plus a 4-byte little-endian image size, then the image digest.

See also
internal_bind_manifest_material
Enumerator
k_ra8_ota_size_field_bytes 

Little-endian width of image_size_bytes.

k_ra8_ota_octet_bits 

Bits per octet for the LE size spread.

Definition at line 111 of file ra8_ota_verify.c.

Function Documentation

◆ internal_bind_manifest_material()

ra8_err_t internal_bind_manifest_material ( const ra8_ota_manifest_t * manifest,
const uint8_t * image_digest,
uint8_t out_bound[k_ra8_ota_sha256_bytes] )
static

Bind manifest metadata (version/url/size) into the signed digest.

The server ECDSA signature must authenticate the manifest metadata an attacker would tamper – not just the image bytes – so this recomputes the digest the verify runs over as SHA-256 of version[32], image_url[256], the 4-byte little-endian image size, then image_digest concatenated in that order (T5-05). Every field is fixed-width (the NUL-padded version / image_url char arrays and a 4-byte little-endian size), so the concatenation is an unambiguous canonical encoding; priv_ota_manifest_decode zero-fills the manifest before decode so the padding is deterministic. The hash streams through the injected SHA-256 interface, the same engine that produced image_digest.

Parameters
[in]manifestDecoded manifest (metadata + digest); non-NULL.
[in]image_digestk_ra8_ota_sha256_bytes body digest; non-NULL.
[out]out_boundk_ra8_ota_sha256_bytes signed-material digest; non-NULL.
Returns
ra8_err_t outcome.
Return values
k_ra8_okout_bound holds the metadata-bound digest.
k_ra8_err_null_ptrA pointer argument was NULL.
otherSHA-256 interface error propagated from a step.
Precondition
The injected crypto SHA-256 interface is wired.
out_bound addresses k_ra8_ota_sha256_bytes writable bytes.
Postcondition
On k_ra8_ok the signature authority runs over metadata + image digest.
No manifest bytes are modified.
Note
Static helper; not thread-safe (shares the single SHA context).
Since
0.1.0

Definition at line 149 of file ra8_ota_verify.c.

References g_ra8_ota_cfg, ra8_ota_manifest_t::image_size_bytes, ra8_ota_manifest_t::image_url, k_ra8_ok, k_ra8_ota_octet_bits, k_ra8_ota_sha256_bytes, k_ra8_ota_size_field_bytes, k_ra8_ota_url_max_bytes, k_ra8_ota_version_str_bytes, RA8_CHECK_NULL_PTR, s_tag, and ra8_ota_manifest_t::version.

Referenced by ra8_ota_verify_signature().

◆ internal_rehash_bank()

ra8_err_t internal_rehash_bank ( const ra8_ota_manifest_t * m,
uint8_t out_digest[32] )
static

Re-hash the inactive bank to re-derive the digest after program.

Re-initialises the SHA accumulator then walks the inactive bank in k_ra8_ota_chunk_bytes chunks via g_ra8_ota_cfg.flash.readback, feeding each one to g_ra8_ota_cfg.crypto.sha256_update. Finalises into out_digest. Loop is bounded by (k_ra8_ota_max_image_bytes / k_ra8_ota_chunk_bytes) + 1.

Parameters
[in]mManifest (provides image_size_bytes).
[out]out_digest32-byte SHA-256 destination.
Returns
ra8_err_t outcome.
Return values
k_ra8_okDigest derived.
otherWhatever the readback / crypto callbacks returned.
Precondition
Module is in verifying.
Pointers non-NULL.
Postcondition
On success out_digest holds SHA-256 of the bank contents.
On failure out_digest content is unspecified.
Note
Static helper; not thread-safe.
Since
0.1.0

Definition at line 70 of file ra8_ota_verify.c.

References g_ra8_ota_buf, g_ra8_ota_cfg, ra8_ota_manifest_t::image_size_bytes, k_ra8_ok, k_ra8_ota_chunk_bytes, and k_ra8_ota_max_image_bytes.

Referenced by ra8_ota_verify_signature().

◆ ra8_ota_verify_signature()

ra8_err_t ra8_ota_verify_signature ( const ra8_ota_manifest_t * manifest)
nodiscard

Verify the freshly-programmed bank against the manifest signature.

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().

Variable Documentation

◆ s_tag

const char* const s_tag = "ra8_ota"
static

Module log tag (private copy; immutable literal).

Definition at line 42 of file ra8_ota_verify.c.