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