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