1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * All the includes that are needed for code using this module to
9  * compile correctly should be #included here.
10  */
11 #include "cc_pal_mem.h"
12 #include "cc_pal_types.h"
13 #include "cc_hal_plat.h"
14 #include "cc_common_math.h"
15 #include "mbedtls_cc_ec_mont_edw_error.h"
16 #include "cc_ec_mont_api.h"
17 #include "ec_mont_local.h"
18 
19 #include "pka_hw_defs.h"
20 #include "pki.h"
21 #include "pka.h"
22 #include "pka_error.h"
23 #include "pka_ec_mont_glob_regs_def.h"
24 
25 
26 /*!
27  * The function executes scalar multiplication by ladder algorithm and PKA HW.
28  *
29  *    Note: 1. SCA protection is not active.
30  *          2. Assumed that PKA was initialized according to EC modulus
31  *             and registers definitions in above included ...def.h file before
32  *             calling the function.
33  *          3. Scalar buffer size in words is equall to EC order (modulus) size.
34  *
35  *  Implicitly defined in/out parameters (registers ID-s):
36  *    EC_MONT_REG_RES [out] - ID of PKA register for output result point in
37  *                  compressed form (coordinate X).
38  *    EC_MONT_REG_X1 [in] - ID of PKA register, containing the input point in
39  *             compressed form (coordinate X1).
40  *
41  * \return CCError_t
42  */
EcMontPkaScalarMultWithLadderExe(uint32_t * scalar,uint32_t scalarSizeBits)43 static CCError_t EcMontPkaScalarMultWithLadderExe(
44                                                    uint32_t *scalar,        /*!< [in] pointer to scalar in LE order of bytes. */
45                                                    uint32_t  scalarSizeBits /*!< [in] exact scalar size in bits. */)
46 {
47         /* DEFINITIONS */
48 
49         CCError_t err = CC_OK;
50         uint32_t swap = 0;
51         uint32_t tmp, currBit;
52         int32_t  i;
53         uint32_t rX2, rX3, rZ2, rZ3; /* variable regisres ID-s */
54 
55         /*   FUNCTION LOGIC  */
56 
57         /* set internally used registers: x2=1; z2=0; x3=x1; z3=1; */
58         rX2 = EC_MONT_REG_X2; rX3 = EC_MONT_REG_X3; rZ2 = EC_MONT_REG_Z2; rZ3 = EC_MONT_REG_Z3;
59 
60         /* clean 4 registers */
61         PkaClearBlockOfRegs(rX2/*firstReg*/, 4/*countOfRegs*/, LEN_ID_N_PKA_REG_BITS);
62         /* set */
63         PKA_SET_BIT0(LEN_ID_N_PKA_REG_BITS, rX2, rX2);
64         PKA_COPY(LEN_ID_N_PKA_REG_BITS, rX3, EC_MONT_REG_X1);
65         PKA_SET_BIT0(LEN_ID_N_PKA_REG_BITS, rZ3, rZ3);
66 
67         /* set EC_MONT_REG_N4 = 4*Mod */
68         PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_N4, EC_MONT_REG_N, EC_MONT_REG_N);
69         PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_N4, EC_MONT_REG_N4, EC_MONT_REG_N4);
70 
71         i = scalarSizeBits - 1;
72         tmp = scalar[(i+CC_BITS_IN_32BIT_WORD-1) / CC_BITS_IN_32BIT_WORD - 1];
73 
74         for (; i >= 0; --i) {
75 
76                 /* get next word of scalar */
77                 if ((i & (CC_BITS_IN_32BIT_WORD - 1)) == (CC_BITS_IN_32BIT_WORD - 1) ) {
78                         tmp = scalar[i / CC_BITS_IN_32BIT_WORD];
79                 }
80 
81                 /* get next bit of scalar */
82                 currBit = (tmp >> (i & (CC_BITS_IN_32BIT_WORD - 1))) & 1;
83 
84                 /* c of registers ID-s */
85                 swap ^= currBit;                                                                // PkiDbgPrintReg("\ni=%3d b=%3d 1-swap=%3d ", i, currBit, swap);
86                 PkiConditionalSecureSwapUint32(&rX2, &rX3, swap);
87                 PkiConditionalSecureSwapUint32(&rZ2, &rZ3, swap);
88                 swap = currBit;                                                                 // PkiDbgPrintReg("2-swap=%3d  start HW loop: \n", swap);
89 
90                 /* ladder: (X1,1),(X2,Z2),(X3,Z3) -> (X2,Z2),(X3,Z3) */
91 
92                 PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, rZ3);            // PkiDbgPrintReg("t2: -z3 =", EC_MONT_REG_T2);
93                 PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T, rX3, EC_MONT_REG_T2);             // PkiDbgPrintReg("t: x3+t2 =", EC_MONT_REG_T);
94                 PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, rZ2);            // PkiDbgPrintReg("t2: -z2= ", EC_MONT_REG_T2);
95                 PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T1, rX2, EC_MONT_REG_T2);            // PkiDbgPrintReg("t1: x2+t2 =", EC_MONT_REG_T1);
96                 PKA_ADD(LEN_ID_N_PKA_REG_BITS, rX2, rZ2, rX2);                                  // PkiDbgPrintReg("x2: z2+x2 =", rX2);
97                 PKA_ADD(LEN_ID_N_PKA_REG_BITS, rZ2, rX3, rZ3);                                  // PkiDbgPrintReg("z2: x3+z3 =", rZ2);
98                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ3, EC_MONT_REG_T, rX2);                        // PkiDbgPrintReg("z3: t*x2 =", rZ3);
99                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ2, EC_MONT_REG_T1, rZ2);                       // PkiDbgPrintReg("z2: t1*z2 =", rZ2);
100                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EC_MONT_REG_T, EC_MONT_REG_T1, EC_MONT_REG_T1);  // PkiDbgPrintReg("t: t1*t1 =", EC_MONT_REG_T);
101                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EC_MONT_REG_T1, rX2, rX2);                       // PkiDbgPrintReg("t1: x2*x2 =", EC_MONT_REG_T1);
102                 PKA_ADD(LEN_ID_N_PKA_REG_BITS, rX3, rZ3, rZ2);                                  // PkiDbgPrintReg("x3: z3+z2 =", rX3);
103                 PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, rZ2);            // PkiDbgPrintReg("t2: -z2 =", EC_MONT_REG_T2);
104                 PKA_ADD(LEN_ID_N_PKA_REG_BITS, rZ2, rZ3, EC_MONT_REG_T2);                       // PkiDbgPrintReg("z2: z3+t2 =", rZ2);
105                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX2, EC_MONT_REG_T1, EC_MONT_REG_T);             // PkiDbgPrintReg("x2: t1*t =", rX2);
106                 PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, EC_MONT_REG_T);  // PkiDbgPrintReg("t2: -t =", EC_MONT_REG_T2);
107                 PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T1, EC_MONT_REG_T1, EC_MONT_REG_T2); // PkiDbgPrintReg("t1: t1+t2 =", EC_MONT_REG_T1);
108                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ2, rZ2, rZ2);                                  // PkiDbgPrintReg("z2: z2*z2 =", rZ2);
109                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX3, rX3, rX3);                                  // PkiDbgPrintReg("x3: x3*x3 =", rX3);
110                 PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, EC_MONT_REG_T, EC_MONT_REG_A24,
111                                     EC_MONT_REG_T1, EC_MONT_REG_T);                             // PkiDbgPrintReg("t: a24*t1+t= ", EC_MONT_REG_T);
112                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ3, EC_MONT_REG_X1, rZ2);                       // PkiDbgPrintReg("z3: x1*z2 =", rZ3);
113                 PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ2, EC_MONT_REG_T1, EC_MONT_REG_T);             // PkiDbgPrintReg("z2: t1*t =", rZ2);
114         }
115         /* Swapping of registers ID-s */
116         PkiConditionalSecureSwapUint32(&rX2, &rX3, swap);
117         PkiConditionalSecureSwapUint32(&rZ2, &rZ3, swap);
118         PKA_MOD_INV_W_EXP(EC_MONT_REG_T, rZ2, rX3/*as temp*/);                                  // PkiDbgPrintReg("t: 1/z2 =", EC_MONT_REG_T);
119         PKA_MOD_MUL(LEN_ID_N_BITS, EC_MONT_REG_RES, rX2, EC_MONT_REG_T);                        // PkiDbgPrintReg("r: x2*t =", EC_MONT_REG_RES);
120 // ???       PKA_REDUCE(LEN_ID_N_BITS, EC_MONT_REG_RES, EC_MONT_REG_RES);                             PkiDbgPrintReg("r: r reduced =", EC_MONT_REG_RES);
121 
122         return err;
123 }
124 
125 
126 /*!
127  * The function performs input/output parameters for scalar
128  * multiplication using ladder algorithm.
129  *
130  *         resPoint(X,_) = k*inPoint(X,_), where:
131  *         both points are given in compressed form (only X coordinates ) with
132  *         LE order of the words.
133  *
134  *         Assuming: the PKA HW is turned on and initialized yet.
135  *
136  * \return CCError_t
137  */
EcMontPkaScalMultWithLadder(uint32_t * resPoint,uint32_t * scalar,uint32_t scalarSizeBits,uint32_t * inPoint,const CCEcMontDomain_t * pEcDomain)138 CCError_t EcMontPkaScalMultWithLadder(
139                                        uint32_t  *resPoint,  /*!< [out] pointer to result EC point (coordinate X). */
140                                        uint32_t  *scalar,    /*!< [in] pointer to scalar. */
141                                        uint32_t   scalarSizeBits, /*!< [in] scalar size in bits. */
142                                        uint32_t  *inPoint,   /*!< [in] pointer to input ECMONT point (coordinate X). */
143                                        const CCEcMontDomain_t *pEcDomain /*!< [in] pointer to EC domain (curve). */)
144 {
145         /* Definitions */
146 
147         CCError_t err = CC_OK;
148         uint32_t scalarSizeWords;
149 
150         /* set scalar bits according to EC Montgomery algorithm:
151            byte[31] = (byte[31] & 127) | 64; byte[0] &= 248; */
152         scalarSizeWords = (scalarSizeBits + CC_BITS_IN_32BIT_WORD - 1) / CC_BITS_IN_32BIT_WORD;
153 
154         /* ********************************************* */
155         /* load all needed data to defined pka registers */
156         /* ********************************************* */
157 
158         /* EC modulus */
159         PkaCopyDataIntoPkaReg(EC_MONT_REG_N/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
160                               pEcDomain->ecModP/*src*/, pEcDomain->ecModSizeInWords);
161         /*Barr. tag.*/
162         PkaCopyDataIntoPkaReg(EC_MONT_REG_NP/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
163                               pEcDomain->ecModBarrTag/*src*/,
164                               CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS/*Barr.tag.*/);
165         /*EC parameter*/
166         PkaCopyDataIntoPkaReg(EC_MONT_REG_A24/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
167                               pEcDomain->ecParam/*src*/, pEcDomain->ecModSizeInWords/*param.size*/);
168         /* input point X1 */
169         PkaCopyDataIntoPkaReg(EC_MONT_REG_X1/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
170                               inPoint/*src*/, pEcDomain->ecModSizeInWords);
171 
172 
173         /*--------------------------------------------------------------------*
174          * perform EC scalar multiplication:  used PKA registers defined in   *
175          *   "pka_ec_mont_glob_regs_def."h file: output is EC_MONT_REG_RES    *
176          *--------------------------------------------------------------------*/
177         err = EcMontPkaScalarMultWithLadderExe(scalar, scalarSizeBits);
178         if (err)
179                 goto EndCommand;
180 
181         /* output result point */
182         PkaCopyDataFromPkaReg(resPoint/*dst*/, scalarSizeWords, EC_MONT_REG_RES/*srcReg*/);
183 
184 EndCommand:
185         return err;
186 }
187