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

Secure-side AES-CMAC seam (real PSA backend / in-tree reference). More...

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

Go to the source code of this file.

Enumerations

enum  ra8_sec_cmac_limits_t : uint16_t {
  k_ra8_sec_cmac_tag_bytes = 16U ,
  k_ra8_sec_cmac_key_128 = 16U ,
  k_ra8_sec_cmac_key_256 = 32U ,
  k_ra8_sec_cmac_max_msg_bytes = 256U
}
 Sizing constants for the secure-side AES-CMAC primitive. More...

Functions

ra8_err_t priv_ra8_sec_cmac_compute (const uint8_t *key, uint16_t key_len, const uint8_t *msg, uint32_t msg_len, uint8_t *out_mac)
 Compute the AES-CMAC tag of a message under a symmetric key.
ra8_err_t priv_ra8_sec_cmac_verify (const uint8_t *key, uint16_t key_len, const uint8_t *msg, uint32_t msg_len, const uint8_t *mac, uint16_t mac_len)
 Verify an AES-CMAC tag against a message under a symmetric key.

Detailed Description

Secure-side AES-CMAC seam (real PSA backend / in-tree reference).

Tag
[Ring 5 / SECAPP] {World: S}

Single-responsibility message-authentication primitive used by the secure-side key importer (key_import.c) to authenticate a wrapped-key blob before it is admitted into the key vault. The MAC is AES-CMAC (NIST SP 800-38B), keyed by a secret the caller supplies – the importer passes the key-authentication key (KAK) it loads from the vault via ra8_key_vault_load_mac_key, so the CMAC key never originates from anything the Non-Secure world can reach.

