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
to_stm32_hmac_ctx(struct crypto_mac_ctx * ctx)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 */
do_hmac_init(struct crypto_mac_ctx * ctx,const uint8_t * key,size_t len)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 */
do_hmac_update(struct crypto_mac_ctx * ctx,const uint8_t * data,size_t len)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 */
do_hmac_final(struct crypto_mac_ctx * ctx,uint8_t * digest,size_t len)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 */
do_hmac_free(struct crypto_mac_ctx * ctx)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 */
do_hmac_copy_state(struct crypto_mac_ctx * dst_ctx,struct crypto_mac_ctx * src_ctx)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 */
stm32_hmac_allocate(struct crypto_mac_ctx ** ctx,uint32_t algo)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
stm32_register_hmac(void)218 TEE_Result stm32_register_hmac(void)
219 {
220 return drvcrypt_register_hmac(&stm32_hmac_allocate);
221 }
222