39typedef enum : uint8_t {
44#include "mbedtls/error.h"
45#include "mbedtls/ssl.h"
46#include "mbedtls/x509_crt.h"
47#include "psa/crypto.h"
52static const char*
const s_ra8_tls_fake_cipher =
"off-target-loopback";
85 mbedtls_ssl_context
ssl;
126 if (session ==
nullptr) {
131 if ((session < base) || (session >= end)) {
172#ifndef RA8_OFF_TARGET
174 mbedtls_ssl_free(&slot->
ssl);
175 mbedtls_ssl_config_free(&slot->
config);
176 mbedtls_x509_crt_free(&slot->
ca);
179 (void)
memset(slot, 0,
sizeof(*slot));
208 const size_t last = cap - 1U;
210 while ((i < last) && (src[i] !=
'\0')) {
231#ifndef RA8_OFF_TARGET
237 const psa_status_t psa_rc = psa_crypto_init();
238 if (psa_rc != PSA_SUCCESS) {
290 if (out_session ==
nullptr) {
293 *out_session =
nullptr;
298 if (
cfg ==
nullptr) {
301 if ((
cfg->bio_send ==
nullptr) || (
cfg->bio_recv ==
nullptr)) {
307#ifndef RA8_OFF_TARGET
335 int authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
336 switch (
cfg->verify_mode) {
338 authmode = MBEDTLS_SSL_VERIFY_NONE;
341 authmode = MBEDTLS_SSL_VERIFY_OPTIONAL;
346 authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
349 mbedtls_ssl_conf_authmode(&slot->
config, authmode);
351 mbedtls_x509_crt_init(&slot->
ca);
352 if ((
cfg->ca_pem !=
nullptr) && (
cfg->ca_pem_len > 0U)) {
354 mbedtls_x509_crt_parse(&slot->
ca, (
const unsigned char*)
cfg->ca_pem,
cfg->ca_pem_len);
356 mbedtls_ssl_conf_ca_chain(&slot->
config, &slot->
ca,
nullptr);
391 mbedtls_ssl_init(&slot->
ssl);
392 mbedtls_ssl_config_init(&slot->
config);
394 const int defaults_rc = mbedtls_ssl_config_defaults(&slot->
config,
395 MBEDTLS_SSL_IS_CLIENT,
396 MBEDTLS_SSL_TRANSPORT_STREAM,
397 MBEDTLS_SSL_PRESET_DEFAULT);
398 if (defaults_rc != 0) {
399 mbedtls_ssl_free(&slot->
ssl);
400 mbedtls_ssl_config_free(&slot->
config);
401 (void)
memset(slot, 0,
sizeof(*slot));
408 const int setup_rc = mbedtls_ssl_setup(&slot->
ssl, &slot->
config);
410 mbedtls_ssl_free(&slot->
ssl);
411 mbedtls_ssl_config_free(&slot->
config);
412 mbedtls_x509_crt_free(&slot->
ca);
413 (void)
memset(slot, 0,
sizeof(*slot));
417 if (
cfg->server_name !=
nullptr) {
418 (void)mbedtls_ssl_set_hostname(&slot->
ssl,
cfg->server_name);
423 mbedtls_ssl_set_bio(&slot->
ssl,
425 (mbedtls_ssl_send_t*)
cfg->bio_send,
426 (mbedtls_ssl_recv_t*)
cfg->bio_recv,
440 if (slot ==
nullptr) {
448#ifndef RA8_OFF_TARGET
454 slot->handshake_done =
false;
470#ifndef RA8_OFF_TARGET
471 mbedtls_ssl_free(&session->
ssl);
472 mbedtls_ssl_config_free(&session->
config);
473 mbedtls_x509_crt_free(&session->
ca);
475 (void)
memset(session, 0,
sizeof(*session));
488#ifndef RA8_OFF_TARGET
489 const int rc = mbedtls_ssl_handshake(&session->
ssl);
493 if ((rc == MBEDTLS_ERR_SSL_WANT_READ) || (rc == MBEDTLS_ERR_SSL_WANT_WRITE)) {
503 const int send_rc = session->
cfg.bio_send(session->
cfg.bio_ctx, &fake_byte, 1U);
507 uint8_t recv_byte = 0U;
508 const int recv_rc = session->
cfg.bio_recv(session->
cfg.bio_ctx, &recv_byte, 1U);
512 session->handshake_done =
true;
519 if (out_sent ==
nullptr) {
530 if ((buf ==
nullptr) && (len > 0U)) {
537#ifndef RA8_OFF_TARGET
538 const int rc = mbedtls_ssl_write(&session->
ssl, buf, len);
540 *out_sent = (size_t)rc;
543 if ((rc == MBEDTLS_ERR_SSL_WANT_READ) || (rc == MBEDTLS_ERR_SSL_WANT_WRITE)) {
548 const int rc = session->
cfg.bio_send(session->
cfg.bio_ctx, buf, len);
552 *out_sent = (size_t)rc;
559 if (out_received ==
nullptr) {
570 if ((buf ==
nullptr) && (len > 0U)) {
577#ifndef RA8_OFF_TARGET
578 const int rc = mbedtls_ssl_read(&session->
ssl, buf, len);
580 *out_received = (size_t)rc;
583 if ((rc == MBEDTLS_ERR_SSL_WANT_READ) || (rc == MBEDTLS_ERR_SSL_WANT_WRITE)) {
586 if (rc == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
591 const int rc = session->
cfg.bio_recv(session->
cfg.bio_ctx, buf, len);
595 *out_received = (size_t)rc;
605 if ((out_id ==
nullptr) || (out_name ==
nullptr) || (name_cap == 0U)) {
618#ifndef RA8_OFF_TARGET
619 const char* name = mbedtls_ssl_get_ciphersuite(&session->
ssl);
620 if (name !=
nullptr) {
621 *out_id = (uint16_t)mbedtls_ssl_get_ciphersuite_id_from_ssl(&session->
ssl);
633 if (out_flags ==
nullptr) {
645#ifndef RA8_OFF_TARGET
646 *out_flags = mbedtls_ssl_get_verify_result(&session->
ssl);
653 if (out_mss ==
nullptr) {
658 const uint16_t overhead =
663 *out_mss = (uint16_t)(mtu - overhead);
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
static bool s_initialized
True once display_init has succeeded.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_would_block
Non-blocking operation would have blocked.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_exists
Item already exists – cannot create again.
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_hw_error
Generic hardware fault detected (error flag set, fault interrupt).
@ k_ra8_err_comm_error
Generic communication error (use a more specific code when possible).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_warn(tag, message)
RA8 log warn.
#define ra8_log_info(tag, message)
RA8 log info.
#define ra8_log_error(tag, message)
RA8 log error.
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.
static ra8_err_t internal_session_validate_args(ra8_tls_session_t *out_session, const ra8_tls_session_cfg_t *cfg)
Validate ra8_tls_session_open inputs before slot acquisition.
static struct ra8_tls_session_handle s_session_pool[k_ra8_tls_max_sessions]
Per-session state pool sized at compile time.
static void internal_pool_reset(void)
Reset every pool slot to a known-clean state.
static struct ra8_tls_session_handle * internal_pool_acquire(void)
Locate the first free slot in the pool.
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.
static ra8_err_t internal_session_mbedtls_setup(struct ra8_tls_session_handle *slot, const ra8_tls_session_cfg_t *cfg)
Run the Mbed TLS init/config/setup sequence for a fresh slot.
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.
static const char *const s_ra8_tls_tag
Logging tag prefix used by every ra8_tls log line.
ra8_err_t ra8_tls_session_close(ra8_tls_session_t session)
Release a TLS session back to the pool.
static bool internal_handle_valid(const struct ra8_tls_session_handle *session)
Validate that a typed handle points into the static pool.
ra8_err_t ra8_tls_handshake(ra8_tls_session_t session)
Iterative TLS handshake driver.
static void internal_apply_verify_cfg(struct ra8_tls_session_handle *slot, const ra8_tls_session_cfg_t *cfg)
Apply the caller's verify-mode and optional trust anchor to a slot.
static void internal_copy_cstr(char *dst, const char *src, size_t cap)
Bounded, always-NUL-terminating C-string copy.
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_mss_clamp(uint16_t mtu, uint16_t *out_mss)
Compute the TCP MSS that keeps a segment inside one MTU frame.
ra8_err_t ra8_tls_global_deinit(void)
Symmetric tear-down for ra8_tls_global_init.
ra8_err_t ra8_tls_global_init(void)
One-shot facade initialisation.
tls_content_type_t
TLS record content type: Handshake (22).
@ k_tls_content_handshake
TLS content handshake.
Tiny TLS facade over the vendored Mbed TLS 4.x stack.
struct ra8_tls_session_handle * ra8_tls_session_t
Opaque TLS session handle (typed pointer into the static pool).
@ k_ra8_tls_max_sessions
Maximum simultaneous TLS sessions handed out by the pool.
@ k_ra8_tls_verify_default
Facade default – same as required.
@ k_ra8_tls_verify_required
Verify and abort the handshake on fail.
@ k_ra8_tls_verify_none
Do not verify the peer certificate.
@ k_ra8_tls_verify_optional
Verify but do not abort on failure.
@ k_ra8_tls_tcp_hdr_bytes
TCP header with no options.
@ k_ra8_tls_mss_min
Smallest MSS worth clamping to.
@ k_ra8_tls_ipv4_hdr_bytes
IPv4 header with no options.
Per-session configuration handed to ra8_tls_session_open.
Forward declaration of the pool slot type.
mbedtls_ssl_config config
Mbed TLS SSL configuration block.
mbedtls_ssl_context ssl
Mbed TLS SSL context.
mbedtls_x509_crt ca
Parsed trust anchor (if cfg.ca_pem).
bool in_use
Slot allocated.
ra8_tls_session_cfg_t cfg
Cached caller configuration.