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