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 #pragma weak stm32_pka_get_platdata
258 
stm32_pka_get_platdata(struct stm32_pka_platdata * pdata)259 int stm32_pka_get_platdata(struct stm32_pka_platdata *pdata)
260 {
261 	return -ENODEV;
262 }
263 
stm32_pka_parse_fdt(void)264 static int stm32_pka_parse_fdt(void)
265 {
266 	int node;
267 	struct dt_node_info info;
268 	void *fdt;
269 
270 	if (fdt_get_address(&fdt) == 0) {
271 		return -FDT_ERR_NOTFOUND;
272 	}
273 
274 	node = dt_get_node(&info, -1, DT_PKA_COMPAT);
275 	if (node < 0) {
276 		ERROR("No PKA entry in DT\n");
277 		return -FDT_ERR_NOTFOUND;
278 	}
279 
280 	if (info.status == DT_DISABLED) {
281 		return -FDT_ERR_NOTFOUND;
282 	}
283 
284 	if ((info.base == 0) || (info.clock < 0) || (info.reset < 0)) {
285 		return -FDT_ERR_BADVALUE;
286 	}
287 
288 	pka_pdata.base = (uintptr_t)info.base;
289 	pka_pdata.clock_id = (unsigned long)info.clock;
290 	pka_pdata.reset_id = (unsigned int)info.reset;
291 
292 	return 0;
293 }
294 
pka_wait_bit(uintptr_t base,uint32_t bit)295 static int pka_wait_bit(uintptr_t base, uint32_t bit)
296 {
297 	uint64_t timeout = timeout_init_us(PKA_TIMEOUT_US);
298 
299 	while ((mmio_read_32(base + _PKA_SR) & bit) != bit) {
300 		if (timeout_elapsed(timeout)) {
301 			WARN("timeout waiting %x\n", bit);
302 			return -ETIMEDOUT;
303 		}
304 	}
305 
306 	return 0;
307 
308 }
309 
pka_disable(uintptr_t base)310 static void pka_disable(uintptr_t base)
311 {
312 	mmio_clrbits_32(base + _PKA_CR, _PKA_CR_EN);
313 }
314 
pka_enable(uintptr_t base,uint32_t mode)315 static int pka_enable(uintptr_t base, uint32_t mode)
316 {
317 	/* Set mode and disable interrupts */
318 	mmio_clrsetbits_32(base + _PKA_CR, _PKA_IT_MASK | _PKA_CR_MODE_MASK,
319 			   _PKA_CR_MODE_MASK & (mode << _PKA_CR_MODE_SHIFT));
320 
321 	mmio_setbits_32(base + _PKA_CR, _PKA_CR_EN);
322 
323 	return pka_wait_bit(base, _PKA_SR_INITOK);
324 }
325 
326 /*
327  * Data are already loaded in PKA internal RAM
328  * MODE is set
329  * We start process, and wait for its end.
330  */
stm32_pka_process(uintptr_t base)331 static int stm32_pka_process(uintptr_t base)
332 {
333 	mmio_setbits_32(base + _PKA_CR, _PKA_CR_START);
334 
335 	return pka_wait_bit(base, _PKA_IT_PROCEND);
336 }
337 
338 /**
339  * @brief Write ECC operand to PKA RAM.
340  * @note  PKA expect to write u64 word, each u64 are: the least significant bit is
341  *        bit 0; the most significant bit is bit 63.
342  *        We write eo_nbw (ECC operand Size) u64, value that depends of the chosen
343  *        prime modulus length in bits.
344  *        First less signicant u64 is written to low address
345  *        Most significant u64 to higher address.
346  *        And at last address we write a u64(0x0)
347  * @note  This function doesn't only manage endianness (as bswap64 do), but also
348  *        complete most significant incomplete u64 with 0 (if data is not a u64
349  *        multiple), and fill u64 last address with 0.
350  * @param addr: PKA_RAM address to write the buffer 'data'
351  * @param data: is a BYTE list with most significant bytes first
352  * @param data_size: nb of byte in data
353  * @param eo_nbw: is ECC Operand size in 64bits word (including the extra 0)
354  *                (note it depends of the prime modulus length, not the data size)
355  * @retval 0 if OK.
356  *         -EINVAL if data_size and eo_nbw are inconsistent, ie data doesn't
357  *         fit in defined eo_nbw, or eo_nbw bigger than hardware limit.
358  */
write_eo_data(uintptr_t addr,uint8_t * data,unsigned int data_size,unsigned int eo_nbw)359 static int write_eo_data(uintptr_t addr, uint8_t *data, unsigned int data_size,
360 			 unsigned int eo_nbw)
361 {
362 	uint32_t word_index;
363 	int data_index;
364 
365 	if ((eo_nbw < OP_NBW_FROM_SIZE(data_size)) || (eo_nbw > MAX_EO_NBW)) {
366 		return -EINVAL;
367 	}
368 
369 	/* Fill value */
370 	data_index = (int)data_size - 1;
371 	for (word_index = 0U; word_index < eo_nbw; word_index++) {
372 		uint64_t tmp = 0ULL;
373 		unsigned int i = 0U;  /* index in the tmp U64 word */
374 
375 		/* Stop if end of tmp or end of data */
376 		while ((i < sizeof(tmp)) && (data_index >= 0)) {
377 			tmp |= (uint64_t)(data[data_index]) << (UINT8_LEN * i);
378 			i++; /* Move byte index in current (u64)tmp */
379 			data_index--; /* Move to just next most significat byte */
380 		}
381 
382 		mmio_write_64(addr + word_index * sizeof(tmp), tmp);
383 	}
384 
385 	return 0;
386 }
387 
get_ecc_op_nbword(enum stm32_pka_ecdsa_curve_id cid)388 static unsigned int get_ecc_op_nbword(enum stm32_pka_ecdsa_curve_id cid)
389 {
390 	if (cid >= ARRAY_SIZE(curve_def)) {
391 		ERROR("CID %u is out of boundaries\n", cid);
392 		panic();
393 	}
394 
395 	return OP_NBW_FROM_LEN(curve_def[cid].n_len);
396 }
397 
stm32_pka_ecdsa_verif_configure_curve(uintptr_t base,enum stm32_pka_ecdsa_curve_id cid)398 static int stm32_pka_ecdsa_verif_configure_curve(uintptr_t base, enum stm32_pka_ecdsa_curve_id cid)
399 {
400 	int ret;
401 	unsigned int eo_nbw = get_ecc_op_nbword(cid);
402 
403 	mmio_write_64(base + _PKA_RAM_N_LEN, curve_def[cid].n_len);
404 	mmio_write_64(base + _PKA_RAM_P_LEN, curve_def[cid].p_len);
405 	mmio_write_64(base + _PKA_RAM_A_SIGN, curve_def[cid].a_sign);
406 
407 	ret = write_eo_data(base + _PKA_RAM_A, curve_def[cid].a, curve_def[cid].a_size, eo_nbw);
408 	if (ret < 0) {
409 		return ret;
410 	}
411 
412 	ret = write_eo_data(base + _PKA_RAM_PRIME_N,
413 			    curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN),
414 			    eo_nbw);
415 	if (ret < 0) {
416 		return ret;
417 	}
418 
419 	ret = write_eo_data(base + _PKA_RAM_P, curve_def[cid].p,
420 			    div_round_up(curve_def[cid].p_len, UINT8_LEN), eo_nbw);
421 	if (ret < 0) {
422 		return ret;
423 	}
424 
425 	ret = write_eo_data(base + _PKA_RAM_XG, curve_def[cid].xg, curve_def[cid].xg_size, eo_nbw);
426 	if (ret < 0) {
427 		return ret;
428 	}
429 
430 	ret = write_eo_data(base + _PKA_RAM_YG, curve_def[cid].yg, curve_def[cid].yg_size, eo_nbw);
431 	if (ret < 0) {
432 		return ret;
433 	}
434 
435 	return 0;
436 }
437 
stm32_pka_ecdsa_verif_check_return(uintptr_t base)438 static int stm32_pka_ecdsa_verif_check_return(uintptr_t base)
439 {
440 	uint64_t value;
441 	uint32_t sr;
442 
443 	sr = mmio_read_32(base + _PKA_SR);
444 	if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
445 		WARN("Detected error(s): %s%s%s\n",
446 		     (sr & _PKA_IT_OPERR) ? "Operation " : "",
447 		     (sr & _PKA_IT_ADDRERR) ? "Address " : "",
448 		     (sr & _PKA_IT_RAMERR) ? "RAM" : "");
449 		return -EINVAL;
450 	}
451 
452 	value = mmio_read_64(base + _PKA_RAM_ECDSA_VERIFY);
453 	if (value == _PKA_RAM_ECDSA_VERIFY_VALID) {
454 		return 0;
455 	}
456 
457 	if (value == _PKA_RAM_ECDSA_VERIFY_INVALID) {
458 		return -EAUTH;
459 	}
460 
461 	return -EINVAL;
462 }
463 
464 /**
465  * @brief Check if BigInt stored in data is 0
466  *
467  * @param data: a BYTE array with most significant bytes first
468  * @param size: data size
469  *
470  * @retval: true: if data represents a 0 value (ie all bytes == 0)
471  *          false: if data represents a non-zero value.
472  */
is_zero(uint8_t * data,unsigned int size)473 static bool is_zero(uint8_t *data, unsigned int size)
474 {
475 	unsigned int i;
476 
477 	for (i = 0U; i < size; i++) {
478 		if (data[i] != 0U) {
479 			return false;
480 		}
481 	}
482 
483 	return true;
484 }
485 
486 /**
487  * @brief Compare two BigInt:
488  * @param xdata_a: a BYTE array with most significant bytes first
489  * @param size_a: nb of Byte of 'a'
490  * @param data_b: a BYTE array with most significant bytes first
491  * @param size_b: nb of Byte of 'b'
492  *
493  * @retval: true if data_a < data_b
494  *          false if data_a >= data_b
495  */
is_smaller(uint8_t * data_a,unsigned int size_a,uint8_t * data_b,unsigned int size_b)496 static bool is_smaller(uint8_t *data_a, unsigned int size_a,
497 		       uint8_t *data_b, unsigned int size_b)
498 {
499 	unsigned int i;
500 
501 	i = MAX(size_a, size_b) + 1U;
502 	do {
503 		uint8_t a, b;
504 
505 		i--;
506 		if (size_a < i) {
507 			a = 0U;
508 		} else {
509 			a = data_a[size_a - i];
510 		}
511 
512 		if (size_b < i) {
513 			b = 0U;
514 		} else {
515 			b = data_b[size_b - i];
516 		}
517 
518 		if (a < b) {
519 			return true;
520 		}
521 
522 		if (a > b) {
523 			return false;
524 		}
525 	} while (i != 0U);
526 
527 	return false;
528 }
529 
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)530 static int stm32_pka_ecdsa_check_param(void *sig_r_ptr, unsigned int sig_r_size,
531 				       void *sig_s_ptr, unsigned int sig_s_size,
532 				       void *pk_x_ptr, unsigned int pk_x_size,
533 				       void *pk_y_ptr, unsigned int pk_y_size,
534 				       enum stm32_pka_ecdsa_curve_id cid)
535 {
536 	/* Public Key check */
537 	/* Check Xq < p */
538 	if (!is_smaller(pk_x_ptr, pk_x_size,
539 			curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) {
540 		WARN("%s Xq < p inval\n", __func__);
541 		return -EINVAL;
542 	}
543 
544 	/* Check Yq < p */
545 	if (!is_smaller(pk_y_ptr, pk_y_size,
546 			curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) {
547 		WARN("%s Yq < p inval\n", __func__);
548 		return -EINVAL;
549 	}
550 
551 	/* Signature check */
552 	/* Check 0 < r < n */
553 	if (!is_smaller(sig_r_ptr, sig_r_size,
554 			curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) &&
555 	    !is_zero(sig_r_ptr, sig_r_size)) {
556 		WARN("%s 0< r < n inval\n", __func__);
557 		return -EINVAL;
558 	}
559 
560 	/* Check 0 < s < n */
561 	if (!is_smaller(sig_s_ptr, sig_s_size,
562 			curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) &&
563 	    !is_zero(sig_s_ptr, sig_s_size)) {
564 		WARN("%s 0< s < n inval\n", __func__);
565 		return -EINVAL;
566 	}
567 
568 	return 0;
569 }
570 
571 /*
572  * @brief  Initialize the PKA driver.
573  * @param  None.
574  * @retval 0 if OK, negative value else.
575  */
stm32_pka_init(void)576 int stm32_pka_init(void)
577 {
578 	int err;
579 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
580 	uint32_t ver;
581 	uint32_t id;
582 #endif
583 
584 	err = stm32_pka_parse_fdt();
585 	if (err != 0) {
586 		err = stm32_pka_get_platdata(&pka_pdata);
587 		if (err != 0) {
588 			return err;
589 		}
590 	}
591 
592 	clk_enable(pka_pdata.clock_id);
593 
594 	if (stm32mp_reset_assert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
595 		panic();
596 	}
597 
598 	udelay(PKA_RESET_DELAY);
599 	if (stm32mp_reset_deassert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
600 		panic();
601 	}
602 
603 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
604 	id = mmio_read_32(pka_pdata.base + _PKA_IPIDR);
605 	ver = mmio_read_32(pka_pdata.base + _PKA_VERR);
606 
607 	VERBOSE("STM32 PKA[%x] V%u.%u\n", id,
608 		(ver & _PKA_VERR_MAJREV_MASK) >> _PKA_VERR_MAJREV_SHIFT,
609 		(ver & _PKA_VERR_MINREV_MASK) >> _PKA_VERR_MINREV_SHIFT);
610 #endif
611 	return 0;
612 }
613 
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)614 int stm32_pka_ecdsa_verif(void *hash, unsigned int hash_size,
615 			  void *sig_r_ptr, unsigned int sig_r_size,
616 			  void *sig_s_ptr, unsigned int sig_s_size,
617 			  void *pk_x_ptr, unsigned int pk_x_size,
618 			  void *pk_y_ptr, unsigned int pk_y_size,
619 			  enum stm32_pka_ecdsa_curve_id cid)
620 {
621 	int ret;
622 	uintptr_t base = pka_pdata.base;
623 	unsigned int eo_nbw = get_ecc_op_nbword(cid);
624 
625 	if ((hash == NULL) || (sig_r_ptr == NULL) || (sig_s_ptr == NULL) ||
626 	    (pk_x_ptr == NULL) || (pk_y_ptr == NULL)) {
627 		INFO("%s invalid input param\n", __func__);
628 		return -EINVAL;
629 	}
630 
631 	ret = stm32_pka_ecdsa_check_param(sig_r_ptr, sig_r_size,
632 					  sig_s_ptr, sig_s_size,
633 					  pk_x_ptr, pk_x_size,
634 					  pk_y_ptr, pk_y_size,
635 					  cid);
636 	if (ret < 0) {
637 		INFO("%s check param error %d\n", __func__, ret);
638 		goto out;
639 	}
640 
641 	if ((mmio_read_32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
642 		INFO("%s busy\n", __func__);
643 		ret = -EBUSY;
644 		goto out;
645 	}
646 
647 	/* Fill PKA RAM */
648 	/* With curve id values */
649 	ret = stm32_pka_ecdsa_verif_configure_curve(base, cid);
650 	if (ret < 0) {
651 		goto out;
652 	}
653 
654 	/* With pubkey */
655 	ret = write_eo_data(base + _PKA_RAM_XQ, pk_x_ptr, pk_x_size, eo_nbw);
656 	if (ret < 0) {
657 		goto out;
658 	}
659 
660 	ret = write_eo_data(base + _PKA_RAM_YQ, pk_y_ptr, pk_y_size, eo_nbw);
661 	if (ret < 0) {
662 		goto out;
663 	}
664 
665 	/* With hash */
666 	ret = write_eo_data(base + _PKA_RAM_HASH_Z, hash, hash_size, eo_nbw);
667 	if (ret < 0) {
668 		goto out;
669 	}
670 
671 	/* With signature */
672 	ret = write_eo_data(base + _PKA_RAM_SIGN_R, sig_r_ptr, sig_r_size, eo_nbw);
673 	if (ret < 0) {
674 		goto out;
675 	}
676 
677 	ret = write_eo_data(base + _PKA_RAM_SIGN_S, sig_s_ptr, sig_s_size, eo_nbw);
678 	if (ret < 0) {
679 		goto out;
680 	}
681 
682 	/* Set mode to ecdsa signature verification */
683 	ret = pka_enable(base, _PKA_CR_MODE_ECDSA_VERIF);
684 	if (ret < 0) {
685 		WARN("%s set mode pka error %d\n", __func__, ret);
686 		goto out;
687 	}
688 
689 	/* Start processing and wait end */
690 	ret = stm32_pka_process(base);
691 	if (ret < 0) {
692 		WARN("%s process error %d\n", __func__, ret);
693 		goto out;
694 	}
695 
696 	/* Check return status */
697 	ret = stm32_pka_ecdsa_verif_check_return(base);
698 
699 	/* Unset end proc */
700 	mmio_setbits_32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
701 
702 out:
703 	/* Disable PKA (will stop all pending proccess and reset RAM) */
704 	pka_disable(base);
705 
706 	return ret;
707 }
708