Skip to content
File

Blob: firmware/platform/crypto_hash.c

c120 lines
1#include <string.h>
2#include "radio_bridge.h"
3#include "esp_err.h"
4#include "sdkconfig.h"
5#include "mbedtls/md.h"
6#include "mbedtls/sha256.h"
7#include "mbedtls/sha512.h"
8#include "mbedtls/platform_util.h"
9 
10#if !CONFIG_IDF_TARGET_ESP32S3
11#error "Review the SHA context lifetime and hardware locking before porting this adapter"
12#endif
13 
14/* The pinned S3 SHA contexts contain only counters, digest words, a partial
15 * block, and scalar mode flags. Hardware locks are released after each update.
16 * No native pointer, allocation, or retained peripheral ownership crosses calls.
17 * Review sha256_alt.h/sha512_alt.h and the port implementations on SDK upgrades. */
18typedef struct {
19 int32_t bits;
20 union {
21 mbedtls_sha256_context sha256;
22 mbedtls_sha512_context sha512;
23 } context;
24} hash_state;
25_Static_assert(sizeof(hash_state) <= RADIO_CRYPTO_HASH_STATE_BYTES, "SHA state ABI capacity");
26 
27int32_t radio_crypto_sha256(const uint8_t *input, size_t length, uint8_t output[32])
28{
29 return mbedtls_sha256(input, length, output, 0);
30}
31 
32int32_t radio_crypto_hmac(int32_t bits, const uint8_t *key, size_t key_length,
33 const radio_crypto_part *parts, size_t count, uint8_t *output,
34 size_t capacity)
35{
36 mbedtls_md_type_t type;
37 switch (bits) {
38 case 160:
39 type = MBEDTLS_MD_SHA1;
40 break;
41 case 256:
42 type = MBEDTLS_MD_SHA256;
43 break;
44 case 384:
45 type = MBEDTLS_MD_SHA384;
46 break;
47 default:
48 return ESP_ERR_INVALID_ARG;
49 }
50 if (count > 8 || capacity < (size_t)bits / 8)
51 return ESP_ERR_INVALID_SIZE;
52 mbedtls_md_context_t context;
53 mbedtls_md_init(&context);
54 int result = mbedtls_md_setup(&context, mbedtls_md_info_from_type(type), 1);
55 if (!result)
56 result = mbedtls_md_hmac_starts(&context, key, key_length);
57 for (size_t i = 0; !result && i < count; i++)
58 result = mbedtls_md_hmac_update(&context, parts[i].bytes, parts[i].length);
59 if (!result)
60 result = mbedtls_md_hmac_finish(&context, output);
61 mbedtls_md_free(&context);
62 return result;
63}
64 
65int32_t radio_crypto_hash_init(uint8_t out[RADIO_CRYPTO_HASH_STATE_BYTES], int32_t bits)
66{
67 if (bits != 256 && bits != 384)
68 return ESP_ERR_INVALID_ARG;
69 hash_state state;
70 memset(&state, 0, sizeof(state));
71 state.bits = bits;
72 int result;
73 if (bits == 256) {
74 mbedtls_sha256_init(&state.context.sha256);
75 result = mbedtls_sha256_starts(&state.context.sha256, 0);
76 } else {
77 mbedtls_sha512_init(&state.context.sha512);
78 result = mbedtls_sha512_starts(&state.context.sha512, 1);
79 }
80 memset(out, 0, RADIO_CRYPTO_HASH_STATE_BYTES);
81 if (!result)
82 memcpy(out, &state, sizeof(state));
83 mbedtls_platform_zeroize(&state, sizeof(state));
84 return result;
85}
86 
87int32_t radio_crypto_hash_update(uint8_t bytes[RADIO_CRYPTO_HASH_STATE_BYTES], const uint8_t *input,
88 size_t length)
89{
90 hash_state state;
91 memcpy(&state, bytes, sizeof(state));
92 int result = ESP_ERR_INVALID_ARG;
93 if (state.bits == 256)
94 result = mbedtls_sha256_update(&state.context.sha256, input, length);
95 else if (state.bits == 384)
96 result = mbedtls_sha512_update(&state.context.sha512, input, length);
97 if (!result)
98 memcpy(bytes, &state, sizeof(state));
99 mbedtls_platform_zeroize(&state, sizeof(state));
100 return result;
101}
102 
103int32_t radio_crypto_hash_finish(const uint8_t bytes[RADIO_CRYPTO_HASH_STATE_BYTES],
104 uint8_t *output, size_t capacity)
105{
106 hash_state state;
107 memcpy(&state, bytes, sizeof(state));
108 uint8_t digest[64] = {0};
109 int result = ESP_ERR_INVALID_ARG;
110 if (state.bits == 256 && capacity >= 32)
111 result = mbedtls_sha256_finish(&state.context.sha256, digest);
112 else if (state.bits == 384 && capacity >= 48)
113 result = mbedtls_sha512_finish(&state.context.sha512, digest);
114 if (!result)
115 memcpy(output, digest, state.bits / 8);
116 mbedtls_platform_zeroize(digest, sizeof(digest));
117 mbedtls_platform_zeroize(&state, sizeof(state));
118 return result;
119}