xref: /optee_os/core/drivers/crypto/stm32/hash.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_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