1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "cc_pal_mem.h"
8 #include "cc_pal_types.h"
9 #include "cc_hal_plat.h"
10 #include "cc_common_math.h"
11 #include "cc_ecpki_error.h"
12 #include "pka_hw_defs.h"
13 #include "pka_error.h"
14 #include "pki.h"
15 #include "pka.h"
16 #include "pka_ec_wrst.h"
17 #include "ec_wrst.h"
18 #include "ec_wrst_error.h"
19 #include "pki_modular_arithmetic.h"
20 #include "pki_dbg.h"
21 #include "pka_ec_wrst_glob_regs.h"
22 #include "pka_ec_wrst_dsa_verify_regs.h"
23
24
25 /*********** PkaDoubleMdf2Mdf function **********************/
26 /**
27 * @brief EC point doubling: p = 2*p1 modified-modified.
28 *
29 * @return - On success CC_OK is returned, on failure an error code.
30 */
PkaDoubleMdf2Mdf(const uint32_t x,const uint32_t y,const uint32_t z,const uint32_t t,const uint32_t x1,const uint32_t y1,const uint32_t z1,const uint32_t t1)31 void PkaDoubleMdf2Mdf(
32 const uint32_t x, const uint32_t y, const uint32_t z, const uint32_t t, /*!< [out] Output modified point coordinates. */
33 const uint32_t x1, const uint32_t y1, const uint32_t z1, const uint32_t t1) /*!< [in] Input modified point coordinates. */
34 {
35 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, y1, y1);
36 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, ECC_REG_T4, z1);
37 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y1, y1);
38 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, x1, x1);
39 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, ECC_REG_T4, ECC_REG_T4);
40 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T4, y, ECC_REG_T4);
41 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x1, x1);
42 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, ECC_REG_T2);
43 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, ECC_REG_T2, x);
44 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, t1, ECC_REG_T2);
45 PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, ECC_REG_N4, ECC_REG_T4);
46 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T2, ECC_REG_T2, ECC_REG_T4);
47 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T4, x);
48 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, x, ECC_REG_T4);
49 PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T3, ECC_REG_N12, ECC_REG_T4);
50 PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
51 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, y);
52 PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
53 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, y, y);
54 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T4, ECC_REG_T4, t1);
55 PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N8, y);
56 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T3, ECC_REG_T2, y);
57 PKA_COPY(LEN_ID_N_PKA_REG_BITS, t, ECC_REG_T4);
58 return;
59 }
60
61 /*********** PkaDoubleMdf2Jcb function **********************/
62 /**
63 * @brief EC point doubling: p = 2*p1 p1 is modified, output is Jacobian
64 *
65 * @return - no return value.
66 */
PkaDoubleMdf2Jcb(const uint32_t x,const uint32_t y,const uint32_t z,const uint32_t x1,const uint32_t y1,const uint32_t z1,const uint32_t t1)67 void PkaDoubleMdf2Jcb(
68 const uint32_t x, const uint32_t y, const uint32_t z, /*!< [out] EC point jacobian coordinates. */
69 const uint32_t x1, const uint32_t y1, const uint32_t z1, const uint32_t t1)/*!< [in] EC point modified coordinates. */
70 {
71 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, y1, y1);
72 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, ECC_REG_T, z1);
73 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y1, y1);
74 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, x1, x1);
75 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, ECC_REG_T, ECC_REG_T);
76 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T, y, ECC_REG_T);
77 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x1, x1);
78 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, ECC_REG_T2);
79 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, ECC_REG_T2, x);
80 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, t1, ECC_REG_T2);
81 PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, ECC_REG_N4, ECC_REG_T);
82 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T2, ECC_REG_T2, ECC_REG_T);
83 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T, x);
84 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, x, ECC_REG_T);
85 PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T3, ECC_REG_N12, ECC_REG_T);
86 PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
87 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, y);
88 PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
89 PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N8, y);
90 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T3, ECC_REG_T2, y);
91 return;
92 }
93
94 /*********** PkaAddJcbAfn2Mdf function **********************/
95 /**
96 * @brief Performs adding of EC points p= p2+p1: affine+jacobian=modified.
97 *
98 * @return - no return value.
99 */
PkaAddJcbAfn2Mdf(const uint32_t x,const uint32_t y,const uint32_t z,const uint32_t t,const uint32_t x1,const uint32_t y1,const uint32_t z1,const uint32_t x2,const uint32_t y2)100 void PkaAddJcbAfn2Mdf(
101 const uint32_t x, const uint32_t y, const uint32_t z, const uint32_t t, /*!< [out] EC point modified coordinates. */
102 const uint32_t x1, const uint32_t y1, const uint32_t z1, /*!< [in] EC point jacobian coordinates. */
103 const uint32_t x2, const uint32_t y2) /*!< [in] EC point affine coordinates. */
104 {
105 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z1, z1);
106 PKA_SUB(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_N12, x1);
107 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, ECC_REG_T1, x2, t, x);
108 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z1, t);
109 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, y2, t);
110 PKA_SUB(LEN_ID_N_PKA_REG_BITS, t, ECC_REG_N4, t);
111 PKA_ADD(LEN_ID_N_PKA_REG_BITS, t, y1, t);
112 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, z1, ECC_REG_T1);
113 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, ECC_REG_T1, ECC_REG_T1);
114 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T1, ECC_REG_T1, ECC_REG_T2);
115 PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T1, ECC_REG_N4, ECC_REG_T1);
116 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, ECC_REG_T1, y1);
117 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x, ECC_REG_T2);
118 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, t, t, ECC_REG_T1);
119 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
120 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
121 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, x, ECC_REG_T2);
122 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, t, ECC_REG_T2, y);
123 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z, z);
124 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, t, t);
125 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, ECC_REG_EC_A, t);
126 return;
127 }
128
129 /*********** PkaJcb2Afn function **********************/
130 /**
131 * @brief Converts the jacobian EC point to affine representation:
132 * p(x,y,z) -> p(x,y)
133 *
134 * @return - On success CC_OK is returned, on failure an error code.
135 */
PkaJcb2Afn(CCEcpkiScaProtection_t scaProtect,const uint32_t x,const uint32_t y,const uint32_t z)136 void PkaJcb2Afn(
137 CCEcpkiScaProtection_t scaProtect, /*!< [in] Flag defining if SCA protection needed (1) or not (0). */
138 const uint32_t x, const uint32_t y, /*!< [in/out] as input - EC point jacobian coordinates;
139 as output - EC point affine coordinates */
140 const uint32_t z) /*!< [in] EC point jacobian coordinates. */
141 {
142 // RL check is the pka_inv_fast works right and delete compilation dependence
143 #ifndef INV_FAST_ALLOWED
144 scaProtect = SCAP_Active;
145 #endif
146 if (scaProtect == SCAP_Inactive) {
147 PKA_MOD_INV(LEN_ID_N_BITS, ECC_REG_AQ, z); // no SCA protect
148 } else {
149 PKA_MOD_INV_W_EXP(ECC_REG_AQ, z, ECC_REG_A_NM2); // SCA protect
150 }
151
152 /* ecc-to-affine */
153 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, ECC_REG_AQ);
154 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_AQ, ECC_REG_AQ, ECC_REG_AQ);
155 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, x, x, ECC_REG_AQ);
156 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, ECC_REG_AQ);
157
158 PKA_REDUCE(LEN_ID_N_BITS,x, x);
159 PKA_REDUCE(LEN_ID_N_BITS,y, y);
160
161 return;
162 }
163
164
165 /*********** PkaAddAff function **********************/
166 /**
167 * @brief pka ecc points adding: affine+affine=affine
168 *
169 * @return - No return value
170 */
PkaAddAff(const uint32_t x,const uint32_t y,const uint32_t x1,const uint32_t y1,const uint32_t x2,const uint32_t y2)171 void PkaAddAff(
172 const uint32_t x, const uint32_t y, /*!< [out] EC point Affine coordinates. */
173 const uint32_t x1, const uint32_t y1, /*!< [in] EC point Affine coordinates. */
174 const uint32_t x2, const uint32_t y2) /*!< [in] EC point Affine coordinates. */
175 {
176 PKA_SUB(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_N1, x1);
177 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_AAA_Z, x, x2);
178 PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, ECC_REG_N1, y2);
179 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, y1, ECC_REG_T);
180 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, ECC_REG_AAA_Z, ECC_REG_AAA_Z);
181 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T1, ECC_REG_AAA_Z, ECC_REG_T2);
182 PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T1, ECC_REG_N4, ECC_REG_T1);
183 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, ECC_REG_T1, y1);
184 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x, ECC_REG_T2);
185 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T, ECC_REG_T, ECC_REG_T1);
186 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
187 PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
188 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, x, ECC_REG_T2);
189 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T, ECC_REG_T2, y);
190 PkaJcb2Afn(SCAP_Inactive, x, y, ECC_REG_AAA_Z);
191
192 return;
193 }
194
195 /*********** PkaSum2ScalarMullt function **********************/
196 /**
197 * @brief The function calculates simultaneously summ of two scalar
198 * multiplications of EC points.
199 *
200 * Used the Strauss algorithm, optimized by A.Klimow:
201 * R = a*P + b*Q, where R,P,Q - EC points, a,b - scalars.
202 *
203 * @author reuvenl (8/26/2014)
204 *
205 * @return - On success CC_OK is returned, on failure an error code.
206 */
PkaSum2ScalarMullt(const uint32_t xr,const uint32_t yr,const uint32_t a,const uint32_t xp,const uint32_t yp,const uint32_t b,const uint32_t xq,const uint32_t yq)207 uint32_t PkaSum2ScalarMullt(
208 const uint32_t xr, const uint32_t yr, /*!< [out] Pka register holding R coordinates. */
209 const uint32_t a, /*!< [in] Pka register holding scalar a. */
210 const uint32_t xp, const uint32_t yp, /*!< [in] Pka register holding P coordinates. */
211 const uint32_t b, /*!< [in] Pka register holding scalar b. */
212 const uint32_t xq, const uint32_t yq) /*!< [in] Pka register holding Q coordinates. */
213 {
214 uint32_t wA, wB, err = 0;
215 uint32_t stat;
216 int32_t b2, i;
217 uint32_t isNewA=true, isNewB=true;
218
219 /* check that a>0 and b>0 */
220 PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, a, 0, stat);
221 if (stat == 1) {
222 err = ECWRST_DSA_VERIFY_2MUL_FACTOR_A_NULL_ERROR;
223 goto End;
224 }
225 PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, b, 0, stat);
226 if (stat == 1) {
227 err = ECWRST_DSA_VERIFY_2MUL_FACTOR_B_NULL_ERROR;
228 goto End;
229 }
230
231 /* get max effective size of factors minus 1 */
232 i = CC_MAX(PkaGetRegEffectiveSizeInBits(a), PkaGetRegEffectiveSizeInBits(b)) - 1;
233
234 PkaAddAff(EC_VERIFY_REG_XPQ, EC_VERIFY_REG_YPQ, xp,yp, xq,yq); // p+q
235
236 #ifdef ARM_DSM
237 *((volatile uint32_t *)(uint32_t)(0x44440000)) = i;
238 #endif
239
240 b2 = PkaGetNextMsBit(a, i, &wA, &isNewA)*2 + PkaGetNextMsBit(b, i, &wB, &isNewB);
241 switch (b2) {
242 case 1:
243 PKA_COPY(LEN_ID_N_PKA_REG_BITS, xr, xq);
244 PKA_COPY(LEN_ID_N_PKA_REG_BITS, yr, yq);
245 break; // 01: r = q
246 case 2:
247 PKA_COPY(LEN_ID_N_PKA_REG_BITS, xr, xp);
248 PKA_COPY(LEN_ID_N_PKA_REG_BITS, yr, yp);
249 break; // 10: r = p
250 case 3:
251 PKA_COPY(LEN_ID_N_PKA_REG_BITS, xr, EC_VERIFY_REG_XPQ);
252 PKA_COPY(LEN_ID_N_PKA_REG_BITS, yr, EC_VERIFY_REG_YPQ);
253 break; // 11: r = p+q
254 default:
255 err = ECWRST_DSA_VERIFY_2MUL_FIRST_B2_ERROR;
256 goto End;
257 }
258 PKA_SET_VAL(EC_VERIFY_REG_ZR, 1);
259 PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TR, ECC_REG_EC_A);
260
261 while (--i >= 0) {
262 #ifdef ARM_DSM
263 *((volatile uint32_t *)(uint32_t)(0x44440000)) = i;
264 #endif
265 b2 = PkaGetNextMsBit(a, i, &wA, &isNewA)*2 + PkaGetNextMsBit(b, i, &wB, &isNewB);
266 if (b2 == 0) {
267 PkaDoubleMdf2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR);
268 } else {
269 PkaDoubleMdf2Jcb(xr,yr,EC_VERIFY_REG_ZR, xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR);
270 switch (b2) {
271 case 1:
272 PkaAddJcbAfn2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR, xq,yq);
273 break; // 01: r += p
274 case 2:
275 PkaAddJcbAfn2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR, xp,yp);
276 break; // 10: r += q
277 case 3:
278 PkaAddJcbAfn2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR, EC_VERIFY_REG_XPQ,EC_VERIFY_REG_YPQ);
279 break; // 11: r += p+q
280 default:
281 err = ECWRST_DSA_VERIFY_2MUL_NEXT_B2_ERROR;
282 goto End;
283 }
284 }
285 }
286 PkaJcb2Afn(SCAP_Inactive, xr, yr, EC_VERIFY_REG_ZR);
287
288 End:
289 return err;
290 }
291
292
293