xref: /rk3399_ARM-atf/drivers/st/crypto/stm32_pka.c (revision cf9346cb83804feb083b56a668eb0a462983e038)
1 /*
2  * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <stdint.h>
10 
11 #include <drivers/clk.h>
12 #include <drivers/delay_timer.h>
13 #include <drivers/st/stm32_pka.h>
14 #include <drivers/st/stm32mp_reset.h>
15 #include <lib/mmio.h>
16 #include <lib/utils.h>
17 #include <libfdt.h>
18 #include <plat/common/platform.h>
19 
20 #include <platform_def.h>
21 
22 /*
23  * For our comprehension in this file
24  *  _len are in BITs
25  *  _size are in BYTEs
26  *  _nbw are in number of PKA_word (PKA_word = u64)
27  */
28 
29 #define UINT8_LEN			8U
30 #define UINT64_LEN			(UINT8_LEN * sizeof(uint64_t))
31 #define WORD_SIZE			(sizeof(uint64_t))
32 #define OP_NBW_FROM_LEN(len)		(DIV_ROUND_UP_2EVAL((len), UINT64_LEN) + 1)
33 #define OP_NBW_FROM_SIZE(s)		OP_NBW_FROM_LEN((s) * UINT8_LEN)
34 #define OP_SIZE_FROM_SIZE(s)		(OP_NBW_FROM_SIZE(s) * WORD_SIZE)
35 
36 #define DT_PKA_COMPAT			"st,stm32-pka64"
37 
38 #define MAX_ECC_SIZE_LEN		640U
39 #define MAX_EO_NBW			OP_NBW_FROM_LEN(MAX_ECC_SIZE_LEN)
40 
41 /* PKA registers */
42 /* PKA control register */
43 #define _PKA_CR				0x0U
44 /* PKA status register */
45 #define _PKA_SR				0x4U
46 /* PKA clear flag register */
47 #define _PKA_CLRFR			0x8U
48 /* PKA version register */
49 #define _PKA_VERR			0x1FF4U
50 /* PKA identification register */
51 #define _PKA_IPIDR			0x1FF8U
52 
53 /* PKA control register fields */
54 #define _PKA_CR_MODE_MASK		GENMASK(13, 8)
55 #define _PKA_CR_MODE_SHIFT		8U
56 #define _PKA_CR_MODE_ADD		0x9U
57 #define _PKA_CR_MODE_ECDSA_VERIF	0x26U
58 #define _PKA_CR_START			BIT(1)
59 #define _PKA_CR_EN			BIT(0)
60 
61 /* PKA status register fields */
62 #define _PKA_SR_BUSY			BIT(16)
63 #define _PKA_SR_LMF			BIT(1)
64 #define _PKA_SR_INITOK			BIT(0)
65 
66 /* PKA it flag fields (used in CR, SR and CLRFR) */
67 #define _PKA_IT_MASK			(GENMASK(21, 19) | BIT(17))
68 #define _PKA_IT_SHIFT			17U
69 #define _PKA_IT_OPERR			BIT(21)
70 #define _PKA_IT_ADDRERR			BIT(20)
71 #define _PKA_IT_RAMERR			BIT(19)
72 #define _PKA_IT_PROCEND			BIT(17)
73 
74 /* PKA version register fields */
75 #define _PKA_VERR_MAJREV_MASK		GENMASK(7, 4)
76 #define _PKA_VERR_MAJREV_SHIFT		4U
77 #define _PKA_VERR_MINREV_MASK		GENMASK(3, 0)
78 #define _PKA_VERR_MINREV_SHIFT		0U
79 
80 /* RAM magic offset */
81 #define _PKA_RAM_START			0x400U
82 #define _PKA_RAM_SIZE			5336U
83 
84 /* ECDSA verification */
85 #define _PKA_RAM_N_LEN			0x408U /* 64 */
86 #define _PKA_RAM_P_LEN			0x4C8U /* 64 */
87 #define _PKA_RAM_A_SIGN			0x468U /* 64 */
88 #define _PKA_RAM_A			0x470U /* EOS */
89 #define _PKA_RAM_P			0x4D0U /* EOS */
90 #define _PKA_RAM_XG			0x678U /* EOS */
91 #define _PKA_RAM_YG			0x6D0U /* EOS */
92 #define _PKA_RAM_XQ			0x12F8U /* EOS */
93 #define _PKA_RAM_YQ			0x1350U /* EOS */
94 #define _PKA_RAM_SIGN_R			0x10E0U /* EOS */
95 #define _PKA_RAM_SIGN_S			0xC68U /* EOS */
96 #define _PKA_RAM_HASH_Z			0x13A8U /* EOS */
97 #define _PKA_RAM_PRIME_N		0x1088U /* EOS */
98 #define _PKA_RAM_ECDSA_VERIFY		0x5D0U /* 64 */
99 #define _PKA_RAM_ECDSA_VERIFY_VALID	0xD60DULL
100 #define _PKA_RAM_ECDSA_VERIFY_INVALID	0xA3B7ULL
101 
102 #define PKA_TIMEOUT_US			1000000U
103 #define TIMEOUT_US_1MS			1000U
104 #define PKA_RESET_DELAY			20U
105 
106 struct curve_parameters {
107 	uint32_t a_sign;  /* 0 positive, 1 negative */
108 	uint8_t *a;    /* Curve coefficient |a| */
109 	size_t a_size;
110 	uint8_t *p;    /* Curve modulus value */
111 	uint32_t p_len;
112 	uint8_t *xg;   /* Curve base point G coordinate x */
113 	size_t xg_size;
114 	uint8_t *yg;   /* Curve base point G coordinate y */
115 	size_t yg_size;
116 	uint8_t *n;    /* Curve prime order n */
117 	uint32_t n_len;
118 };
119 
120 static const struct curve_parameters curve_def[] = {
121 #if PKA_USE_NIST_P256
122 	[PKA_NIST_P256] = {
123 		.p_len = 256U,
124 		.n_len = 256U,
125 		.p  = (uint8_t[]){0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
126 				  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 				  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
128 				  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
129 		.n  = (uint8_t[]){0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
130 				  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
131 				  0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
132 				  0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51},
133 		.a_sign = 1U,
134 		.a = (uint8_t[]){0x03},
135 		.a_size = 1U,
136 		.xg = (uint8_t[]){0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47,
137 				  0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
138 				  0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
139 				  0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96},
140 		.xg_size = 32U,
141 		.yg = (uint8_t[]){0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B,
142 				  0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
143 				  0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
144 				  0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5},
145 		.yg_size = 32U,
146 	},
147 #endif
148 #if PKA_USE_BRAINPOOL_P256R1
149 	[PKA_BRAINPOOL_P256R1] = {
150 		.p_len = 256,
151 		.n_len = 256,
152 		.p  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
153 				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
154 				  0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
155 				  0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77},
156 		.n  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
157 				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71,
158 				  0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7,
159 				  0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7},
160 		.a  = (uint8_t[]){0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57,
161 				  0xEE, 0xF6, 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7,
162 				  0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C,
163 				  0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9},
164 		.a_size = 32U,
165 		.xg = (uint8_t[]){0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB,
166 				  0x2C, 0x4B, 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF,
167 				  0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2,
168 				  0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62},
169 		.xg_size = 32U,
170 		.yg = (uint8_t[]){0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD,
171 				  0x97, 0xF8, 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9,
172 				  0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54,
173 				  0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97},
174 		.yg_size = 32U,
175 	},
176 #endif
177 #if PKA_USE_BRAINPOOL_P256T1
178 	[PKA_BRAINPOOL_P256T1] = {
179 		.p_len = 256,
180 		.n_len = 256,
181 		.p  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
182 				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
183 				  0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
184 				  0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77},
185 		.n  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
186 				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71,
187 				  0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7,
188 				  0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7},
189 		.a  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
190 				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
191 				  0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
192 				  0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x74},
193 		.a_size = 32U,
194 		.xg = (uint8_t[]){0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7,
195 				  0x73, 0x22, 0x13, 0xB2, 0x3A, 0x65, 0x61, 0x49,
196 				  0xAF, 0xA1, 0x42, 0xC4, 0x7A, 0xAF, 0xBC, 0x2B,
197 				  0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13, 0x05, 0xF4},
198 		.xg_size = 32U,
199 		.yg = (uint8_t[]){0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D,
200 				  0x7F, 0x7B, 0x22, 0xE1, 0x46, 0x44, 0x41, 0x7E,
201 				  0x69, 0xBC, 0xB6, 0xDE, 0x39, 0xD0, 0x27, 0x00,
202 				  0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25, 0xC9, 0xBE},
203 		.yg_size = 32U,
204 	},
205 #endif
206 #if PKA_USE_NIST_P521
207 	[PKA_NIST_P521] = {
208 		.p_len = 521,
209 		.n_len = 521,
210 		.p  = (uint8_t[]){                                    0x01, 0xff,
211 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
212 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
213 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
214 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
215 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
216 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
217 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
218 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
219 		.n  = (uint8_t[]){                                    0x01, 0xff,
220 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
221 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
222 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
223 				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
224 				  0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b,
225 				  0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, 0xa5, 0xd0,
226 				  0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
227 				  0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09},
228 		.a_sign = 1,
229 		.a  = (uint8_t[]){0x03},
230 		.a_size = 1U,
231 		.xg = (uint8_t[]){                                          0xc6,
232 				  0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd,
233 				  0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42,
234 				  0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21,
235 				  0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba,
236 				  0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28,
237 				  0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde,
238 				  0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b,
239 				  0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66},
240 		.xg_size = 65U,
241 		.yg = (uint8_t[]){                                    0x01, 0x18,
242 				  0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,
243 				  0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
244 				  0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
245 				  0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c,
246 				  0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
247 				  0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
248 				  0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40,
249 				  0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50},
250 		.yg_size = 66U,
251 	},
252 #endif
253 };
254 
255 static struct stm32_pka_platdata pka_pdata;
256 
257 static int stm32_pka_parse_fdt(void)
258 {
259 	int node;
260 	struct dt_node_info info;
261 	void *fdt;
262 
263 	if (fdt_get_address(&fdt) == 0) {
264 		return -FDT_ERR_NOTFOUND;
265 	}
266 
267 	node = dt_get_node(&info, -1, DT_PKA_COMPAT);
268 	if (node < 0) {
269 		ERROR("No PKA entry in DT\n");
270 		return -FDT_ERR_NOTFOUND;
271 	}
272 
273 	if (info.status == DT_DISABLED) {
274 		return -FDT_ERR_NOTFOUND;
275 	}
276 
277 	if ((info.base == 0) || (info.clock < 0) || (info.reset < 0)) {
278 		return -FDT_ERR_BADVALUE;
279 	}
280 
281 	pka_pdata.base = (uintptr_t)info.base;
282 	pka_pdata.clock_id = (unsigned long)info.clock;
283 	pka_pdata.reset_id = (unsigned int)info.reset;
284 
285 	return 0;
286 }
287 
288 static int pka_wait_bit(uintptr_t base, uint32_t bit)
289 {
290 	uint64_t timeout = timeout_init_us(PKA_TIMEOUT_US);
291 
292 	while ((mmio_read_32(base + _PKA_SR) & bit) != bit) {
293 		if (timeout_elapsed(timeout)) {
294 			WARN("timeout waiting %x\n", bit);
295 			return -ETIMEDOUT;
296 		}
297 	}
298 
299 	return 0;
300 
301 }
302 
303 static void pka_disable(uintptr_t base)
304 {
305 	mmio_clrbits_32(base + _PKA_CR, _PKA_CR_EN);
306 }
307 
308 static int pka_enable(uintptr_t base, uint32_t mode)
309 {
310 	/* Set mode and disable interrupts */
311 	mmio_clrsetbits_32(base + _PKA_CR, _PKA_IT_MASK | _PKA_CR_MODE_MASK,
312 			   _PKA_CR_MODE_MASK & (mode << _PKA_CR_MODE_SHIFT));
313 
314 	mmio_setbits_32(base + _PKA_CR, _PKA_CR_EN);
315 
316 	return pka_wait_bit(base, _PKA_SR_INITOK);
317 }
318 
319 /*
320  * Data are already loaded in PKA internal RAM
321  * MODE is set
322  * We start process, and wait for its end.
323  */
324 static int stm32_pka_process(uintptr_t base)
325 {
326 	mmio_setbits_32(base + _PKA_CR, _PKA_CR_START);
327 
328 	return pka_wait_bit(base, _PKA_IT_PROCEND);
329 }
330 
331 /**
332  * @brief Write ECC operand to PKA RAM.
333  * @note  PKA expect to write u64 word, each u64 are: the least significant bit is
334  *        bit 0; the most significant bit is bit 63.
335  *        We write eo_nbw (ECC operand Size) u64, value that depends of the chosen
336  *        prime modulus length in bits.
337  *        First less signicant u64 is written to low address
338  *        Most significant u64 to higher address.
339  *        And at last address we write a u64(0x0)
340  * @note  This function doesn't only manage endianness (as bswap64 do), but also
341  *        complete most significant incomplete u64 with 0 (if data is not a u64
342  *        multiple), and fill u64 last address with 0.
343  * @param addr: PKA_RAM address to write the buffer 'data'
344  * @param data: is a BYTE list with most significant bytes first
345  * @param data_size: nb of byte in data
346  * @param eo_nbw: is ECC Operand size in 64bits word (including the extra 0)
347  *                (note it depends of the prime modulus length, not the data size)
348  * @retval 0 if OK.
349  *         -EINVAL if data_size and eo_nbw are inconsistent, ie data doesn't
350  *         fit in defined eo_nbw, or eo_nbw bigger than hardware limit.
351  */
352 static int write_eo_data(uintptr_t addr, uint8_t *data, unsigned int data_size,
353 			 unsigned int eo_nbw)
354 {
355 	uint32_t word_index;
356 	int data_index;
357 
358 	if ((eo_nbw < OP_NBW_FROM_SIZE(data_size)) || (eo_nbw > MAX_EO_NBW)) {
359 		return -EINVAL;
360 	}
361 
362 	/* Fill value */
363 	data_index = (int)data_size - 1;
364 	for (word_index = 0U; word_index < eo_nbw; word_index++) {
365 		uint64_t tmp = 0ULL;
366 		unsigned int i = 0U;  /* index in the tmp U64 word */
367 
368 		/* Stop if end of tmp or end of data */
369 		while ((i < sizeof(tmp)) && (data_index >= 0)) {
370 			tmp |= (uint64_t)(data[data_index]) << (UINT8_LEN * i);
371 			i++; /* Move byte index in current (u64)tmp */
372 			data_index--; /* Move to just next most significat byte */
373 		}
374 
375 		mmio_write_64(addr + word_index * sizeof(tmp), tmp);
376 	}
377 
378 	return 0;
379 }
380 
381 static unsigned int get_ecc_op_nbword(enum stm32_pka_ecdsa_curve_id cid)
382 {
383 	if (cid >= ARRAY_SIZE(curve_def)) {
384 		ERROR("CID %u is out of boundaries\n", cid);
385 		panic();
386 	}
387 
388 	return OP_NBW_FROM_LEN(curve_def[cid].n_len);
389 }
390 
391 static int stm32_pka_ecdsa_verif_configure_curve(uintptr_t base, enum stm32_pka_ecdsa_curve_id cid)
392 {
393 	int ret;
394 	unsigned int eo_nbw = get_ecc_op_nbword(cid);
395 
396 	mmio_write_64(base + _PKA_RAM_N_LEN, curve_def[cid].n_len);
397 	mmio_write_64(base + _PKA_RAM_P_LEN, curve_def[cid].p_len);
398 	mmio_write_64(base + _PKA_RAM_A_SIGN, curve_def[cid].a_sign);
399 
400 	ret = write_eo_data(base + _PKA_RAM_A, curve_def[cid].a, curve_def[cid].a_size, eo_nbw);
401 	if (ret < 0) {
402 		return ret;
403 	}
404 
405 	ret = write_eo_data(base + _PKA_RAM_PRIME_N,
406 			    curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN),
407 			    eo_nbw);
408 	if (ret < 0) {
409 		return ret;
410 	}
411 
412 	ret = write_eo_data(base + _PKA_RAM_P, curve_def[cid].p,
413 			    div_round_up(curve_def[cid].p_len, UINT8_LEN), eo_nbw);
414 	if (ret < 0) {
415 		return ret;
416 	}
417 
418 	ret = write_eo_data(base + _PKA_RAM_XG, curve_def[cid].xg, curve_def[cid].xg_size, eo_nbw);
419 	if (ret < 0) {
420 		return ret;
421 	}
422 
423 	ret = write_eo_data(base + _PKA_RAM_YG, curve_def[cid].yg, curve_def[cid].yg_size, eo_nbw);
424 	if (ret < 0) {
425 		return ret;
426 	}
427 
428 	return 0;
429 }
430 
431 static int stm32_pka_ecdsa_verif_check_return(uintptr_t base)
432 {
433 	uint64_t value;
434 	uint32_t sr;
435 
436 	sr = mmio_read_32(base + _PKA_SR);
437 	if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
438 		WARN("Detected error(s): %s%s%s\n",
439 		     (sr & _PKA_IT_OPERR) ? "Operation " : "",
440 		     (sr & _PKA_IT_ADDRERR) ? "Address " : "",
441 		     (sr & _PKA_IT_RAMERR) ? "RAM" : "");
442 		return -EINVAL;
443 	}
444 
445 	value = mmio_read_64(base + _PKA_RAM_ECDSA_VERIFY);
446 	if (value == _PKA_RAM_ECDSA_VERIFY_VALID) {
447 		return 0;
448 	}
449 
450 	if (value == _PKA_RAM_ECDSA_VERIFY_INVALID) {
451 		return -EAUTH;
452 	}
453 
454 	return -EINVAL;
455 }
456 
457 /**
458  * @brief Check if BigInt stored in data is 0
459  *
460  * @param data: a BYTE array with most significant bytes first
461  * @param size: data size
462  *
463  * @retval: true: if data represents a 0 value (ie all bytes == 0)
464  *          false: if data represents a non-zero value.
465  */
466 static bool is_zero(uint8_t *data, unsigned int size)
467 {
468 	unsigned int i;
469 
470 	for (i = 0U; i < size; i++) {
471 		if (data[i] != 0U) {
472 			return false;
473 		}
474 	}
475 
476 	return true;
477 }
478 
479 /**
480  * @brief Compare two BigInt:
481  * @param xdata_a: a BYTE array with most significant bytes first
482  * @param size_a: nb of Byte of 'a'
483  * @param data_b: a BYTE array with most significant bytes first
484  * @param size_b: nb of Byte of 'b'
485  *
486  * @retval: true if data_a < data_b
487  *          false if data_a >= data_b
488  */
489 static bool is_smaller(uint8_t *data_a, unsigned int size_a,
490 		       uint8_t *data_b, unsigned int size_b)
491 {
492 	unsigned int i;
493 
494 	i = MAX(size_a, size_b) + 1U;
495 	do {
496 		uint8_t a, b;
497 
498 		i--;
499 		if (size_a < i) {
500 			a = 0U;
501 		} else {
502 			a = data_a[size_a - i];
503 		}
504 
505 		if (size_b < i) {
506 			b = 0U;
507 		} else {
508 			b = data_b[size_b - i];
509 		}
510 
511 		if (a < b) {
512 			return true;
513 		}
514 
515 		if (a > b) {
516 			return false;
517 		}
518 	} while (i != 0U);
519 
520 	return false;
521 }
522 
523 static int stm32_pka_ecdsa_check_param(void *sig_r_ptr, unsigned int sig_r_size,
524 				       void *sig_s_ptr, unsigned int sig_s_size,
525 				       void *pk_x_ptr, unsigned int pk_x_size,
526 				       void *pk_y_ptr, unsigned int pk_y_size,
527 				       enum stm32_pka_ecdsa_curve_id cid)
528 {
529 	/* Public Key check */
530 	/* Check Xq < p */
531 	if (!is_smaller(pk_x_ptr, pk_x_size,
532 			curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) {
533 		WARN("%s Xq < p inval\n", __func__);
534 		return -EINVAL;
535 	}
536 
537 	/* Check Yq < p */
538 	if (!is_smaller(pk_y_ptr, pk_y_size,
539 			curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) {
540 		WARN("%s Yq < p inval\n", __func__);
541 		return -EINVAL;
542 	}
543 
544 	/* Signature check */
545 	/* Check 0 < r < n */
546 	if (!is_smaller(sig_r_ptr, sig_r_size,
547 			curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) &&
548 	    !is_zero(sig_r_ptr, sig_r_size)) {
549 		WARN("%s 0< r < n inval\n", __func__);
550 		return -EINVAL;
551 	}
552 
553 	/* Check 0 < s < n */
554 	if (!is_smaller(sig_s_ptr, sig_s_size,
555 			curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) &&
556 	    !is_zero(sig_s_ptr, sig_s_size)) {
557 		WARN("%s 0< s < n inval\n", __func__);
558 		return -EINVAL;
559 	}
560 
561 	return 0;
562 }
563 
564 /*
565  * @brief  Initialize the PKA driver.
566  * @param  None.
567  * @retval 0 if OK, negative value else.
568  */
569 int stm32_pka_init(void)
570 {
571 	int err;
572 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
573 	uint32_t ver;
574 	uint32_t id;
575 #endif
576 
577 	err = stm32_pka_parse_fdt();
578 	if (err != 0) {
579 		return err;
580 	}
581 
582 	clk_enable(pka_pdata.clock_id);
583 
584 	if (stm32mp_reset_assert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
585 		panic();
586 	}
587 
588 	udelay(PKA_RESET_DELAY);
589 	if (stm32mp_reset_deassert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
590 		panic();
591 	}
592 
593 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
594 	id = mmio_read_32(pka_pdata.base + _PKA_IPIDR);
595 	ver = mmio_read_32(pka_pdata.base + _PKA_VERR);
596 
597 	VERBOSE("STM32 PKA[%x] V%u.%u\n", id,
598 		(ver & _PKA_VERR_MAJREV_MASK) >> _PKA_VERR_MAJREV_SHIFT,
599 		(ver & _PKA_VERR_MINREV_MASK) >> _PKA_VERR_MINREV_SHIFT);
600 #endif
601 	return 0;
602 }
603 
604 int stm32_pka_ecdsa_verif(void *hash, unsigned int hash_size,
605 			  void *sig_r_ptr, unsigned int sig_r_size,
606 			  void *sig_s_ptr, unsigned int sig_s_size,
607 			  void *pk_x_ptr, unsigned int pk_x_size,
608 			  void *pk_y_ptr, unsigned int pk_y_size,
609 			  enum stm32_pka_ecdsa_curve_id cid)
610 {
611 	int ret;
612 	uintptr_t base = pka_pdata.base;
613 	unsigned int eo_nbw = get_ecc_op_nbword(cid);
614 
615 	if ((hash == NULL) || (sig_r_ptr == NULL) || (sig_s_ptr == NULL) ||
616 	    (pk_x_ptr == NULL) || (pk_y_ptr == NULL)) {
617 		INFO("%s invalid input param\n", __func__);
618 		return -EINVAL;
619 	}
620 
621 	ret = stm32_pka_ecdsa_check_param(sig_r_ptr, sig_r_size,
622 					  sig_s_ptr, sig_s_size,
623 					  pk_x_ptr, pk_x_size,
624 					  pk_y_ptr, pk_y_size,
625 					  cid);
626 	if (ret < 0) {
627 		INFO("%s check param error %d\n", __func__, ret);
628 		goto out;
629 	}
630 
631 	if ((mmio_read_32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
632 		INFO("%s busy\n", __func__);
633 		ret = -EBUSY;
634 		goto out;
635 	}
636 
637 	/* Fill PKA RAM */
638 	/* With curve id values */
639 	ret = stm32_pka_ecdsa_verif_configure_curve(base, cid);
640 	if (ret < 0) {
641 		goto out;
642 	}
643 
644 	/* With pubkey */
645 	ret = write_eo_data(base + _PKA_RAM_XQ, pk_x_ptr, pk_x_size, eo_nbw);
646 	if (ret < 0) {
647 		goto out;
648 	}
649 
650 	ret = write_eo_data(base + _PKA_RAM_YQ, pk_y_ptr, pk_y_size, eo_nbw);
651 	if (ret < 0) {
652 		goto out;
653 	}
654 
655 	/* With hash */
656 	ret = write_eo_data(base + _PKA_RAM_HASH_Z, hash, hash_size, eo_nbw);
657 	if (ret < 0) {
658 		goto out;
659 	}
660 
661 	/* With signature */
662 	ret = write_eo_data(base + _PKA_RAM_SIGN_R, sig_r_ptr, sig_r_size, eo_nbw);
663 	if (ret < 0) {
664 		goto out;
665 	}
666 
667 	ret = write_eo_data(base + _PKA_RAM_SIGN_S, sig_s_ptr, sig_s_size, eo_nbw);
668 	if (ret < 0) {
669 		goto out;
670 	}
671 
672 	/* Set mode to ecdsa signature verification */
673 	ret = pka_enable(base, _PKA_CR_MODE_ECDSA_VERIF);
674 	if (ret < 0) {
675 		WARN("%s set mode pka error %d\n", __func__, ret);
676 		goto out;
677 	}
678 
679 	/* Start processing and wait end */
680 	ret = stm32_pka_process(base);
681 	if (ret < 0) {
682 		WARN("%s process error %d\n", __func__, ret);
683 		goto out;
684 	}
685 
686 	/* Check return status */
687 	ret = stm32_pka_ecdsa_verif_check_return(base);
688 
689 	/* Unset end proc */
690 	mmio_setbits_32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
691 
692 out:
693 	/* Disable PKA (will stop all pending proccess and reset RAM) */
694 	pka_disable(base);
695 
696 	return ret;
697 }
698