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