xref: /optee_os/core/drivers/crypto/stm32/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 <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, &reg, &reg_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