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