1*e880aa97SNicolas Toromanoff // SPDX-License-Identifier: BSD-2-Clause
2*e880aa97SNicolas Toromanoff /*
3*e880aa97SNicolas Toromanoff * Copyright (c) 2021-2025, STMicroelectronics - All Rights Reserved
4*e880aa97SNicolas Toromanoff */
5*e880aa97SNicolas Toromanoff
6*e880aa97SNicolas Toromanoff #include <assert.h>
7*e880aa97SNicolas Toromanoff #include <crypto/crypto_impl.h>
8*e880aa97SNicolas Toromanoff #include <crypto/crypto.h>
9*e880aa97SNicolas Toromanoff #include <drvcrypt_mac.h>
10*e880aa97SNicolas Toromanoff #include <drvcrypt.h>
11*e880aa97SNicolas Toromanoff #include <kernel/dt.h>
12*e880aa97SNicolas Toromanoff #include <string.h>
13*e880aa97SNicolas Toromanoff
14*e880aa97SNicolas Toromanoff #include "common.h"
15*e880aa97SNicolas Toromanoff #include "stm32_hash.h"
16*e880aa97SNicolas Toromanoff
17*e880aa97SNicolas Toromanoff static const struct crypto_mac_ops hmac_ops;
18*e880aa97SNicolas Toromanoff
19*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx {
20*e880aa97SNicolas Toromanoff struct crypto_mac_ctx mac_ctx;
21*e880aa97SNicolas Toromanoff struct stm32_hash_context hash;
22*e880aa97SNicolas Toromanoff uint8_t *key;
23*e880aa97SNicolas Toromanoff size_t key_len;
24*e880aa97SNicolas Toromanoff };
25*e880aa97SNicolas Toromanoff
to_stm32_hmac_ctx(struct crypto_mac_ctx * ctx)26*e880aa97SNicolas Toromanoff static struct stm32_hmac_ctx *to_stm32_hmac_ctx(struct crypto_mac_ctx *ctx)
27*e880aa97SNicolas Toromanoff {
28*e880aa97SNicolas Toromanoff assert(ctx && ctx->ops == &hmac_ops);
29*e880aa97SNicolas Toromanoff
30*e880aa97SNicolas Toromanoff return container_of(ctx, struct stm32_hmac_ctx, mac_ctx);
31*e880aa97SNicolas Toromanoff }
32*e880aa97SNicolas Toromanoff
33*e880aa97SNicolas Toromanoff /*
34*e880aa97SNicolas Toromanoff * Initialization of the hmac operation
35*e880aa97SNicolas Toromanoff *
36*e880aa97SNicolas Toromanoff * @ctx Operation software context
37*e880aa97SNicolas Toromanoff * @key Key used for hmac operation
38*e880aa97SNicolas Toromanoff * @len Length of @key in bytes
39*e880aa97SNicolas Toromanoff */
do_hmac_init(struct crypto_mac_ctx * ctx,const uint8_t * key,size_t len)40*e880aa97SNicolas Toromanoff static TEE_Result do_hmac_init(struct crypto_mac_ctx *ctx, const uint8_t *key,
41*e880aa97SNicolas Toromanoff size_t len)
42*e880aa97SNicolas Toromanoff {
43*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx);
44*e880aa97SNicolas Toromanoff
45*e880aa97SNicolas Toromanoff /*
46*e880aa97SNicolas Toromanoff * If hmac_init() is called again,
47*e880aa97SNicolas Toromanoff * we won't need the previously saved key.
48*e880aa97SNicolas Toromanoff */
49*e880aa97SNicolas Toromanoff if (c->key)
50*e880aa97SNicolas Toromanoff free(c->key);
51*e880aa97SNicolas Toromanoff
52*e880aa97SNicolas Toromanoff c->key = malloc(len);
53*e880aa97SNicolas Toromanoff if (!c->key) {
54*e880aa97SNicolas Toromanoff c->key_len = 0;
55*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
56*e880aa97SNicolas Toromanoff }
57*e880aa97SNicolas Toromanoff memcpy(c->key, key, len);
58*e880aa97SNicolas Toromanoff c->key_len = len;
59*e880aa97SNicolas Toromanoff
60*e880aa97SNicolas Toromanoff return stm32_hash_init(&c->hash, c->key, c->key_len);
61*e880aa97SNicolas Toromanoff }
62*e880aa97SNicolas Toromanoff
63*e880aa97SNicolas Toromanoff /*
64*e880aa97SNicolas Toromanoff * Update the hmac operation
65*e880aa97SNicolas Toromanoff *
66*e880aa97SNicolas Toromanoff * @ctx Operation software context
67*e880aa97SNicolas Toromanoff * @data Data to hmac
68*e880aa97SNicolas Toromanoff * @len Data length
69*e880aa97SNicolas Toromanoff */
do_hmac_update(struct crypto_mac_ctx * ctx,const uint8_t * data,size_t len)70*e880aa97SNicolas Toromanoff static TEE_Result do_hmac_update(struct crypto_mac_ctx *ctx,
71*e880aa97SNicolas Toromanoff const uint8_t *data, size_t len)
72*e880aa97SNicolas Toromanoff {
73*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx);
74*e880aa97SNicolas Toromanoff
75*e880aa97SNicolas Toromanoff if (!c->key) {
76*e880aa97SNicolas Toromanoff EMSG("NULL key pointer");
77*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
78*e880aa97SNicolas Toromanoff }
79*e880aa97SNicolas Toromanoff
80*e880aa97SNicolas Toromanoff return stm32_hash_update(&c->hash, data, len);
81*e880aa97SNicolas Toromanoff }
82*e880aa97SNicolas Toromanoff
83*e880aa97SNicolas Toromanoff /*
84*e880aa97SNicolas Toromanoff * Finalize the hmac operation
85*e880aa97SNicolas Toromanoff *
86*e880aa97SNicolas Toromanoff * @ctx Operation software context
87*e880aa97SNicolas Toromanoff * @digest [out] hmac digest buffer
88*e880aa97SNicolas Toromanoff * @len Digest buffer length
89*e880aa97SNicolas Toromanoff */
do_hmac_final(struct crypto_mac_ctx * ctx,uint8_t * digest,size_t len)90*e880aa97SNicolas Toromanoff static TEE_Result do_hmac_final(struct crypto_mac_ctx *ctx, uint8_t *digest,
91*e880aa97SNicolas Toromanoff size_t len)
92*e880aa97SNicolas Toromanoff {
93*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx);
94*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
95*e880aa97SNicolas Toromanoff uint8_t block_digest[STM32_HASH_MAX_DIGEST_SIZE] = { 0 };
96*e880aa97SNicolas Toromanoff uint8_t *tmp_digest = digest;
97*e880aa97SNicolas Toromanoff
98*e880aa97SNicolas Toromanoff if (!c->key) {
99*e880aa97SNicolas Toromanoff EMSG("NULL key pointer");
100*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
101*e880aa97SNicolas Toromanoff }
102*e880aa97SNicolas Toromanoff
103*e880aa97SNicolas Toromanoff if (len < stm32_hash_digest_size(&c->hash))
104*e880aa97SNicolas Toromanoff tmp_digest = block_digest;
105*e880aa97SNicolas Toromanoff
106*e880aa97SNicolas Toromanoff res = stm32_hash_final(&c->hash, tmp_digest, c->key, c->key_len);
107*e880aa97SNicolas Toromanoff
108*e880aa97SNicolas Toromanoff if (res == TEE_SUCCESS && len < stm32_hash_digest_size(&c->hash))
109*e880aa97SNicolas Toromanoff memcpy(digest, tmp_digest, len);
110*e880aa97SNicolas Toromanoff
111*e880aa97SNicolas Toromanoff return res;
112*e880aa97SNicolas Toromanoff }
113*e880aa97SNicolas Toromanoff
114*e880aa97SNicolas Toromanoff /*
115*e880aa97SNicolas Toromanoff * Free the SW hmac context
116*e880aa97SNicolas Toromanoff *
117*e880aa97SNicolas Toromanoff * @ctx [in/out] Caller context variable
118*e880aa97SNicolas Toromanoff */
do_hmac_free(struct crypto_mac_ctx * ctx)119*e880aa97SNicolas Toromanoff static void do_hmac_free(struct crypto_mac_ctx *ctx)
120*e880aa97SNicolas Toromanoff {
121*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx);
122*e880aa97SNicolas Toromanoff
123*e880aa97SNicolas Toromanoff free(c->key);
124*e880aa97SNicolas Toromanoff stm32_hash_free(&c->hash);
125*e880aa97SNicolas Toromanoff free(c);
126*e880aa97SNicolas Toromanoff }
127*e880aa97SNicolas Toromanoff
128*e880aa97SNicolas Toromanoff /*
129*e880aa97SNicolas Toromanoff * Copy Software HMAC Context
130*e880aa97SNicolas Toromanoff *
131*e880aa97SNicolas Toromanoff * @dst_ctx [out] Reference the context destination
132*e880aa97SNicolas Toromanoff * @src_ctx Reference the context source
133*e880aa97SNicolas Toromanoff */
do_hmac_copy_state(struct crypto_mac_ctx * dst_ctx,struct crypto_mac_ctx * src_ctx)134*e880aa97SNicolas Toromanoff static void do_hmac_copy_state(struct crypto_mac_ctx *dst_ctx,
135*e880aa97SNicolas Toromanoff struct crypto_mac_ctx *src_ctx)
136*e880aa97SNicolas Toromanoff {
137*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx *src = to_stm32_hmac_ctx(src_ctx);
138*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx *dst = to_stm32_hmac_ctx(dst_ctx);
139*e880aa97SNicolas Toromanoff
140*e880aa97SNicolas Toromanoff memcpy(&dst->mac_ctx, &src->mac_ctx, sizeof(dst->mac_ctx));
141*e880aa97SNicolas Toromanoff stm32_hash_deep_copy(&dst->hash, &src->hash);
142*e880aa97SNicolas Toromanoff
143*e880aa97SNicolas Toromanoff dst->key_len = src->key_len;
144*e880aa97SNicolas Toromanoff
145*e880aa97SNicolas Toromanoff if (src->key)
146*e880aa97SNicolas Toromanoff dst->key = malloc(dst->key_len);
147*e880aa97SNicolas Toromanoff
148*e880aa97SNicolas Toromanoff if (dst->key && src->key)
149*e880aa97SNicolas Toromanoff memcpy(dst->key, src->key, dst->key_len);
150*e880aa97SNicolas Toromanoff else
151*e880aa97SNicolas Toromanoff dst->key_len = 0;
152*e880aa97SNicolas Toromanoff }
153*e880aa97SNicolas Toromanoff
154*e880aa97SNicolas Toromanoff /*
155*e880aa97SNicolas Toromanoff * Registration of the hmac Driver
156*e880aa97SNicolas Toromanoff */
157*e880aa97SNicolas Toromanoff static const struct crypto_mac_ops hmac_ops = {
158*e880aa97SNicolas Toromanoff .init = do_hmac_init,
159*e880aa97SNicolas Toromanoff .update = do_hmac_update,
160*e880aa97SNicolas Toromanoff .final = do_hmac_final,
161*e880aa97SNicolas Toromanoff .free_ctx = do_hmac_free,
162*e880aa97SNicolas Toromanoff .copy_state = do_hmac_copy_state,
163*e880aa97SNicolas Toromanoff };
164*e880aa97SNicolas Toromanoff
165*e880aa97SNicolas Toromanoff /*
166*e880aa97SNicolas Toromanoff * Allocate the internal HMAC data context
167*e880aa97SNicolas Toromanoff *
168*e880aa97SNicolas Toromanoff * @ctx [out] Caller context variable
169*e880aa97SNicolas Toromanoff * @algo OP_TEE Algorithm ID
170*e880aa97SNicolas Toromanoff */
stm32_hmac_allocate(struct crypto_mac_ctx ** ctx,uint32_t algo)171*e880aa97SNicolas Toromanoff static TEE_Result stm32_hmac_allocate(struct crypto_mac_ctx **ctx,
172*e880aa97SNicolas Toromanoff uint32_t algo)
173*e880aa97SNicolas Toromanoff {
174*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
175*e880aa97SNicolas Toromanoff enum stm32_hash_algo stm32_algo = STM32_HASH_MD5;
176*e880aa97SNicolas Toromanoff struct stm32_hmac_ctx *c = NULL;
177*e880aa97SNicolas Toromanoff
178*e880aa97SNicolas Toromanoff switch (TEE_ALG_GET_MAIN_ALG(algo)) {
179*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_MD5:
180*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_MD5;
181*e880aa97SNicolas Toromanoff break;
182*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA1:
183*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA1;
184*e880aa97SNicolas Toromanoff break;
185*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA224:
186*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA224;
187*e880aa97SNicolas Toromanoff break;
188*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA256:
189*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA256;
190*e880aa97SNicolas Toromanoff break;
191*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA384:
192*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA384;
193*e880aa97SNicolas Toromanoff break;
194*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA512:
195*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA512;
196*e880aa97SNicolas Toromanoff break;
197*e880aa97SNicolas Toromanoff default:
198*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
199*e880aa97SNicolas Toromanoff }
200*e880aa97SNicolas Toromanoff
201*e880aa97SNicolas Toromanoff c = calloc(1, sizeof(*c));
202*e880aa97SNicolas Toromanoff if (!c)
203*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
204*e880aa97SNicolas Toromanoff
205*e880aa97SNicolas Toromanoff res = stm32_hash_alloc(&c->hash, STM32_HMAC_MODE, stm32_algo);
206*e880aa97SNicolas Toromanoff if (res) {
207*e880aa97SNicolas Toromanoff free(c);
208*e880aa97SNicolas Toromanoff return res;
209*e880aa97SNicolas Toromanoff }
210*e880aa97SNicolas Toromanoff
211*e880aa97SNicolas Toromanoff FMSG("Using HMAC %d", stm32_algo);
212*e880aa97SNicolas Toromanoff c->mac_ctx.ops = &hmac_ops;
213*e880aa97SNicolas Toromanoff *ctx = &c->mac_ctx;
214*e880aa97SNicolas Toromanoff
215*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
216*e880aa97SNicolas Toromanoff }
217*e880aa97SNicolas Toromanoff
stm32_register_hmac(void)218*e880aa97SNicolas Toromanoff TEE_Result stm32_register_hmac(void)
219*e880aa97SNicolas Toromanoff {
220*e880aa97SNicolas Toromanoff return drvcrypt_register_hmac(&stm32_hmac_allocate);
221*e880aa97SNicolas Toromanoff }
222