1*81f5b20cSNicolas Toromanoff // SPDX-License-Identifier: BSD-3-Clause
2*81f5b20cSNicolas Toromanoff /*
3*81f5b20cSNicolas Toromanoff * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
4*81f5b20cSNicolas Toromanoff */
5*81f5b20cSNicolas Toromanoff
6*81f5b20cSNicolas Toromanoff #include <assert.h>
7*81f5b20cSNicolas Toromanoff #include <config.h>
8*81f5b20cSNicolas Toromanoff #include <drivers/clk.h>
9*81f5b20cSNicolas Toromanoff #include <drivers/clk_dt.h>
10*81f5b20cSNicolas Toromanoff #include <io.h>
11*81f5b20cSNicolas Toromanoff #include <kernel/boot.h>
12*81f5b20cSNicolas Toromanoff #include <kernel/delay.h>
13*81f5b20cSNicolas Toromanoff #include <kernel/dt.h>
14*81f5b20cSNicolas Toromanoff #include <kernel/mutex.h>
15*81f5b20cSNicolas Toromanoff #include <kernel/pm.h>
16*81f5b20cSNicolas Toromanoff #include <kernel/pm.h>
17*81f5b20cSNicolas Toromanoff #include <libfdt.h>
18*81f5b20cSNicolas Toromanoff #include <mm/core_memprot.h>
19*81f5b20cSNicolas Toromanoff #include <stm32_util.h>
20*81f5b20cSNicolas Toromanoff #include <tee_api_types.h>
21*81f5b20cSNicolas Toromanoff
22*81f5b20cSNicolas Toromanoff #include "common.h"
23*81f5b20cSNicolas Toromanoff #include "stm32_pka.h"
24*81f5b20cSNicolas Toromanoff
25*81f5b20cSNicolas Toromanoff /*
26*81f5b20cSNicolas Toromanoff * For our comprehension in this file
27*81f5b20cSNicolas Toromanoff * _len are in BITs
28*81f5b20cSNicolas Toromanoff * _size are in BYTEs
29*81f5b20cSNicolas Toromanoff * _nbw are in number of PKA_word (PKA_word = u64)
30*81f5b20cSNicolas Toromanoff */
31*81f5b20cSNicolas Toromanoff
32*81f5b20cSNicolas Toromanoff #define INT8_LEN U(8)
33*81f5b20cSNicolas Toromanoff #define INT64_LEN (INT8_LEN * sizeof(uint64_t))
34*81f5b20cSNicolas Toromanoff #define WORD_SIZE sizeof(uint64_t)
35*81f5b20cSNicolas Toromanoff #define OP_NBW_FROM_LEN(len) (ROUNDUP_DIV((len), INT64_LEN) + 1)
36*81f5b20cSNicolas Toromanoff #define OP_NBW_FROM_SIZE(s) OP_NBW_FROM_LEN((s) * INT8_LEN)
37*81f5b20cSNicolas Toromanoff #define OP_SIZE_FROM_SIZE(s) (OP_NBW_FROM_SIZE(s) * WORD_SIZE)
38*81f5b20cSNicolas Toromanoff
39*81f5b20cSNicolas Toromanoff #define MAX_EO_NBW OP_NBW_FROM_LEN(PKA_MAX_ECC_LEN)
40*81f5b20cSNicolas Toromanoff
41*81f5b20cSNicolas Toromanoff /* PKA registers */
42*81f5b20cSNicolas Toromanoff #define _PKA_CR U(0x0)
43*81f5b20cSNicolas Toromanoff #define _PKA_SR U(0x4)
44*81f5b20cSNicolas Toromanoff #define _PKA_CLRFR U(0x8)
45*81f5b20cSNicolas Toromanoff #define _PKA_VERR U(0x1FF4)
46*81f5b20cSNicolas Toromanoff #define _PKA_IPIDR U(0x1FF8)
47*81f5b20cSNicolas Toromanoff
48*81f5b20cSNicolas Toromanoff /* PKA control register fields */
49*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_MASK GENMASK_32(13, 8)
50*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_R2MODN U(0x01)
51*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_SHIFT U(0x08)
52*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_ADD U(0x09)
53*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_ECC_KP U(0x20)
54*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_ECDSA_SIGN U(0x24)
55*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_ECDSA_VERIF U(0x26)
56*81f5b20cSNicolas Toromanoff #define _PKA_CR_MODE_POINT_CHECK U(0x28)
57*81f5b20cSNicolas Toromanoff #define _PKA_CR_START BIT(1)
58*81f5b20cSNicolas Toromanoff #define _PKA_CR_EN BIT(0)
59*81f5b20cSNicolas Toromanoff
60*81f5b20cSNicolas Toromanoff /* PKA status register fields */
61*81f5b20cSNicolas Toromanoff #define _PKA_SR_BUSY BIT(16)
62*81f5b20cSNicolas Toromanoff #define _PKA_SR_LMF BIT(1)
63*81f5b20cSNicolas Toromanoff #define _PKA_SR_INITOK BIT(0)
64*81f5b20cSNicolas Toromanoff
65*81f5b20cSNicolas Toromanoff /* PKA it flag fields (used in CR, SR and CLRFR) */
66*81f5b20cSNicolas Toromanoff #define _PKA_IT_MASK (GENMASK_32(21, 19) | BIT(17))
67*81f5b20cSNicolas Toromanoff #define _PKA_IT_SHIFT U(17)
68*81f5b20cSNicolas Toromanoff #define _PKA_IT_OPERR BIT(21)
69*81f5b20cSNicolas Toromanoff #define _PKA_IT_ADDRERR BIT(20)
70*81f5b20cSNicolas Toromanoff #define _PKA_IT_RAMERR BIT(19)
71*81f5b20cSNicolas Toromanoff #define _PKA_IT_PROCEND BIT(17)
72*81f5b20cSNicolas Toromanoff
73*81f5b20cSNicolas Toromanoff /* PKA version register fields */
74*81f5b20cSNicolas Toromanoff #define _PKA_VERR_MAJREV_MASK GENMASK_32(7, 4)
75*81f5b20cSNicolas Toromanoff #define _PKA_VERR_MAJREV_SHIFT U(4)
76*81f5b20cSNicolas Toromanoff #define _PKA_VERR_MINREV_MASK GENMASK_32(3, 0)
77*81f5b20cSNicolas Toromanoff #define _PKA_VERR_MINREV_SHIFT U(0)
78*81f5b20cSNicolas Toromanoff
79*81f5b20cSNicolas Toromanoff /* PKA identification register value */
80*81f5b20cSNicolas Toromanoff #define _PKA_IDID U(0x00170072)
81*81f5b20cSNicolas Toromanoff
82*81f5b20cSNicolas Toromanoff /* RAM magic offset */
83*81f5b20cSNicolas Toromanoff #define _PKA_RAM_START U(0x400)
84*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIZE U(5336)
85*81f5b20cSNicolas Toromanoff
86*81f5b20cSNicolas Toromanoff /* Montgomery parameter computation (R*R mod n) */
87*81f5b20cSNicolas Toromanoff #define _PKA_RAM_R2MODN_N_LEN U(0x408) /* 64 */
88*81f5b20cSNicolas Toromanoff #define _PKA_RAM_R2MODN_PRIME_N U(0x1088) /* EOS */
89*81f5b20cSNicolas Toromanoff #define _PKA_RAM_R2MODN_OUT U(0x620) /* EOS */
90*81f5b20cSNicolas Toromanoff
91*81f5b20cSNicolas Toromanoff /* ECC check if point P is on curve */
92*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_N_LEN U(0x408) /* 64 */
93*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_A_SIGN U(0x410) /* 64 */
94*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_A U(0x418) /* EOS */
95*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_B U(0x520) /* EOS */
96*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_P U(0x470) /* EOS */
97*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_XP U(0x578) /* EOS */
98*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_YP U(0x5D0) /* EOS */
99*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_R2MODN U(0x4C8) /* EOS */
100*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_RES U(0x680) /* 64 */
101*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_RES_YES ULL(0xD60D)
102*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_RES_NO ULL(0xA3B7)
103*81f5b20cSNicolas Toromanoff #define _PKA_RAM_ONCURVE_RES_TOOBIG ULL(0xF946)
104*81f5b20cSNicolas Toromanoff
105*81f5b20cSNicolas Toromanoff /* ECC Fp scalar multiplication (kP) */
106*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_N_LEN U(0x400) /* 64 */
107*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_P_LEN U(0x408) /* 64 */
108*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_A_SIGN U(0x410) /* 64 */
109*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_A U(0x418) /* EOS */
110*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_B U(0x520) /* EOS */
111*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_P U(0x1088) /* EOS */
112*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_K U(0x12A0) /* EOS */
113*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_XP U(0x578) /* EOS */
114*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_YP U(0x470) /* EOS */
115*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_PRIME_N U(0xF88) /* EOS */
116*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_RES U(0x680) /* 64 */
117*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_RES_SUCCESS ULL(0xD60D)
118*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_RES_FAIL ULL(0xCBC9)
119*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_X U(0x578) /* EOS*/
120*81f5b20cSNicolas Toromanoff #define _PKA_RAM_KP_Y U(0x5D0) /* EOS*/
121*81f5b20cSNicolas Toromanoff
122*81f5b20cSNicolas Toromanoff /* ECDSA sign */
123*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_N_LEN U(0x400) /* 64 */
124*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_P_LEN U(0x408) /* 64 */
125*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_A_SIGN U(0x410) /* 64 */
126*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_A U(0x418) /* EOS */
127*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_B U(0x520) /* EOS */
128*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_P U(0x1088) /* EOS */
129*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_K U(0x12A0) /* EOS */
130*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_XG U(0x578) /* EOS */
131*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_YG U(0x470) /* EOS */
132*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_HASH_Z U(0xFE8) /* EOS */
133*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_D U(0xF28) /* EOS */
134*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_PRIME_N U(0xF88) /* EOS */
135*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_RES U(0xFE0) /* 64 */
136*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_RES_SUCCESS ULL(0xD60D)
137*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_RES_FAIL ULL(0xCBC9)
138*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_RES_R0 ULL(0xA3B7)
139*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_RES_S0 ULL(0xF946)
140*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_R U(0x730) /* EOS*/
141*81f5b20cSNicolas Toromanoff #define _PKA_RAM_SIGN_S U(0x788) /* EOS*/
142*81f5b20cSNicolas Toromanoff
143*81f5b20cSNicolas Toromanoff /* ECDSA verification */
144*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_N_LEN U(0x408) /* 64 */
145*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_P_LEN U(0x4C8) /* 64 */
146*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_A_SIGN U(0x468) /* 64 */
147*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_A U(0x470) /* EOS */
148*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_P U(0x4D0) /* EOS */
149*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_XG U(0x678) /* EOS */
150*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_YG U(0x6D0) /* EOS */
151*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_XQ U(0x12F8) /* EOS */
152*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_YQ U(0x1350) /* EOS */
153*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_SIGN_R U(0x10E0) /* EOS */
154*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_SIGN_S U(0xC68) /* EOS */
155*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_HASH_Z U(0x13A8) /* EOS */
156*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_PRIME_N U(0x1088) /* EOS */
157*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_RES U(0x5D0) /* 64 */
158*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_RES_VALID ULL(0xD60D)
159*81f5b20cSNicolas Toromanoff #define _PKA_RAM_VERIF_RES_INVALID ULL(0xA3B7)
160*81f5b20cSNicolas Toromanoff
161*81f5b20cSNicolas Toromanoff #define PKA_TIMEOUT_US U(1000000)
162*81f5b20cSNicolas Toromanoff #define TIMEOUT_US_1MS U(1000)
163*81f5b20cSNicolas Toromanoff #define PKA_RESET_DELAY U(20)
164*81f5b20cSNicolas Toromanoff
165*81f5b20cSNicolas Toromanoff enum pka_op {
166*81f5b20cSNicolas Toromanoff SIGN,
167*81f5b20cSNicolas Toromanoff VERIF,
168*81f5b20cSNicolas Toromanoff SCALAR_MUL,
169*81f5b20cSNicolas Toromanoff ON_CURVE,
170*81f5b20cSNicolas Toromanoff
171*81f5b20cSNicolas Toromanoff PKA_OP_LAST
172*81f5b20cSNicolas Toromanoff };
173*81f5b20cSNicolas Toromanoff
174*81f5b20cSNicolas Toromanoff enum pka_ram_index {
175*81f5b20cSNicolas Toromanoff N_LEN,
176*81f5b20cSNicolas Toromanoff P_LEN,
177*81f5b20cSNicolas Toromanoff A_SIGN,
178*81f5b20cSNicolas Toromanoff COEFF_A,
179*81f5b20cSNicolas Toromanoff COEFF_B,
180*81f5b20cSNicolas Toromanoff PRIME_N,
181*81f5b20cSNicolas Toromanoff VAL_P,
182*81f5b20cSNicolas Toromanoff GPOINT_X,
183*81f5b20cSNicolas Toromanoff GPOINT_Y,
184*81f5b20cSNicolas Toromanoff
185*81f5b20cSNicolas Toromanoff PKA_RAM_INDEX_LAST
186*81f5b20cSNicolas Toromanoff };
187*81f5b20cSNicolas Toromanoff
188*81f5b20cSNicolas Toromanoff static const uint32_t pka_ram[PKA_OP_LAST][PKA_RAM_INDEX_LAST] = {
189*81f5b20cSNicolas Toromanoff [SIGN] = {
190*81f5b20cSNicolas Toromanoff [N_LEN] = _PKA_RAM_SIGN_N_LEN,
191*81f5b20cSNicolas Toromanoff [P_LEN] = _PKA_RAM_SIGN_P_LEN,
192*81f5b20cSNicolas Toromanoff [A_SIGN] = _PKA_RAM_SIGN_A_SIGN,
193*81f5b20cSNicolas Toromanoff [COEFF_A] = _PKA_RAM_SIGN_A,
194*81f5b20cSNicolas Toromanoff [COEFF_B] = _PKA_RAM_SIGN_B,
195*81f5b20cSNicolas Toromanoff [PRIME_N] = _PKA_RAM_SIGN_PRIME_N,
196*81f5b20cSNicolas Toromanoff [VAL_P] = _PKA_RAM_SIGN_P,
197*81f5b20cSNicolas Toromanoff [GPOINT_X] = _PKA_RAM_SIGN_XG,
198*81f5b20cSNicolas Toromanoff [GPOINT_Y] = _PKA_RAM_SIGN_YG
199*81f5b20cSNicolas Toromanoff },
200*81f5b20cSNicolas Toromanoff [VERIF] = {
201*81f5b20cSNicolas Toromanoff [N_LEN] = _PKA_RAM_VERIF_N_LEN,
202*81f5b20cSNicolas Toromanoff [P_LEN] = _PKA_RAM_VERIF_P_LEN,
203*81f5b20cSNicolas Toromanoff [A_SIGN] = _PKA_RAM_VERIF_A_SIGN,
204*81f5b20cSNicolas Toromanoff [COEFF_A] = _PKA_RAM_VERIF_A,
205*81f5b20cSNicolas Toromanoff [COEFF_B] = 0,
206*81f5b20cSNicolas Toromanoff [PRIME_N] = _PKA_RAM_VERIF_PRIME_N,
207*81f5b20cSNicolas Toromanoff [VAL_P] = _PKA_RAM_VERIF_P,
208*81f5b20cSNicolas Toromanoff [GPOINT_X] = _PKA_RAM_VERIF_XG,
209*81f5b20cSNicolas Toromanoff [GPOINT_Y] = _PKA_RAM_VERIF_YG
210*81f5b20cSNicolas Toromanoff },
211*81f5b20cSNicolas Toromanoff [SCALAR_MUL] = {
212*81f5b20cSNicolas Toromanoff [N_LEN] = _PKA_RAM_KP_N_LEN,
213*81f5b20cSNicolas Toromanoff [P_LEN] = _PKA_RAM_KP_P_LEN,
214*81f5b20cSNicolas Toromanoff [A_SIGN] = _PKA_RAM_KP_A_SIGN,
215*81f5b20cSNicolas Toromanoff [COEFF_A] = _PKA_RAM_KP_A,
216*81f5b20cSNicolas Toromanoff [COEFF_B] = _PKA_RAM_KP_B,
217*81f5b20cSNicolas Toromanoff [PRIME_N] = _PKA_RAM_KP_PRIME_N,
218*81f5b20cSNicolas Toromanoff [VAL_P] = _PKA_RAM_KP_P,
219*81f5b20cSNicolas Toromanoff [GPOINT_X] = 0,
220*81f5b20cSNicolas Toromanoff [GPOINT_Y] = 0,
221*81f5b20cSNicolas Toromanoff },
222*81f5b20cSNicolas Toromanoff [ON_CURVE] = {
223*81f5b20cSNicolas Toromanoff [N_LEN] = _PKA_RAM_ONCURVE_N_LEN,
224*81f5b20cSNicolas Toromanoff [P_LEN] = 0,
225*81f5b20cSNicolas Toromanoff [A_SIGN] = _PKA_RAM_ONCURVE_A_SIGN,
226*81f5b20cSNicolas Toromanoff [COEFF_A] = _PKA_RAM_ONCURVE_A,
227*81f5b20cSNicolas Toromanoff [COEFF_B] = _PKA_RAM_ONCURVE_B,
228*81f5b20cSNicolas Toromanoff [PRIME_N] = 0,
229*81f5b20cSNicolas Toromanoff [VAL_P] = _PKA_RAM_ONCURVE_P,
230*81f5b20cSNicolas Toromanoff [GPOINT_X] = 0,
231*81f5b20cSNicolas Toromanoff [GPOINT_Y] = 0,
232*81f5b20cSNicolas Toromanoff },
233*81f5b20cSNicolas Toromanoff };
234*81f5b20cSNicolas Toromanoff
235*81f5b20cSNicolas Toromanoff /* struct curve_parameters - EC curve parameneters for PKA
236*81f5b20cSNicolas Toromanoff * @a_sign: Sign of coefficient A: 0 positive, 1 negative
237*81f5b20cSNicolas Toromanoff * @a: Curve coefficient |a|
238*81f5b20cSNicolas Toromanoff * @b: Curve coefficient b
239*81f5b20cSNicolas Toromanoff * @p: Curve modulus value
240*81f5b20cSNicolas Toromanoff * @p_len: Modulus bit length
241*81f5b20cSNicolas Toromanoff * @g: Curve base G point
242*81f5b20cSNicolas Toromanoff * @n: Curve prime order n
243*81f5b20cSNicolas Toromanoff * @n_len: Curve prime order bit size
244*81f5b20cSNicolas Toromanoff */
245*81f5b20cSNicolas Toromanoff struct curve_parameters {
246*81f5b20cSNicolas Toromanoff uint32_t a_sign;
247*81f5b20cSNicolas Toromanoff struct stm32_pka_bn a;
248*81f5b20cSNicolas Toromanoff struct stm32_pka_bn b;
249*81f5b20cSNicolas Toromanoff struct stm32_pka_bn p;
250*81f5b20cSNicolas Toromanoff uint32_t p_len;
251*81f5b20cSNicolas Toromanoff struct stm32_pka_point g;
252*81f5b20cSNicolas Toromanoff struct stm32_pka_bn n;
253*81f5b20cSNicolas Toromanoff uint32_t n_len;
254*81f5b20cSNicolas Toromanoff };
255*81f5b20cSNicolas Toromanoff
256*81f5b20cSNicolas Toromanoff static const struct curve_parameters curve_def[] = {
257*81f5b20cSNicolas Toromanoff [PKA_NIST_P192] = {
258*81f5b20cSNicolas Toromanoff .p_len = U(192),
259*81f5b20cSNicolas Toromanoff .p = {
260*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
261*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
262*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
263*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
264*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xfe,
265*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
266*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff
267*81f5b20cSNicolas Toromanoff },
268*81f5b20cSNicolas Toromanoff .size = U(24),
269*81f5b20cSNicolas Toromanoff },
270*81f5b20cSNicolas Toromanoff .n_len = U(192),
271*81f5b20cSNicolas Toromanoff .n = {
272*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
273*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
274*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
275*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
276*81f5b20cSNicolas Toromanoff 0x99, 0xde, 0xf8, 0x36,
277*81f5b20cSNicolas Toromanoff 0x14, 0x6b, 0xc9, 0xb1,
278*81f5b20cSNicolas Toromanoff 0xb4, 0xd2, 0x28, 0x31
279*81f5b20cSNicolas Toromanoff },
280*81f5b20cSNicolas Toromanoff .size = U(24),
281*81f5b20cSNicolas Toromanoff },
282*81f5b20cSNicolas Toromanoff .a_sign = U(1),
283*81f5b20cSNicolas Toromanoff .a = {
284*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){ 0x03 },
285*81f5b20cSNicolas Toromanoff .size = U(1),
286*81f5b20cSNicolas Toromanoff },
287*81f5b20cSNicolas Toromanoff .b = {
288*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
289*81f5b20cSNicolas Toromanoff 0x64, 0x21, 0x05, 0x19,
290*81f5b20cSNicolas Toromanoff 0xe5, 0x9c, 0x80, 0xe7,
291*81f5b20cSNicolas Toromanoff 0x0f, 0xa7, 0xe9, 0xab,
292*81f5b20cSNicolas Toromanoff 0x72, 0x24, 0x30, 0x49,
293*81f5b20cSNicolas Toromanoff 0xfe, 0xb8, 0xde, 0xec,
294*81f5b20cSNicolas Toromanoff 0xc1, 0x46, 0xb9, 0xb1
295*81f5b20cSNicolas Toromanoff },
296*81f5b20cSNicolas Toromanoff .size = U(24),
297*81f5b20cSNicolas Toromanoff },
298*81f5b20cSNicolas Toromanoff .g = {
299*81f5b20cSNicolas Toromanoff .x = {
300*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
301*81f5b20cSNicolas Toromanoff 0x18, 0x8d, 0xa8, 0x0e,
302*81f5b20cSNicolas Toromanoff 0xb0, 0x30, 0x90, 0xf6,
303*81f5b20cSNicolas Toromanoff 0x7c, 0xbf, 0x20, 0xeb,
304*81f5b20cSNicolas Toromanoff 0x43, 0xa1, 0x88, 0x00,
305*81f5b20cSNicolas Toromanoff 0xf4, 0xff, 0x0a, 0xfd,
306*81f5b20cSNicolas Toromanoff 0x82, 0xff, 0x10, 0x12
307*81f5b20cSNicolas Toromanoff },
308*81f5b20cSNicolas Toromanoff .size = U(24),
309*81f5b20cSNicolas Toromanoff },
310*81f5b20cSNicolas Toromanoff .y = {
311*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
312*81f5b20cSNicolas Toromanoff 0x07, 0x19, 0x2b, 0x95,
313*81f5b20cSNicolas Toromanoff 0xff, 0xc8, 0xda, 0x78,
314*81f5b20cSNicolas Toromanoff 0x63, 0x10, 0x11, 0xed,
315*81f5b20cSNicolas Toromanoff 0x6b, 0x24, 0xcd, 0xd5,
316*81f5b20cSNicolas Toromanoff 0x73, 0xf9, 0x77, 0xa1,
317*81f5b20cSNicolas Toromanoff 0x1e, 0x79, 0x48, 0x11
318*81f5b20cSNicolas Toromanoff },
319*81f5b20cSNicolas Toromanoff .size = U(24),
320*81f5b20cSNicolas Toromanoff },
321*81f5b20cSNicolas Toromanoff },
322*81f5b20cSNicolas Toromanoff },
323*81f5b20cSNicolas Toromanoff [PKA_NIST_P224] = {
324*81f5b20cSNicolas Toromanoff .p_len = U(224),
325*81f5b20cSNicolas Toromanoff .p = {
326*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
327*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
328*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
329*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
330*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
331*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
332*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
333*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x01
334*81f5b20cSNicolas Toromanoff },
335*81f5b20cSNicolas Toromanoff .size = U(28),
336*81f5b20cSNicolas Toromanoff },
337*81f5b20cSNicolas Toromanoff .n_len = U(224),
338*81f5b20cSNicolas Toromanoff .n = {
339*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
340*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
341*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
342*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
343*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0x16, 0xa2,
344*81f5b20cSNicolas Toromanoff 0xe0, 0xb8, 0xf0, 0x3e,
345*81f5b20cSNicolas Toromanoff 0x13, 0xdd, 0x29, 0x45,
346*81f5b20cSNicolas Toromanoff 0x5c, 0x5c, 0x2a, 0x3d
347*81f5b20cSNicolas Toromanoff },
348*81f5b20cSNicolas Toromanoff .size = U(28),
349*81f5b20cSNicolas Toromanoff },
350*81f5b20cSNicolas Toromanoff .a_sign = U(1),
351*81f5b20cSNicolas Toromanoff .a = {
352*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){ 0x03 },
353*81f5b20cSNicolas Toromanoff .size = U(1),
354*81f5b20cSNicolas Toromanoff },
355*81f5b20cSNicolas Toromanoff .b = {
356*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
357*81f5b20cSNicolas Toromanoff 0xb4, 0x05, 0x0a, 0x85,
358*81f5b20cSNicolas Toromanoff 0x0c, 0x04, 0xb3, 0xab,
359*81f5b20cSNicolas Toromanoff 0xf5, 0x41, 0x32, 0x56,
360*81f5b20cSNicolas Toromanoff 0x50, 0x44, 0xb0, 0xb7,
361*81f5b20cSNicolas Toromanoff 0xd7, 0xbf, 0xd8, 0xba,
362*81f5b20cSNicolas Toromanoff 0x27, 0x0b, 0x39, 0x43,
363*81f5b20cSNicolas Toromanoff 0x23, 0x55, 0xff, 0xb4},
364*81f5b20cSNicolas Toromanoff .size = U(28),
365*81f5b20cSNicolas Toromanoff },
366*81f5b20cSNicolas Toromanoff .g = {
367*81f5b20cSNicolas Toromanoff .x = {
368*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
369*81f5b20cSNicolas Toromanoff 0xb7, 0x0e, 0x0c, 0xbd,
370*81f5b20cSNicolas Toromanoff 0x6b, 0xb4, 0xbf, 0x7f,
371*81f5b20cSNicolas Toromanoff 0x32, 0x13, 0x90, 0xb9,
372*81f5b20cSNicolas Toromanoff 0x4a, 0x03, 0xc1, 0xd3,
373*81f5b20cSNicolas Toromanoff 0x56, 0xc2, 0x11, 0x22,
374*81f5b20cSNicolas Toromanoff 0x34, 0x32, 0x80, 0xd6,
375*81f5b20cSNicolas Toromanoff 0x11, 0x5c, 0x1d, 0x21
376*81f5b20cSNicolas Toromanoff },
377*81f5b20cSNicolas Toromanoff .size = U(28),
378*81f5b20cSNicolas Toromanoff },
379*81f5b20cSNicolas Toromanoff .y = {
380*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
381*81f5b20cSNicolas Toromanoff 0xbd, 0x37, 0x63, 0x88,
382*81f5b20cSNicolas Toromanoff 0xb5, 0xf7, 0x23, 0xfb,
383*81f5b20cSNicolas Toromanoff 0x4c, 0x22, 0xdf, 0xe6,
384*81f5b20cSNicolas Toromanoff 0xcd, 0x43, 0x75, 0xa0,
385*81f5b20cSNicolas Toromanoff 0x5a, 0x07, 0x47, 0x64,
386*81f5b20cSNicolas Toromanoff 0x44, 0xd5, 0x81, 0x99,
387*81f5b20cSNicolas Toromanoff 0x85, 0x00, 0x7e, 0x34
388*81f5b20cSNicolas Toromanoff },
389*81f5b20cSNicolas Toromanoff .size = U(28),
390*81f5b20cSNicolas Toromanoff },
391*81f5b20cSNicolas Toromanoff },
392*81f5b20cSNicolas Toromanoff },
393*81f5b20cSNicolas Toromanoff [PKA_NIST_P256] = {
394*81f5b20cSNicolas Toromanoff .p_len = U(256),
395*81f5b20cSNicolas Toromanoff .p = {
396*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
397*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
398*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x01,
399*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
400*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
401*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
402*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
403*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
404*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff
405*81f5b20cSNicolas Toromanoff },
406*81f5b20cSNicolas Toromanoff .size = U(32),
407*81f5b20cSNicolas Toromanoff },
408*81f5b20cSNicolas Toromanoff .n_len = U(256),
409*81f5b20cSNicolas Toromanoff .n = {
410*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
411*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
412*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
413*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
414*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
415*81f5b20cSNicolas Toromanoff 0xbc, 0xe6, 0xfa, 0xad,
416*81f5b20cSNicolas Toromanoff 0xa7, 0x17, 0x9e, 0x84,
417*81f5b20cSNicolas Toromanoff 0xf3, 0xb9, 0xca, 0xc2,
418*81f5b20cSNicolas Toromanoff 0xfc, 0x63, 0x25, 0x51
419*81f5b20cSNicolas Toromanoff },
420*81f5b20cSNicolas Toromanoff .size = U(32),
421*81f5b20cSNicolas Toromanoff },
422*81f5b20cSNicolas Toromanoff .a_sign = U(1),
423*81f5b20cSNicolas Toromanoff .a = {
424*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){ 0x03 },
425*81f5b20cSNicolas Toromanoff .size = U(1),
426*81f5b20cSNicolas Toromanoff },
427*81f5b20cSNicolas Toromanoff .b = {
428*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
429*81f5b20cSNicolas Toromanoff 0x5a, 0xc6, 0x35, 0xd8,
430*81f5b20cSNicolas Toromanoff 0xaa, 0x3a, 0x93, 0xe7,
431*81f5b20cSNicolas Toromanoff 0xb3, 0xeb, 0xbd, 0x55,
432*81f5b20cSNicolas Toromanoff 0x76, 0x98, 0x86, 0xbc,
433*81f5b20cSNicolas Toromanoff 0x65, 0x1d, 0x06, 0xb0,
434*81f5b20cSNicolas Toromanoff 0xcc, 0x53, 0xb0, 0xf6,
435*81f5b20cSNicolas Toromanoff 0x3b, 0xce, 0x3c, 0x3e,
436*81f5b20cSNicolas Toromanoff 0x27, 0xd2, 0x60, 0x4b
437*81f5b20cSNicolas Toromanoff },
438*81f5b20cSNicolas Toromanoff .size = U(32),
439*81f5b20cSNicolas Toromanoff },
440*81f5b20cSNicolas Toromanoff .g = {
441*81f5b20cSNicolas Toromanoff .x = {
442*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
443*81f5b20cSNicolas Toromanoff 0x6b, 0x17, 0xd1, 0xf2,
444*81f5b20cSNicolas Toromanoff 0xe1, 0x2c, 0x42, 0x47,
445*81f5b20cSNicolas Toromanoff 0xf8, 0xbc, 0xe6, 0xe5,
446*81f5b20cSNicolas Toromanoff 0x63, 0xa4, 0x40, 0xf2,
447*81f5b20cSNicolas Toromanoff 0x77, 0x03, 0x7d, 0x81,
448*81f5b20cSNicolas Toromanoff 0x2d, 0xeb, 0x33, 0xa0,
449*81f5b20cSNicolas Toromanoff 0xf4, 0xa1, 0x39, 0x45,
450*81f5b20cSNicolas Toromanoff 0xd8, 0x98, 0xc2, 0x96
451*81f5b20cSNicolas Toromanoff },
452*81f5b20cSNicolas Toromanoff .size = U(32),
453*81f5b20cSNicolas Toromanoff },
454*81f5b20cSNicolas Toromanoff .y = {
455*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
456*81f5b20cSNicolas Toromanoff 0x4f, 0xe3, 0x42, 0xe2,
457*81f5b20cSNicolas Toromanoff 0xfe, 0x1a, 0x7f, 0x9b,
458*81f5b20cSNicolas Toromanoff 0x8e, 0xe7, 0xeb, 0x4a,
459*81f5b20cSNicolas Toromanoff 0x7c, 0x0f, 0x9e, 0x16,
460*81f5b20cSNicolas Toromanoff 0x2b, 0xce, 0x33, 0x57,
461*81f5b20cSNicolas Toromanoff 0x6b, 0x31, 0x5e, 0xce,
462*81f5b20cSNicolas Toromanoff 0xcb, 0xb6, 0x40, 0x68,
463*81f5b20cSNicolas Toromanoff 0x37, 0xbf, 0x51, 0xf5
464*81f5b20cSNicolas Toromanoff },
465*81f5b20cSNicolas Toromanoff .size = U(32),
466*81f5b20cSNicolas Toromanoff },
467*81f5b20cSNicolas Toromanoff },
468*81f5b20cSNicolas Toromanoff },
469*81f5b20cSNicolas Toromanoff [PKA_NIST_P384] = {
470*81f5b20cSNicolas Toromanoff .p_len = U(384),
471*81f5b20cSNicolas Toromanoff .p = {
472*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
473*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
474*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
475*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
476*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
477*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
478*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
479*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
480*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xfe,
481*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
482*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
483*81f5b20cSNicolas Toromanoff 0x00, 0x00, 0x00, 0x00,
484*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff
485*81f5b20cSNicolas Toromanoff },
486*81f5b20cSNicolas Toromanoff .size = U(48),
487*81f5b20cSNicolas Toromanoff },
488*81f5b20cSNicolas Toromanoff .n_len = U(384),
489*81f5b20cSNicolas Toromanoff .n = {
490*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
491*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
492*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
493*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
494*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
495*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
496*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
497*81f5b20cSNicolas Toromanoff 0xc7, 0x63, 0x4d, 0x81,
498*81f5b20cSNicolas Toromanoff 0xf4, 0x37, 0x2d, 0xdf,
499*81f5b20cSNicolas Toromanoff 0x58, 0x1a, 0x0d, 0xb2,
500*81f5b20cSNicolas Toromanoff 0x48, 0xb0, 0xa7, 0x7a,
501*81f5b20cSNicolas Toromanoff 0xec, 0xec, 0x19, 0x6a,
502*81f5b20cSNicolas Toromanoff 0xcc, 0xc5, 0x29, 0x73
503*81f5b20cSNicolas Toromanoff },
504*81f5b20cSNicolas Toromanoff .size = U(48),
505*81f5b20cSNicolas Toromanoff },
506*81f5b20cSNicolas Toromanoff .a_sign = U(1),
507*81f5b20cSNicolas Toromanoff .a = {
508*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){ 0x03 },
509*81f5b20cSNicolas Toromanoff .size = U(1),
510*81f5b20cSNicolas Toromanoff },
511*81f5b20cSNicolas Toromanoff .b = {
512*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
513*81f5b20cSNicolas Toromanoff 0xb3, 0x31, 0x2f, 0xa7,
514*81f5b20cSNicolas Toromanoff 0xe2, 0x3e, 0xe7, 0xe4,
515*81f5b20cSNicolas Toromanoff 0x98, 0x8e, 0x05, 0x6b,
516*81f5b20cSNicolas Toromanoff 0xe3, 0xf8, 0x2d, 0x19,
517*81f5b20cSNicolas Toromanoff 0x18, 0x1d, 0x9c, 0x6e,
518*81f5b20cSNicolas Toromanoff 0xfe, 0x81, 0x41, 0x12,
519*81f5b20cSNicolas Toromanoff 0x03, 0x14, 0x08, 0x8f,
520*81f5b20cSNicolas Toromanoff 0x50, 0x13, 0x87, 0x5a,
521*81f5b20cSNicolas Toromanoff 0xc6, 0x56, 0x39, 0x8d,
522*81f5b20cSNicolas Toromanoff 0x8a, 0x2e, 0xd1, 0x9d,
523*81f5b20cSNicolas Toromanoff 0x2a, 0x85, 0xc8, 0xed,
524*81f5b20cSNicolas Toromanoff 0xd3, 0xec, 0x2a, 0xef
525*81f5b20cSNicolas Toromanoff },
526*81f5b20cSNicolas Toromanoff .size = U(48),
527*81f5b20cSNicolas Toromanoff },
528*81f5b20cSNicolas Toromanoff .g = {
529*81f5b20cSNicolas Toromanoff .x = {
530*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
531*81f5b20cSNicolas Toromanoff 0xaa, 0x87, 0xca, 0x22,
532*81f5b20cSNicolas Toromanoff 0xbe, 0x8b, 0x05, 0x37,
533*81f5b20cSNicolas Toromanoff 0x8e, 0xb1, 0xc7, 0x1e,
534*81f5b20cSNicolas Toromanoff 0xf3, 0x20, 0xad, 0x74,
535*81f5b20cSNicolas Toromanoff 0x6e, 0x1d, 0x3b, 0x62,
536*81f5b20cSNicolas Toromanoff 0x8b, 0xa7, 0x9b, 0x98,
537*81f5b20cSNicolas Toromanoff 0x59, 0xf7, 0x41, 0xe0,
538*81f5b20cSNicolas Toromanoff 0x82, 0x54, 0x2a, 0x38,
539*81f5b20cSNicolas Toromanoff 0x55, 0x02, 0xf2, 0x5d,
540*81f5b20cSNicolas Toromanoff 0xbf, 0x55, 0x29, 0x6c,
541*81f5b20cSNicolas Toromanoff 0x3a, 0x54, 0x5e, 0x38,
542*81f5b20cSNicolas Toromanoff 0x72, 0x76, 0x0a, 0xb7
543*81f5b20cSNicolas Toromanoff },
544*81f5b20cSNicolas Toromanoff .size = U(48),
545*81f5b20cSNicolas Toromanoff },
546*81f5b20cSNicolas Toromanoff .y = {
547*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
548*81f5b20cSNicolas Toromanoff 0x36, 0x17, 0xde, 0x4a,
549*81f5b20cSNicolas Toromanoff 0x96, 0x26, 0x2c, 0x6f,
550*81f5b20cSNicolas Toromanoff 0x5d, 0x9e, 0x98, 0xbf,
551*81f5b20cSNicolas Toromanoff 0x92, 0x92, 0xdc, 0x29,
552*81f5b20cSNicolas Toromanoff 0xf8, 0xf4, 0x1d, 0xbd,
553*81f5b20cSNicolas Toromanoff 0x28, 0x9a, 0x14, 0x7c,
554*81f5b20cSNicolas Toromanoff 0xe9, 0xda, 0x31, 0x13,
555*81f5b20cSNicolas Toromanoff 0xb5, 0xf0, 0xb8, 0xc0,
556*81f5b20cSNicolas Toromanoff 0x0a, 0x60, 0xb1, 0xce,
557*81f5b20cSNicolas Toromanoff 0x1d, 0x7e, 0x81, 0x9d,
558*81f5b20cSNicolas Toromanoff 0x7a, 0x43, 0x1d, 0x7c,
559*81f5b20cSNicolas Toromanoff 0x90, 0xea, 0x0e, 0x5f
560*81f5b20cSNicolas Toromanoff },
561*81f5b20cSNicolas Toromanoff .size = U(48),
562*81f5b20cSNicolas Toromanoff },
563*81f5b20cSNicolas Toromanoff },
564*81f5b20cSNicolas Toromanoff },
565*81f5b20cSNicolas Toromanoff [PKA_NIST_P521] = {
566*81f5b20cSNicolas Toromanoff .p_len = U(521),
567*81f5b20cSNicolas Toromanoff .p = {
568*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
569*81f5b20cSNicolas Toromanoff 0x01, 0xff, 0xff, 0xff,
570*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
571*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
572*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
573*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
574*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
575*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
576*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
577*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
578*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
579*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
580*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
581*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
582*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
583*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
584*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
585*81f5b20cSNicolas Toromanoff 0xff, 0xff
586*81f5b20cSNicolas Toromanoff },
587*81f5b20cSNicolas Toromanoff .size = U(66),
588*81f5b20cSNicolas Toromanoff },
589*81f5b20cSNicolas Toromanoff .n_len = U(521),
590*81f5b20cSNicolas Toromanoff .n = {
591*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
592*81f5b20cSNicolas Toromanoff 0x01, 0xff, 0xff, 0xff,
593*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
594*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
595*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
596*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
597*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
598*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
599*81f5b20cSNicolas Toromanoff 0xff, 0xff, 0xff, 0xff,
600*81f5b20cSNicolas Toromanoff 0xff, 0xfa, 0x51, 0x86,
601*81f5b20cSNicolas Toromanoff 0x87, 0x83, 0xbf, 0x2f,
602*81f5b20cSNicolas Toromanoff 0x96, 0x6b, 0x7f, 0xcc,
603*81f5b20cSNicolas Toromanoff 0x01, 0x48, 0xf7, 0x09,
604*81f5b20cSNicolas Toromanoff 0xa5, 0xd0, 0x3b, 0xb5,
605*81f5b20cSNicolas Toromanoff 0xc9, 0xb8, 0x89, 0x9c,
606*81f5b20cSNicolas Toromanoff 0x47, 0xae, 0xbb, 0x6f,
607*81f5b20cSNicolas Toromanoff 0xb7, 0x1e, 0x91, 0x38,
608*81f5b20cSNicolas Toromanoff 0x64, 0x09
609*81f5b20cSNicolas Toromanoff },
610*81f5b20cSNicolas Toromanoff .size = U(66),
611*81f5b20cSNicolas Toromanoff },
612*81f5b20cSNicolas Toromanoff .a_sign = U(1),
613*81f5b20cSNicolas Toromanoff .a = {
614*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){ 0x03 },
615*81f5b20cSNicolas Toromanoff .size = U(1),
616*81f5b20cSNicolas Toromanoff },
617*81f5b20cSNicolas Toromanoff .b = {
618*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
619*81f5b20cSNicolas Toromanoff 0x51, 0x95, 0x3e, 0xb9,
620*81f5b20cSNicolas Toromanoff 0x61, 0x8e, 0x1c, 0x9a,
621*81f5b20cSNicolas Toromanoff 0x1f, 0x92, 0x9a, 0x21,
622*81f5b20cSNicolas Toromanoff 0xa0, 0xb6, 0x85, 0x40,
623*81f5b20cSNicolas Toromanoff 0xee, 0xa2, 0xda, 0x72,
624*81f5b20cSNicolas Toromanoff 0x5b, 0x99, 0xb3, 0x15,
625*81f5b20cSNicolas Toromanoff 0xf3, 0xb8, 0xb4, 0x89,
626*81f5b20cSNicolas Toromanoff 0x91, 0x8e, 0xf1, 0x09,
627*81f5b20cSNicolas Toromanoff 0xe1, 0x56, 0x19, 0x39,
628*81f5b20cSNicolas Toromanoff 0x51, 0xec, 0x7e, 0x93,
629*81f5b20cSNicolas Toromanoff 0x7b, 0x16, 0x52, 0xc0,
630*81f5b20cSNicolas Toromanoff 0xbd, 0x3b, 0xb1, 0xbf,
631*81f5b20cSNicolas Toromanoff 0x07, 0x35, 0x73, 0xdf,
632*81f5b20cSNicolas Toromanoff 0x88, 0x3d, 0x2c, 0x34,
633*81f5b20cSNicolas Toromanoff 0xf1, 0xef, 0x45, 0x1f,
634*81f5b20cSNicolas Toromanoff 0xd4, 0x6b, 0x50, 0x3f,
635*81f5b20cSNicolas Toromanoff 0x00
636*81f5b20cSNicolas Toromanoff },
637*81f5b20cSNicolas Toromanoff .size = U(65),
638*81f5b20cSNicolas Toromanoff },
639*81f5b20cSNicolas Toromanoff .g = {
640*81f5b20cSNicolas Toromanoff .x = {
641*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
642*81f5b20cSNicolas Toromanoff 0xc6, 0x85, 0x8e, 0x06,
643*81f5b20cSNicolas Toromanoff 0xb7, 0x04, 0x04, 0xe9,
644*81f5b20cSNicolas Toromanoff 0xcd, 0x9e, 0x3e, 0xcb,
645*81f5b20cSNicolas Toromanoff 0x66, 0x23, 0x95, 0xb4,
646*81f5b20cSNicolas Toromanoff 0x42, 0x9c, 0x64, 0x81,
647*81f5b20cSNicolas Toromanoff 0x39, 0x05, 0x3f, 0xb5,
648*81f5b20cSNicolas Toromanoff 0x21, 0xf8, 0x28, 0xaf,
649*81f5b20cSNicolas Toromanoff 0x60, 0x6b, 0x4d, 0x3d,
650*81f5b20cSNicolas Toromanoff 0xba, 0xa1, 0x4b, 0x5e,
651*81f5b20cSNicolas Toromanoff 0x77, 0xef, 0xe7, 0x59,
652*81f5b20cSNicolas Toromanoff 0x28, 0xfe, 0x1d, 0xc1,
653*81f5b20cSNicolas Toromanoff 0x27, 0xa2, 0xff, 0xa8,
654*81f5b20cSNicolas Toromanoff 0xde, 0x33, 0x48, 0xb3,
655*81f5b20cSNicolas Toromanoff 0xc1, 0x85, 0x6a, 0x42,
656*81f5b20cSNicolas Toromanoff 0x9b, 0xf9, 0x7e, 0x7e,
657*81f5b20cSNicolas Toromanoff 0x31, 0xc2, 0xe5, 0xbd,
658*81f5b20cSNicolas Toromanoff 0x66
659*81f5b20cSNicolas Toromanoff },
660*81f5b20cSNicolas Toromanoff .size = U(65),
661*81f5b20cSNicolas Toromanoff },
662*81f5b20cSNicolas Toromanoff .y = {
663*81f5b20cSNicolas Toromanoff .val = (uint8_t[]){
664*81f5b20cSNicolas Toromanoff 0x01, 0x18, 0x39, 0x29,
665*81f5b20cSNicolas Toromanoff 0x6a, 0x78, 0x9a, 0x3b,
666*81f5b20cSNicolas Toromanoff 0xc0, 0x04, 0x5c, 0x8a,
667*81f5b20cSNicolas Toromanoff 0x5f, 0xb4, 0x2c, 0x7d,
668*81f5b20cSNicolas Toromanoff 0x1b, 0xd9, 0x98, 0xf5,
669*81f5b20cSNicolas Toromanoff 0x44, 0x49, 0x57, 0x9b,
670*81f5b20cSNicolas Toromanoff 0x44, 0x68, 0x17, 0xaf,
671*81f5b20cSNicolas Toromanoff 0xbd, 0x17, 0x27, 0x3e,
672*81f5b20cSNicolas Toromanoff 0x66, 0x2c, 0x97, 0xee,
673*81f5b20cSNicolas Toromanoff 0x72, 0x99, 0x5e, 0xf4,
674*81f5b20cSNicolas Toromanoff 0x26, 0x40, 0xc5, 0x50,
675*81f5b20cSNicolas Toromanoff 0xb9, 0x01, 0x3f, 0xad,
676*81f5b20cSNicolas Toromanoff 0x07, 0x61, 0x35, 0x3c,
677*81f5b20cSNicolas Toromanoff 0x70, 0x86, 0xa2, 0x72,
678*81f5b20cSNicolas Toromanoff 0xc2, 0x40, 0x88, 0xbe,
679*81f5b20cSNicolas Toromanoff 0x94, 0x76, 0x9f, 0xd1,
680*81f5b20cSNicolas Toromanoff 0x66, 0x50
681*81f5b20cSNicolas Toromanoff },
682*81f5b20cSNicolas Toromanoff .size = U(66),
683*81f5b20cSNicolas Toromanoff },
684*81f5b20cSNicolas Toromanoff },
685*81f5b20cSNicolas Toromanoff },
686*81f5b20cSNicolas Toromanoff };
687*81f5b20cSNicolas Toromanoff
688*81f5b20cSNicolas Toromanoff struct stm32_pka_platdata {
689*81f5b20cSNicolas Toromanoff vaddr_t base;
690*81f5b20cSNicolas Toromanoff struct clk *clk;
691*81f5b20cSNicolas Toromanoff struct clk *clk_rng;
692*81f5b20cSNicolas Toromanoff struct rstctrl *reset;
693*81f5b20cSNicolas Toromanoff /* Protect PKA HW instance access */
694*81f5b20cSNicolas Toromanoff struct mutex *lock;
695*81f5b20cSNicolas Toromanoff };
696*81f5b20cSNicolas Toromanoff
697*81f5b20cSNicolas Toromanoff static struct stm32_pka_platdata pka_pdata;
698*81f5b20cSNicolas Toromanoff static struct mutex pka_lock = MUTEX_INITIALIZER;
699*81f5b20cSNicolas Toromanoff
pka_wait_bit(const vaddr_t base,const uint32_t bit_mask)700*81f5b20cSNicolas Toromanoff static TEE_Result pka_wait_bit(const vaddr_t base, const uint32_t bit_mask)
701*81f5b20cSNicolas Toromanoff {
702*81f5b20cSNicolas Toromanoff uint32_t value = 0;
703*81f5b20cSNicolas Toromanoff
704*81f5b20cSNicolas Toromanoff if (IO_READ32_POLL_TIMEOUT(base + _PKA_SR, value,
705*81f5b20cSNicolas Toromanoff (value & bit_mask) == bit_mask, 0,
706*81f5b20cSNicolas Toromanoff PKA_TIMEOUT_US)) {
707*81f5b20cSNicolas Toromanoff DMSG("timeout waiting 0x%"PRIx32, bit_mask);
708*81f5b20cSNicolas Toromanoff return TEE_ERROR_BUSY;
709*81f5b20cSNicolas Toromanoff }
710*81f5b20cSNicolas Toromanoff
711*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
712*81f5b20cSNicolas Toromanoff }
713*81f5b20cSNicolas Toromanoff
pka_disable(const vaddr_t base)714*81f5b20cSNicolas Toromanoff static void pka_disable(const vaddr_t base)
715*81f5b20cSNicolas Toromanoff {
716*81f5b20cSNicolas Toromanoff io_clrbits32(base + _PKA_CR, _PKA_CR_EN);
717*81f5b20cSNicolas Toromanoff }
718*81f5b20cSNicolas Toromanoff
pka_enable(const vaddr_t base,const uint32_t mode)719*81f5b20cSNicolas Toromanoff static TEE_Result pka_enable(const vaddr_t base, const uint32_t mode)
720*81f5b20cSNicolas Toromanoff {
721*81f5b20cSNicolas Toromanoff /* Set mode and disable interrupts */
722*81f5b20cSNicolas Toromanoff io_clrsetbits32(base + _PKA_CR, _PKA_IT_MASK | _PKA_CR_MODE_MASK,
723*81f5b20cSNicolas Toromanoff SHIFT_U32(mode, _PKA_CR_MODE_SHIFT));
724*81f5b20cSNicolas Toromanoff
725*81f5b20cSNicolas Toromanoff io_setbits32(base + _PKA_CR, _PKA_CR_EN);
726*81f5b20cSNicolas Toromanoff
727*81f5b20cSNicolas Toromanoff return pka_wait_bit(base, _PKA_SR_INITOK);
728*81f5b20cSNicolas Toromanoff }
729*81f5b20cSNicolas Toromanoff
730*81f5b20cSNicolas Toromanoff /*
731*81f5b20cSNicolas Toromanoff * Data are already loaded in PKA internal RAM,
732*81f5b20cSNicolas Toromanoff * MODE is set,
733*81f5b20cSNicolas Toromanoff * we start process, and wait for its end.
734*81f5b20cSNicolas Toromanoff */
stm32_pka_process(const vaddr_t base)735*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_process(const vaddr_t base)
736*81f5b20cSNicolas Toromanoff {
737*81f5b20cSNicolas Toromanoff io_setbits32(base + _PKA_CR, _PKA_CR_START);
738*81f5b20cSNicolas Toromanoff
739*81f5b20cSNicolas Toromanoff return pka_wait_bit(base, _PKA_IT_PROCEND);
740*81f5b20cSNicolas Toromanoff }
741*81f5b20cSNicolas Toromanoff
742*81f5b20cSNicolas Toromanoff /**
743*81f5b20cSNicolas Toromanoff * Read ECC operand from PKA RAM
744*81f5b20cSNicolas Toromanoff *
745*81f5b20cSNicolas Toromanoff * PKA reads u64 words, for each u64 LSB is bit 0, MSB is bit 63.
746*81f5b20cSNicolas Toromanoff * We read @eo_nbw (ECC operand Size) u64. The value of @eo_nbw depends
747*81f5b20cSNicolas Toromanoff * on the chosen prime modulus length in bits.
748*81f5b20cSNicolas Toromanoff *
749*81f5b20cSNicolas Toromanoff * First less significant u64 is read from lowest address.
750*81f5b20cSNicolas Toromanoff * Last u64 is expected to be equal to 0x0.
751*81f5b20cSNicolas Toromanoff *
752*81f5b20cSNicolas Toromanoff * This function manages:
753*81f5b20cSNicolas Toromanoff * - Endianness (as bswap64 do)
754*81f5b20cSNicolas Toromanoff * - Padding of incomplete u64 with 0 (if @data is not a u64 multiple).
755*81f5b20cSNicolas Toromanoff *
756*81f5b20cSNicolas Toromanoff * @addr: PKA_RAM address to read from to the buffer @data.
757*81f5b20cSNicolas Toromanoff * @data: will be a BYTE list with most significant bytes first.
758*81f5b20cSNicolas Toromanoff * @data_size: [in] @data size,
759*81f5b20cSNicolas Toromanoff * [out] nb of bytes in @data.
760*81f5b20cSNicolas Toromanoff * @eo_nbw: is ECC Operand size in 64-bit words (including the extra 0)
761*81f5b20cSNicolas Toromanoff * (note it depends on the prime modulus length, not the @data size).
762*81f5b20cSNicolas Toromanoff * @return TEE_SUCCESS if OK.
763*81f5b20cSNicolas Toromanoff * TEE_ERROR_SECURITY if the last u64 word is not 0.
764*81f5b20cSNicolas Toromanoff * TEE_ERROR_BAD_PARAMETERS if @data_size and @eo_nbw are inconsistent,
765*81f5b20cSNicolas Toromanoff * i.e. @data doesn't fit in defined @eo_nbw, or @eo_nbw bigger than
766*81f5b20cSNicolas Toromanoff * hardware limit, or if [in]@data_size is too small to get the @data.
767*81f5b20cSNicolas Toromanoff */
read_eo_data(const vaddr_t addr,uint8_t * data,const unsigned int data_size,const unsigned int eo_nbw)768*81f5b20cSNicolas Toromanoff static TEE_Result read_eo_data(const vaddr_t addr, uint8_t *data,
769*81f5b20cSNicolas Toromanoff const unsigned int data_size,
770*81f5b20cSNicolas Toromanoff const unsigned int eo_nbw)
771*81f5b20cSNicolas Toromanoff {
772*81f5b20cSNicolas Toromanoff uint32_t word_index = U(0);
773*81f5b20cSNicolas Toromanoff int data_index = (int)data_size - 1;
774*81f5b20cSNicolas Toromanoff uint64_t tmp = ULL(0);
775*81f5b20cSNicolas Toromanoff
776*81f5b20cSNicolas Toromanoff if (eo_nbw < OP_NBW_FROM_SIZE(data_size) || eo_nbw > MAX_EO_NBW)
777*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
778*81f5b20cSNicolas Toromanoff
779*81f5b20cSNicolas Toromanoff /* Fill value */
780*81f5b20cSNicolas Toromanoff for (word_index = U(0); word_index < eo_nbw - 1; word_index++) {
781*81f5b20cSNicolas Toromanoff /* Index in the tmp U64 word */
782*81f5b20cSNicolas Toromanoff unsigned int i = U(0);
783*81f5b20cSNicolas Toromanoff
784*81f5b20cSNicolas Toromanoff tmp = io_read64(addr + word_index * sizeof(tmp));
785*81f5b20cSNicolas Toromanoff
786*81f5b20cSNicolas Toromanoff while ((i < sizeof(tmp)) && (data_index >= 0)) {
787*81f5b20cSNicolas Toromanoff data[data_index] = tmp & 0xFF;
788*81f5b20cSNicolas Toromanoff tmp = tmp >> INT8_LEN;
789*81f5b20cSNicolas Toromanoff
790*81f5b20cSNicolas Toromanoff /* Move byte index in current (u64)tmp */
791*81f5b20cSNicolas Toromanoff i++;
792*81f5b20cSNicolas Toromanoff
793*81f5b20cSNicolas Toromanoff /* Move to next most significant byte */
794*81f5b20cSNicolas Toromanoff data_index--;
795*81f5b20cSNicolas Toromanoff }
796*81f5b20cSNicolas Toromanoff }
797*81f5b20cSNicolas Toromanoff
798*81f5b20cSNicolas Toromanoff /* The last u64 should be 0 */
799*81f5b20cSNicolas Toromanoff tmp = io_read64(addr + word_index * sizeof(tmp));
800*81f5b20cSNicolas Toromanoff if (tmp)
801*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
802*81f5b20cSNicolas Toromanoff
803*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
804*81f5b20cSNicolas Toromanoff }
805*81f5b20cSNicolas Toromanoff
806*81f5b20cSNicolas Toromanoff /**
807*81f5b20cSNicolas Toromanoff * Write ECC operand to PKA RAM.
808*81f5b20cSNicolas Toromanoff *
809*81f5b20cSNicolas Toromanoff * PKA expects to write u64 words, with each u64 word having the least
810*81f5b20cSNicolas Toromanoff * significant bit as bit 0 and the most significant bit as bit 63.
811*81f5b20cSNicolas Toromanoff * We write @eo_nbw (ECC operand size) u64 words, a value that depends on the
812*81f5b20cSNicolas Toromanoff * chosen prime modulus length in bits.
813*81f5b20cSNicolas Toromanoff *
814*81f5b20cSNicolas Toromanoff * The least significant u64 word is written to the lowest address.
815*81f5b20cSNicolas Toromanoff * Finally, at the last address, we write a u64(0x0).
816*81f5b20cSNicolas Toromanoff *
817*81f5b20cSNicolas Toromanoff * This function manages:
818*81f5b20cSNicolas Toromanoff * - Endianness (as bswap64 does)
819*81f5b20cSNicolas Toromanoff * - Padding incomplete u64 words with 0 (if data is not a u64 multiple)
820*81f5b20cSNicolas Toromanoff * - Filling the last u64 address with 0.
821*81f5b20cSNicolas Toromanoff *
822*81f5b20cSNicolas Toromanoff * @addr: PKA_RAM address to write the buffer 'data'.
823*81f5b20cSNicolas Toromanoff * @data: A byte array with the most significant bytes first.
824*81f5b20cSNicolas Toromanoff * @data_size: Number of bytes in data.
825*81f5b20cSNicolas Toromanoff * @eo_nbw: ECC Operand size in 64-bit words (including the extra 0)
826*81f5b20cSNicolas Toromanoff * (Note: it depends on the prime modulus length, not the data size).
827*81f5b20cSNicolas Toromanoff *
828*81f5b20cSNicolas Toromanoff * @return TEE_SUCCESS if OK.
829*81f5b20cSNicolas Toromanoff * TEE_ERROR_BAD_PARAMETERS if @data_size and @eo_nbw are inconsistent,
830*81f5b20cSNicolas Toromanoff * i.e., @data doesn't fit in defined @eo_nbw, or @eo_nbw is bigger than
831*81f5b20cSNicolas Toromanoff * the hardware limit.
832*81f5b20cSNicolas Toromanoff */
write_eo_data(const vaddr_t addr,const uint8_t * data,const unsigned int data_size,const unsigned int eo_nbw)833*81f5b20cSNicolas Toromanoff static TEE_Result write_eo_data(const vaddr_t addr, const uint8_t *data,
834*81f5b20cSNicolas Toromanoff const unsigned int data_size,
835*81f5b20cSNicolas Toromanoff const unsigned int eo_nbw)
836*81f5b20cSNicolas Toromanoff {
837*81f5b20cSNicolas Toromanoff uint32_t word_index = U(0);
838*81f5b20cSNicolas Toromanoff int data_index = (int)data_size - 1;
839*81f5b20cSNicolas Toromanoff
840*81f5b20cSNicolas Toromanoff if (eo_nbw < OP_NBW_FROM_SIZE(data_size) || eo_nbw > MAX_EO_NBW)
841*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
842*81f5b20cSNicolas Toromanoff
843*81f5b20cSNicolas Toromanoff /* Fill value */
844*81f5b20cSNicolas Toromanoff for (word_index = U(0); word_index < eo_nbw; word_index++) {
845*81f5b20cSNicolas Toromanoff uint64_t tmp = ULL(0);
846*81f5b20cSNicolas Toromanoff /* Index in the tmp U64 word */
847*81f5b20cSNicolas Toromanoff unsigned int i = U(0);
848*81f5b20cSNicolas Toromanoff
849*81f5b20cSNicolas Toromanoff /* Stop if end of tmp or end of data */
850*81f5b20cSNicolas Toromanoff while ((i < sizeof(tmp)) && (data_index >= 0)) {
851*81f5b20cSNicolas Toromanoff tmp |= SHIFT_U64(data[data_index], (INT8_LEN * i));
852*81f5b20cSNicolas Toromanoff /* Move byte index in current (u64)tmp */
853*81f5b20cSNicolas Toromanoff i++;
854*81f5b20cSNicolas Toromanoff /* Move to next most significant byte */
855*81f5b20cSNicolas Toromanoff data_index--;
856*81f5b20cSNicolas Toromanoff }
857*81f5b20cSNicolas Toromanoff
858*81f5b20cSNicolas Toromanoff io_write64(addr + word_index * sizeof(tmp), tmp);
859*81f5b20cSNicolas Toromanoff }
860*81f5b20cSNicolas Toromanoff
861*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
862*81f5b20cSNicolas Toromanoff }
863*81f5b20cSNicolas Toromanoff
get_ecc_op_nbword(const enum stm32_pka_curve_id cid)864*81f5b20cSNicolas Toromanoff static unsigned int get_ecc_op_nbword(const enum stm32_pka_curve_id cid)
865*81f5b20cSNicolas Toromanoff {
866*81f5b20cSNicolas Toromanoff if (cid < 0 || cid >= PKA_LAST_CID)
867*81f5b20cSNicolas Toromanoff return 0;
868*81f5b20cSNicolas Toromanoff
869*81f5b20cSNicolas Toromanoff return OP_NBW_FROM_LEN(curve_def[cid].n_len);
870*81f5b20cSNicolas Toromanoff }
871*81f5b20cSNicolas Toromanoff
stm32_pka_configure_curve(const vaddr_t base,const enum pka_op op,const enum stm32_pka_curve_id cid)872*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_configure_curve(const vaddr_t base,
873*81f5b20cSNicolas Toromanoff const enum pka_op op,
874*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
875*81f5b20cSNicolas Toromanoff {
876*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
877*81f5b20cSNicolas Toromanoff unsigned int eo_nbw = get_ecc_op_nbword(cid);
878*81f5b20cSNicolas Toromanoff
879*81f5b20cSNicolas Toromanoff io_write64(base + pka_ram[op][N_LEN], curve_def[cid].n_len);
880*81f5b20cSNicolas Toromanoff if (pka_ram[op][P_LEN])
881*81f5b20cSNicolas Toromanoff io_write64(base + pka_ram[op][P_LEN], curve_def[cid].p_len);
882*81f5b20cSNicolas Toromanoff
883*81f5b20cSNicolas Toromanoff io_write64(base + pka_ram[op][A_SIGN], curve_def[cid].a_sign);
884*81f5b20cSNicolas Toromanoff
885*81f5b20cSNicolas Toromanoff res = write_eo_data(base + pka_ram[op][COEFF_A], curve_def[cid].a.val,
886*81f5b20cSNicolas Toromanoff curve_def[cid].a.size, eo_nbw);
887*81f5b20cSNicolas Toromanoff if (res)
888*81f5b20cSNicolas Toromanoff return res;
889*81f5b20cSNicolas Toromanoff
890*81f5b20cSNicolas Toromanoff if (pka_ram[op][COEFF_B]) {
891*81f5b20cSNicolas Toromanoff res = write_eo_data(base + pka_ram[op][COEFF_B],
892*81f5b20cSNicolas Toromanoff curve_def[cid].b.val, curve_def[cid].b.size,
893*81f5b20cSNicolas Toromanoff eo_nbw);
894*81f5b20cSNicolas Toromanoff if (res)
895*81f5b20cSNicolas Toromanoff return res;
896*81f5b20cSNicolas Toromanoff }
897*81f5b20cSNicolas Toromanoff
898*81f5b20cSNicolas Toromanoff if (pka_ram[op][PRIME_N]) {
899*81f5b20cSNicolas Toromanoff res = write_eo_data(base + pka_ram[op][PRIME_N],
900*81f5b20cSNicolas Toromanoff curve_def[cid].n.val, curve_def[cid].n.size,
901*81f5b20cSNicolas Toromanoff eo_nbw);
902*81f5b20cSNicolas Toromanoff if (res)
903*81f5b20cSNicolas Toromanoff return res;
904*81f5b20cSNicolas Toromanoff }
905*81f5b20cSNicolas Toromanoff
906*81f5b20cSNicolas Toromanoff res = write_eo_data(base + pka_ram[op][VAL_P], curve_def[cid].p.val,
907*81f5b20cSNicolas Toromanoff curve_def[cid].p.size, eo_nbw);
908*81f5b20cSNicolas Toromanoff if (res)
909*81f5b20cSNicolas Toromanoff return res;
910*81f5b20cSNicolas Toromanoff
911*81f5b20cSNicolas Toromanoff if (pka_ram[op][GPOINT_X]) {
912*81f5b20cSNicolas Toromanoff res = write_eo_data(base + pka_ram[op][GPOINT_X],
913*81f5b20cSNicolas Toromanoff curve_def[cid].g.x.val,
914*81f5b20cSNicolas Toromanoff curve_def[cid].g.x.size, eo_nbw);
915*81f5b20cSNicolas Toromanoff if (res)
916*81f5b20cSNicolas Toromanoff return res;
917*81f5b20cSNicolas Toromanoff }
918*81f5b20cSNicolas Toromanoff
919*81f5b20cSNicolas Toromanoff if (pka_ram[op][GPOINT_Y]) {
920*81f5b20cSNicolas Toromanoff res = write_eo_data(base + pka_ram[op][GPOINT_Y],
921*81f5b20cSNicolas Toromanoff curve_def[cid].g.y.val,
922*81f5b20cSNicolas Toromanoff curve_def[cid].g.y.size, eo_nbw);
923*81f5b20cSNicolas Toromanoff if (res)
924*81f5b20cSNicolas Toromanoff return res;
925*81f5b20cSNicolas Toromanoff }
926*81f5b20cSNicolas Toromanoff
927*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
928*81f5b20cSNicolas Toromanoff }
929*81f5b20cSNicolas Toromanoff
930*81f5b20cSNicolas Toromanoff /**
931*81f5b20cSNicolas Toromanoff * Check if stm32_pka_bn stored is equal to 0
932*81f5b20cSNicolas Toromanoff *
933*81f5b20cSNicolas Toromanoff * @d: Number to test.
934*81f5b20cSNicolas Toromanoff * @return: true: if @d represents a 0 value (i.e. all bytes == 0)
935*81f5b20cSNicolas Toromanoff * false: if @d represents a non-zero value.
936*81f5b20cSNicolas Toromanoff */
is_zero(const struct stm32_pka_bn * d)937*81f5b20cSNicolas Toromanoff static bool is_zero(const struct stm32_pka_bn *d)
938*81f5b20cSNicolas Toromanoff {
939*81f5b20cSNicolas Toromanoff unsigned int i = U(0);
940*81f5b20cSNicolas Toromanoff
941*81f5b20cSNicolas Toromanoff assert(d);
942*81f5b20cSNicolas Toromanoff
943*81f5b20cSNicolas Toromanoff for (i = U(0); i < d->size; i++)
944*81f5b20cSNicolas Toromanoff if (d->val[i] != U(0))
945*81f5b20cSNicolas Toromanoff return false;
946*81f5b20cSNicolas Toromanoff
947*81f5b20cSNicolas Toromanoff return true;
948*81f5b20cSNicolas Toromanoff }
949*81f5b20cSNicolas Toromanoff
950*81f5b20cSNicolas Toromanoff /**
951*81f5b20cSNicolas Toromanoff * Compare two stm32_pka_bn:
952*81f5b20cSNicolas Toromanoff *
953*81f5b20cSNicolas Toromanoff * @a: Number to test.
954*81f5b20cSNicolas Toromanoff * @b: Number to test.
955*81f5b20cSNicolas Toromanoff * @return: true if @a < @b
956*81f5b20cSNicolas Toromanoff * false if @a >= @b
957*81f5b20cSNicolas Toromanoff */
is_smaller(const struct stm32_pka_bn * a,const struct stm32_pka_bn * b)958*81f5b20cSNicolas Toromanoff static bool is_smaller(const struct stm32_pka_bn *a,
959*81f5b20cSNicolas Toromanoff const struct stm32_pka_bn *b)
960*81f5b20cSNicolas Toromanoff {
961*81f5b20cSNicolas Toromanoff unsigned int i = 0;
962*81f5b20cSNicolas Toromanoff
963*81f5b20cSNicolas Toromanoff for (i = MAX(a->size, b->size); i > U(0); i--) {
964*81f5b20cSNicolas Toromanoff uint8_t _a = U(0);
965*81f5b20cSNicolas Toromanoff uint8_t _b = U(0);
966*81f5b20cSNicolas Toromanoff
967*81f5b20cSNicolas Toromanoff if (a->size >= i)
968*81f5b20cSNicolas Toromanoff _a = a->val[a->size - i];
969*81f5b20cSNicolas Toromanoff if (b->size >= i)
970*81f5b20cSNicolas Toromanoff _b = b->val[b->size - i];
971*81f5b20cSNicolas Toromanoff
972*81f5b20cSNicolas Toromanoff if (_a < _b)
973*81f5b20cSNicolas Toromanoff return true;
974*81f5b20cSNicolas Toromanoff if (_a > _b)
975*81f5b20cSNicolas Toromanoff return false;
976*81f5b20cSNicolas Toromanoff }
977*81f5b20cSNicolas Toromanoff
978*81f5b20cSNicolas Toromanoff return false;
979*81f5b20cSNicolas Toromanoff }
980*81f5b20cSNicolas Toromanoff
stm32_pka_get_max_size(size_t * bytes,size_t * bits,const enum stm32_pka_curve_id cid)981*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_get_max_size(size_t *bytes, size_t *bits,
982*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
983*81f5b20cSNicolas Toromanoff {
984*81f5b20cSNicolas Toromanoff if (cid < 0 || cid >= PKA_LAST_CID)
985*81f5b20cSNicolas Toromanoff return TEE_ERROR_NOT_SUPPORTED;
986*81f5b20cSNicolas Toromanoff
987*81f5b20cSNicolas Toromanoff if (bits)
988*81f5b20cSNicolas Toromanoff *bits = curve_def[cid].n_len;
989*81f5b20cSNicolas Toromanoff
990*81f5b20cSNicolas Toromanoff if (bytes)
991*81f5b20cSNicolas Toromanoff *bytes = curve_def[cid].n.size;
992*81f5b20cSNicolas Toromanoff
993*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
994*81f5b20cSNicolas Toromanoff }
995*81f5b20cSNicolas Toromanoff
stm32_pka_compute_r2modn_ret(const vaddr_t base,struct stm32_pka_bn * v,const unsigned int eo_nbw)996*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_compute_r2modn_ret(const vaddr_t base,
997*81f5b20cSNicolas Toromanoff struct stm32_pka_bn *v,
998*81f5b20cSNicolas Toromanoff const unsigned int eo_nbw)
999*81f5b20cSNicolas Toromanoff {
1000*81f5b20cSNicolas Toromanoff uint32_t sr = U(0);
1001*81f5b20cSNicolas Toromanoff
1002*81f5b20cSNicolas Toromanoff sr = io_read32(base + _PKA_SR);
1003*81f5b20cSNicolas Toromanoff if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
1004*81f5b20cSNicolas Toromanoff EMSG("Detected error(s): %s%s%s",
1005*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_OPERR) ? "Operation " : "",
1006*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_ADDRERR) ? "Address " : "",
1007*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_RAMERR) ? "RAM" : "");
1008*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
1009*81f5b20cSNicolas Toromanoff }
1010*81f5b20cSNicolas Toromanoff
1011*81f5b20cSNicolas Toromanoff return read_eo_data(base + _PKA_RAM_R2MODN_OUT, v->val, v->size,
1012*81f5b20cSNicolas Toromanoff eo_nbw);
1013*81f5b20cSNicolas Toromanoff }
1014*81f5b20cSNicolas Toromanoff
stm32_pka_compute_montgomery(const struct stm32_pka_bn * n,const size_t n_len,struct stm32_pka_bn * r2modn)1015*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_compute_montgomery(const struct stm32_pka_bn *n,
1016*81f5b20cSNicolas Toromanoff const size_t n_len,
1017*81f5b20cSNicolas Toromanoff struct stm32_pka_bn *r2modn)
1018*81f5b20cSNicolas Toromanoff {
1019*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1020*81f5b20cSNicolas Toromanoff vaddr_t base = pka_pdata.base;
1021*81f5b20cSNicolas Toromanoff unsigned int eo_nbw = OP_NBW_FROM_LEN(n_len);
1022*81f5b20cSNicolas Toromanoff
1023*81f5b20cSNicolas Toromanoff if (!n_len || !n || !r2modn)
1024*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1025*81f5b20cSNicolas Toromanoff
1026*81f5b20cSNicolas Toromanoff mutex_lock(pka_pdata.lock);
1027*81f5b20cSNicolas Toromanoff
1028*81f5b20cSNicolas Toromanoff if ((io_read32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
1029*81f5b20cSNicolas Toromanoff EMSG("PKA is busy");
1030*81f5b20cSNicolas Toromanoff res = TEE_ERROR_BUSY;
1031*81f5b20cSNicolas Toromanoff goto out;
1032*81f5b20cSNicolas Toromanoff }
1033*81f5b20cSNicolas Toromanoff
1034*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with n_len */
1035*81f5b20cSNicolas Toromanoff io_write64(base + _PKA_RAM_R2MODN_N_LEN, n_len);
1036*81f5b20cSNicolas Toromanoff
1037*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with n */
1038*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_R2MODN_PRIME_N, n->val, n->size,
1039*81f5b20cSNicolas Toromanoff eo_nbw);
1040*81f5b20cSNicolas Toromanoff if (res)
1041*81f5b20cSNicolas Toromanoff goto out;
1042*81f5b20cSNicolas Toromanoff
1043*81f5b20cSNicolas Toromanoff /* Set mode to Montgomery parameter computation */
1044*81f5b20cSNicolas Toromanoff res = pka_enable(base, _PKA_CR_MODE_R2MODN);
1045*81f5b20cSNicolas Toromanoff if (res) {
1046*81f5b20cSNicolas Toromanoff EMSG("Set mode pka error %"PRIx32, res);
1047*81f5b20cSNicolas Toromanoff goto out;
1048*81f5b20cSNicolas Toromanoff }
1049*81f5b20cSNicolas Toromanoff
1050*81f5b20cSNicolas Toromanoff /* Start processing and wait end */
1051*81f5b20cSNicolas Toromanoff res = stm32_pka_process(base);
1052*81f5b20cSNicolas Toromanoff if (res) {
1053*81f5b20cSNicolas Toromanoff EMSG("process error %"PRIx32, res);
1054*81f5b20cSNicolas Toromanoff goto out;
1055*81f5b20cSNicolas Toromanoff }
1056*81f5b20cSNicolas Toromanoff
1057*81f5b20cSNicolas Toromanoff /* Get return value */
1058*81f5b20cSNicolas Toromanoff res = stm32_pka_compute_r2modn_ret(base, r2modn, eo_nbw);
1059*81f5b20cSNicolas Toromanoff
1060*81f5b20cSNicolas Toromanoff /* Unset end proc */
1061*81f5b20cSNicolas Toromanoff io_setbits32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
1062*81f5b20cSNicolas Toromanoff
1063*81f5b20cSNicolas Toromanoff out:
1064*81f5b20cSNicolas Toromanoff /* Disable PKA (will stop all pending process and reset RAM) */
1065*81f5b20cSNicolas Toromanoff pka_disable(base);
1066*81f5b20cSNicolas Toromanoff
1067*81f5b20cSNicolas Toromanoff mutex_unlock(pka_pdata.lock);
1068*81f5b20cSNicolas Toromanoff
1069*81f5b20cSNicolas Toromanoff return res;
1070*81f5b20cSNicolas Toromanoff }
1071*81f5b20cSNicolas Toromanoff
stm32_pka_ecc_compute_montgomery(struct stm32_pka_bn * r2modn,const enum stm32_pka_curve_id cid)1072*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_ecc_compute_montgomery(struct stm32_pka_bn *r2modn,
1073*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1074*81f5b20cSNicolas Toromanoff {
1075*81f5b20cSNicolas Toromanoff return stm32_pka_compute_montgomery(&curve_def[cid].p,
1076*81f5b20cSNicolas Toromanoff curve_def[cid].p_len, r2modn);
1077*81f5b20cSNicolas Toromanoff }
1078*81f5b20cSNicolas Toromanoff
stm32_pka_is_point_on_param(const struct stm32_pka_point * p,enum stm32_pka_curve_id cid)1079*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_is_point_on_param(const struct stm32_pka_point *p,
1080*81f5b20cSNicolas Toromanoff enum stm32_pka_curve_id cid)
1081*81f5b20cSNicolas Toromanoff {
1082*81f5b20cSNicolas Toromanoff /* Check Xp < p */
1083*81f5b20cSNicolas Toromanoff if (!is_smaller(&p->x, &curve_def[cid].p)) {
1084*81f5b20cSNicolas Toromanoff EMSG("Xp < p inval");
1085*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1086*81f5b20cSNicolas Toromanoff }
1087*81f5b20cSNicolas Toromanoff
1088*81f5b20cSNicolas Toromanoff /* Check Yp < p */
1089*81f5b20cSNicolas Toromanoff if (!is_smaller(&p->y, &curve_def[cid].p)) {
1090*81f5b20cSNicolas Toromanoff EMSG("Yp < p inval");
1091*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1092*81f5b20cSNicolas Toromanoff }
1093*81f5b20cSNicolas Toromanoff
1094*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1095*81f5b20cSNicolas Toromanoff }
1096*81f5b20cSNicolas Toromanoff
stm32_pka_is_point_on_curve_ret(const vaddr_t base)1097*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_is_point_on_curve_ret(const vaddr_t base)
1098*81f5b20cSNicolas Toromanoff {
1099*81f5b20cSNicolas Toromanoff uint64_t value = ULL(0);
1100*81f5b20cSNicolas Toromanoff uint32_t sr = U(0);
1101*81f5b20cSNicolas Toromanoff
1102*81f5b20cSNicolas Toromanoff sr = io_read32(base + _PKA_SR);
1103*81f5b20cSNicolas Toromanoff if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
1104*81f5b20cSNicolas Toromanoff EMSG("Detected error(s): %s%s%s",
1105*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_OPERR) ? "Operation " : "",
1106*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_ADDRERR) ? "Address " : "",
1107*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_RAMERR) ? "RAM" : "");
1108*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
1109*81f5b20cSNicolas Toromanoff }
1110*81f5b20cSNicolas Toromanoff
1111*81f5b20cSNicolas Toromanoff value = io_read64(base + _PKA_RAM_ONCURVE_RES);
1112*81f5b20cSNicolas Toromanoff if (value == _PKA_RAM_ONCURVE_RES_YES)
1113*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1114*81f5b20cSNicolas Toromanoff else
1115*81f5b20cSNicolas Toromanoff return TEE_ERROR_GENERIC;
1116*81f5b20cSNicolas Toromanoff }
1117*81f5b20cSNicolas Toromanoff
stm32_pka_is_point_on_curve(const struct stm32_pka_point * p,const struct stm32_pka_bn * r2modn,const enum stm32_pka_curve_id cid)1118*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_is_point_on_curve(const struct stm32_pka_point *p,
1119*81f5b20cSNicolas Toromanoff const struct stm32_pka_bn *r2modn,
1120*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1121*81f5b20cSNicolas Toromanoff {
1122*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1123*81f5b20cSNicolas Toromanoff vaddr_t base = pka_pdata.base;
1124*81f5b20cSNicolas Toromanoff unsigned int eo_nbw = get_ecc_op_nbword(cid);
1125*81f5b20cSNicolas Toromanoff
1126*81f5b20cSNicolas Toromanoff if (!eo_nbw || !p)
1127*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1128*81f5b20cSNicolas Toromanoff
1129*81f5b20cSNicolas Toromanoff mutex_lock(pka_pdata.lock);
1130*81f5b20cSNicolas Toromanoff
1131*81f5b20cSNicolas Toromanoff res = stm32_pka_is_point_on_param(p, cid);
1132*81f5b20cSNicolas Toromanoff if (res) {
1133*81f5b20cSNicolas Toromanoff EMSG("check param error %"PRIx32, res);
1134*81f5b20cSNicolas Toromanoff goto out;
1135*81f5b20cSNicolas Toromanoff }
1136*81f5b20cSNicolas Toromanoff
1137*81f5b20cSNicolas Toromanoff if ((io_read32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
1138*81f5b20cSNicolas Toromanoff EMSG("PKA is busy");
1139*81f5b20cSNicolas Toromanoff res = TEE_ERROR_BUSY;
1140*81f5b20cSNicolas Toromanoff goto out;
1141*81f5b20cSNicolas Toromanoff }
1142*81f5b20cSNicolas Toromanoff
1143*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with curve id values */
1144*81f5b20cSNicolas Toromanoff res = stm32_pka_configure_curve(base, ON_CURVE, cid);
1145*81f5b20cSNicolas Toromanoff if (res)
1146*81f5b20cSNicolas Toromanoff goto out;
1147*81f5b20cSNicolas Toromanoff
1148*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with Montgomery parameter R*R mod n */
1149*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_ONCURVE_R2MODN, r2modn->val,
1150*81f5b20cSNicolas Toromanoff r2modn->size, eo_nbw);
1151*81f5b20cSNicolas Toromanoff if (res)
1152*81f5b20cSNicolas Toromanoff goto out;
1153*81f5b20cSNicolas Toromanoff
1154*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with P */
1155*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_ONCURVE_XP, p->x.val, p->x.size,
1156*81f5b20cSNicolas Toromanoff eo_nbw);
1157*81f5b20cSNicolas Toromanoff if (res)
1158*81f5b20cSNicolas Toromanoff goto out;
1159*81f5b20cSNicolas Toromanoff
1160*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_ONCURVE_YP, p->y.val, p->y.size,
1161*81f5b20cSNicolas Toromanoff eo_nbw);
1162*81f5b20cSNicolas Toromanoff if (res)
1163*81f5b20cSNicolas Toromanoff goto out;
1164*81f5b20cSNicolas Toromanoff
1165*81f5b20cSNicolas Toromanoff /* Set mode to point on the curve check */
1166*81f5b20cSNicolas Toromanoff res = pka_enable(base, _PKA_CR_MODE_POINT_CHECK);
1167*81f5b20cSNicolas Toromanoff if (res) {
1168*81f5b20cSNicolas Toromanoff EMSG("Set mode pka error %"PRIx32, res);
1169*81f5b20cSNicolas Toromanoff goto out;
1170*81f5b20cSNicolas Toromanoff }
1171*81f5b20cSNicolas Toromanoff
1172*81f5b20cSNicolas Toromanoff /* Start processing and wait end */
1173*81f5b20cSNicolas Toromanoff res = stm32_pka_process(base);
1174*81f5b20cSNicolas Toromanoff if (res) {
1175*81f5b20cSNicolas Toromanoff EMSG("process error %"PRIx32, res);
1176*81f5b20cSNicolas Toromanoff goto out;
1177*81f5b20cSNicolas Toromanoff }
1178*81f5b20cSNicolas Toromanoff
1179*81f5b20cSNicolas Toromanoff /* Get return value */
1180*81f5b20cSNicolas Toromanoff res = stm32_pka_is_point_on_curve_ret(base);
1181*81f5b20cSNicolas Toromanoff
1182*81f5b20cSNicolas Toromanoff /* Unset end proc */
1183*81f5b20cSNicolas Toromanoff io_setbits32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
1184*81f5b20cSNicolas Toromanoff
1185*81f5b20cSNicolas Toromanoff out:
1186*81f5b20cSNicolas Toromanoff /* Disable PKA (will stop all pending process and reset RAM) */
1187*81f5b20cSNicolas Toromanoff pka_disable(base);
1188*81f5b20cSNicolas Toromanoff
1189*81f5b20cSNicolas Toromanoff mutex_unlock(pka_pdata.lock);
1190*81f5b20cSNicolas Toromanoff
1191*81f5b20cSNicolas Toromanoff return res;
1192*81f5b20cSNicolas Toromanoff }
1193*81f5b20cSNicolas Toromanoff
stm32_pka_ecdsa_verif_param(const struct stm32_pka_bn * sig_r,const struct stm32_pka_bn * sig_s,const struct stm32_pka_point * pk,const enum stm32_pka_curve_id cid)1194*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_ecdsa_verif_param(const struct stm32_pka_bn *sig_r,
1195*81f5b20cSNicolas Toromanoff const struct stm32_pka_bn *sig_s,
1196*81f5b20cSNicolas Toromanoff const struct stm32_pka_point *pk,
1197*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1198*81f5b20cSNicolas Toromanoff {
1199*81f5b20cSNicolas Toromanoff /* Public Key check */
1200*81f5b20cSNicolas Toromanoff /* Check Xq < p */
1201*81f5b20cSNicolas Toromanoff if (!is_smaller(&pk->x, &curve_def[cid].p)) {
1202*81f5b20cSNicolas Toromanoff EMSG("Xq < p inval");
1203*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1204*81f5b20cSNicolas Toromanoff }
1205*81f5b20cSNicolas Toromanoff
1206*81f5b20cSNicolas Toromanoff /* Check Yq < p */
1207*81f5b20cSNicolas Toromanoff if (!is_smaller(&pk->y, &curve_def[cid].p)) {
1208*81f5b20cSNicolas Toromanoff EMSG("Yq < p inval");
1209*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1210*81f5b20cSNicolas Toromanoff }
1211*81f5b20cSNicolas Toromanoff
1212*81f5b20cSNicolas Toromanoff /* Signature check */
1213*81f5b20cSNicolas Toromanoff /* Check 0 < r < n */
1214*81f5b20cSNicolas Toromanoff if (!is_smaller(sig_r, &curve_def[cid].n) || is_zero(sig_r)) {
1215*81f5b20cSNicolas Toromanoff EMSG("0 < r < n invalid");
1216*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1217*81f5b20cSNicolas Toromanoff }
1218*81f5b20cSNicolas Toromanoff
1219*81f5b20cSNicolas Toromanoff /* Check 0 < s < n */
1220*81f5b20cSNicolas Toromanoff if (!is_smaller(sig_s, &curve_def[cid].n) || is_zero(sig_s)) {
1221*81f5b20cSNicolas Toromanoff EMSG("0 < s < n invalid");
1222*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1223*81f5b20cSNicolas Toromanoff }
1224*81f5b20cSNicolas Toromanoff
1225*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1226*81f5b20cSNicolas Toromanoff }
1227*81f5b20cSNicolas Toromanoff
stm32_pka_ecdsa_verif_ret(const vaddr_t base)1228*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_ecdsa_verif_ret(const vaddr_t base)
1229*81f5b20cSNicolas Toromanoff {
1230*81f5b20cSNicolas Toromanoff uint64_t value = ULL(0);
1231*81f5b20cSNicolas Toromanoff uint32_t sr = U(0);
1232*81f5b20cSNicolas Toromanoff
1233*81f5b20cSNicolas Toromanoff sr = io_read32(base + _PKA_SR);
1234*81f5b20cSNicolas Toromanoff if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
1235*81f5b20cSNicolas Toromanoff EMSG("Detected error(s): %s%s%s",
1236*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_OPERR) ? "Operation " : "",
1237*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_ADDRERR) ? "Address " : "",
1238*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_RAMERR) ? "RAM" : "");
1239*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
1240*81f5b20cSNicolas Toromanoff }
1241*81f5b20cSNicolas Toromanoff
1242*81f5b20cSNicolas Toromanoff value = io_read64(base + _PKA_RAM_VERIF_RES);
1243*81f5b20cSNicolas Toromanoff if (value == _PKA_RAM_VERIF_RES_VALID)
1244*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1245*81f5b20cSNicolas Toromanoff
1246*81f5b20cSNicolas Toromanoff if (value == _PKA_RAM_VERIF_RES_INVALID)
1247*81f5b20cSNicolas Toromanoff return TEE_ERROR_SIGNATURE_INVALID;
1248*81f5b20cSNicolas Toromanoff
1249*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1250*81f5b20cSNicolas Toromanoff }
1251*81f5b20cSNicolas Toromanoff
stm32_pka_ecdsa_verif(const void * hash,unsigned int hash_size,const struct stm32_pka_bn * sig_r,const struct stm32_pka_bn * sig_s,const struct stm32_pka_point * pk,const enum stm32_pka_curve_id cid)1252*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_ecdsa_verif(const void *hash, unsigned int hash_size,
1253*81f5b20cSNicolas Toromanoff const struct stm32_pka_bn *sig_r,
1254*81f5b20cSNicolas Toromanoff const struct stm32_pka_bn *sig_s,
1255*81f5b20cSNicolas Toromanoff const struct stm32_pka_point *pk,
1256*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1257*81f5b20cSNicolas Toromanoff {
1258*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1259*81f5b20cSNicolas Toromanoff uint32_t n_len_bytes = curve_def[cid].n_len / INT8_LEN;
1260*81f5b20cSNicolas Toromanoff vaddr_t base = pka_pdata.base;
1261*81f5b20cSNicolas Toromanoff unsigned int eo_nbw = get_ecc_op_nbword(cid);
1262*81f5b20cSNicolas Toromanoff
1263*81f5b20cSNicolas Toromanoff if (!eo_nbw || !hash || !sig_r || !sig_s || !pk)
1264*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1265*81f5b20cSNicolas Toromanoff
1266*81f5b20cSNicolas Toromanoff mutex_lock(pka_pdata.lock);
1267*81f5b20cSNicolas Toromanoff
1268*81f5b20cSNicolas Toromanoff res = stm32_pka_ecdsa_verif_param(sig_r, sig_s, pk, cid);
1269*81f5b20cSNicolas Toromanoff if (res) {
1270*81f5b20cSNicolas Toromanoff EMSG("check param error %"PRIx32, res);
1271*81f5b20cSNicolas Toromanoff goto out;
1272*81f5b20cSNicolas Toromanoff }
1273*81f5b20cSNicolas Toromanoff
1274*81f5b20cSNicolas Toromanoff if ((io_read32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
1275*81f5b20cSNicolas Toromanoff EMSG("PKA is busy");
1276*81f5b20cSNicolas Toromanoff res = TEE_ERROR_BUSY;
1277*81f5b20cSNicolas Toromanoff goto out;
1278*81f5b20cSNicolas Toromanoff }
1279*81f5b20cSNicolas Toromanoff
1280*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with curve id values */
1281*81f5b20cSNicolas Toromanoff res = stm32_pka_configure_curve(base, VERIF, cid);
1282*81f5b20cSNicolas Toromanoff if (res)
1283*81f5b20cSNicolas Toromanoff goto out;
1284*81f5b20cSNicolas Toromanoff
1285*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with pubkey */
1286*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_VERIF_XQ, pk->x.val, pk->x.size,
1287*81f5b20cSNicolas Toromanoff eo_nbw);
1288*81f5b20cSNicolas Toromanoff if (res)
1289*81f5b20cSNicolas Toromanoff goto out;
1290*81f5b20cSNicolas Toromanoff
1291*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_VERIF_YQ, pk->y.val, pk->y.size,
1292*81f5b20cSNicolas Toromanoff eo_nbw);
1293*81f5b20cSNicolas Toromanoff if (res)
1294*81f5b20cSNicolas Toromanoff goto out;
1295*81f5b20cSNicolas Toromanoff
1296*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with hash */
1297*81f5b20cSNicolas Toromanoff if (n_len_bytes < hash_size) {
1298*81f5b20cSNicolas Toromanoff /*
1299*81f5b20cSNicolas Toromanoff * Hash size is greater than ECDSA prime curve size.
1300*81f5b20cSNicolas Toromanoff * Truncate hash and use leftmost bits of the hash.
1301*81f5b20cSNicolas Toromanoff * NIST.FIPS.186-5.pdf
1302*81f5b20cSNicolas Toromanoff */
1303*81f5b20cSNicolas Toromanoff hash_size = n_len_bytes;
1304*81f5b20cSNicolas Toromanoff }
1305*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_VERIF_HASH_Z, hash, hash_size,
1306*81f5b20cSNicolas Toromanoff eo_nbw);
1307*81f5b20cSNicolas Toromanoff if (res)
1308*81f5b20cSNicolas Toromanoff goto out;
1309*81f5b20cSNicolas Toromanoff
1310*81f5b20cSNicolas Toromanoff /* Fill PKA RAM with signature */
1311*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_VERIF_SIGN_R, sig_r->val,
1312*81f5b20cSNicolas Toromanoff sig_r->size, eo_nbw);
1313*81f5b20cSNicolas Toromanoff if (res)
1314*81f5b20cSNicolas Toromanoff goto out;
1315*81f5b20cSNicolas Toromanoff
1316*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_VERIF_SIGN_S, sig_s->val,
1317*81f5b20cSNicolas Toromanoff sig_s->size, eo_nbw);
1318*81f5b20cSNicolas Toromanoff if (res)
1319*81f5b20cSNicolas Toromanoff goto out;
1320*81f5b20cSNicolas Toromanoff
1321*81f5b20cSNicolas Toromanoff /* Set mode to ECDSA signature verification */
1322*81f5b20cSNicolas Toromanoff res = pka_enable(base, _PKA_CR_MODE_ECDSA_VERIF);
1323*81f5b20cSNicolas Toromanoff if (res) {
1324*81f5b20cSNicolas Toromanoff EMSG("set mode pka error %"PRIx32, res);
1325*81f5b20cSNicolas Toromanoff goto out;
1326*81f5b20cSNicolas Toromanoff }
1327*81f5b20cSNicolas Toromanoff
1328*81f5b20cSNicolas Toromanoff /* Start processing and wait end */
1329*81f5b20cSNicolas Toromanoff res = stm32_pka_process(base);
1330*81f5b20cSNicolas Toromanoff if (res) {
1331*81f5b20cSNicolas Toromanoff EMSG("process error %"PRIx32, res);
1332*81f5b20cSNicolas Toromanoff goto out;
1333*81f5b20cSNicolas Toromanoff }
1334*81f5b20cSNicolas Toromanoff
1335*81f5b20cSNicolas Toromanoff /* Check return status */
1336*81f5b20cSNicolas Toromanoff res = stm32_pka_ecdsa_verif_ret(base);
1337*81f5b20cSNicolas Toromanoff
1338*81f5b20cSNicolas Toromanoff /* Unset end proc */
1339*81f5b20cSNicolas Toromanoff io_setbits32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
1340*81f5b20cSNicolas Toromanoff
1341*81f5b20cSNicolas Toromanoff out:
1342*81f5b20cSNicolas Toromanoff /* Disable PKA (will stop all pending process and reset RAM) */
1343*81f5b20cSNicolas Toromanoff pka_disable(base);
1344*81f5b20cSNicolas Toromanoff
1345*81f5b20cSNicolas Toromanoff mutex_unlock(pka_pdata.lock);
1346*81f5b20cSNicolas Toromanoff
1347*81f5b20cSNicolas Toromanoff return res;
1348*81f5b20cSNicolas Toromanoff }
1349*81f5b20cSNicolas Toromanoff
stm32_pka_ecdsa_sign_param(const struct stm32_pka_bn * k)1350*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_ecdsa_sign_param(const struct stm32_pka_bn *k)
1351*81f5b20cSNicolas Toromanoff {
1352*81f5b20cSNicolas Toromanoff if (k->size > PKA_MAX_ECC_SIZE) {
1353*81f5b20cSNicolas Toromanoff EMSG("0 <= k < 2**640 invalid");
1354*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1355*81f5b20cSNicolas Toromanoff }
1356*81f5b20cSNicolas Toromanoff
1357*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1358*81f5b20cSNicolas Toromanoff }
1359*81f5b20cSNicolas Toromanoff
stm32_pka_ecdsa_sign_ret(const vaddr_t base,struct stm32_pka_bn * sig_r,struct stm32_pka_bn * sig_s,const unsigned int eo_nbw)1360*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_ecdsa_sign_ret(const vaddr_t base,
1361*81f5b20cSNicolas Toromanoff struct stm32_pka_bn *sig_r,
1362*81f5b20cSNicolas Toromanoff struct stm32_pka_bn *sig_s,
1363*81f5b20cSNicolas Toromanoff const unsigned int eo_nbw)
1364*81f5b20cSNicolas Toromanoff {
1365*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1366*81f5b20cSNicolas Toromanoff uint64_t value = ULL(0);
1367*81f5b20cSNicolas Toromanoff uint32_t sr = U(0);
1368*81f5b20cSNicolas Toromanoff
1369*81f5b20cSNicolas Toromanoff sr = io_read32(base + _PKA_SR);
1370*81f5b20cSNicolas Toromanoff if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
1371*81f5b20cSNicolas Toromanoff EMSG("Detected error(s): %s%s%s",
1372*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_OPERR) ? "Operation " : "",
1373*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_ADDRERR) ? "Address " : "",
1374*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_RAMERR) ? "RAM" : "");
1375*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
1376*81f5b20cSNicolas Toromanoff }
1377*81f5b20cSNicolas Toromanoff
1378*81f5b20cSNicolas Toromanoff value = io_read64(base + _PKA_RAM_SIGN_RES);
1379*81f5b20cSNicolas Toromanoff
1380*81f5b20cSNicolas Toromanoff if (value == _PKA_RAM_SIGN_RES_FAIL)
1381*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
1382*81f5b20cSNicolas Toromanoff
1383*81f5b20cSNicolas Toromanoff if (value == _PKA_RAM_SIGN_RES_R0) {
1384*81f5b20cSNicolas Toromanoff value = _PKA_RAM_SIGN_RES_SUCCESS;
1385*81f5b20cSNicolas Toromanoff memset(sig_r->val, 0, sig_r->size);
1386*81f5b20cSNicolas Toromanoff } else {
1387*81f5b20cSNicolas Toromanoff res = read_eo_data(base + _PKA_RAM_SIGN_R, sig_r->val,
1388*81f5b20cSNicolas Toromanoff sig_r->size, eo_nbw);
1389*81f5b20cSNicolas Toromanoff if (res)
1390*81f5b20cSNicolas Toromanoff return res;
1391*81f5b20cSNicolas Toromanoff }
1392*81f5b20cSNicolas Toromanoff
1393*81f5b20cSNicolas Toromanoff if (value == _PKA_RAM_SIGN_RES_S0) {
1394*81f5b20cSNicolas Toromanoff value = _PKA_RAM_SIGN_RES_SUCCESS;
1395*81f5b20cSNicolas Toromanoff memset(sig_s->val, 0, sig_s->size);
1396*81f5b20cSNicolas Toromanoff } else {
1397*81f5b20cSNicolas Toromanoff res = read_eo_data(base + _PKA_RAM_SIGN_S, sig_s->val,
1398*81f5b20cSNicolas Toromanoff sig_s->size, eo_nbw);
1399*81f5b20cSNicolas Toromanoff if (res)
1400*81f5b20cSNicolas Toromanoff return res;
1401*81f5b20cSNicolas Toromanoff }
1402*81f5b20cSNicolas Toromanoff
1403*81f5b20cSNicolas Toromanoff if (value != _PKA_RAM_SIGN_RES_SUCCESS)
1404*81f5b20cSNicolas Toromanoff return TEE_ERROR_GENERIC;
1405*81f5b20cSNicolas Toromanoff
1406*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1407*81f5b20cSNicolas Toromanoff }
1408*81f5b20cSNicolas Toromanoff
stm32_pka_ecdsa_sign(const void * hash,unsigned int hash_size,struct stm32_pka_bn * sig_r,struct stm32_pka_bn * sig_s,const struct stm32_pka_bn * d,const struct stm32_pka_bn * k,const enum stm32_pka_curve_id cid)1409*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_ecdsa_sign(const void *hash, unsigned int hash_size,
1410*81f5b20cSNicolas Toromanoff struct stm32_pka_bn *sig_r,
1411*81f5b20cSNicolas Toromanoff struct stm32_pka_bn *sig_s,
1412*81f5b20cSNicolas Toromanoff const struct stm32_pka_bn *d,
1413*81f5b20cSNicolas Toromanoff const struct stm32_pka_bn *k,
1414*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1415*81f5b20cSNicolas Toromanoff {
1416*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1417*81f5b20cSNicolas Toromanoff uint32_t n_len_bytes = curve_def[cid].n_len / INT8_LEN;
1418*81f5b20cSNicolas Toromanoff vaddr_t base = pka_pdata.base;
1419*81f5b20cSNicolas Toromanoff unsigned int eo_nbw = get_ecc_op_nbword(cid);
1420*81f5b20cSNicolas Toromanoff
1421*81f5b20cSNicolas Toromanoff if (!eo_nbw || !hash || !sig_r || !sig_s || !d || !k)
1422*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1423*81f5b20cSNicolas Toromanoff
1424*81f5b20cSNicolas Toromanoff mutex_lock(pka_pdata.lock);
1425*81f5b20cSNicolas Toromanoff
1426*81f5b20cSNicolas Toromanoff res = stm32_pka_ecdsa_sign_param(k);
1427*81f5b20cSNicolas Toromanoff if (res) {
1428*81f5b20cSNicolas Toromanoff EMSG("check param error %"PRIx32, res);
1429*81f5b20cSNicolas Toromanoff goto out;
1430*81f5b20cSNicolas Toromanoff }
1431*81f5b20cSNicolas Toromanoff
1432*81f5b20cSNicolas Toromanoff if ((io_read32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
1433*81f5b20cSNicolas Toromanoff EMSG("PKA is busy");
1434*81f5b20cSNicolas Toromanoff res = TEE_ERROR_BUSY;
1435*81f5b20cSNicolas Toromanoff goto out;
1436*81f5b20cSNicolas Toromanoff }
1437*81f5b20cSNicolas Toromanoff
1438*81f5b20cSNicolas Toromanoff /* Fill PKA RAM */
1439*81f5b20cSNicolas Toromanoff /* With curve id values */
1440*81f5b20cSNicolas Toromanoff res = stm32_pka_configure_curve(base, SIGN, cid);
1441*81f5b20cSNicolas Toromanoff if (res)
1442*81f5b20cSNicolas Toromanoff goto out;
1443*81f5b20cSNicolas Toromanoff
1444*81f5b20cSNicolas Toromanoff /* With K (random number) */
1445*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_SIGN_K, k->val, k->size, eo_nbw);
1446*81f5b20cSNicolas Toromanoff if (res)
1447*81f5b20cSNicolas Toromanoff goto out;
1448*81f5b20cSNicolas Toromanoff
1449*81f5b20cSNicolas Toromanoff /* With private key d */
1450*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_SIGN_D, d->val, d->size, eo_nbw);
1451*81f5b20cSNicolas Toromanoff if (res)
1452*81f5b20cSNicolas Toromanoff goto out;
1453*81f5b20cSNicolas Toromanoff
1454*81f5b20cSNicolas Toromanoff /* With hash */
1455*81f5b20cSNicolas Toromanoff if (n_len_bytes < hash_size) {
1456*81f5b20cSNicolas Toromanoff /*
1457*81f5b20cSNicolas Toromanoff * Hash size is greater than ECDSA prime curve size.
1458*81f5b20cSNicolas Toromanoff * Truncate hash and use leftmost bits of the hash.
1459*81f5b20cSNicolas Toromanoff * NIST.FIPS.186-4.pdf
1460*81f5b20cSNicolas Toromanoff */
1461*81f5b20cSNicolas Toromanoff hash_size = n_len_bytes;
1462*81f5b20cSNicolas Toromanoff }
1463*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_SIGN_HASH_Z, hash, hash_size,
1464*81f5b20cSNicolas Toromanoff eo_nbw);
1465*81f5b20cSNicolas Toromanoff if (res)
1466*81f5b20cSNicolas Toromanoff goto out;
1467*81f5b20cSNicolas Toromanoff
1468*81f5b20cSNicolas Toromanoff /* Set mode to ECDSA signature */
1469*81f5b20cSNicolas Toromanoff res = pka_enable(base, _PKA_CR_MODE_ECDSA_SIGN);
1470*81f5b20cSNicolas Toromanoff if (res) {
1471*81f5b20cSNicolas Toromanoff EMSG("Set mode pka error %"PRIx32, res);
1472*81f5b20cSNicolas Toromanoff goto out;
1473*81f5b20cSNicolas Toromanoff }
1474*81f5b20cSNicolas Toromanoff
1475*81f5b20cSNicolas Toromanoff /* Start processing and wait end */
1476*81f5b20cSNicolas Toromanoff res = stm32_pka_process(base);
1477*81f5b20cSNicolas Toromanoff if (res) {
1478*81f5b20cSNicolas Toromanoff EMSG("process error %"PRIx32, res);
1479*81f5b20cSNicolas Toromanoff goto out;
1480*81f5b20cSNicolas Toromanoff }
1481*81f5b20cSNicolas Toromanoff
1482*81f5b20cSNicolas Toromanoff /* Get return value */
1483*81f5b20cSNicolas Toromanoff res = stm32_pka_ecdsa_sign_ret(base, sig_r, sig_s, eo_nbw);
1484*81f5b20cSNicolas Toromanoff
1485*81f5b20cSNicolas Toromanoff /* Unset end proc */
1486*81f5b20cSNicolas Toromanoff io_setbits32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
1487*81f5b20cSNicolas Toromanoff
1488*81f5b20cSNicolas Toromanoff out:
1489*81f5b20cSNicolas Toromanoff /* Disable PKA (will stop all pending process and reset RAM) */
1490*81f5b20cSNicolas Toromanoff pka_disable(base);
1491*81f5b20cSNicolas Toromanoff
1492*81f5b20cSNicolas Toromanoff mutex_unlock(pka_pdata.lock);
1493*81f5b20cSNicolas Toromanoff
1494*81f5b20cSNicolas Toromanoff return res;
1495*81f5b20cSNicolas Toromanoff }
1496*81f5b20cSNicolas Toromanoff
stm32_pka_ecc_sc_mul_param(const struct stm32_pka_bn * k,const struct stm32_pka_point * p,const enum stm32_pka_curve_id cid)1497*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_ecc_sc_mul_param(const struct stm32_pka_bn *k,
1498*81f5b20cSNicolas Toromanoff const struct stm32_pka_point *p,
1499*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1500*81f5b20cSNicolas Toromanoff {
1501*81f5b20cSNicolas Toromanoff if (k->size > PKA_MAX_ECC_SIZE) {
1502*81f5b20cSNicolas Toromanoff EMSG("0 <= k < 2**640 inval");
1503*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1504*81f5b20cSNicolas Toromanoff }
1505*81f5b20cSNicolas Toromanoff
1506*81f5b20cSNicolas Toromanoff if (!is_smaller(&p->x, &curve_def[cid].p)) {
1507*81f5b20cSNicolas Toromanoff EMSG("Xp < p inval");
1508*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1509*81f5b20cSNicolas Toromanoff }
1510*81f5b20cSNicolas Toromanoff
1511*81f5b20cSNicolas Toromanoff if (!is_smaller(&p->y, &curve_def[cid].p)) {
1512*81f5b20cSNicolas Toromanoff EMSG("Yp < p inval");
1513*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1514*81f5b20cSNicolas Toromanoff }
1515*81f5b20cSNicolas Toromanoff
1516*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1517*81f5b20cSNicolas Toromanoff }
1518*81f5b20cSNicolas Toromanoff
stm32_pka_ecc_kp_ret(const vaddr_t base,struct stm32_pka_point * kp,const unsigned int eo_nbw)1519*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_ecc_kp_ret(const vaddr_t base,
1520*81f5b20cSNicolas Toromanoff struct stm32_pka_point *kp,
1521*81f5b20cSNicolas Toromanoff const unsigned int eo_nbw)
1522*81f5b20cSNicolas Toromanoff {
1523*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1524*81f5b20cSNicolas Toromanoff uint64_t value = ULL(0);
1525*81f5b20cSNicolas Toromanoff uint32_t sr = U(0);
1526*81f5b20cSNicolas Toromanoff
1527*81f5b20cSNicolas Toromanoff sr = io_read32(base + _PKA_SR);
1528*81f5b20cSNicolas Toromanoff if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
1529*81f5b20cSNicolas Toromanoff EMSG("Detected error(s): %s%s%s",
1530*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_OPERR) ? "Operation " : "",
1531*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_ADDRERR) ? "Address " : "",
1532*81f5b20cSNicolas Toromanoff (sr & _PKA_IT_RAMERR) ? "RAM" : "");
1533*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
1534*81f5b20cSNicolas Toromanoff }
1535*81f5b20cSNicolas Toromanoff
1536*81f5b20cSNicolas Toromanoff value = io_read64(base + _PKA_RAM_KP_RES);
1537*81f5b20cSNicolas Toromanoff if (value == _PKA_RAM_KP_RES_FAIL)
1538*81f5b20cSNicolas Toromanoff return TEE_ERROR_SECURITY;
1539*81f5b20cSNicolas Toromanoff
1540*81f5b20cSNicolas Toromanoff if (value != _PKA_RAM_KP_RES_SUCCESS)
1541*81f5b20cSNicolas Toromanoff return TEE_ERROR_GENERIC;
1542*81f5b20cSNicolas Toromanoff
1543*81f5b20cSNicolas Toromanoff res = read_eo_data(base + _PKA_RAM_KP_X, kp->x.val, kp->x.size, eo_nbw);
1544*81f5b20cSNicolas Toromanoff if (res)
1545*81f5b20cSNicolas Toromanoff return res;
1546*81f5b20cSNicolas Toromanoff
1547*81f5b20cSNicolas Toromanoff return read_eo_data(base + _PKA_RAM_KP_Y, kp->y.val, kp->y.size,
1548*81f5b20cSNicolas Toromanoff eo_nbw);
1549*81f5b20cSNicolas Toromanoff }
1550*81f5b20cSNicolas Toromanoff
stm32_pka_ecc_scalar_mul(const struct stm32_pka_bn * k,const struct stm32_pka_point * p,struct stm32_pka_point * kp,const enum stm32_pka_curve_id cid)1551*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_ecc_scalar_mul(const struct stm32_pka_bn *k,
1552*81f5b20cSNicolas Toromanoff const struct stm32_pka_point *p,
1553*81f5b20cSNicolas Toromanoff struct stm32_pka_point *kp,
1554*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1555*81f5b20cSNicolas Toromanoff {
1556*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1557*81f5b20cSNicolas Toromanoff vaddr_t base = pka_pdata.base;
1558*81f5b20cSNicolas Toromanoff unsigned int eo_nbw = get_ecc_op_nbword(cid);
1559*81f5b20cSNicolas Toromanoff
1560*81f5b20cSNicolas Toromanoff if (!eo_nbw || !k || !p || !kp)
1561*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1562*81f5b20cSNicolas Toromanoff
1563*81f5b20cSNicolas Toromanoff mutex_lock(pka_pdata.lock);
1564*81f5b20cSNicolas Toromanoff
1565*81f5b20cSNicolas Toromanoff res = stm32_pka_ecc_sc_mul_param(k, p, cid);
1566*81f5b20cSNicolas Toromanoff if (res) {
1567*81f5b20cSNicolas Toromanoff EMSG("check param error %"PRIx32, res);
1568*81f5b20cSNicolas Toromanoff goto out;
1569*81f5b20cSNicolas Toromanoff }
1570*81f5b20cSNicolas Toromanoff
1571*81f5b20cSNicolas Toromanoff if ((io_read32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
1572*81f5b20cSNicolas Toromanoff EMSG("PKA is busy");
1573*81f5b20cSNicolas Toromanoff res = TEE_ERROR_BUSY;
1574*81f5b20cSNicolas Toromanoff goto out;
1575*81f5b20cSNicolas Toromanoff }
1576*81f5b20cSNicolas Toromanoff
1577*81f5b20cSNicolas Toromanoff /* Fill PKA RAM */
1578*81f5b20cSNicolas Toromanoff /* With curve id values */
1579*81f5b20cSNicolas Toromanoff res = stm32_pka_configure_curve(base, SCALAR_MUL, cid);
1580*81f5b20cSNicolas Toromanoff if (res)
1581*81f5b20cSNicolas Toromanoff goto out;
1582*81f5b20cSNicolas Toromanoff
1583*81f5b20cSNicolas Toromanoff /* With k */
1584*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_KP_K, k->val, k->size, eo_nbw);
1585*81f5b20cSNicolas Toromanoff if (res)
1586*81f5b20cSNicolas Toromanoff goto out;
1587*81f5b20cSNicolas Toromanoff
1588*81f5b20cSNicolas Toromanoff /* With xP */
1589*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_KP_XP, p->x.val, p->x.size, eo_nbw);
1590*81f5b20cSNicolas Toromanoff if (res)
1591*81f5b20cSNicolas Toromanoff goto out;
1592*81f5b20cSNicolas Toromanoff
1593*81f5b20cSNicolas Toromanoff /* With yP */
1594*81f5b20cSNicolas Toromanoff res = write_eo_data(base + _PKA_RAM_KP_YP, p->y.val, p->y.size, eo_nbw);
1595*81f5b20cSNicolas Toromanoff if (res)
1596*81f5b20cSNicolas Toromanoff goto out;
1597*81f5b20cSNicolas Toromanoff
1598*81f5b20cSNicolas Toromanoff /* Set mode to ecc scalar multiplication */
1599*81f5b20cSNicolas Toromanoff res = pka_enable(base, _PKA_CR_MODE_ECC_KP);
1600*81f5b20cSNicolas Toromanoff if (res) {
1601*81f5b20cSNicolas Toromanoff EMSG("Set mode pka error %"PRIx32, res);
1602*81f5b20cSNicolas Toromanoff goto out;
1603*81f5b20cSNicolas Toromanoff }
1604*81f5b20cSNicolas Toromanoff
1605*81f5b20cSNicolas Toromanoff /* Start processing and wait end */
1606*81f5b20cSNicolas Toromanoff res = stm32_pka_process(base);
1607*81f5b20cSNicolas Toromanoff if (res) {
1608*81f5b20cSNicolas Toromanoff EMSG("process error %"PRIx32, res);
1609*81f5b20cSNicolas Toromanoff goto out;
1610*81f5b20cSNicolas Toromanoff }
1611*81f5b20cSNicolas Toromanoff
1612*81f5b20cSNicolas Toromanoff /* Get return value */
1613*81f5b20cSNicolas Toromanoff res = stm32_pka_ecc_kp_ret(base, kp, eo_nbw);
1614*81f5b20cSNicolas Toromanoff
1615*81f5b20cSNicolas Toromanoff /* Unset end proc */
1616*81f5b20cSNicolas Toromanoff io_setbits32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
1617*81f5b20cSNicolas Toromanoff
1618*81f5b20cSNicolas Toromanoff out:
1619*81f5b20cSNicolas Toromanoff /* Disable PKA (will stop all pending process and reset RAM) */
1620*81f5b20cSNicolas Toromanoff pka_disable(base);
1621*81f5b20cSNicolas Toromanoff
1622*81f5b20cSNicolas Toromanoff mutex_unlock(pka_pdata.lock);
1623*81f5b20cSNicolas Toromanoff
1624*81f5b20cSNicolas Toromanoff return res;
1625*81f5b20cSNicolas Toromanoff }
1626*81f5b20cSNicolas Toromanoff
stm32_pka_edac_gen_pubkey(const struct stm32_pka_bn * k,struct stm32_pka_point * pk,const enum stm32_pka_curve_id cid)1627*81f5b20cSNicolas Toromanoff TEE_Result stm32_pka_edac_gen_pubkey(const struct stm32_pka_bn *k,
1628*81f5b20cSNicolas Toromanoff struct stm32_pka_point *pk,
1629*81f5b20cSNicolas Toromanoff const enum stm32_pka_curve_id cid)
1630*81f5b20cSNicolas Toromanoff {
1631*81f5b20cSNicolas Toromanoff return stm32_pka_ecc_scalar_mul(k, &curve_def[cid].g, pk, cid);
1632*81f5b20cSNicolas Toromanoff }
1633*81f5b20cSNicolas Toromanoff
stm32_pka_parse_fdt(struct stm32_pka_platdata * pdata,const void * fdt,int node)1634*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_parse_fdt(struct stm32_pka_platdata *pdata,
1635*81f5b20cSNicolas Toromanoff const void *fdt, int node)
1636*81f5b20cSNicolas Toromanoff {
1637*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1638*81f5b20cSNicolas Toromanoff size_t reg_size = 0;
1639*81f5b20cSNicolas Toromanoff paddr_t reg = 0;
1640*81f5b20cSNicolas Toromanoff
1641*81f5b20cSNicolas Toromanoff res = rstctrl_dt_get_by_index(fdt, node, 0, &pdata->reset);
1642*81f5b20cSNicolas Toromanoff if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
1643*81f5b20cSNicolas Toromanoff return res;
1644*81f5b20cSNicolas Toromanoff
1645*81f5b20cSNicolas Toromanoff res = clk_dt_get_by_name(fdt, node, "bus", &pdata->clk);
1646*81f5b20cSNicolas Toromanoff if (res)
1647*81f5b20cSNicolas Toromanoff return res;
1648*81f5b20cSNicolas Toromanoff
1649*81f5b20cSNicolas Toromanoff res = clk_dt_get_by_name(fdt, node, "rng", &pdata->clk_rng);
1650*81f5b20cSNicolas Toromanoff if (res)
1651*81f5b20cSNicolas Toromanoff return res;
1652*81f5b20cSNicolas Toromanoff
1653*81f5b20cSNicolas Toromanoff if (fdt_reg_info(fdt, node, ®, ®_size))
1654*81f5b20cSNicolas Toromanoff return TEE_ERROR_BAD_PARAMETERS;
1655*81f5b20cSNicolas Toromanoff
1656*81f5b20cSNicolas Toromanoff pdata->base = (vaddr_t)phys_to_virt(reg, MEM_AREA_IO_SEC, reg_size);
1657*81f5b20cSNicolas Toromanoff if (!pdata->base)
1658*81f5b20cSNicolas Toromanoff panic();
1659*81f5b20cSNicolas Toromanoff
1660*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1661*81f5b20cSNicolas Toromanoff }
1662*81f5b20cSNicolas Toromanoff
stm32_pka_reset(void)1663*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_reset(void)
1664*81f5b20cSNicolas Toromanoff {
1665*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1666*81f5b20cSNicolas Toromanoff
1667*81f5b20cSNicolas Toromanoff if (!pka_pdata.reset)
1668*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1669*81f5b20cSNicolas Toromanoff
1670*81f5b20cSNicolas Toromanoff res = rstctrl_assert_to(pka_pdata.reset, TIMEOUT_US_1MS);
1671*81f5b20cSNicolas Toromanoff if (res)
1672*81f5b20cSNicolas Toromanoff return res;
1673*81f5b20cSNicolas Toromanoff
1674*81f5b20cSNicolas Toromanoff udelay(PKA_RESET_DELAY);
1675*81f5b20cSNicolas Toromanoff
1676*81f5b20cSNicolas Toromanoff return rstctrl_deassert_to(pka_pdata.reset, TIMEOUT_US_1MS);
1677*81f5b20cSNicolas Toromanoff }
1678*81f5b20cSNicolas Toromanoff
stm32_pka_pm(enum pm_op op,uint32_t pm_hint,const struct pm_callback_handle * hdl __unused)1679*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_pm(enum pm_op op, uint32_t pm_hint,
1680*81f5b20cSNicolas Toromanoff const struct pm_callback_handle *hdl __unused)
1681*81f5b20cSNicolas Toromanoff {
1682*81f5b20cSNicolas Toromanoff switch (op) {
1683*81f5b20cSNicolas Toromanoff case PM_OP_SUSPEND:
1684*81f5b20cSNicolas Toromanoff clk_disable(pka_pdata.clk);
1685*81f5b20cSNicolas Toromanoff clk_disable(pka_pdata.clk_rng);
1686*81f5b20cSNicolas Toromanoff
1687*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1688*81f5b20cSNicolas Toromanoff case PM_OP_RESUME:
1689*81f5b20cSNicolas Toromanoff if (clk_enable(pka_pdata.clk_rng) || clk_enable(pka_pdata.clk))
1690*81f5b20cSNicolas Toromanoff panic();
1691*81f5b20cSNicolas Toromanoff
1692*81f5b20cSNicolas Toromanoff if (PM_HINT_IS_STATE(pm_hint, CONTEXT) && stm32_pka_reset())
1693*81f5b20cSNicolas Toromanoff panic();
1694*81f5b20cSNicolas Toromanoff
1695*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1696*81f5b20cSNicolas Toromanoff default:
1697*81f5b20cSNicolas Toromanoff return TEE_ERROR_NOT_IMPLEMENTED;
1698*81f5b20cSNicolas Toromanoff }
1699*81f5b20cSNicolas Toromanoff }
1700*81f5b20cSNicolas Toromanoff
stm32_pka_probe(const void * fdt,int node,const void * compat_data __unused)1701*81f5b20cSNicolas Toromanoff static TEE_Result stm32_pka_probe(const void *fdt, int node,
1702*81f5b20cSNicolas Toromanoff const void *compat_data __unused)
1703*81f5b20cSNicolas Toromanoff {
1704*81f5b20cSNicolas Toromanoff TEE_Result res = TEE_ERROR_GENERIC;
1705*81f5b20cSNicolas Toromanoff
1706*81f5b20cSNicolas Toromanoff res = stm32_pka_parse_fdt(&pka_pdata, fdt, node);
1707*81f5b20cSNicolas Toromanoff if (res)
1708*81f5b20cSNicolas Toromanoff return res;
1709*81f5b20cSNicolas Toromanoff
1710*81f5b20cSNicolas Toromanoff if (clk_enable(pka_pdata.clk) || clk_enable(pka_pdata.clk_rng))
1711*81f5b20cSNicolas Toromanoff panic();
1712*81f5b20cSNicolas Toromanoff
1713*81f5b20cSNicolas Toromanoff if (stm32_pka_reset())
1714*81f5b20cSNicolas Toromanoff panic();
1715*81f5b20cSNicolas Toromanoff
1716*81f5b20cSNicolas Toromanoff pka_pdata.lock = &pka_lock;
1717*81f5b20cSNicolas Toromanoff
1718*81f5b20cSNicolas Toromanoff if (IS_ENABLED(CFG_CRYPTO_DRV_ECC)) {
1719*81f5b20cSNicolas Toromanoff res = stm32_register_ecc();
1720*81f5b20cSNicolas Toromanoff if (res) {
1721*81f5b20cSNicolas Toromanoff EMSG("Failed to register to ecc: %#"PRIx32, res);
1722*81f5b20cSNicolas Toromanoff panic();
1723*81f5b20cSNicolas Toromanoff }
1724*81f5b20cSNicolas Toromanoff }
1725*81f5b20cSNicolas Toromanoff
1726*81f5b20cSNicolas Toromanoff register_pm_core_service_cb(stm32_pka_pm, NULL, "stm32-pka");
1727*81f5b20cSNicolas Toromanoff
1728*81f5b20cSNicolas Toromanoff return TEE_SUCCESS;
1729*81f5b20cSNicolas Toromanoff }
1730*81f5b20cSNicolas Toromanoff
1731*81f5b20cSNicolas Toromanoff static const struct dt_device_match pka_match_table[] = {
1732*81f5b20cSNicolas Toromanoff { .compatible = "st,stm32mp13-pka" },
1733*81f5b20cSNicolas Toromanoff { }
1734*81f5b20cSNicolas Toromanoff };
1735*81f5b20cSNicolas Toromanoff
1736*81f5b20cSNicolas Toromanoff DEFINE_DT_DRIVER(stm32_pka_dt_driver) = {
1737*81f5b20cSNicolas Toromanoff .name = "stm32-pka",
1738*81f5b20cSNicolas Toromanoff .match_table = pka_match_table,
1739*81f5b20cSNicolas Toromanoff .probe = &stm32_pka_probe,
1740*81f5b20cSNicolas Toromanoff };
1741