xref: /optee_os/core/drivers/crypto/stm32/hmac.c (revision e880aa971c990f571fe4832de04c6cbd9cb1c65e)
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