This module is a dependency-inversion seam with two interchangeable (Liskov-substitutable) backends selected at compile time. Both compute the identical, standard AES-CMAC, so a blob authenticated by one verifies under the other:

  • RA8_KEY_IMPORT_PSA_CMAC defined – routes to the vendored TF-PSA-Crypto (psa_mac_compute / psa_mac_verify with PSA_ALG_CMAC over PSA_KEY_TYPE_AES). No build defines this flag, so this backend is not compiled anywhere today (#619).
  • otherwise – the path every build actually takes, host and firmware alike: a self-contained in-tree AES-128 / AES-256 + CMAC reference (FIPS 197 + SP 800-38B). It is real cryptography, not a forgeable placeholder: the host suite pins it to the published NIST SP 800-38B known-answer vectors.

Unlike the forgeable length-tagged XOR fold it replaces, neither backend is guarded by the RA8_INSECURE_STUB_CRYPTO fail-closed fence: an AES-CMAC forgery requires recovering the KAK, so there is no insecure placeholder to hide behind a production stub.

Definition in file sec_cmac_internal.h.

Enumeration Type Documentation

◆ ra8_sec_cmac_limits_t

enum ra8_sec_cmac_limits_t : uint16_t

Sizing constants for the secure-side AES-CMAC primitive.

The tag length is one AES block (128 bits). AES-CMAC accepts a 128- or 256-bit key; the importer keys it with a 256-bit KAK. msg length is statically capped so every internal loop has a provable bound (NASA Power of 10 Rule 2).

Invariant
k_ra8_sec_cmac_tag_bytes equals the AES block size.
k_ra8_sec_cmac_key_256 >= k_ra8_sec_cmac_key_128.
See also
priv_ra8_sec_cmac_compute()
NIST SP 800-38B "The CMAC Mode for Authentication".
Enumerator
k_ra8_sec_cmac_tag_bytes 

CMAC tag length (one AES block).

k_ra8_sec_cmac_key_128 

AES-128 key length in bytes.

k_ra8_sec_cmac_key_256 

AES-256 key length in bytes.

k_ra8_sec_cmac_max_msg_bytes 

Largest authenticated message.

Definition at line 68 of file sec_cmac_internal.h.

Function Documentation

◆ priv_ra8_sec_cmac_compute()

ra8_err_t priv_ra8_sec_cmac_compute ( const uint8_t * key,
uint16_t key_len,
const uint8_t * msg,
uint32_t msg_len,
uint8_t * out_mac )
nodiscard

Compute the AES-CMAC tag of a message under a symmetric key.

Runs NIST SP 800-38B CMAC over msg with AES as the block cipher. key_len selects AES-128 (k_ra8_sec_cmac_key_128) or AES-256 (k_ra8_sec_cmac_key_256). The 16-byte tag is written to out_mac. The active backend (PSA or the in-tree reference) is chosen at compile time and produces the identical standard tag.

Parameters
[in]keySymmetric CMAC key (secret; caller-owned secure copy).
[in]key_lenKey length: 16 (AES-128) or 32 (AES-256) bytes.
[in]msgMessage to authenticate; NULL only when msg_len==0.
[in]msg_lenMessage length, 0 .. k_ra8_sec_cmac_max_msg_bytes.
[out]out_macDestination for the k_ra8_sec_cmac_tag_bytes tag.
Returns
ra8_err_t error code.
Return values
k_ra8_okTag computed and written.
k_ra8_err_null_ptrkey or out_mac (or msg when msg_len!=0) was NULL.
k_ra8_err_invalid_argkey_len was neither 16 nor 32.
k_ra8_err_invalid_sizemsg_len exceeded the static cap.
k_ra8_err_hw_errorPSA backend reported a fault (PSA build).
Precondition
key and out_mac are non-NULL.
key_len is 16 or 32.
Postcondition
On k_ra8_ok, out_mac[0..15] holds the CMAC tag.
On any error, no output byte is relied upon by the caller.
Note
Not thread-safe; secure-side serial dispatch only.
Example:
ra8_err_t priv_ra8_sec_cmac_compute(const uint8_t *key, uint16_t key_len, const uint8_t *msg, uint32_t msg_len, uint8_t *out_mac)
Compute the AES-CMAC tag of a message under a symmetric key.
Definition sec_cmac.c:632
@ k_ra8_sec_cmac_key_256
AES-256 key length in bytes.
@ k_ra8_sec_cmac_tag_bytes
CMAC tag length (one AES block).
See also
priv_ra8_sec_cmac_verify()
NIST SP 800-38B Sec 6.2 "MAC Generation".
Since
0.1.0

Definition at line 632 of file sec_cmac.c.

References internal_cmac_check_args(), internal_cmac_tag(), k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by priv_ra8_key_import_build_blob().

◆ priv_ra8_sec_cmac_verify()

ra8_err_t priv_ra8_sec_cmac_verify ( const uint8_t * key,
uint16_t key_len,
const uint8_t * msg,
uint32_t msg_len,
const uint8_t * mac,
uint16_t mac_len )
nodiscard

Verify an AES-CMAC tag against a message under a symmetric key.

Recomputes the CMAC of msg under key and compares it, in constant time, to the caller-supplied mac. A single flipped message or tag byte, or a truncated tag (mac_len != k_ra8_sec_cmac_tag_bytes), makes the verdict fail. The verdict is the module's security-critical decision.

Parameters
[in]keySymmetric CMAC key (secret; caller-owned secure copy).
[in]key_lenKey length: 16 (AES-128) or 32 (AES-256) bytes.
[in]msgAuthenticated message; NULL only when msg_len==0.
[in]msg_lenMessage length, 0 .. k_ra8_sec_cmac_max_msg_bytes.
[in]macCandidate tag to check.
[in]mac_lenLength of mac; must equal k_ra8_sec_cmac_tag_bytes.
Returns
ra8_err_t error code.
Return values
k_ra8_okTag is authentic.
k_ra8_err_invalid_argTag mismatch, wrong mac_len, or bad key_len.
k_ra8_err_null_ptrkey or mac (or msg when msg_len!=0) was NULL.
k_ra8_err_invalid_sizemsg_len exceeded the static cap.
k_ra8_err_hw_errorPSA backend reported a fault (PSA build).
Precondition
key and mac are non-NULL.
key_len is 16 or 32.
Postcondition
No output state is produced; the return code is the whole result.
msg and mac are unmodified.
Note
Not thread-safe; secure-side serial dispatch only.
MC/DC:
Verdict decision if ((mac_len != k_ra8_sec_cmac_tag_bytes) || !ra8_ct_equal(computed, mac, k_ra8_sec_cmac_tag_bytes)) (2 conditions):
  • C1 = mac_len is not the expected tag length.
  • C2 = the recomputed tag does not equal mac. N=2 -> N+1=3 minimal vectors:
  • V1 (C1=F, C2=F): correct length + authentic tag -> decision F -> ok.
  • V2 (C1=T): truncated tag -> decision T (short-circuits C2) -> reject.
  • V3 (C1=F, C2=T): correct length + one flipped tag byte -> decision T -> reject. V1+V2 vary C1 (masked C2); V1+V3 vary C2 with C1 held F. Satisfies DO-178C 6.4.4.2 minimal MC/DC.
See also
priv_ra8_sec_cmac_compute()
NIST SP 800-38B Sec 6.3 "MAC Verification".
Since
0.1.0

Definition at line 647 of file sec_cmac.c.

References internal_cmac_check_args(), internal_cmac_tag(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_sec_cmac_tag_bytes, RA8_CHECK_NULL_PTR, ra8_ct_equal(), ra8_secure_memzero(), and s_tag.

Referenced by internal_verify_cmac().