37static const char*
s_tag =
"KEYV";
49#if defined(RA8_INSECURE_STUB_CRYPTO) || defined(RA8_OFF_TARGET)
52typedef enum : uint16_t {
53 k_sha256_msg_bytes = 32U,
55 k_sha256_block_bytes = 64U,
59typedef enum : uint8_t {
60 k_sha256_pad_pos = 32U,
61 k_sha256_pad_marker = 0x80U,
62 k_sha256_pad_zero_start = 33U,
63 k_sha256_len_b0 = 56U,
64 k_sha256_len_b1 = 57U,
65 k_sha256_len_b2 = 58U,
66 k_sha256_len_b3 = 59U,
67 k_sha256_len_b4 = 60U,
68 k_sha256_len_b5 = 61U,
69 k_sha256_len_b6 = 62U,
70 k_sha256_len_b7 = 63U,
71 k_sha256_len_hi = 0x01U,
72 k_sha256_byte_shift = 24U,
76typedef enum : uint8_t {
77 k_sha256_ssig0_r0 = 7U,
78 k_sha256_ssig0_r1 = 18U,
79 k_sha256_ssig0_sh = 3U,
80 k_sha256_ssig1_r0 = 17U,
81 k_sha256_ssig1_r1 = 19U,
82 k_sha256_ssig1_sh = 10U,
83 k_sha256_bsig1_r0 = 6U,
84 k_sha256_bsig1_r1 = 11U,
85 k_sha256_bsig1_r2 = 25U,
86 k_sha256_bsig0_r0 = 2U,
87 k_sha256_bsig0_r1 = 13U,
88 k_sha256_bsig0_r2 = 22U,
89 k_sha256_back15 = 15U,
94typedef enum : uint8_t {
111} ra8_key_vault_slot_t;
116typedef enum : uint16_t {
117 k_kv_mac_key_128 = 16U,
118 k_kv_mac_key_256 = 32U,
119} ra8_kv_mac_key_len_t;
144static uint16_t s_mac_key_len = 0U;
159static const uint32_t k_sha256_k[64] = {
160 0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU, 0x59f111f1U, 0x923f82a4U,
161 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U, 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU,
162 0x9bdc06a7U, 0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU, 0x2de92c6fU,
163 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U, 0xa831c66dU, 0xb00327c8U, 0xbf597fc7U,
164 0xc6e00bf3U, 0xd5a79147U, 0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
165 0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U, 0xa2bfe8a1U, 0xa81a664bU,
166 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U, 0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U,
167 0x1e376c08U, 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU, 0x682e6ff3U,
168 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U, 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U,
172static const uint32_t k_sha256_h0[8] = {
204RA8_INTERNAL static uint32_t internal_rotr(uint32_t x, uint32_t n)
206 return (x >> n) | (x << (32U - n));
236RA8_INTERNAL static void internal_sha256_build_block(
const uint8_t* in32, uint8_t* block)
241 for (uint32_t i = 0U; i < k_sha256_msg_bytes; ++i) {
244 block[k_sha256_pad_pos] = k_sha256_pad_marker;
245 for (uint32_t i = k_sha256_pad_zero_start; i < k_sha256_len_b0; ++i) {
249 block[k_sha256_len_b0] = 0U;
250 block[k_sha256_len_b1] = 0U;
251 block[k_sha256_len_b2] = 0U;
252 block[k_sha256_len_b3] = 0U;
253 block[k_sha256_len_b4] = 0U;
254 block[k_sha256_len_b5] = 0U;
255 block[k_sha256_len_b6] = k_sha256_len_hi;
256 block[k_sha256_len_b7] = 0x00U;
279RA8_INTERNAL static void internal_sha256_schedule(
const uint8_t* block, uint32_t* w)
281 for (uint32_t i = 0U; i < 16U; ++i) {
282 w[i] = ((uint32_t)block[(i * 4U) + 0U] << k_sha256_byte_shift) |
283 ((uint32_t)block[(i * 4U) + 1U] << 16U) | ((uint32_t)block[(i * 4U) + 2U] << 8U) |
284 ((uint32_t)block[(i * 4U) + 3U]);
286 for (uint32_t i = 16U; i < k_sha256_words; ++i) {
287 const uint32_t s0 = internal_rotr(w[i - k_sha256_back15], k_sha256_ssig0_r0) ^
288 internal_rotr(w[i - k_sha256_back15], k_sha256_ssig0_r1) ^
289 (w[i - k_sha256_back15] >> k_sha256_ssig0_sh);
290 const uint32_t s1 = internal_rotr(w[i - 2U], k_sha256_ssig1_r0) ^
291 internal_rotr(w[i - 2U], k_sha256_ssig1_r1) ^
292 (w[i - 2U] >> k_sha256_ssig1_sh);
293 w[i] = w[i - 16U] + s0 + w[i - k_sha256_back7] + s1;
319RA8_INTERNAL static void internal_sha256_compress(
const uint32_t* w, uint8_t* out32)
321 uint32_t a = k_sha256_h0[k_sha256_st_a];
322 uint32_t b = k_sha256_h0[k_sha256_st_b];
323 uint32_t c = k_sha256_h0[k_sha256_st_c];
324 uint32_t d = k_sha256_h0[k_sha256_st_d];
325 uint32_t e = k_sha256_h0[k_sha256_st_e];
326 uint32_t f = k_sha256_h0[k_sha256_st_f];
327 uint32_t g = k_sha256_h0[k_sha256_st_g];
328 uint32_t h = k_sha256_h0[k_sha256_st_h];
330 for (uint32_t i = 0U; i < k_sha256_words; ++i) {
331 const uint32_t s1 = internal_rotr(e, k_sha256_bsig1_r0) ^ internal_rotr(e, k_sha256_bsig1_r1) ^
332 internal_rotr(e, k_sha256_bsig1_r2);
333 const uint32_t ch = (e & f) ^ (~e & g);
334 const uint32_t temp1 = h + s1 + ch + k_sha256_k[i] + w[i];
335 const uint32_t s0 = internal_rotr(a, k_sha256_bsig0_r0) ^ internal_rotr(a, k_sha256_bsig0_r1) ^
336 internal_rotr(a, k_sha256_bsig0_r2);
337 const uint32_t maj = (a & b) ^ (a & c) ^ (b & c);
338 const uint32_t temp2 = s0 + maj;
349 const uint32_t hh[8] = {
350 a + k_sha256_h0[k_sha256_st_a],
351 b + k_sha256_h0[k_sha256_st_b],
352 c + k_sha256_h0[k_sha256_st_c],
353 d + k_sha256_h0[k_sha256_st_d],
354 e + k_sha256_h0[k_sha256_st_e],
355 f + k_sha256_h0[k_sha256_st_f],
356 g + k_sha256_h0[k_sha256_st_g],
357 h + k_sha256_h0[k_sha256_st_h],
359 for (uint32_t i = 0U; i < 8U; ++i) {
360 out32[(i * 4U) + 0U] = (uint8_t)(hh[i] >> k_sha256_byte_shift);
361 out32[(i * 4U) + 1U] = (uint8_t)(hh[i] >> 16U);
362 out32[(i * 4U) + 2U] = (uint8_t)(hh[i] >> 8U);
363 out32[(i * 4U) + 3U] = (uint8_t)(hh[i]);
389RA8_INTERNAL static void internal_sha256_32(
const uint8_t* in32, uint8_t* out32)
391 uint8_t block[k_sha256_block_bytes];
392 uint32_t w[k_sha256_words];
393 internal_sha256_build_block(in32, block);
394 internal_sha256_schedule(block, w);
395 internal_sha256_compress(w, out32);
427 s_vault[s].key[i] = 0U;
469 s_vault[slot].key[i] = key[i];
511 scratch[i] = (uint8_t)(s_vault[slot].key[i] ^ challenge[i]);
513 internal_sha256_32(scratch, out);
526 if ((key_len != (uint16_t)k_kv_mac_key_128) && (key_len != (uint16_t)k_kv_mac_key_256)) {
530 s_mac_key[i] = (i < key_len) ? key[i] : 0U;
532 s_mac_key_len = key_len;
540 if (s_mac_key_len == 0U) {
543 if (out_cap < s_mac_key_len) {
546 for (uint16_t i = 0U; i < s_mac_key_len; ++i) {
547 out[i] = s_mac_key[i];
549 *out_len = s_mac_key_len;
ra8_err_t ra8_key_vault_sha256_xor_challenge(uint16_t slot, const uint8_t *challenge, uint8_t *out)
Compute SHA-256(key XOR challenge) for slot.
ra8_err_t ra8_key_vault_set_mac_key(const uint8_t *key, uint16_t key_len)
Provision the key-authentication key (KAK) used to MAC key imports.
ra8_err_t ra8_key_vault_store(uint16_t slot, const uint8_t *key)
Programme a 256-bit symmetric key into a vault slot.
ra8_err_t ra8_key_vault_init(void)
Initialise the vault (zero every slot).
ra8_err_t ra8_key_vault_load_mac_key(uint8_t *out, uint16_t out_cap, uint16_t *out_len)
Copy the provisioned key-authentication key for a secure caller.
Secure-only symmetric key store.
@ k_ra8_key_vault_mac_key_bytes
Max key-authentication key.
@ k_ra8_key_vault_key_bytes
256-bit symmetric key.
@ k_ra8_key_vault_slots
Number of stored keys.
static const char * s_tag
Logging / check tag.
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.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Secure-comparison primitives for the crypto / secure-boot paths.
void ra8_secure_memzero(void *ptr, size_t len)
Securely zero a buffer such that the write cannot be optimised away.