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