|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Tiny TLS facade over the vendored Mbed TLS 4.x stack. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_tls_session_cfg |
Typedefs | |
| typedef int(* | ra8_tls_bio_send_fn) (void *ctx, const uint8_t *buf, size_t len) |
| BIO send callback signature (write ciphertext to transport). | |
| typedef int(* | ra8_tls_bio_recv_fn) (void *ctx, uint8_t *buf, size_t len) |
| BIO receive callback signature (read ciphertext from transport). | |
| typedef struct ra8_tls_session_cfg | ra8_tls_session_cfg_t |
| typedef struct ra8_tls_session_handle * | ra8_tls_session_t |
| Opaque TLS session handle (typed pointer into the static pool). | |
Enumerations | |
| enum | ra8_tls_limits_t : uint8_t { k_ra8_tls_max_sessions = 4U , k_ra8_tls_cipher_name_cap = 48U } |
| Static-pool sizing constants for the TLS facade. More... | |
| enum | ra8_tls_net_const_t : uint16_t { k_ra8_tls_ipv4_hdr_bytes = 20U , k_ra8_tls_tcp_hdr_bytes = 20U , k_ra8_tls_mtu_min = 128U , k_ra8_tls_mss_min = 64U } |
| Transport-sizing constants used by ra8_tls_mss_clamp. More... | |
| enum | ra8_tls_verify_mode_t : uint8_t { k_ra8_tls_verify_default = 0U , k_ra8_tls_verify_none = 1U , k_ra8_tls_verify_optional = 2U , k_ra8_tls_verify_required = 3U } |
| Peer-certificate verification policy for a session. More... | |
Functions | |
| ra8_err_t | ra8_tls_global_init (void) |
| One-shot facade initialisation. | |
| ra8_err_t | ra8_tls_global_deinit (void) |
| Symmetric tear-down for ra8_tls_global_init. | |
| ra8_err_t | ra8_tls_session_open (ra8_tls_session_t *out_session, const ra8_tls_session_cfg_t *cfg) |
| Allocate a TLS session from the static pool. | |
| ra8_err_t | ra8_tls_session_close (ra8_tls_session_t session) |
| Release a TLS session back to the pool. | |
| ra8_err_t | ra8_tls_handshake (ra8_tls_session_t session) |
| Iterative TLS handshake driver. | |
| ra8_err_t | ra8_tls_send (ra8_tls_session_t session, const uint8_t *buf, size_t len, size_t *out_sent) |
| Encrypt and send application data. | |
| ra8_err_t | ra8_tls_recv (ra8_tls_session_t session, uint8_t *buf, size_t len, size_t *out_received) |
| Decrypt and receive application data. | |
| ra8_err_t | ra8_tls_get_cipher_suite (ra8_tls_session_t session, uint16_t *out_id, char *out_name, size_t name_cap) |
| Report the negotiated cipher suite for a session. | |
| ra8_err_t | ra8_tls_get_verify_result (ra8_tls_session_t session, uint32_t *out_flags) |
| Report the peer-certificate verification result for a session. | |
| ra8_err_t | ra8_tls_mss_clamp (uint16_t mtu, uint16_t *out_mss) |
| Compute the TCP MSS that keeps a segment inside one MTU frame. | |
Tiny TLS facade over the vendored Mbed TLS 4.x stack.
ra8_tls is a thin, project-shaped wrapper around the third-party Mbed TLS 4.x + TF-PSA-Crypto 1.x library that ships under libs/third_party/mbedtls and libs/third_party/tf-psa-crypto. The goal is twofold:
* +---------------------------+ ra8_tls_handshake * | App (HTTPS / MQTT / OTA) | ra8_tls_send / ra8_tls_recv * +-------------+-------------+ * | * v * +---------------------------+ ra8_tls (this header) * | Mbed TLS 4.x + TF-PSA | * +-------------+-------------+ * | * v * +---------------------------+ user-supplied BIO callbacks * | Transport (NetX Duo) | * +---------------------------+ *
The transport is bound through the BIO callbacks on ra8_tls_session_cfg_t – the facade itself does not know about NetX Duo. The NetX Duo adapter lives in a follow-up library.
One global init brings the PSA crypto layer online. The session-scoped APIs are not internally synchronised: callers that dispatch the same session from multiple threads must serialise the calls themselves (typical embedded usage opens a session from one task and never shares it).
Definition in file ra8_tls.h.
| typedef int(* ra8_tls_bio_recv_fn) (void *ctx, uint8_t *buf, size_t len) |
BIO receive callback signature (read ciphertext from transport).
Mirrors the Mbed TLS mbedtls_ssl_recv_t contract: returns the number of bytes consumed, 0 on EOF, or a negative Mbed TLS error code (MBEDTLS_ERR_SSL_WANT_READ for non-blocking would-block).
| [in,out] | ctx | Opaque user pointer registered through ra8_tls_session_cfg_t::bio_ctx. |
| [out] | buf | Buffer to fill with up to len bytes. |
| [in] | len | Capacity of buf in bytes. |
| typedef int(* ra8_tls_bio_send_fn) (void *ctx, const uint8_t *buf, size_t len) |
BIO send callback signature (write ciphertext to transport).
Mirrors the Mbed TLS mbedtls_ssl_send_t contract: returns the number of bytes accepted by the transport, or a negative Mbed TLS error code on failure (MBEDTLS_ERR_SSL_WANT_WRITE for non-blocking would-block).
| [in,out] | ctx | Opaque user pointer registered through ra8_tls_session_cfg_t::bio_ctx. |
| [in] | buf | Buffer holding len bytes of ciphertext. |
| [in] | len | Length of buf in bytes. |
| typedef struct ra8_tls_session_cfg ra8_tls_session_cfg_t |
| typedef struct ra8_tls_session_handle* ra8_tls_session_t |
Opaque TLS session handle (typed pointer into the static pool).
NULL is a sentinel for "uninitialized handle". The only legal way to obtain a non-NULL value is ra8_tls_session_open; passing any other pointer to ra8_tls_session_close and friends is undefined behaviour from the caller's perspective and yields k_ra8_err_invalid_arg from this facade.
| enum ra8_tls_limits_t : uint8_t |
Static-pool sizing constants for the TLS facade.
These bounds are chosen to fit four concurrent TLS sessions on the RA8D2 SRAM budget while leaving headroom for ThreadX stacks and NetX Duo packet pools. Increasing the count requires re-sizing s_session_pool in ra8_tls.c.
| Enumerator | |
|---|---|
| k_ra8_tls_max_sessions | Maximum simultaneous TLS sessions handed out by the pool. NASA Power of 10 Rule 3 cap: any further open returns k_ra8_err_no_mem. |
| k_ra8_tls_cipher_name_cap | Capacity (bytes) a caller must reserve for a cipher-suite name. ra8_tls_get_cipher_suite never writes more than this many bytes (including the terminating NUL) into the caller buffer; the longest IANA suite string plus NUL fits comfortably. |
| enum ra8_tls_net_const_t : uint16_t |
Transport-sizing constants used by ra8_tls_mss_clamp.
The RA8D2 ESWM has a documented large-frame egress defect (issue #21): frames over roughly half a KiB corrupt on the wire, so the whole networking stack is pinned to a 128-byte MTU. A TLS client that dials over TCP must therefore clamp its TCP Maximum Segment Size (MSS) so every segment – TLS record bytes included – fits inside one 128-byte MTU frame after the fixed IPv4 + TCP header overhead. These constants express that arithmetic without a bare literal.
| enum ra8_tls_verify_mode_t : uint8_t |
Peer-certificate verification policy for a session.
Maps onto the Mbed TLS MBEDTLS_SSL_VERIFY_* authentication modes. The zero value is a safe default (behaves as required) so a zero-initialised ra8_tls_session_cfg_t never silently disables verification.
| ra8_err_t ra8_tls_get_cipher_suite | ( | ra8_tls_session_t | session, |
| uint16_t * | out_id, | ||
| char * | out_name, | ||
| size_t | name_cap ) |
Report the negotiated cipher suite for a session.
After a successful ra8_tls_handshake this returns the IANA cipher-suite name (e.g. TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256) and its 16-bit IANA identifier so an application can log exactly what was negotiated. In RA8_OFF_TARGET (host unit-test build) the handshake is a loopback drain rather than a real negotiation, so a deterministic sentinel is reported: out_name becomes "off-target-loopback" and *out_id becomes 0. The output name is always NUL-terminated and never exceeds name_cap bytes.
| [in] | session | Open session handle in the application-data state. |
| [out] | out_id | Receives the 16-bit IANA cipher-suite id (0 when unknown / fake). |
| [out] | out_name | Receives the NUL-terminated cipher-suite name. Truncated to fit when the real name is longer. |
| [in] | name_cap | Capacity of out_name in bytes; must be >= 1. |
| k_ra8_ok | Cipher reported into the outputs. |
| k_ra8_err_invalid_arg | Any pointer NULL, name_cap zero, or session invalid. |
| k_ra8_err_not_initialized | Module not initialized. |
Definition at line 600 of file ra8_tls.c.
References internal_copy_cstr(), internal_handle_valid(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, s_initialized, and ra8_tls_session_handle::ssl.
Referenced by demo_report().
| ra8_err_t ra8_tls_get_verify_result | ( | ra8_tls_session_t | session, |
| uint32_t * | out_flags ) |
Report the peer-certificate verification result for a session.
Wraps mbedtls_ssl_get_verify_result: 0 means the peer chain satisfied the configured verify_mode; any non-zero value is the OR of MBEDTLS_X509_BADCERT_* / MBEDTLS_X509_BADCRL_* flags. In RA8_OFF_TARGET the loopback path reports 0 (verified).
| [in] | session | Open session handle in the application-data state. |
| [out] | out_flags | Receives the verification bit set (0 == OK). |
| k_ra8_ok | Result written to *out_flags. |
| k_ra8_err_invalid_arg | out_flags NULL or session invalid. |
| k_ra8_err_not_initialized | Module not initialized. |
Definition at line 631 of file ra8_tls.c.
References internal_handle_valid(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, s_initialized, and ra8_tls_session_handle::ssl.
Referenced by demo_report().
| ra8_err_t ra8_tls_global_deinit | ( | void | ) |
Symmetric tear-down for ra8_tls_global_init.
Frees every still-open session, wipes the CTR_DRBG state, and marks the module uninitialized so a subsequent ra8_tls_global_init succeeds again.
| k_ra8_ok | Facade torn down. |
| k_ra8_err_not_initialized | ra8_tls_global_init was never called. |
Definition at line 249 of file ra8_tls.c.
References internal_pool_reset(), k_ra8_err_not_initialized, k_ra8_ok, and s_initialized.
Referenced by demo_run_tls().
| ra8_err_t ra8_tls_global_init | ( | void | ) |
One-shot facade initialisation.
Brings the PSA crypto layer online and marks the session pool empty. Mbed TLS 4.x sources randomness from PSA (psa_generate_random) rather than a facade-owned CTR_DRBG, so the actual entropy is drawn lazily on the first random call through the application-supplied mbedtls_psa_external_get_random hook (the RSIP TRNG on hardware). Safe to call exactly once per boot; subsequent calls without a matching ra8_tls_global_deinit return k_ra8_err_exists.
Algorithm:
| k_ra8_ok | Facade ready. |
| k_ra8_err_exists | Already initialized this boot. |
| k_ra8_err_hw_error | psa_crypto_init failed. |
Definition at line 222 of file ra8_tls.c.
References internal_pool_reset(), k_ra8_err_exists, k_ra8_err_hw_error, k_ra8_ok, ra8_log_error, ra8_log_info, ra8_log_warn, s_initialized, and s_ra8_tls_tag.
Referenced by demo_run_tls().
| ra8_err_t ra8_tls_handshake | ( | ra8_tls_session_t | session | ) |
Iterative TLS handshake driver.
Wraps mbedtls_ssl_handshake and translates its return value into an ra8_err_t. Returns k_ra8_err_would_block while the underlying BIO is non-blocking and waiting for I/O so the caller can loop without consuming the entire transport-level event budget.
In RA8_OFF_TARGET (host unit-test build) the call short- circuits to k_ra8_ok after a single BIO drain so the loopback test path can complete without a real cryptographic handshake.
| [in,out] | session | Open session handle. |
| k_ra8_ok | Handshake complete. |
| k_ra8_err_invalid_arg | session invalid. |
| k_ra8_err_not_initialized | Module not initialized. |
| k_ra8_err_would_block | BIO is non-blocking; retry later. |
| k_ra8_err_comm_error | Mbed TLS reported a fatal handshake failure (cert / protocol / decode). |
Definition at line 479 of file ra8_tls.c.
References ra8_tls_session_handle::cfg, internal_handle_valid(), k_ra8_err_comm_error, k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_err_would_block, k_ra8_ok, k_tls_content_handshake, ra8_log_error, s_initialized, s_ra8_tls_tag, and ra8_tls_session_handle::ssl.
Referenced by demo_handshake().
| ra8_err_t ra8_tls_mss_clamp | ( | uint16_t | mtu, |
| uint16_t * | out_mss ) |
Compute the TCP MSS that keeps a segment inside one MTU frame.
Pure arithmetic helper for TLS-over-TCP clients on the #21-pinned 128-byte MTU link: subtracts the fixed IPv4 + TCP header overhead from mtu to yield the largest TCP payload (Maximum Segment Size) that still fits one Ethernet frame the ESWM egress transmits cleanly. The result is what a caller feeds to the transport (e.g. an Mbed TLS maximum-fragment-length hint or a NetX Duo socket MSS) so the TLS record layer never asks the MAC to send an over-length frame.
| [in] | mtu | Link MTU in bytes (payload, excluding the 14-byte Ethernet header); must be >= k_ra8_tls_mtu_min. |
| [out] | out_mss | Receives the clamped MSS (mtu - IPv4 - TCP) in bytes. |
| k_ra8_ok | MSS written to *out_mss. |
| k_ra8_err_invalid_arg | out_mss NULL, or mtu too small to leave at least k_ra8_tls_mss_min bytes. |
mtu leaves room for a >= k_ra8_tls_mss_min byte segment. Definition at line 651 of file ra8_tls.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_tls_ipv4_hdr_bytes, k_ra8_tls_mss_min, and k_ra8_tls_tcp_hdr_bytes.
Referenced by demo_run_tls().
| ra8_err_t ra8_tls_recv | ( | ra8_tls_session_t | session, |
| uint8_t * | buf, | ||
| size_t | len, | ||
| size_t * | out_received ) |
Decrypt and receive application data.
Wraps mbedtls_ssl_read. *out_received == 0 together with k_ra8_ok denotes a clean peer close-notify; k_ra8_err_would_block means the underlying transport had no data ready.
| [in,out] | session | Open session handle in the application-data state. |
| [out] | buf | Plaintext output buffer. |
| [in] | len | Capacity of buf in bytes. |
| [out] | out_received | Bytes decrypted into buf. |
| k_ra8_ok | Decrypted *out_received bytes (0 on clean close). |
| k_ra8_err_invalid_arg | Any pointer NULL or session invalid. |
| k_ra8_err_not_initialized | Module not initialized. |
| k_ra8_err_would_block | No ciphertext available yet. |
| k_ra8_err_comm_error | Fatal TLS-layer error. |
Definition at line 557 of file ra8_tls.c.
References ra8_tls_session_handle::cfg, internal_handle_valid(), k_ra8_err_comm_error, k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_err_would_block, k_ra8_ok, s_initialized, and ra8_tls_session_handle::ssl.
Referenced by demo_exchange().
| ra8_err_t ra8_tls_send | ( | ra8_tls_session_t | session, |
| const uint8_t * | buf, | ||
| size_t | len, | ||
| size_t * | out_sent ) |
Encrypt and send application data.
Wraps mbedtls_ssl_write. Returns the number of bytes accepted by the TLS layer through out_sent; partial writes are reported back to the caller so they can advance their buffer pointer.
| [in,out] | session | Open session handle in the application-data state. |
| [in] | buf | Plaintext input buffer. |
| [in] | len | Number of bytes to send (0 is a no-op). |
| [out] | out_sent | Bytes consumed by the TLS layer (always <= len). |
| k_ra8_ok | Wrote *out_sent bytes. |
| k_ra8_err_invalid_arg | Any pointer NULL or session invalid. |
| k_ra8_err_not_initialized | Module not initialized. |
| k_ra8_err_would_block | Non-blocking BIO returned WANT_WRITE. |
| k_ra8_err_comm_error | Fatal TLS-layer error. |
Definition at line 517 of file ra8_tls.c.
References ra8_tls_session_handle::cfg, internal_handle_valid(), k_ra8_err_comm_error, k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_err_would_block, k_ra8_ok, s_initialized, and ra8_tls_session_handle::ssl.
Referenced by demo_exchange().
| ra8_err_t ra8_tls_session_close | ( | ra8_tls_session_t | session | ) |
Release a TLS session back to the pool.
Validates that session actually points into the pool, runs mbedtls_ssl_free / mbedtls_ssl_config_free on the slot, and clears the in-use bit. Safe to call on any open session, even one that has not completed its handshake.
| [in,out] | session | Handle previously returned by ra8_tls_session_open. |
| k_ra8_ok | Slot released. |
| k_ra8_err_invalid_arg | session is NULL or does not point into the pool. |
| k_ra8_err_not_initialized | ra8_tls_global_init was never called. |
Definition at line 461 of file ra8_tls.c.
References ra8_tls_session_handle::ca, ra8_tls_session_handle::config, internal_handle_valid(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, memset(), s_initialized, and ra8_tls_session_handle::ssl.
Referenced by demo_run_tls().
| ra8_err_t ra8_tls_session_open | ( | ra8_tls_session_t * | out_session, |
| const ra8_tls_session_cfg_t * | cfg ) |
Allocate a TLS session from the static pool.
Searches the in-use bitmap for a free slot, copies cfg into the slot, runs mbedtls_ssl_setup / mbedtls_ssl_set_bio and returns the typed pointer through out_session.
| [out] | out_session | Receives the new opaque handle on success. Set to NULL on any non-success return. |
| [in] | cfg | Session configuration; both BIO callbacks must be non-NULL. The struct itself is copied; the caller may free it on return. |
| k_ra8_ok | Session allocated and ready for handshake. |
| k_ra8_err_invalid_arg | out_session or cfg is NULL, or one of the BIO callbacks is NULL. |
| k_ra8_err_not_initialized | ra8_tls_global_init was never called. |
| k_ra8_err_no_mem | Pool exhausted (more than k_ra8_tls_max_sessions open). |
Definition at line 432 of file ra8_tls.c.
References ra8_tls_session_handle::cfg, ra8_tls_session_handle::in_use, internal_pool_acquire(), internal_session_mbedtls_setup(), internal_session_validate_args(), k_ra8_err_no_mem, k_ra8_ok, ra8_log_warn, and s_ra8_tls_tag.
Referenced by demo_run_tls().