1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_ECC
18
19 #include "ecc_local.h"
20 #include "bsl_err_internal.h"
21 #include "ecp_nistp224.h"
22 #include "ecp_nistp256.h"
23 #include "ecp_nistp521.h"
24 #include "ecp_sm2.h"
25
26
27 typedef struct {
28 uint32_t id;
29 const ECC_Method *ecMeth;
30 } ECC_MethodMap;
31
32 #if defined(HITLS_SIXTY_FOUR_BITS)
33 #if (((defined(HITLS_CRYPTO_CURVE_NISTP224) || defined(HITLS_CRYPTO_CURVE_NISTP521)) && \
34 !defined(HITLS_CRYPTO_NIST_USE_ACCEL)) || \
35 defined(HITLS_CRYPTO_CURVE_NISTP384) || \
36 (defined(HITLS_CRYPTO_CURVE_NISTP256) && (!defined(HITLS_CRYPTO_CURVE_NISTP256_ASM) || \
37 (!defined(HITLS_CRYPTO_NIST_ECC_ACCELERATE))) && (!defined(HITLS_CRYPTO_NIST_USE_ACCEL))))
38 static const ECC_Method EC_METHOD_NIST = {
39 .pointMulAdd = ECP_PointMulAdd,
40 .pointMul = ECP_PointMul,
41 .pointMulFast = ECP_PointMulFast,
42 .pointAddAffine = ECP_NistPointAddAffine,
43 .pointDouble = ECP_NistPointDouble,
44 .pointMultDouble = ECP_NistPointMultDouble,
45 .modInv = BN_ModInv,
46 .point2AffineWithInv = ECP_Point2AffineWithInv,
47 .point2Affine = ECP_Point2Affine,
48 .bnModNistEccMul = BN_ModNistEccMul,
49 .bnModNistEccSqr = BN_ModNistEccSqr,
50 .modOrdInv = ECP_ModOrderInv,
51 .pointAdd = ECP_NistPointAdd,
52 };
53 #endif
54 #endif // HITLS_SIXTY_FOUR_BITS
55
56 #ifdef HITLS_CRYPTO_CURVE_MONT_NIST
57 static const ECC_Method EC_METHOD_NIST_MONT = {
58 .pointMulAdd = ECP_PointMulAdd,
59 .pointMul = ECP_PointMulMont,
60 .pointMulFast = ECP_PointMulFast,
61 .pointDouble = ECP_NistPointDoubleMont,
62 .pointMultDouble = ECP_NistPointMultDoubleMont,
63 .modInv = BN_ModInv,
64 .point2Affine = ECP_Point2AffineMont,
65 .bnModNistEccMul = BN_EcPrimeMontMul,
66 .bnModNistEccSqr = BN_EcPrimeMontSqr,
67 .modOrdInv = ECP_ModOrderInv,
68 .pointAdd = ECP_NistPointAddMont,
69 .pointAddAffine = ECP_NistPointAddAffineMont,
70 .bnMontEnc = BnMontEnc,
71 .bnMontDec = BnMontDec,
72 };
73 #endif // HITLS_CRYPTO_CURVE_MONT_NIST
74
75 #ifdef HITLS_CRYPTO_CURVE_SM2_ASM
76 // method implementation of SM2
77 static const ECC_Method EC_METHOD_SM2_ASM = {
78 .pointMulAdd = ECP_Sm2PointMulAdd,
79 .pointMul = ECP_Sm2PointMul,
80 .pointMulFast = ECP_Sm2PointMulFast,
81 .pointAddAffine = ECP_Sm2PointAddAffine,
82 .pointDouble = ECP_Sm2PointDouble,
83 .pointMultDouble = ECP_NistPointMultDouble,
84 .modInv = BN_ModInv,
85 .point2AffineWithInv = ECP_Point2AffineWithInv,
86 .point2Affine = ECP_Sm2Point2Affine,
87 .bnModNistEccMul = BN_ModSm2EccMul,
88 .bnModNistEccSqr = BN_ModSm2EccSqr,
89 .modOrdInv = ECP_Sm2OrderInv,
90 .pointAdd = ECP_NistPointAdd,
91 };
92 #endif
93
94 #if defined(HITLS_CRYPTO_CURVE_SM2) && !defined(HITLS_CRYPTO_CURVE_SM2_ASM) && defined(HITLS_SIXTY_FOUR_BITS)
95 static const ECC_Method EC_METHOD_SM2_NIST = {
96 .pointMulAdd = ECP_PointMulAdd,
97 .pointMul = ECP_PointMul,
98 .pointMulFast = ECP_PointMulFast,
99 .pointAddAffine = ECP_NistPointAddAffine,
100 .pointDouble = ECP_NistPointDouble,
101 .pointMultDouble = ECP_NistPointMultDouble,
102 .modInv = BN_ModInv,
103 .point2AffineWithInv = ECP_Point2AffineWithInv,
104 .point2Affine = ECP_Point2Affine,
105 .bnModNistEccMul = BN_ModSm2EccMul,
106 .bnModNistEccSqr = BN_ModSm2EccSqr,
107 .modOrdInv = ECP_ModOrderInv,
108 .pointAdd = ECP_NistPointAdd,
109 };
110 #endif
111
112 #if defined(HITLS_CRYPTO_CURVE_BP256R1) || defined(HITLS_CRYPTO_CURVE_BP384R1) || \
113 defined(HITLS_CRYPTO_CURVE_BP512R1)
114 // Montgomery Ladder Optimization for General Curves in Prime Domain
115 static const ECC_Method EC_METHOD_PRIME_MONT = {
116 .pointMulAdd = ECP_PointMulAdd,
117 .pointMul = ECP_PointMulMont,
118 .pointDouble = ECP_PrimePointDoubleMont,
119 .pointMulFast = ECP_PointMulFast,
120 .pointMultDouble = ECP_PrimePointMultDoubleMont,
121 .modInv = BN_ModInv,
122 .point2Affine = ECP_Point2AffineMont,
123 .bnModNistEccMul = BN_EcPrimeMontMul,
124 .bnModNistEccSqr = BN_EcPrimeMontSqr,
125 .modOrdInv = ECP_ModOrderInv,
126 .pointAdd = ECP_PrimePointAddMont,
127 .pointAddAffine = ECP_PrimePointAddAffineMont,
128 .bnMontEnc = BnMontEnc,
129 .bnMontDec = BnMontDec,
130 };
131 #endif
132
133 #ifdef HITLS_CRYPTO_NIST_USE_ACCEL
134 #ifdef HITLS_CRYPTO_CURVE_NISTP224
135 static const ECC_Method EC_METHOD_NIST_P224 = {
136 .pointMulAdd = ECP224_PointMulAdd,
137 .pointMul = ECP224_PointMul,
138 .pointMulFast = ECP224_PointMul,
139 .pointAddAffine = ECP_NistPointAddAffine,
140 .pointDouble = ECP_NistPointDouble,
141 .pointMultDouble = ECP_NistPointMultDouble,
142 .modInv = BN_ModInv,
143 .point2AffineWithInv = ECP_Point2AffineWithInv,
144 .point2Affine = ECP224_Point2Affine,
145 .bnModNistEccMul = BN_ModNistEccMul,
146 .bnModNistEccSqr = BN_ModNistEccSqr,
147 .modOrdInv = ECP_ModOrderInv,
148 };
149 #endif
150
151 #ifdef HITLS_CRYPTO_CURVE_NISTP521
152 static const ECC_Method EC_METHOD_NIST_P521 = {
153 .pointMulAdd = ECP521_PointMulAdd,
154 .pointMul = ECP521_PointMul,
155 .pointMulFast = ECP521_PointMul,
156 .pointAddAffine = ECP_NistPointAddAffine,
157 .pointDouble = ECP_NistPointDouble,
158 .pointMultDouble = ECP_NistPointMultDouble,
159 .modInv = BN_ModInv,
160 .point2AffineWithInv = ECP_Point2AffineWithInv,
161 .point2Affine = ECP521_Point2Affine,
162 .bnModNistEccMul = BN_ModNistEccMul,
163 .bnModNistEccSqr = BN_ModNistEccSqr,
164 .modOrdInv = ECP_ModOrderInv,
165 };
166 #endif
167 #endif // HITLS_CRYPTO_NIST_USE_ACCEL
168
169 #ifdef HITLS_CRYPTO_CURVE_NISTP256
170 #if ((defined(HITLS_CRYPTO_CURVE_NISTP256_ASM) && defined(HITLS_CRYPTO_NIST_ECC_ACCELERATE)) || \
171 (!defined(HITLS_CRYPTO_CURVE_NISTP256_ASM) && defined(HITLS_CRYPTO_NIST_USE_ACCEL)))
172 static const ECC_Method EC_METHOD_NIST_P256 = {
173 .pointMulAdd = ECP256_PointMulAdd,
174 .pointMul = ECP256_PointMul,
175 .pointMulFast = ECP256_PointMul,
176 .pointAddAffine = ECP_NistPointAddAffine,
177 .pointDouble = ECP_NistPointDouble,
178 .pointMultDouble = ECP_NistPointMultDouble,
179 .modInv = BN_ModInv,
180 .point2AffineWithInv = ECP_Point2AffineWithInv,
181 .point2Affine = ECP256_Point2Affine,
182 .bnModNistEccMul = BN_ModNistEccMul,
183 .bnModNistEccSqr = BN_ModNistEccSqr,
184 .modOrdInv = ECP256_ModOrderInv,
185 };
186 #endif
187 #endif
188
189 static const ECC_MethodMap EC_METHODS[] = {
190 // p224
191 #ifdef HITLS_CRYPTO_CURVE_NISTP224
192 #ifdef HITLS_CRYPTO_NIST_USE_ACCEL
193 { CRYPT_ECC_NISTP224, &EC_METHOD_NIST_P224 }, // Depends on uint128.
194 #elif defined(HITLS_SIXTY_FOUR_BITS)
195 { CRYPT_ECC_NISTP224, &EC_METHOD_NIST }, // Common nist cal + fast modulus reduction of Bn
196 #else
197 { CRYPT_ECC_NISTP224, &EC_METHOD_NIST_MONT },
198 #endif
199 #endif
200
201 // p256
202 #ifdef HITLS_CRYPTO_CURVE_NISTP256
203 #if defined(HITLS_CRYPTO_CURVE_NISTP256_ASM) && defined(HITLS_CRYPTO_NIST_ECC_ACCELERATE)
204 { CRYPT_ECC_NISTP256, &EC_METHOD_NIST_P256 }, // The ECC assembly optimization does not depend on uint128.
205 #elif (!defined(HITLS_CRYPTO_CURVE_NISTP256_ASM) && defined(HITLS_CRYPTO_NIST_USE_ACCEL))
206 { CRYPT_ECC_NISTP256, &EC_METHOD_NIST_P256 }, // Non-assembled ECC optimization based on uint128
207 #elif defined(HITLS_SIXTY_FOUR_BITS)
208 { CRYPT_ECC_NISTP256, &EC_METHOD_NIST }, // Common nist calculation + fast modulus reduction of Bn
209 #else
210 { CRYPT_ECC_NISTP256, &EC_METHOD_NIST_MONT },
211 #endif
212 #endif
213
214 // p384
215 #ifdef HITLS_CRYPTO_CURVE_NISTP384
216 #if defined(HITLS_SIXTY_FOUR_BITS)
217 { CRYPT_ECC_NISTP384, &EC_METHOD_NIST }, // Common nist calculation + fast modulus reduction of Bn
218 #else
219 { CRYPT_ECC_NISTP384, &EC_METHOD_NIST_MONT },
220 #endif
221 #endif
222
223 // p521
224 #ifdef HITLS_CRYPTO_CURVE_NISTP521
225 #ifdef HITLS_CRYPTO_NIST_USE_ACCEL
226 { CRYPT_ECC_NISTP521, &EC_METHOD_NIST_P521 }, // Non-assembly optimization, depending on uint128
227 #elif defined(HITLS_SIXTY_FOUR_BITS)
228 { CRYPT_ECC_NISTP521, &EC_METHOD_NIST }, // nist calculation + fast modulus reduction of Bn
229 #else
230 { CRYPT_ECC_NISTP521, &EC_METHOD_NIST_MONT },
231 #endif
232 #endif
233
234 // bp256
235 #ifdef HITLS_CRYPTO_CURVE_BP256R1
236 { CRYPT_ECC_BRAINPOOLP256R1, &EC_METHOD_PRIME_MONT },
237 #endif
238
239 // bp384
240 #ifdef HITLS_CRYPTO_CURVE_BP384R1
241 { CRYPT_ECC_BRAINPOOLP384R1, &EC_METHOD_PRIME_MONT },
242 #endif
243
244 // bp512
245 #ifdef HITLS_CRYPTO_CURVE_BP512R1
246 { CRYPT_ECC_BRAINPOOLP512R1, &EC_METHOD_PRIME_MONT },
247 #endif
248
249 #ifdef HITLS_CRYPTO_CURVE_SM2
250 #ifdef HITLS_CRYPTO_CURVE_SM2_ASM
251 { CRYPT_ECC_SM2, &EC_METHOD_SM2_ASM },
252 #elif defined(HITLS_SIXTY_FOUR_BITS)
253 { CRYPT_ECC_SM2, &EC_METHOD_SM2_NIST },
254 #else
255 { CRYPT_ECC_SM2, &EC_METHOD_NIST_MONT },
256 #endif
257 #endif
258 };
259
260
ECC_FindMethod(CRYPT_PKEY_ParaId id)261 const ECC_Method *ECC_FindMethod(CRYPT_PKEY_ParaId id)
262 {
263 for (uint32_t i = 0; i < sizeof(EC_METHODS) / sizeof(EC_METHODS[0]); i++) {
264 if (EC_METHODS[i].id == id) {
265 return EC_METHODS[i].ecMeth;
266 }
267 }
268 return NULL;
269 }
270 #endif /* HITLS_CRYPTO_ECC */
271