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_hash.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_hash_ops hash_ops;
18*e880aa97SNicolas Toromanoff
19*e880aa97SNicolas Toromanoff struct stm32_hash_ctx {
20*e880aa97SNicolas Toromanoff struct crypto_hash_ctx ch_ctx;
21*e880aa97SNicolas Toromanoff struct stm32_hash_context hash;
22*e880aa97SNicolas Toromanoff };
23*e880aa97SNicolas Toromanoff
to_stm32_hash_ctx(struct crypto_hash_ctx * ctx)24*e880aa97SNicolas Toromanoff static struct stm32_hash_ctx *to_stm32_hash_ctx(struct crypto_hash_ctx *ctx)
25*e880aa97SNicolas Toromanoff {
26*e880aa97SNicolas Toromanoff assert(ctx && ctx->ops == &hash_ops);
27*e880aa97SNicolas Toromanoff
28*e880aa97SNicolas Toromanoff return container_of(ctx, struct stm32_hash_ctx, ch_ctx);
29*e880aa97SNicolas Toromanoff }
30*e880aa97SNicolas Toromanoff
31*e880aa97SNicolas Toromanoff /*
32*e880aa97SNicolas Toromanoff * Initialization of the Hash operation
33*e880aa97SNicolas Toromanoff *
34*e880aa97SNicolas Toromanoff * @ctx Operation software context
35*e880aa97SNicolas Toromanoff */
do_hash_init(struct crypto_hash_ctx * ctx)36*e880aa97SNicolas Toromanoff static TEE_Result do_hash_init(struct crypto_hash_ctx *ctx)
37*e880aa97SNicolas Toromanoff {
38*e880aa97SNicolas Toromanoff struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx);
39*e880aa97SNicolas Toromanoff
40*e880aa97SNicolas Toromanoff return stm32_hash_init(&c->hash, NULL, 0);
41*e880aa97SNicolas Toromanoff }
42*e880aa97SNicolas Toromanoff
43*e880aa97SNicolas Toromanoff /*
44*e880aa97SNicolas Toromanoff * Update the Hash operation
45*e880aa97SNicolas Toromanoff *
46*e880aa97SNicolas Toromanoff * @ctx Operation software context
47*e880aa97SNicolas Toromanoff * @data Data to hash
48*e880aa97SNicolas Toromanoff * @len Data length
49*e880aa97SNicolas Toromanoff */
do_hash_update(struct crypto_hash_ctx * ctx,const uint8_t * data,size_t len)50*e880aa97SNicolas Toromanoff static TEE_Result do_hash_update(struct crypto_hash_ctx *ctx,
51*e880aa97SNicolas Toromanoff const uint8_t *data, size_t len)
52*e880aa97SNicolas Toromanoff {
53*e880aa97SNicolas Toromanoff struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx);
54*e880aa97SNicolas Toromanoff
55*e880aa97SNicolas Toromanoff return stm32_hash_update(&c->hash, data, len);
56*e880aa97SNicolas Toromanoff }
57*e880aa97SNicolas Toromanoff
58*e880aa97SNicolas Toromanoff /*
59*e880aa97SNicolas Toromanoff * Finalize the Hash operation
60*e880aa97SNicolas Toromanoff *
61*e880aa97SNicolas Toromanoff * @ctx Operation software context
62*e880aa97SNicolas Toromanoff * @digest [out] Hash digest buffer
63*e880aa97SNicolas Toromanoff * @len Digest buffer length
64*e880aa97SNicolas Toromanoff */
do_hash_final(struct crypto_hash_ctx * ctx,uint8_t * digest,size_t len)65*e880aa97SNicolas Toromanoff static TEE_Result do_hash_final(struct crypto_hash_ctx *ctx, uint8_t *digest,
66*e880aa97SNicolas Toromanoff size_t len)
67*e880aa97SNicolas Toromanoff {
68*e880aa97SNicolas Toromanoff struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx);
69*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
70*e880aa97SNicolas Toromanoff uint8_t block_digest[STM32_HASH_MAX_DIGEST_SIZE] = { 0 };
71*e880aa97SNicolas Toromanoff uint8_t *tmp_digest = digest;
72*e880aa97SNicolas Toromanoff
73*e880aa97SNicolas Toromanoff if (len < stm32_hash_digest_size(&c->hash))
74*e880aa97SNicolas Toromanoff tmp_digest = block_digest;
75*e880aa97SNicolas Toromanoff
76*e880aa97SNicolas Toromanoff res = stm32_hash_final(&c->hash, tmp_digest, NULL, 0);
77*e880aa97SNicolas Toromanoff
78*e880aa97SNicolas Toromanoff if (res == TEE_SUCCESS && len < stm32_hash_digest_size(&c->hash))
79*e880aa97SNicolas Toromanoff memcpy(digest, tmp_digest, len);
80*e880aa97SNicolas Toromanoff
81*e880aa97SNicolas Toromanoff return res;
82*e880aa97SNicolas Toromanoff }
83*e880aa97SNicolas Toromanoff
84*e880aa97SNicolas Toromanoff /*
85*e880aa97SNicolas Toromanoff * Free the SW hashing data context
86*e880aa97SNicolas Toromanoff *
87*e880aa97SNicolas Toromanoff * @ctx [in/out] Caller context variable
88*e880aa97SNicolas Toromanoff */
do_hash_free(struct crypto_hash_ctx * ctx)89*e880aa97SNicolas Toromanoff static void do_hash_free(struct crypto_hash_ctx *ctx)
90*e880aa97SNicolas Toromanoff {
91*e880aa97SNicolas Toromanoff struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx);
92*e880aa97SNicolas Toromanoff
93*e880aa97SNicolas Toromanoff stm32_hash_free(&c->hash);
94*e880aa97SNicolas Toromanoff free(c);
95*e880aa97SNicolas Toromanoff }
96*e880aa97SNicolas Toromanoff
97*e880aa97SNicolas Toromanoff /*
98*e880aa97SNicolas Toromanoff * Copy Software Hashing Context
99*e880aa97SNicolas Toromanoff *
100*e880aa97SNicolas Toromanoff * @dst_ctx [out] Reference the context destination
101*e880aa97SNicolas Toromanoff * @src_ctx Reference the context source
102*e880aa97SNicolas Toromanoff */
do_hash_copy_state(struct crypto_hash_ctx * dst_ctx,struct crypto_hash_ctx * src_ctx)103*e880aa97SNicolas Toromanoff static void do_hash_copy_state(struct crypto_hash_ctx *dst_ctx,
104*e880aa97SNicolas Toromanoff struct crypto_hash_ctx *src_ctx)
105*e880aa97SNicolas Toromanoff {
106*e880aa97SNicolas Toromanoff struct stm32_hash_ctx *src = to_stm32_hash_ctx(src_ctx);
107*e880aa97SNicolas Toromanoff struct stm32_hash_ctx *dst = to_stm32_hash_ctx(dst_ctx);
108*e880aa97SNicolas Toromanoff
109*e880aa97SNicolas Toromanoff memcpy(&dst->ch_ctx, &src->ch_ctx, sizeof(dst->ch_ctx));
110*e880aa97SNicolas Toromanoff stm32_hash_deep_copy(&dst->hash, &src->hash);
111*e880aa97SNicolas Toromanoff }
112*e880aa97SNicolas Toromanoff
113*e880aa97SNicolas Toromanoff /*
114*e880aa97SNicolas Toromanoff * Registration of the hash Driver
115*e880aa97SNicolas Toromanoff */
116*e880aa97SNicolas Toromanoff static const struct crypto_hash_ops hash_ops = {
117*e880aa97SNicolas Toromanoff .init = do_hash_init,
118*e880aa97SNicolas Toromanoff .update = do_hash_update,
119*e880aa97SNicolas Toromanoff .final = do_hash_final,
120*e880aa97SNicolas Toromanoff .free_ctx = do_hash_free,
121*e880aa97SNicolas Toromanoff .copy_state = do_hash_copy_state,
122*e880aa97SNicolas Toromanoff };
123*e880aa97SNicolas Toromanoff
124*e880aa97SNicolas Toromanoff /*
125*e880aa97SNicolas Toromanoff * Allocate the internal hashing data context
126*e880aa97SNicolas Toromanoff *
127*e880aa97SNicolas Toromanoff * @ctx [out] Caller context variable
128*e880aa97SNicolas Toromanoff * @algo OP_TEE Algorithm ID
129*e880aa97SNicolas Toromanoff */
stm32_hash_allocate(struct crypto_hash_ctx ** ctx,uint32_t algo)130*e880aa97SNicolas Toromanoff static TEE_Result stm32_hash_allocate(struct crypto_hash_ctx **ctx,
131*e880aa97SNicolas Toromanoff uint32_t algo)
132*e880aa97SNicolas Toromanoff {
133*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
134*e880aa97SNicolas Toromanoff struct stm32_hash_ctx *c = NULL;
135*e880aa97SNicolas Toromanoff enum stm32_hash_algo stm32_algo = STM32_HASH_SHA256;
136*e880aa97SNicolas Toromanoff
137*e880aa97SNicolas Toromanoff /* Convert TEE Algo id to stm32 hash id */
138*e880aa97SNicolas Toromanoff switch (TEE_ALG_GET_MAIN_ALG(algo)) {
139*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_MD5:
140*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_MD5;
141*e880aa97SNicolas Toromanoff break;
142*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA1:
143*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA1;
144*e880aa97SNicolas Toromanoff break;
145*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA224:
146*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA224;
147*e880aa97SNicolas Toromanoff break;
148*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA256:
149*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA256;
150*e880aa97SNicolas Toromanoff break;
151*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA384:
152*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA384;
153*e880aa97SNicolas Toromanoff break;
154*e880aa97SNicolas Toromanoff case TEE_MAIN_ALGO_SHA512:
155*e880aa97SNicolas Toromanoff stm32_algo = STM32_HASH_SHA512;
156*e880aa97SNicolas Toromanoff break;
157*e880aa97SNicolas Toromanoff default:
158*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
159*e880aa97SNicolas Toromanoff }
160*e880aa97SNicolas Toromanoff
161*e880aa97SNicolas Toromanoff c = calloc(1, sizeof(*c));
162*e880aa97SNicolas Toromanoff if (!c)
163*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
164*e880aa97SNicolas Toromanoff
165*e880aa97SNicolas Toromanoff res = stm32_hash_alloc(&c->hash, STM32_HASH_MODE, stm32_algo);
166*e880aa97SNicolas Toromanoff if (res) {
167*e880aa97SNicolas Toromanoff free(c);
168*e880aa97SNicolas Toromanoff return res;
169*e880aa97SNicolas Toromanoff }
170*e880aa97SNicolas Toromanoff
171*e880aa97SNicolas Toromanoff FMSG("Using HASH %"PRIu32, stm32_algo);
172*e880aa97SNicolas Toromanoff c->ch_ctx.ops = &hash_ops;
173*e880aa97SNicolas Toromanoff *ctx = &c->ch_ctx;
174*e880aa97SNicolas Toromanoff
175*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
176*e880aa97SNicolas Toromanoff }
177*e880aa97SNicolas Toromanoff
stm32_register_hash(void)178*e880aa97SNicolas Toromanoff TEE_Result stm32_register_hash(void)
179*e880aa97SNicolas Toromanoff {
180*e880aa97SNicolas Toromanoff return drvcrypt_register_hash(&stm32_hash_allocate);
181*e880aa97SNicolas Toromanoff }
182