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 <config.h>
8*e880aa97SNicolas Toromanoff #include <drivers/clk_dt.h>
9*e880aa97SNicolas Toromanoff #include <drivers/clk.h>
10*e880aa97SNicolas Toromanoff #include <drivers/rstctrl.h>
11*e880aa97SNicolas Toromanoff #include <io.h>
12*e880aa97SNicolas Toromanoff #include <kernel/delay.h>
13*e880aa97SNicolas Toromanoff #include <kernel/dt.h>
14*e880aa97SNicolas Toromanoff #include <kernel/mutex.h>
15*e880aa97SNicolas Toromanoff #include <libfdt.h>
16*e880aa97SNicolas Toromanoff #include <stm32_util.h>
17*e880aa97SNicolas Toromanoff #include <utee_defines.h>
18*e880aa97SNicolas Toromanoff #include <util.h>
19*e880aa97SNicolas Toromanoff
20*e880aa97SNicolas Toromanoff #include "common.h"
21*e880aa97SNicolas Toromanoff #include "stm32_hash.h"
22*e880aa97SNicolas Toromanoff
23*e880aa97SNicolas Toromanoff #define _HASH_CR U(0x00)
24*e880aa97SNicolas Toromanoff #define _HASH_DIN U(0x04)
25*e880aa97SNicolas Toromanoff #define _HASH_STR U(0x08)
26*e880aa97SNicolas Toromanoff #define _HASH_IMR U(0x20)
27*e880aa97SNicolas Toromanoff #define _HASH_SR U(0x24)
28*e880aa97SNicolas Toromanoff #define _HASH_HR(x) (U(0x310) + ((x) * U(0x04)))
29*e880aa97SNicolas Toromanoff #define _HASH_VERR U(0x3F4)
30*e880aa97SNicolas Toromanoff #define _HASH_CSR(x) (U(0xF8) + ((x) * U(0x04)))
31*e880aa97SNicolas Toromanoff
32*e880aa97SNicolas Toromanoff /* Control Register */
33*e880aa97SNicolas Toromanoff #define _HASH_CR_INIT BIT(2)
34*e880aa97SNicolas Toromanoff #define _HASH_CR_MODE BIT(6)
35*e880aa97SNicolas Toromanoff #define _HASH_CR_DATATYPE_SHIFT U(4)
36*e880aa97SNicolas Toromanoff #define _HASH_CR_DATATYPE_NONE SHIFT_U32(U(0), _HASH_CR_DATATYPE_SHIFT)
37*e880aa97SNicolas Toromanoff #define _HASH_CR_DATATYPE_HALFWORD SHIFT_U32(U(1), _HASH_CR_DATATYPE_SHIFT)
38*e880aa97SNicolas Toromanoff #define _HASH_CR_DATATYPE_BYTE SHIFT_U32(U(2), _HASH_CR_DATATYPE_SHIFT)
39*e880aa97SNicolas Toromanoff #define _HASH_CR_DATATYPE_BIT SHIFT_U32(U(3), _HASH_CR_DATATYPE_SHIFT)
40*e880aa97SNicolas Toromanoff #define _HASH_CR_LKEY BIT(16)
41*e880aa97SNicolas Toromanoff
42*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHIFT U(17)
43*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_MD5 BIT(7)
44*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA1 SHIFT_U32(U(0x0), _HASH_CR_ALGO_SHIFT)
45*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA224 SHIFT_U32(U(0x2), _HASH_CR_ALGO_SHIFT)
46*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA256 SHIFT_U32(U(0x3), _HASH_CR_ALGO_SHIFT)
47*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA256_IF_MD5 (BIT(18) | BIT(7))
48*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA384 SHIFT_U32(U(0xC), _HASH_CR_ALGO_SHIFT)
49*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA512_224 SHIFT_U32(U(0xD), _HASH_CR_ALGO_SHIFT)
50*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA512_256 SHIFT_U32(U(0xE), _HASH_CR_ALGO_SHIFT)
51*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA512 SHIFT_U32(U(0xF), _HASH_CR_ALGO_SHIFT)
52*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA3_224 SHIFT_U32(U(0x4), _HASH_CR_ALGO_SHIFT)
53*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA3_256 SHIFT_U32(U(0x5), _HASH_CR_ALGO_SHIFT)
54*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA3_384 SHIFT_U32(U(0x6), _HASH_CR_ALGO_SHIFT)
55*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHA3_512 SHIFT_U32(U(0x7), _HASH_CR_ALGO_SHIFT)
56*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHAKE128 SHIFT_U32(U(0x8), _HASH_CR_ALGO_SHIFT)
57*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_SHAKE256 SHIFT_U32(U(0x9), _HASH_CR_ALGO_SHIFT)
58*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_RAWSHAKE128 SHIFT_U32(U(0xA), _HASH_CR_ALGO_SHIFT)
59*e880aa97SNicolas Toromanoff #define _HASH_CR_ALGO_RAWSHAKE256 SHIFT_U32(U(0xB), _HASH_CR_ALGO_SHIFT)
60*e880aa97SNicolas Toromanoff
61*e880aa97SNicolas Toromanoff /* Status Flags */
62*e880aa97SNicolas Toromanoff #define _HASH_SR_DINIS BIT(0)
63*e880aa97SNicolas Toromanoff #define _HASH_SR_DCIS BIT(1)
64*e880aa97SNicolas Toromanoff #define _HASH_SR_BUSY BIT(3)
65*e880aa97SNicolas Toromanoff #define _HASH_SR_NBWP_MASK GENMASK_32(13, 9)
66*e880aa97SNicolas Toromanoff #define _HASH_SR_NBWP_OFF 9
67*e880aa97SNicolas Toromanoff #define _HASH_SR_NBWE_MASK GENMASK_32(21, 16)
68*e880aa97SNicolas Toromanoff #define _HASH_SR_NBWE_OFF 16
69*e880aa97SNicolas Toromanoff
70*e880aa97SNicolas Toromanoff /* STR Register */
71*e880aa97SNicolas Toromanoff #define _HASH_STR_NBLW_MASK GENMASK_32(4, 0)
72*e880aa97SNicolas Toromanoff #define _HASH_STR_DCAL BIT(8)
73*e880aa97SNicolas Toromanoff
74*e880aa97SNicolas Toromanoff /* _iHASH_VERR bit fields */
75*e880aa97SNicolas Toromanoff #define _HASH_VERR_MINREV GENMASK_32(3, 0)
76*e880aa97SNicolas Toromanoff #define _HASH_VERR_MAJREV GENMASK_32(7, 4)
77*e880aa97SNicolas Toromanoff
78*e880aa97SNicolas Toromanoff /* Digest size in nb of uint32_t */
79*e880aa97SNicolas Toromanoff #define MD5_DIGEST_U32 U(4)
80*e880aa97SNicolas Toromanoff #define SHA1_DIGEST_U32 U(5)
81*e880aa97SNicolas Toromanoff #define SHA224_DIGEST_U32 U(7)
82*e880aa97SNicolas Toromanoff #define SHA256_DIGEST_U32 U(8)
83*e880aa97SNicolas Toromanoff #define SHA384_DIGEST_U32 U(12)
84*e880aa97SNicolas Toromanoff #define SHA512_224_DIGEST_U32 U(7)
85*e880aa97SNicolas Toromanoff #define SHA512_256_DIGEST_U32 U(8)
86*e880aa97SNicolas Toromanoff #define SHA512_DIGEST_U32 U(16)
87*e880aa97SNicolas Toromanoff #define SHA3_224_DIGEST_U32 U(7)
88*e880aa97SNicolas Toromanoff #define SHA3_256_DIGEST_U32 U(8)
89*e880aa97SNicolas Toromanoff #define SHA3_384_DIGEST_U32 U(12)
90*e880aa97SNicolas Toromanoff #define SHA3_512_DIGEST_U32 U(16)
91*e880aa97SNicolas Toromanoff
92*e880aa97SNicolas Toromanoff /* Internal block size */
93*e880aa97SNicolas Toromanoff #define MD5_BLOCK_SIZE U(64)
94*e880aa97SNicolas Toromanoff #define SHA1_BLOCK_SIZE U(64)
95*e880aa97SNicolas Toromanoff #define SHA224_BLOCK_SIZE U(64)
96*e880aa97SNicolas Toromanoff #define SHA256_BLOCK_SIZE U(64)
97*e880aa97SNicolas Toromanoff #define SHA384_BLOCK_SIZE U(128)
98*e880aa97SNicolas Toromanoff #define SHA512_224_BLOCK_SIZE U(128)
99*e880aa97SNicolas Toromanoff #define SHA512_256_BLOCK_SIZE U(128)
100*e880aa97SNicolas Toromanoff #define SHA512_BLOCK_SIZE U(128)
101*e880aa97SNicolas Toromanoff #define SHA3_224_BLOCK_SIZE U(144)
102*e880aa97SNicolas Toromanoff #define SHA3_256_BLOCK_SIZE U(136)
103*e880aa97SNicolas Toromanoff #define SHA3_384_BLOCK_SIZE U(104)
104*e880aa97SNicolas Toromanoff #define SHA3_512_BLOCK_SIZE U(72)
105*e880aa97SNicolas Toromanoff
106*e880aa97SNicolas Toromanoff /* Define the registers needed to save context */
107*e880aa97SNicolas Toromanoff #define SAVE_SMALL U(1)
108*e880aa97SNicolas Toromanoff #define SAVE_BIG U(2)
109*e880aa97SNicolas Toromanoff #define SAVE_SHA3 U(3)
110*e880aa97SNicolas Toromanoff
111*e880aa97SNicolas Toromanoff #define SAVE_SMALL_NB_REG U(22)
112*e880aa97SNicolas Toromanoff #define SAVE_SMALL_FIRST_REG U(0)
113*e880aa97SNicolas Toromanoff #define SAVE_SMALL_HMAC_NB_REG U(16)
114*e880aa97SNicolas Toromanoff #define SAVE_SMALL_HMAC_FIRST_REG U(38)
115*e880aa97SNicolas Toromanoff #define SAVE_BIG_NB_REG U(91)
116*e880aa97SNicolas Toromanoff #define SAVE_BIG_FIRST_REG U(0)
117*e880aa97SNicolas Toromanoff #define SAVE_BIG_HMAC_NB_REG U(12)
118*e880aa97SNicolas Toromanoff #define SAVE_BIG_HMAC_FIRST_REG U(91)
119*e880aa97SNicolas Toromanoff #define SAVE_SHA3_NB_REG U(72)
120*e880aa97SNicolas Toromanoff #define SAVE_SHA3_FIRST_REG U(0)
121*e880aa97SNicolas Toromanoff #define SAVE_SHA3_HMAC_NB_REG U(72)
122*e880aa97SNicolas Toromanoff #define SAVE_SHA3_HMAC_FIRST_REG U(16)
123*e880aa97SNicolas Toromanoff
124*e880aa97SNicolas Toromanoff #define RESET_TIMEOUT_US_1MS U(1000)
125*e880aa97SNicolas Toromanoff #define HASH_TIMEOUT_US U(10000)
126*e880aa97SNicolas Toromanoff
127*e880aa97SNicolas Toromanoff /* Define capabilities */
128*e880aa97SNicolas Toromanoff #define CAPS_MD5 BIT(0)
129*e880aa97SNicolas Toromanoff #define CAPS_SHA1 BIT(1)
130*e880aa97SNicolas Toromanoff #define CAPS_SHA2_224 BIT(2)
131*e880aa97SNicolas Toromanoff #define CAPS_SHA2_256 BIT(3)
132*e880aa97SNicolas Toromanoff #define CAPS_SHA2_384 BIT(4)
133*e880aa97SNicolas Toromanoff #define CAPS_SHA2_512 BIT(5)
134*e880aa97SNicolas Toromanoff #define CAPS_SHA3 BIT(6)
135*e880aa97SNicolas Toromanoff
136*e880aa97SNicolas Toromanoff struct stm32_hash_compat {
137*e880aa97SNicolas Toromanoff uint32_t caps;
138*e880aa97SNicolas Toromanoff };
139*e880aa97SNicolas Toromanoff
140*e880aa97SNicolas Toromanoff struct stm32_hash_platdata {
141*e880aa97SNicolas Toromanoff vaddr_t base;
142*e880aa97SNicolas Toromanoff struct clk *clock;
143*e880aa97SNicolas Toromanoff struct rstctrl *reset;
144*e880aa97SNicolas Toromanoff struct stm32_hash_compat *compat;
145*e880aa97SNicolas Toromanoff };
146*e880aa97SNicolas Toromanoff
147*e880aa97SNicolas Toromanoff struct stm32_hash_device {
148*e880aa97SNicolas Toromanoff struct stm32_hash_platdata pdata;
149*e880aa97SNicolas Toromanoff struct mutex lock; /* Protect HASH HW instance access */
150*e880aa97SNicolas Toromanoff };
151*e880aa97SNicolas Toromanoff
152*e880aa97SNicolas Toromanoff static struct stm32_hash_device *stm32_hash;
153*e880aa97SNicolas Toromanoff
wait_end_busy(vaddr_t base)154*e880aa97SNicolas Toromanoff static TEE_Result wait_end_busy(vaddr_t base)
155*e880aa97SNicolas Toromanoff {
156*e880aa97SNicolas Toromanoff uint32_t value = 0;
157*e880aa97SNicolas Toromanoff uint32_t addr = base + _HASH_SR;
158*e880aa97SNicolas Toromanoff
159*e880aa97SNicolas Toromanoff /* Timeout may append due to a schedule after the while(timeout()) */
160*e880aa97SNicolas Toromanoff if (IO_READ32_POLL_TIMEOUT(addr, value, !(value & _HASH_SR_BUSY), 0,
161*e880aa97SNicolas Toromanoff HASH_TIMEOUT_US)) {
162*e880aa97SNicolas Toromanoff EMSG("Busy timeout");
163*e880aa97SNicolas Toromanoff return TEE_ERROR_BUSY;
164*e880aa97SNicolas Toromanoff }
165*e880aa97SNicolas Toromanoff
166*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
167*e880aa97SNicolas Toromanoff }
168*e880aa97SNicolas Toromanoff
wait_digest_ready(vaddr_t base)169*e880aa97SNicolas Toromanoff static int wait_digest_ready(vaddr_t base)
170*e880aa97SNicolas Toromanoff {
171*e880aa97SNicolas Toromanoff uint32_t value = 0;
172*e880aa97SNicolas Toromanoff uint32_t addr = base + _HASH_SR;
173*e880aa97SNicolas Toromanoff
174*e880aa97SNicolas Toromanoff /* Timeout may append due to a schedule after the while(test) */
175*e880aa97SNicolas Toromanoff if (IO_READ32_POLL_TIMEOUT(addr, value, value & _HASH_SR_DCIS, 0,
176*e880aa97SNicolas Toromanoff HASH_TIMEOUT_US)) {
177*e880aa97SNicolas Toromanoff EMSG("Ready timeout");
178*e880aa97SNicolas Toromanoff return TEE_ERROR_BUSY;
179*e880aa97SNicolas Toromanoff }
180*e880aa97SNicolas Toromanoff
181*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
182*e880aa97SNicolas Toromanoff }
183*e880aa97SNicolas Toromanoff
hash_write_data(vaddr_t base,uint32_t data)184*e880aa97SNicolas Toromanoff static TEE_Result hash_write_data(vaddr_t base, uint32_t data)
185*e880aa97SNicolas Toromanoff {
186*e880aa97SNicolas Toromanoff io_write32(base + _HASH_DIN, data);
187*e880aa97SNicolas Toromanoff
188*e880aa97SNicolas Toromanoff return wait_end_busy(base);
189*e880aa97SNicolas Toromanoff }
190*e880aa97SNicolas Toromanoff
write_key(vaddr_t base,const uint8_t * key,size_t len)191*e880aa97SNicolas Toromanoff static TEE_Result write_key(vaddr_t base, const uint8_t *key, size_t len)
192*e880aa97SNicolas Toromanoff {
193*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
194*e880aa97SNicolas Toromanoff uint32_t tmp_buf = 0;
195*e880aa97SNicolas Toromanoff
196*e880aa97SNicolas Toromanoff io_clrsetbits32(base + _HASH_STR, _HASH_STR_NBLW_MASK,
197*e880aa97SNicolas Toromanoff 8 * (len % sizeof(uint32_t)));
198*e880aa97SNicolas Toromanoff
199*e880aa97SNicolas Toromanoff while (len / sizeof(uint32_t)) {
200*e880aa97SNicolas Toromanoff memcpy(&tmp_buf, key, sizeof(uint32_t));
201*e880aa97SNicolas Toromanoff res = hash_write_data(base, tmp_buf);
202*e880aa97SNicolas Toromanoff if (res)
203*e880aa97SNicolas Toromanoff return res;
204*e880aa97SNicolas Toromanoff
205*e880aa97SNicolas Toromanoff key += sizeof(uint32_t);
206*e880aa97SNicolas Toromanoff len -= sizeof(uint32_t);
207*e880aa97SNicolas Toromanoff }
208*e880aa97SNicolas Toromanoff
209*e880aa97SNicolas Toromanoff if (len) {
210*e880aa97SNicolas Toromanoff tmp_buf = 0;
211*e880aa97SNicolas Toromanoff memcpy(&tmp_buf, key, len);
212*e880aa97SNicolas Toromanoff res = hash_write_data(base, tmp_buf);
213*e880aa97SNicolas Toromanoff if (res)
214*e880aa97SNicolas Toromanoff return res;
215*e880aa97SNicolas Toromanoff }
216*e880aa97SNicolas Toromanoff
217*e880aa97SNicolas Toromanoff io_setbits32(base + _HASH_STR, _HASH_STR_DCAL);
218*e880aa97SNicolas Toromanoff
219*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
220*e880aa97SNicolas Toromanoff }
221*e880aa97SNicolas Toromanoff
get_save_registers(struct stm32_hash_context * c,size_t * nb_regs,size_t * first,size_t * hmac_nb_regs,size_t * hmac_first)222*e880aa97SNicolas Toromanoff static void get_save_registers(struct stm32_hash_context *c, size_t *nb_regs,
223*e880aa97SNicolas Toromanoff size_t *first, size_t *hmac_nb_regs,
224*e880aa97SNicolas Toromanoff size_t *hmac_first)
225*e880aa97SNicolas Toromanoff {
226*e880aa97SNicolas Toromanoff switch (c->save_mode) {
227*e880aa97SNicolas Toromanoff case SAVE_SMALL:
228*e880aa97SNicolas Toromanoff *nb_regs = SAVE_SMALL_NB_REG;
229*e880aa97SNicolas Toromanoff *first = SAVE_SMALL_FIRST_REG;
230*e880aa97SNicolas Toromanoff if (c->mode == STM32_HMAC_MODE) {
231*e880aa97SNicolas Toromanoff *hmac_nb_regs = SAVE_SMALL_HMAC_NB_REG;
232*e880aa97SNicolas Toromanoff *hmac_first = SAVE_SMALL_HMAC_FIRST_REG;
233*e880aa97SNicolas Toromanoff }
234*e880aa97SNicolas Toromanoff break;
235*e880aa97SNicolas Toromanoff
236*e880aa97SNicolas Toromanoff case SAVE_BIG:
237*e880aa97SNicolas Toromanoff *nb_regs = SAVE_BIG_NB_REG;
238*e880aa97SNicolas Toromanoff *first = SAVE_BIG_FIRST_REG;
239*e880aa97SNicolas Toromanoff if (c->mode == STM32_HMAC_MODE) {
240*e880aa97SNicolas Toromanoff *hmac_nb_regs = SAVE_BIG_HMAC_NB_REG;
241*e880aa97SNicolas Toromanoff *hmac_first = SAVE_BIG_HMAC_FIRST_REG;
242*e880aa97SNicolas Toromanoff }
243*e880aa97SNicolas Toromanoff break;
244*e880aa97SNicolas Toromanoff
245*e880aa97SNicolas Toromanoff case SAVE_SHA3:
246*e880aa97SNicolas Toromanoff *nb_regs = SAVE_SHA3_NB_REG;
247*e880aa97SNicolas Toromanoff *first = SAVE_SHA3_FIRST_REG;
248*e880aa97SNicolas Toromanoff if (c->mode == STM32_HMAC_MODE) {
249*e880aa97SNicolas Toromanoff *hmac_nb_regs = SAVE_SHA3_HMAC_NB_REG;
250*e880aa97SNicolas Toromanoff *hmac_first = SAVE_SHA3_HMAC_FIRST_REG;
251*e880aa97SNicolas Toromanoff }
252*e880aa97SNicolas Toromanoff break;
253*e880aa97SNicolas Toromanoff
254*e880aa97SNicolas Toromanoff default:
255*e880aa97SNicolas Toromanoff break;
256*e880aa97SNicolas Toromanoff }
257*e880aa97SNicolas Toromanoff }
258*e880aa97SNicolas Toromanoff
save_context(struct stm32_hash_context * c)259*e880aa97SNicolas Toromanoff static TEE_Result save_context(struct stm32_hash_context *c)
260*e880aa97SNicolas Toromanoff {
261*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
262*e880aa97SNicolas Toromanoff size_t i = 0;
263*e880aa97SNicolas Toromanoff size_t nb_reg = 0;
264*e880aa97SNicolas Toromanoff size_t first = 0;
265*e880aa97SNicolas Toromanoff size_t hmac_nb_reg = 0;
266*e880aa97SNicolas Toromanoff size_t hmac_first = 0;
267*e880aa97SNicolas Toromanoff vaddr_t base = c->dev->pdata.base;
268*e880aa97SNicolas Toromanoff
269*e880aa97SNicolas Toromanoff res = wait_end_busy(base);
270*e880aa97SNicolas Toromanoff if (res)
271*e880aa97SNicolas Toromanoff return res;
272*e880aa97SNicolas Toromanoff
273*e880aa97SNicolas Toromanoff /* Check that FIFO is empty */
274*e880aa97SNicolas Toromanoff if (!(io_read32(base + _HASH_SR) & _HASH_SR_DINIS))
275*e880aa97SNicolas Toromanoff return TEE_ERROR_BAD_STATE;
276*e880aa97SNicolas Toromanoff
277*e880aa97SNicolas Toromanoff c->imr = io_read32(base + _HASH_IMR);
278*e880aa97SNicolas Toromanoff c->str = io_read32(base + _HASH_STR);
279*e880aa97SNicolas Toromanoff c->cr = io_read32(base + _HASH_CR);
280*e880aa97SNicolas Toromanoff
281*e880aa97SNicolas Toromanoff get_save_registers(c, &nb_reg, &first, &hmac_nb_reg, &hmac_first);
282*e880aa97SNicolas Toromanoff
283*e880aa97SNicolas Toromanoff if (!c->csr)
284*e880aa97SNicolas Toromanoff return TEE_ERROR_BAD_STATE;
285*e880aa97SNicolas Toromanoff
286*e880aa97SNicolas Toromanoff /* Save context registers */
287*e880aa97SNicolas Toromanoff for (i = 0; i < nb_reg; i++)
288*e880aa97SNicolas Toromanoff c->csr[i] = io_read32(base + _HASH_CSR(i + first));
289*e880aa97SNicolas Toromanoff /* Save HMAC context registers */
290*e880aa97SNicolas Toromanoff for (i = 0 ; i < hmac_nb_reg; i++)
291*e880aa97SNicolas Toromanoff c->csr[i + nb_reg] = io_read32(base + _HASH_CSR(i +
292*e880aa97SNicolas Toromanoff hmac_first));
293*e880aa97SNicolas Toromanoff
294*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
295*e880aa97SNicolas Toromanoff }
296*e880aa97SNicolas Toromanoff
restore_context(struct stm32_hash_context * c)297*e880aa97SNicolas Toromanoff static TEE_Result restore_context(struct stm32_hash_context *c)
298*e880aa97SNicolas Toromanoff {
299*e880aa97SNicolas Toromanoff size_t i = 0;
300*e880aa97SNicolas Toromanoff size_t nb_reg = 0;
301*e880aa97SNicolas Toromanoff size_t first = 0;
302*e880aa97SNicolas Toromanoff size_t hmac_nb_reg = 0;
303*e880aa97SNicolas Toromanoff size_t hmac_first = 0;
304*e880aa97SNicolas Toromanoff vaddr_t base = c->dev->pdata.base;
305*e880aa97SNicolas Toromanoff
306*e880aa97SNicolas Toromanoff io_write32(base + _HASH_IMR, c->imr);
307*e880aa97SNicolas Toromanoff io_write32(base + _HASH_STR, c->str);
308*e880aa97SNicolas Toromanoff io_write32(base + _HASH_CR, c->cr | _HASH_CR_INIT);
309*e880aa97SNicolas Toromanoff
310*e880aa97SNicolas Toromanoff get_save_registers(c, &nb_reg, &first, &hmac_nb_reg, &hmac_first);
311*e880aa97SNicolas Toromanoff
312*e880aa97SNicolas Toromanoff if (!c->csr)
313*e880aa97SNicolas Toromanoff return TEE_ERROR_BAD_STATE;
314*e880aa97SNicolas Toromanoff
315*e880aa97SNicolas Toromanoff /* Restore context registers */
316*e880aa97SNicolas Toromanoff for (i = 0; i < nb_reg; i++)
317*e880aa97SNicolas Toromanoff io_write32(base + _HASH_CSR(i + first), c->csr[i]);
318*e880aa97SNicolas Toromanoff
319*e880aa97SNicolas Toromanoff /* Restore HMAC context registers */
320*e880aa97SNicolas Toromanoff for (i = 0 ; i < hmac_nb_reg; i++)
321*e880aa97SNicolas Toromanoff io_write32(base + _HASH_CSR(i + hmac_first),
322*e880aa97SNicolas Toromanoff c->csr[i + nb_reg]);
323*e880aa97SNicolas Toromanoff
324*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
325*e880aa97SNicolas Toromanoff }
326*e880aa97SNicolas Toromanoff
hw_init(struct stm32_hash_context * c,const uint8_t * key,size_t len)327*e880aa97SNicolas Toromanoff static TEE_Result hw_init(struct stm32_hash_context *c, const uint8_t *key,
328*e880aa97SNicolas Toromanoff size_t len)
329*e880aa97SNicolas Toromanoff {
330*e880aa97SNicolas Toromanoff uint32_t reg_cr = 0;
331*e880aa97SNicolas Toromanoff vaddr_t base = c->dev->pdata.base;
332*e880aa97SNicolas Toromanoff
333*e880aa97SNicolas Toromanoff reg_cr = _HASH_CR_INIT | _HASH_CR_DATATYPE_BYTE;
334*e880aa97SNicolas Toromanoff
335*e880aa97SNicolas Toromanoff switch (c->algo) {
336*e880aa97SNicolas Toromanoff case STM32_HASH_MD5:
337*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_MD5;
338*e880aa97SNicolas Toromanoff break;
339*e880aa97SNicolas Toromanoff case STM32_HASH_SHA1:
340*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA1;
341*e880aa97SNicolas Toromanoff break;
342*e880aa97SNicolas Toromanoff case STM32_HASH_SHA224:
343*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA224;
344*e880aa97SNicolas Toromanoff break;
345*e880aa97SNicolas Toromanoff case STM32_HASH_SHA384:
346*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA384;
347*e880aa97SNicolas Toromanoff break;
348*e880aa97SNicolas Toromanoff case STM32_HASH_SHA512:
349*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA512;
350*e880aa97SNicolas Toromanoff break;
351*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_224:
352*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA3_224;
353*e880aa97SNicolas Toromanoff break;
354*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_256:
355*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA3_256;
356*e880aa97SNicolas Toromanoff break;
357*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_384:
358*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA3_384;
359*e880aa97SNicolas Toromanoff break;
360*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_512:
361*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA3_512;
362*e880aa97SNicolas Toromanoff break;
363*e880aa97SNicolas Toromanoff /* Default selected algo is SHA256 */
364*e880aa97SNicolas Toromanoff case STM32_HASH_SHA256:
365*e880aa97SNicolas Toromanoff if (c->dev->pdata.compat->caps & CAPS_MD5)
366*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA256_IF_MD5;
367*e880aa97SNicolas Toromanoff else
368*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_ALGO_SHA256;
369*e880aa97SNicolas Toromanoff
370*e880aa97SNicolas Toromanoff break;
371*e880aa97SNicolas Toromanoff default:
372*e880aa97SNicolas Toromanoff return TEE_ERROR_BAD_STATE;
373*e880aa97SNicolas Toromanoff }
374*e880aa97SNicolas Toromanoff
375*e880aa97SNicolas Toromanoff if (c->mode == STM32_HMAC_MODE) {
376*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_MODE;
377*e880aa97SNicolas Toromanoff
378*e880aa97SNicolas Toromanoff if (len > c->block_size)
379*e880aa97SNicolas Toromanoff reg_cr |= _HASH_CR_LKEY;
380*e880aa97SNicolas Toromanoff
381*e880aa97SNicolas Toromanoff io_write32(base + _HASH_CR, reg_cr);
382*e880aa97SNicolas Toromanoff
383*e880aa97SNicolas Toromanoff return write_key(base, key, len);
384*e880aa97SNicolas Toromanoff }
385*e880aa97SNicolas Toromanoff
386*e880aa97SNicolas Toromanoff io_write32(base + _HASH_CR, reg_cr);
387*e880aa97SNicolas Toromanoff
388*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
389*e880aa97SNicolas Toromanoff }
390*e880aa97SNicolas Toromanoff
hash_get_digest(struct stm32_hash_context * c,uint8_t * digest)391*e880aa97SNicolas Toromanoff static TEE_Result hash_get_digest(struct stm32_hash_context *c, uint8_t *digest)
392*e880aa97SNicolas Toromanoff {
393*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
394*e880aa97SNicolas Toromanoff vaddr_t base = c->dev->pdata.base;
395*e880aa97SNicolas Toromanoff uint32_t i = 0;
396*e880aa97SNicolas Toromanoff uint32_t dsg = 0;
397*e880aa97SNicolas Toromanoff
398*e880aa97SNicolas Toromanoff res = wait_digest_ready(base);
399*e880aa97SNicolas Toromanoff if (res)
400*e880aa97SNicolas Toromanoff return res;
401*e880aa97SNicolas Toromanoff
402*e880aa97SNicolas Toromanoff for (i = 0; i < c->digest_u32; i++) {
403*e880aa97SNicolas Toromanoff dsg = TEE_U32_FROM_BIG_ENDIAN(io_read32(base + _HASH_HR(i)));
404*e880aa97SNicolas Toromanoff memcpy(digest + (i * sizeof(uint32_t)), &dsg, sizeof(uint32_t));
405*e880aa97SNicolas Toromanoff }
406*e880aa97SNicolas Toromanoff
407*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
408*e880aa97SNicolas Toromanoff }
409*e880aa97SNicolas Toromanoff
stm32_hash_digest_size(struct stm32_hash_context * c)410*e880aa97SNicolas Toromanoff size_t stm32_hash_digest_size(struct stm32_hash_context *c)
411*e880aa97SNicolas Toromanoff {
412*e880aa97SNicolas Toromanoff assert(c);
413*e880aa97SNicolas Toromanoff
414*e880aa97SNicolas Toromanoff return c->digest_u32 * sizeof(uint32_t);
415*e880aa97SNicolas Toromanoff }
416*e880aa97SNicolas Toromanoff
stm32_hash_deep_copy(struct stm32_hash_context * dst,struct stm32_hash_context * src)417*e880aa97SNicolas Toromanoff TEE_Result stm32_hash_deep_copy(struct stm32_hash_context *dst,
418*e880aa97SNicolas Toromanoff struct stm32_hash_context *src)
419*e880aa97SNicolas Toromanoff {
420*e880aa97SNicolas Toromanoff size_t nb_reg = 0;
421*e880aa97SNicolas Toromanoff size_t first = 0;
422*e880aa97SNicolas Toromanoff size_t hmac_nb_reg = 0;
423*e880aa97SNicolas Toromanoff size_t hmac_first = 0;
424*e880aa97SNicolas Toromanoff uint32_t *dst_buf = NULL;
425*e880aa97SNicolas Toromanoff uint32_t *dst_csr = NULL;
426*e880aa97SNicolas Toromanoff
427*e880aa97SNicolas Toromanoff if (!dst || !src || dst->mode != src->mode || dst->algo != src->algo)
428*e880aa97SNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
429*e880aa97SNicolas Toromanoff
430*e880aa97SNicolas Toromanoff dst_buf = dst->remain.buf;
431*e880aa97SNicolas Toromanoff dst_csr = dst->csr;
432*e880aa97SNicolas Toromanoff *dst = *src;
433*e880aa97SNicolas Toromanoff dst->remain.buf = dst_buf;
434*e880aa97SNicolas Toromanoff dst->csr = dst_csr;
435*e880aa97SNicolas Toromanoff
436*e880aa97SNicolas Toromanoff memcpy(dst->remain.buf, src->remain.buf, dst->remain.len);
437*e880aa97SNicolas Toromanoff get_save_registers(dst, &nb_reg, &first, &hmac_nb_reg, &hmac_first);
438*e880aa97SNicolas Toromanoff memcpy(dst->csr, src->csr, (nb_reg + hmac_nb_reg) * sizeof(uint32_t));
439*e880aa97SNicolas Toromanoff
440*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
441*e880aa97SNicolas Toromanoff }
442*e880aa97SNicolas Toromanoff
stm32_hash_alloc(struct stm32_hash_context * c,enum stm32_hash_mode mode,enum stm32_hash_algo algo)443*e880aa97SNicolas Toromanoff TEE_Result stm32_hash_alloc(struct stm32_hash_context *c,
444*e880aa97SNicolas Toromanoff enum stm32_hash_mode mode,
445*e880aa97SNicolas Toromanoff enum stm32_hash_algo algo)
446*e880aa97SNicolas Toromanoff {
447*e880aa97SNicolas Toromanoff size_t nb_reg = 0;
448*e880aa97SNicolas Toromanoff size_t first = 0;
449*e880aa97SNicolas Toromanoff size_t hmac_nb_reg = 0;
450*e880aa97SNicolas Toromanoff size_t hmac_first = 0;
451*e880aa97SNicolas Toromanoff
452*e880aa97SNicolas Toromanoff assert(c);
453*e880aa97SNicolas Toromanoff
454*e880aa97SNicolas Toromanoff /* Check if initialized */
455*e880aa97SNicolas Toromanoff if (!stm32_hash)
456*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
457*e880aa97SNicolas Toromanoff
458*e880aa97SNicolas Toromanoff c->dev = stm32_hash;
459*e880aa97SNicolas Toromanoff c->mode = mode;
460*e880aa97SNicolas Toromanoff c->algo = algo;
461*e880aa97SNicolas Toromanoff
462*e880aa97SNicolas Toromanoff switch (algo) {
463*e880aa97SNicolas Toromanoff case STM32_HASH_MD5:
464*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_MD5))
465*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
466*e880aa97SNicolas Toromanoff
467*e880aa97SNicolas Toromanoff c->digest_u32 = MD5_DIGEST_U32;
468*e880aa97SNicolas Toromanoff c->block_size = MD5_BLOCK_SIZE;
469*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SMALL;
470*e880aa97SNicolas Toromanoff break;
471*e880aa97SNicolas Toromanoff case STM32_HASH_SHA1:
472*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA1))
473*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
474*e880aa97SNicolas Toromanoff
475*e880aa97SNicolas Toromanoff c->digest_u32 = SHA1_DIGEST_U32;
476*e880aa97SNicolas Toromanoff c->block_size = SHA1_BLOCK_SIZE;
477*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SMALL;
478*e880aa97SNicolas Toromanoff break;
479*e880aa97SNicolas Toromanoff case STM32_HASH_SHA224:
480*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA2_224))
481*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
482*e880aa97SNicolas Toromanoff
483*e880aa97SNicolas Toromanoff c->digest_u32 = SHA224_DIGEST_U32;
484*e880aa97SNicolas Toromanoff c->block_size = SHA224_BLOCK_SIZE;
485*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SMALL;
486*e880aa97SNicolas Toromanoff break;
487*e880aa97SNicolas Toromanoff case STM32_HASH_SHA256:
488*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA2_256))
489*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
490*e880aa97SNicolas Toromanoff
491*e880aa97SNicolas Toromanoff c->digest_u32 = SHA256_DIGEST_U32;
492*e880aa97SNicolas Toromanoff c->block_size = SHA256_BLOCK_SIZE;
493*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SMALL;
494*e880aa97SNicolas Toromanoff break;
495*e880aa97SNicolas Toromanoff case STM32_HASH_SHA384:
496*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA2_384))
497*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
498*e880aa97SNicolas Toromanoff
499*e880aa97SNicolas Toromanoff c->digest_u32 = SHA384_DIGEST_U32;
500*e880aa97SNicolas Toromanoff c->block_size = SHA384_BLOCK_SIZE;
501*e880aa97SNicolas Toromanoff c->save_mode = SAVE_BIG;
502*e880aa97SNicolas Toromanoff break;
503*e880aa97SNicolas Toromanoff case STM32_HASH_SHA512:
504*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA2_512))
505*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
506*e880aa97SNicolas Toromanoff
507*e880aa97SNicolas Toromanoff c->digest_u32 = SHA512_DIGEST_U32;
508*e880aa97SNicolas Toromanoff c->block_size = SHA512_BLOCK_SIZE;
509*e880aa97SNicolas Toromanoff c->save_mode = SAVE_BIG;
510*e880aa97SNicolas Toromanoff break;
511*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_224:
512*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA3))
513*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
514*e880aa97SNicolas Toromanoff
515*e880aa97SNicolas Toromanoff c->digest_u32 = SHA3_224_DIGEST_U32;
516*e880aa97SNicolas Toromanoff c->block_size = SHA3_224_BLOCK_SIZE;
517*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SHA3;
518*e880aa97SNicolas Toromanoff break;
519*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_256:
520*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA3))
521*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
522*e880aa97SNicolas Toromanoff
523*e880aa97SNicolas Toromanoff c->digest_u32 = SHA3_256_DIGEST_U32;
524*e880aa97SNicolas Toromanoff c->block_size = SHA3_256_BLOCK_SIZE;
525*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SHA3;
526*e880aa97SNicolas Toromanoff break;
527*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_384:
528*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA3))
529*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
530*e880aa97SNicolas Toromanoff
531*e880aa97SNicolas Toromanoff c->digest_u32 = SHA3_384_DIGEST_U32;
532*e880aa97SNicolas Toromanoff c->block_size = SHA3_384_BLOCK_SIZE;
533*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SHA3;
534*e880aa97SNicolas Toromanoff break;
535*e880aa97SNicolas Toromanoff case STM32_HASH_SHA3_512:
536*e880aa97SNicolas Toromanoff if (!(c->dev->pdata.compat->caps & CAPS_SHA3))
537*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
538*e880aa97SNicolas Toromanoff
539*e880aa97SNicolas Toromanoff c->digest_u32 = SHA3_512_DIGEST_U32;
540*e880aa97SNicolas Toromanoff c->block_size = SHA3_512_BLOCK_SIZE;
541*e880aa97SNicolas Toromanoff c->save_mode = SAVE_SHA3;
542*e880aa97SNicolas Toromanoff break;
543*e880aa97SNicolas Toromanoff default:
544*e880aa97SNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
545*e880aa97SNicolas Toromanoff }
546*e880aa97SNicolas Toromanoff
547*e880aa97SNicolas Toromanoff /*
548*e880aa97SNicolas Toromanoff * The queue size is block_size + one register at first
549*e880aa97SNicolas Toromanoff * then block_size.
550*e880aa97SNicolas Toromanoff * So we may need to save at max queue_size + 3 bytes.
551*e880aa97SNicolas Toromanoff * Let allocate a number of uin32_t: queue_size + 4.
552*e880aa97SNicolas Toromanoff */
553*e880aa97SNicolas Toromanoff c->remain.buf = calloc(c->block_size + sizeof(uint32_t), 1);
554*e880aa97SNicolas Toromanoff if (!c->remain.buf)
555*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
556*e880aa97SNicolas Toromanoff
557*e880aa97SNicolas Toromanoff get_save_registers(c, &nb_reg, &first, &hmac_nb_reg, &hmac_first);
558*e880aa97SNicolas Toromanoff
559*e880aa97SNicolas Toromanoff c->csr = calloc(nb_reg + hmac_nb_reg, sizeof(uint32_t));
560*e880aa97SNicolas Toromanoff if (!c->csr) {
561*e880aa97SNicolas Toromanoff free(c->remain.buf);
562*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
563*e880aa97SNicolas Toromanoff }
564*e880aa97SNicolas Toromanoff
565*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
566*e880aa97SNicolas Toromanoff }
567*e880aa97SNicolas Toromanoff
stm32_hash_free(struct stm32_hash_context * c)568*e880aa97SNicolas Toromanoff void stm32_hash_free(struct stm32_hash_context *c)
569*e880aa97SNicolas Toromanoff {
570*e880aa97SNicolas Toromanoff if (!c)
571*e880aa97SNicolas Toromanoff return;
572*e880aa97SNicolas Toromanoff
573*e880aa97SNicolas Toromanoff free(c->remain.buf);
574*e880aa97SNicolas Toromanoff free(c->csr);
575*e880aa97SNicolas Toromanoff }
576*e880aa97SNicolas Toromanoff
stm32_hash_update(struct stm32_hash_context * c,const uint8_t * buffer,size_t len)577*e880aa97SNicolas Toromanoff TEE_Result stm32_hash_update(struct stm32_hash_context *c,
578*e880aa97SNicolas Toromanoff const uint8_t *buffer, size_t len)
579*e880aa97SNicolas Toromanoff {
580*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
581*e880aa97SNicolas Toromanoff size_t next_queue_size = c->queue_size;
582*e880aa97SNicolas Toromanoff vaddr_t base = 0;
583*e880aa97SNicolas Toromanoff
584*e880aa97SNicolas Toromanoff assert(c);
585*e880aa97SNicolas Toromanoff
586*e880aa97SNicolas Toromanoff base = c->dev->pdata.base;
587*e880aa97SNicolas Toromanoff
588*e880aa97SNicolas Toromanoff if (!len || !buffer)
589*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
590*e880aa97SNicolas Toromanoff
591*e880aa97SNicolas Toromanoff mutex_lock(&c->dev->lock);
592*e880aa97SNicolas Toromanoff if (clk_enable(c->dev->pdata.clock)) {
593*e880aa97SNicolas Toromanoff EMSG("Fail to enable clk %s",
594*e880aa97SNicolas Toromanoff clk_get_name(c->dev->pdata.clock));
595*e880aa97SNicolas Toromanoff panic();
596*e880aa97SNicolas Toromanoff }
597*e880aa97SNicolas Toromanoff
598*e880aa97SNicolas Toromanoff res = restore_context(c);
599*e880aa97SNicolas Toromanoff if (res)
600*e880aa97SNicolas Toromanoff goto exit;
601*e880aa97SNicolas Toromanoff
602*e880aa97SNicolas Toromanoff /* We cannot fill the fifo */
603*e880aa97SNicolas Toromanoff if (c->remain.len + len < c->queue_size) {
604*e880aa97SNicolas Toromanoff if (!c->remain.buf) {
605*e880aa97SNicolas Toromanoff res = TEE_ERROR_BAD_STATE;
606*e880aa97SNicolas Toromanoff goto exit;
607*e880aa97SNicolas Toromanoff }
608*e880aa97SNicolas Toromanoff
609*e880aa97SNicolas Toromanoff memcpy(((uint8_t *)c->remain.buf) + c->remain.len, buffer, len);
610*e880aa97SNicolas Toromanoff c->remain.len += len;
611*e880aa97SNicolas Toromanoff
612*e880aa97SNicolas Toromanoff /*
613*e880aa97SNicolas Toromanoff * We don't need to save status as we didn't change IP
614*e880aa97SNicolas Toromanoff * internal state.
615*e880aa97SNicolas Toromanoff */
616*e880aa97SNicolas Toromanoff goto exit;
617*e880aa97SNicolas Toromanoff } else {
618*e880aa97SNicolas Toromanoff next_queue_size = c->block_size;
619*e880aa97SNicolas Toromanoff }
620*e880aa97SNicolas Toromanoff
621*e880aa97SNicolas Toromanoff /* First write data saved in previous update */
622*e880aa97SNicolas Toromanoff if (c->remain.len) {
623*e880aa97SNicolas Toromanoff size_t align = 0;
624*e880aa97SNicolas Toromanoff size_t i = 0;
625*e880aa97SNicolas Toromanoff
626*e880aa97SNicolas Toromanoff if (!c->remain.buf) {
627*e880aa97SNicolas Toromanoff res = TEE_ERROR_BAD_STATE;
628*e880aa97SNicolas Toromanoff goto exit;
629*e880aa97SNicolas Toromanoff }
630*e880aa97SNicolas Toromanoff
631*e880aa97SNicolas Toromanoff /* Add bytes needed to align saved data */
632*e880aa97SNicolas Toromanoff align = ROUNDUP(c->remain.len, sizeof(uint32_t)) -
633*e880aa97SNicolas Toromanoff c->remain.len;
634*e880aa97SNicolas Toromanoff memcpy(((uint8_t *)c->remain.buf) + c->remain.len, buffer,
635*e880aa97SNicolas Toromanoff align);
636*e880aa97SNicolas Toromanoff c->remain.len += align;
637*e880aa97SNicolas Toromanoff buffer += align;
638*e880aa97SNicolas Toromanoff len -= align;
639*e880aa97SNicolas Toromanoff
640*e880aa97SNicolas Toromanoff for (i = 0; i < c->remain.len / sizeof(uint32_t); i++) {
641*e880aa97SNicolas Toromanoff res = hash_write_data(base, c->remain.buf[i]);
642*e880aa97SNicolas Toromanoff if (res)
643*e880aa97SNicolas Toromanoff goto exit;
644*e880aa97SNicolas Toromanoff
645*e880aa97SNicolas Toromanoff c->remain.buf[i] = 0; /* Reset to 0 */
646*e880aa97SNicolas Toromanoff }
647*e880aa97SNicolas Toromanoff
648*e880aa97SNicolas Toromanoff /* No more saved data */
649*e880aa97SNicolas Toromanoff c->remain.len = 0;
650*e880aa97SNicolas Toromanoff }
651*e880aa97SNicolas Toromanoff
652*e880aa97SNicolas Toromanoff /*
653*e880aa97SNicolas Toromanoff * Here, the data should be written to the FIFO until we cannot
654*e880aa97SNicolas Toromanoff * guarantee anymore that the data that we write will trigger a
655*e880aa97SNicolas Toromanoff * process of data. Then we write the remaining data until DINIS
656*e880aa97SNicolas Toromanoff * is set to 1 by hardware, meaning that a complete block can be
657*e880aa97SNicolas Toromanoff * sent. Data written will be saved during save_context() and
658*e880aa97SNicolas Toromanoff * remaining data not written (if there's any) will be saved in
659*e880aa97SNicolas Toromanoff * c->remain.buf.
660*e880aa97SNicolas Toromanoff */
661*e880aa97SNicolas Toromanoff while (len >= c->queue_size ||
662*e880aa97SNicolas Toromanoff !(io_read32(base + _HASH_SR) & _HASH_SR_DINIS)) {
663*e880aa97SNicolas Toromanoff uint32_t tmp_buf = 0;
664*e880aa97SNicolas Toromanoff
665*e880aa97SNicolas Toromanoff memcpy(&tmp_buf, buffer, sizeof(uint32_t));
666*e880aa97SNicolas Toromanoff res = hash_write_data(base, tmp_buf);
667*e880aa97SNicolas Toromanoff if (res)
668*e880aa97SNicolas Toromanoff goto exit;
669*e880aa97SNicolas Toromanoff
670*e880aa97SNicolas Toromanoff buffer += sizeof(uint32_t);
671*e880aa97SNicolas Toromanoff len -= sizeof(uint32_t);
672*e880aa97SNicolas Toromanoff }
673*e880aa97SNicolas Toromanoff
674*e880aa97SNicolas Toromanoff c->queue_size = next_queue_size;
675*e880aa97SNicolas Toromanoff
676*e880aa97SNicolas Toromanoff if (len) {
677*e880aa97SNicolas Toromanoff assert(c->remain.len == 0);
678*e880aa97SNicolas Toromanoff
679*e880aa97SNicolas Toromanoff if (!c->remain.buf) {
680*e880aa97SNicolas Toromanoff res = TEE_ERROR_BAD_STATE;
681*e880aa97SNicolas Toromanoff goto exit;
682*e880aa97SNicolas Toromanoff }
683*e880aa97SNicolas Toromanoff
684*e880aa97SNicolas Toromanoff memcpy(c->remain.buf, buffer, len);
685*e880aa97SNicolas Toromanoff c->remain.len = len;
686*e880aa97SNicolas Toromanoff }
687*e880aa97SNicolas Toromanoff
688*e880aa97SNicolas Toromanoff res = save_context(c);
689*e880aa97SNicolas Toromanoff
690*e880aa97SNicolas Toromanoff exit:
691*e880aa97SNicolas Toromanoff clk_disable(c->dev->pdata.clock);
692*e880aa97SNicolas Toromanoff mutex_unlock(&c->dev->lock);
693*e880aa97SNicolas Toromanoff
694*e880aa97SNicolas Toromanoff return res;
695*e880aa97SNicolas Toromanoff }
696*e880aa97SNicolas Toromanoff
stm32_hash_final(struct stm32_hash_context * c,uint8_t * digest,const uint8_t * key,size_t len)697*e880aa97SNicolas Toromanoff TEE_Result stm32_hash_final(struct stm32_hash_context *c, uint8_t *digest,
698*e880aa97SNicolas Toromanoff const uint8_t *key, size_t len)
699*e880aa97SNicolas Toromanoff {
700*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
701*e880aa97SNicolas Toromanoff vaddr_t base = 0;
702*e880aa97SNicolas Toromanoff
703*e880aa97SNicolas Toromanoff assert(c);
704*e880aa97SNicolas Toromanoff
705*e880aa97SNicolas Toromanoff base = c->dev->pdata.base;
706*e880aa97SNicolas Toromanoff
707*e880aa97SNicolas Toromanoff if ((!key || !len) && c->mode != STM32_HASH_MODE)
708*e880aa97SNicolas Toromanoff return TEE_ERROR_BAD_STATE;
709*e880aa97SNicolas Toromanoff
710*e880aa97SNicolas Toromanoff mutex_lock(&c->dev->lock);
711*e880aa97SNicolas Toromanoff if (clk_enable(c->dev->pdata.clock)) {
712*e880aa97SNicolas Toromanoff EMSG("Fail to enable clk %s",
713*e880aa97SNicolas Toromanoff clk_get_name(c->dev->pdata.clock));
714*e880aa97SNicolas Toromanoff panic();
715*e880aa97SNicolas Toromanoff }
716*e880aa97SNicolas Toromanoff
717*e880aa97SNicolas Toromanoff res = restore_context(c);
718*e880aa97SNicolas Toromanoff if (res)
719*e880aa97SNicolas Toromanoff goto exit;
720*e880aa97SNicolas Toromanoff
721*e880aa97SNicolas Toromanoff if (c->remain.len) {
722*e880aa97SNicolas Toromanoff size_t i = 0;
723*e880aa97SNicolas Toromanoff
724*e880aa97SNicolas Toromanoff for (i = 0;
725*e880aa97SNicolas Toromanoff i < ROUNDUP_DIV(c->remain.len, sizeof(uint32_t));
726*e880aa97SNicolas Toromanoff i++) {
727*e880aa97SNicolas Toromanoff res = hash_write_data(base, c->remain.buf[i]);
728*e880aa97SNicolas Toromanoff if (res)
729*e880aa97SNicolas Toromanoff goto exit;
730*e880aa97SNicolas Toromanoff c->remain.buf[i] = 0; /* Reset to 0 */
731*e880aa97SNicolas Toromanoff }
732*e880aa97SNicolas Toromanoff
733*e880aa97SNicolas Toromanoff io_clrsetbits32(base + _HASH_STR, _HASH_STR_NBLW_MASK,
734*e880aa97SNicolas Toromanoff 8 * (c->remain.len % sizeof(uint32_t)));
735*e880aa97SNicolas Toromanoff
736*e880aa97SNicolas Toromanoff /* No more saved data */
737*e880aa97SNicolas Toromanoff c->remain.len = 0;
738*e880aa97SNicolas Toromanoff } else {
739*e880aa97SNicolas Toromanoff io_clrbits32(base + _HASH_STR, _HASH_STR_NBLW_MASK);
740*e880aa97SNicolas Toromanoff }
741*e880aa97SNicolas Toromanoff
742*e880aa97SNicolas Toromanoff io_setbits32(base + _HASH_STR, _HASH_STR_DCAL);
743*e880aa97SNicolas Toromanoff
744*e880aa97SNicolas Toromanoff if (c->mode == STM32_HMAC_MODE) {
745*e880aa97SNicolas Toromanoff res = write_key(base, key, len);
746*e880aa97SNicolas Toromanoff if (res)
747*e880aa97SNicolas Toromanoff goto exit;
748*e880aa97SNicolas Toromanoff }
749*e880aa97SNicolas Toromanoff
750*e880aa97SNicolas Toromanoff res = hash_get_digest(c, digest);
751*e880aa97SNicolas Toromanoff
752*e880aa97SNicolas Toromanoff exit:
753*e880aa97SNicolas Toromanoff clk_disable(c->dev->pdata.clock);
754*e880aa97SNicolas Toromanoff mutex_unlock(&c->dev->lock);
755*e880aa97SNicolas Toromanoff
756*e880aa97SNicolas Toromanoff return res;
757*e880aa97SNicolas Toromanoff }
758*e880aa97SNicolas Toromanoff
stm32_hash_init(struct stm32_hash_context * c,const uint8_t * key,size_t len)759*e880aa97SNicolas Toromanoff TEE_Result stm32_hash_init(struct stm32_hash_context *c, const uint8_t *key,
760*e880aa97SNicolas Toromanoff size_t len)
761*e880aa97SNicolas Toromanoff {
762*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
763*e880aa97SNicolas Toromanoff
764*e880aa97SNicolas Toromanoff assert(c);
765*e880aa97SNicolas Toromanoff
766*e880aa97SNicolas Toromanoff if ((!key || !len) && c->mode != STM32_HASH_MODE)
767*e880aa97SNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
768*e880aa97SNicolas Toromanoff
769*e880aa97SNicolas Toromanoff mutex_lock(&c->dev->lock);
770*e880aa97SNicolas Toromanoff
771*e880aa97SNicolas Toromanoff if (clk_enable(c->dev->pdata.clock)) {
772*e880aa97SNicolas Toromanoff EMSG("Fail to enable clk %s",
773*e880aa97SNicolas Toromanoff clk_get_name(c->dev->pdata.clock));
774*e880aa97SNicolas Toromanoff panic();
775*e880aa97SNicolas Toromanoff }
776*e880aa97SNicolas Toromanoff
777*e880aa97SNicolas Toromanoff c->remain.len = 0;
778*e880aa97SNicolas Toromanoff /* First queue is block_size + one register */
779*e880aa97SNicolas Toromanoff c->queue_size = c->block_size + sizeof(uint32_t);
780*e880aa97SNicolas Toromanoff memset(c->remain.buf, 0, c->queue_size);
781*e880aa97SNicolas Toromanoff
782*e880aa97SNicolas Toromanoff res = hw_init(c, key, len);
783*e880aa97SNicolas Toromanoff if (res)
784*e880aa97SNicolas Toromanoff goto exit;
785*e880aa97SNicolas Toromanoff
786*e880aa97SNicolas Toromanoff res = save_context(c);
787*e880aa97SNicolas Toromanoff
788*e880aa97SNicolas Toromanoff exit:
789*e880aa97SNicolas Toromanoff clk_disable(c->dev->pdata.clock);
790*e880aa97SNicolas Toromanoff mutex_unlock(&c->dev->lock);
791*e880aa97SNicolas Toromanoff
792*e880aa97SNicolas Toromanoff return res;
793*e880aa97SNicolas Toromanoff }
794*e880aa97SNicolas Toromanoff
stm32_hash_parse_fdt(struct stm32_hash_platdata * pdata,const void * fdt,int node,const void * compat_data)795*e880aa97SNicolas Toromanoff static TEE_Result stm32_hash_parse_fdt(struct stm32_hash_platdata *pdata,
796*e880aa97SNicolas Toromanoff const void *fdt, int node,
797*e880aa97SNicolas Toromanoff const void *compat_data)
798*e880aa97SNicolas Toromanoff {
799*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
800*e880aa97SNicolas Toromanoff size_t reg_size = 0;
801*e880aa97SNicolas Toromanoff paddr_t reg = 0;
802*e880aa97SNicolas Toromanoff
803*e880aa97SNicolas Toromanoff res = rstctrl_dt_get_by_index(fdt, node, 0, &pdata->reset);
804*e880aa97SNicolas Toromanoff if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
805*e880aa97SNicolas Toromanoff return res;
806*e880aa97SNicolas Toromanoff
807*e880aa97SNicolas Toromanoff res = clk_dt_get_by_index(fdt, node, 0, &pdata->clock);
808*e880aa97SNicolas Toromanoff if (res)
809*e880aa97SNicolas Toromanoff return res;
810*e880aa97SNicolas Toromanoff
811*e880aa97SNicolas Toromanoff res = fdt_reg_info(fdt, node, ®, ®_size);
812*e880aa97SNicolas Toromanoff if (res)
813*e880aa97SNicolas Toromanoff return res;
814*e880aa97SNicolas Toromanoff
815*e880aa97SNicolas Toromanoff pdata->base = (vaddr_t)phys_to_virt(reg, MEM_AREA_IO_SEC, reg_size);
816*e880aa97SNicolas Toromanoff if (!pdata->base)
817*e880aa97SNicolas Toromanoff panic();
818*e880aa97SNicolas Toromanoff
819*e880aa97SNicolas Toromanoff pdata->compat = (struct stm32_hash_compat *)compat_data;
820*e880aa97SNicolas Toromanoff
821*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
822*e880aa97SNicolas Toromanoff }
823*e880aa97SNicolas Toromanoff
stm32_hash_probe(const void * fdt,int node,const void * compat_data)824*e880aa97SNicolas Toromanoff static TEE_Result stm32_hash_probe(const void *fdt, int node,
825*e880aa97SNicolas Toromanoff const void *compat_data)
826*e880aa97SNicolas Toromanoff {
827*e880aa97SNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
828*e880aa97SNicolas Toromanoff uint32_t __maybe_unused rev = 0;
829*e880aa97SNicolas Toromanoff struct stm32_hash_platdata temp_pdata = { };
830*e880aa97SNicolas Toromanoff
831*e880aa97SNicolas Toromanoff res = stm32_hash_parse_fdt(&temp_pdata, fdt, node, compat_data);
832*e880aa97SNicolas Toromanoff if (res)
833*e880aa97SNicolas Toromanoff return res;
834*e880aa97SNicolas Toromanoff
835*e880aa97SNicolas Toromanoff stm32_hash = calloc(1, sizeof(*stm32_hash));
836*e880aa97SNicolas Toromanoff if (!stm32_hash)
837*e880aa97SNicolas Toromanoff return TEE_ERROR_OUT_OF_MEMORY;
838*e880aa97SNicolas Toromanoff
839*e880aa97SNicolas Toromanoff stm32_hash->pdata = temp_pdata;
840*e880aa97SNicolas Toromanoff
841*e880aa97SNicolas Toromanoff if (clk_enable(stm32_hash->pdata.clock)) {
842*e880aa97SNicolas Toromanoff EMSG("Fail to enable clk %s",
843*e880aa97SNicolas Toromanoff clk_get_name(stm32_hash->pdata.clock));
844*e880aa97SNicolas Toromanoff panic();
845*e880aa97SNicolas Toromanoff }
846*e880aa97SNicolas Toromanoff
847*e880aa97SNicolas Toromanoff rev = io_read32(stm32_hash->pdata.base + _HASH_VERR);
848*e880aa97SNicolas Toromanoff FMSG("STM32 HASH v%"PRIu32".%"PRIu32, (rev & _HASH_VERR_MAJREV) >> 4,
849*e880aa97SNicolas Toromanoff rev & _HASH_VERR_MINREV);
850*e880aa97SNicolas Toromanoff
851*e880aa97SNicolas Toromanoff if (stm32_hash->pdata.reset &&
852*e880aa97SNicolas Toromanoff rstctrl_assert_to(stm32_hash->pdata.reset, RESET_TIMEOUT_US_1MS))
853*e880aa97SNicolas Toromanoff panic();
854*e880aa97SNicolas Toromanoff
855*e880aa97SNicolas Toromanoff if (stm32_hash->pdata.reset &&
856*e880aa97SNicolas Toromanoff rstctrl_deassert_to(stm32_hash->pdata.reset, RESET_TIMEOUT_US_1MS))
857*e880aa97SNicolas Toromanoff panic();
858*e880aa97SNicolas Toromanoff
859*e880aa97SNicolas Toromanoff mutex_init(&stm32_hash->lock);
860*e880aa97SNicolas Toromanoff
861*e880aa97SNicolas Toromanoff clk_disable(stm32_hash->pdata.clock);
862*e880aa97SNicolas Toromanoff
863*e880aa97SNicolas Toromanoff if (IS_ENABLED(CFG_CRYPTO_DRV_HASH)) {
864*e880aa97SNicolas Toromanoff res = stm32_register_hash();
865*e880aa97SNicolas Toromanoff if (res) {
866*e880aa97SNicolas Toromanoff EMSG("Failed to register to HASH: %#"PRIx32, res);
867*e880aa97SNicolas Toromanoff panic();
868*e880aa97SNicolas Toromanoff }
869*e880aa97SNicolas Toromanoff }
870*e880aa97SNicolas Toromanoff
871*e880aa97SNicolas Toromanoff if (IS_ENABLED(CFG_CRYPTO_DRV_MAC)) {
872*e880aa97SNicolas Toromanoff res = stm32_register_hmac();
873*e880aa97SNicolas Toromanoff if (res) {
874*e880aa97SNicolas Toromanoff EMSG("Failed to register to HMAC : %#"PRIx32, res);
875*e880aa97SNicolas Toromanoff panic();
876*e880aa97SNicolas Toromanoff }
877*e880aa97SNicolas Toromanoff }
878*e880aa97SNicolas Toromanoff
879*e880aa97SNicolas Toromanoff return TEE_SUCCESS;
880*e880aa97SNicolas Toromanoff }
881*e880aa97SNicolas Toromanoff
882*e880aa97SNicolas Toromanoff static const struct stm32_hash_compat mp13_compat = {
883*e880aa97SNicolas Toromanoff .caps = CAPS_SHA1 | CAPS_SHA2_224 | CAPS_SHA2_256 | CAPS_SHA2_384 |
884*e880aa97SNicolas Toromanoff CAPS_SHA2_512 | CAPS_SHA3,
885*e880aa97SNicolas Toromanoff };
886*e880aa97SNicolas Toromanoff
887*e880aa97SNicolas Toromanoff static const struct stm32_hash_compat mp15_compat = {
888*e880aa97SNicolas Toromanoff .caps = CAPS_MD5 | CAPS_SHA1 | CAPS_SHA2_224 | CAPS_SHA2_256,
889*e880aa97SNicolas Toromanoff };
890*e880aa97SNicolas Toromanoff
891*e880aa97SNicolas Toromanoff static const struct dt_device_match hash_match_table[] = {
892*e880aa97SNicolas Toromanoff { .compatible = "st,stm32mp13-hash", .compat_data = &mp13_compat },
893*e880aa97SNicolas Toromanoff { .compatible = "st,stm32f756-hash", .compat_data = &mp15_compat },
894*e880aa97SNicolas Toromanoff { }
895*e880aa97SNicolas Toromanoff };
896*e880aa97SNicolas Toromanoff
897*e880aa97SNicolas Toromanoff DEFINE_DT_DRIVER(stm32_hash_dt_driver) = {
898*e880aa97SNicolas Toromanoff .name = "stm32-hash",
899*e880aa97SNicolas Toromanoff .match_table = hash_match_table,
900*e880aa97SNicolas Toromanoff .probe = &stm32_hash_probe,
901*e880aa97SNicolas Toromanoff };
902