Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/freebl/ecl/ecl.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 #include "mpi.h" | |
6 #include "mplogic.h" | |
7 #include "ecl.h" | |
8 #include "ecl-priv.h" | |
9 #include "ec2.h" | |
10 #include "ecp.h" | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 | |
14 /* Allocate memory for a new ECGroup object. */ | |
15 ECGroup * | |
16 ECGroup_new() | |
17 { | |
18 mp_err res = MP_OKAY; | |
19 ECGroup *group; | |
20 group = (ECGroup *) malloc(sizeof(ECGroup)); | |
21 if (group == NULL) | |
22 return NULL; | |
23 group->constructed = MP_YES; | |
24 group->meth = NULL; | |
25 group->text = NULL; | |
26 MP_DIGITS(&group->curvea) = 0; | |
27 MP_DIGITS(&group->curveb) = 0; | |
28 MP_DIGITS(&group->genx) = 0; | |
29 MP_DIGITS(&group->geny) = 0; | |
30 MP_DIGITS(&group->order) = 0; | |
31 group->base_point_mul = NULL; | |
32 group->points_mul = NULL; | |
33 group->validate_point = NULL; | |
34 group->extra1 = NULL; | |
35 group->extra2 = NULL; | |
36 group->extra_free = NULL; | |
37 MP_CHECKOK(mp_init(&group->curvea)); | |
38 MP_CHECKOK(mp_init(&group->curveb)); | |
39 MP_CHECKOK(mp_init(&group->genx)); | |
40 MP_CHECKOK(mp_init(&group->geny)); | |
41 MP_CHECKOK(mp_init(&group->order)); | |
42 | |
43 CLEANUP: | |
44 if (res != MP_OKAY) { | |
45 ECGroup_free(group); | |
46 return NULL; | |
47 } | |
48 return group; | |
49 } | |
50 | |
51 /* Construct a generic ECGroup for elliptic curves over prime fields. */ | |
52 ECGroup * | |
53 ECGroup_consGFp(const mp_int *irr, const mp_int *curvea, | |
54 const mp_int *curveb, const mp_int *genx, | |
55 const mp_int *geny, const mp_int *order, int cofactor) | |
56 { | |
57 mp_err res = MP_OKAY; | |
58 ECGroup *group = NULL; | |
59 | |
60 group = ECGroup_new(); | |
61 if (group == NULL) | |
62 return NULL; | |
63 | |
64 group->meth = GFMethod_consGFp(irr); | |
65 if (group->meth == NULL) { | |
66 res = MP_MEM; | |
67 goto CLEANUP; | |
68 } | |
69 MP_CHECKOK(mp_copy(curvea, &group->curvea)); | |
70 MP_CHECKOK(mp_copy(curveb, &group->curveb)); | |
71 MP_CHECKOK(mp_copy(genx, &group->genx)); | |
72 MP_CHECKOK(mp_copy(geny, &group->geny)); | |
73 MP_CHECKOK(mp_copy(order, &group->order)); | |
74 group->cofactor = cofactor; | |
75 group->point_add = &ec_GFp_pt_add_aff; | |
76 group->point_sub = &ec_GFp_pt_sub_aff; | |
77 group->point_dbl = &ec_GFp_pt_dbl_aff; | |
78 group->point_mul = &ec_GFp_pt_mul_jm_wNAF; | |
79 group->base_point_mul = NULL; | |
80 group->points_mul = &ec_GFp_pts_mul_jac; | |
81 group->validate_point = &ec_GFp_validate_point; | |
82 | |
83 CLEANUP: | |
84 if (res != MP_OKAY) { | |
85 ECGroup_free(group); | |
86 return NULL; | |
87 } | |
88 return group; | |
89 } | |
90 | |
91 /* Construct a generic ECGroup for elliptic curves over prime fields with | |
92 * field arithmetic implemented in Montgomery coordinates. */ | |
93 ECGroup * | |
94 ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea, | |
95 const mp_int *curveb, const mp_int *genx, | |
96 const mp_int *geny, const mp_int *order, int cofactor) | |
97 { | |
98 mp_err res = MP_OKAY; | |
99 ECGroup *group = NULL; | |
100 | |
101 group = ECGroup_new(); | |
102 if (group == NULL) | |
103 return NULL; | |
104 | |
105 group->meth = GFMethod_consGFp_mont(irr); | |
106 if (group->meth == NULL) { | |
107 res = MP_MEM; | |
108 goto CLEANUP; | |
109 } | |
110 MP_CHECKOK(group->meth-> | |
111 field_enc(curvea, &group->curvea, group->meth)); | |
112 MP_CHECKOK(group->meth-> | |
113 field_enc(curveb, &group->curveb, group->meth)); | |
114 MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth)); | |
115 MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth)); | |
116 MP_CHECKOK(mp_copy(order, &group->order)); | |
117 group->cofactor = cofactor; | |
118 group->point_add = &ec_GFp_pt_add_aff; | |
119 group->point_sub = &ec_GFp_pt_sub_aff; | |
120 group->point_dbl = &ec_GFp_pt_dbl_aff; | |
121 group->point_mul = &ec_GFp_pt_mul_jm_wNAF; | |
122 group->base_point_mul = NULL; | |
123 group->points_mul = &ec_GFp_pts_mul_jac; | |
124 group->validate_point = &ec_GFp_validate_point; | |
125 | |
126 CLEANUP: | |
127 if (res != MP_OKAY) { | |
128 ECGroup_free(group); | |
129 return NULL; | |
130 } | |
131 return group; | |
132 } | |
133 | |
134 #ifdef NSS_ECC_MORE_THAN_SUITE_B | |
135 /* Construct a generic ECGroup for elliptic curves over binary polynomial | |
136 * fields. */ | |
137 ECGroup * | |
138 ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5], | |
139 const mp_int *curvea, const mp_int *curveb, | |
140 const mp_int *genx, const mp_int *geny, | |
141 const mp_int *order, int cofactor) | |
142 { | |
143 mp_err res = MP_OKAY; | |
144 ECGroup *group = NULL; | |
145 | |
146 group = ECGroup_new(); | |
147 if (group == NULL) | |
148 return NULL; | |
149 | |
150 group->meth = GFMethod_consGF2m(irr, irr_arr); | |
151 if (group->meth == NULL) { | |
152 res = MP_MEM; | |
153 goto CLEANUP; | |
154 } | |
155 MP_CHECKOK(mp_copy(curvea, &group->curvea)); | |
156 MP_CHECKOK(mp_copy(curveb, &group->curveb)); | |
157 MP_CHECKOK(mp_copy(genx, &group->genx)); | |
158 MP_CHECKOK(mp_copy(geny, &group->geny)); | |
159 MP_CHECKOK(mp_copy(order, &group->order)); | |
160 group->cofactor = cofactor; | |
161 group->point_add = &ec_GF2m_pt_add_aff; | |
162 group->point_sub = &ec_GF2m_pt_sub_aff; | |
163 group->point_dbl = &ec_GF2m_pt_dbl_aff; | |
164 group->point_mul = &ec_GF2m_pt_mul_mont; | |
165 group->base_point_mul = NULL; | |
166 group->points_mul = &ec_pts_mul_basic; | |
167 group->validate_point = &ec_GF2m_validate_point; | |
168 | |
169 CLEANUP: | |
170 if (res != MP_OKAY) { | |
171 ECGroup_free(group); | |
172 return NULL; | |
173 } | |
174 return group; | |
175 } | |
176 #endif | |
177 | |
178 /* Construct ECGroup from hex parameters and name, if any. Called by | |
179 * ECGroup_fromHex and ECGroup_fromName. */ | |
180 ECGroup * | |
181 ecgroup_fromNameAndHex(const ECCurveName name, | |
182 const ECCurveParams * params) | |
183 { | |
184 mp_int irr, curvea, curveb, genx, geny, order; | |
185 int bits; | |
186 ECGroup *group = NULL; | |
187 mp_err res = MP_OKAY; | |
188 | |
189 /* initialize values */ | |
190 MP_DIGITS(&irr) = 0; | |
191 MP_DIGITS(&curvea) = 0; | |
192 MP_DIGITS(&curveb) = 0; | |
193 MP_DIGITS(&genx) = 0; | |
194 MP_DIGITS(&geny) = 0; | |
195 MP_DIGITS(&order) = 0; | |
196 MP_CHECKOK(mp_init(&irr)); | |
197 MP_CHECKOK(mp_init(&curvea)); | |
198 MP_CHECKOK(mp_init(&curveb)); | |
199 MP_CHECKOK(mp_init(&genx)); | |
200 MP_CHECKOK(mp_init(&geny)); | |
201 MP_CHECKOK(mp_init(&order)); | |
202 MP_CHECKOK(mp_read_radix(&irr, params->irr, 16)); | |
203 MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16)); | |
204 MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16)); | |
205 MP_CHECKOK(mp_read_radix(&genx, params->genx, 16)); | |
206 MP_CHECKOK(mp_read_radix(&geny, params->geny, 16)); | |
207 MP_CHECKOK(mp_read_radix(&order, params->order, 16)); | |
208 | |
209 /* determine number of bits */ | |
210 bits = mpl_significant_bits(&irr) - 1; | |
211 if (bits < MP_OKAY) { | |
212 res = bits; | |
213 goto CLEANUP; | |
214 } | |
215 | |
216 /* determine which optimizations (if any) to use */ | |
217 if (params->field == ECField_GFp) { | |
218 switch (name) { | |
219 #ifdef NSS_ECC_MORE_THAN_SUITE_B | |
220 #ifdef ECL_USE_FP | |
221 case ECCurve_SECG_PRIME_160R1: | |
222 group = | |
223 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, | |
224 &order, params->cofactor); | |
225 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
226 MP_CHECKOK(ec_group_set_secp160r1_fp(group)); | |
227 break; | |
228 #endif | |
229 case ECCurve_SECG_PRIME_192R1: | |
230 #ifdef ECL_USE_FP | |
231 group = | |
232 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, | |
233 &order, params->cofactor); | |
234 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
235 MP_CHECKOK(ec_group_set_nistp192_fp(group)); | |
236 #else | |
237 group = | |
238 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, | |
239 &order, params->cofactor); | |
240 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
241 MP_CHECKOK(ec_group_set_gfp192(group, name)); | |
242 #endif | |
243 break; | |
244 case ECCurve_SECG_PRIME_224R1: | |
245 #ifdef ECL_USE_FP | |
246 group = | |
247 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, | |
248 &order, params->cofactor); | |
249 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
250 MP_CHECKOK(ec_group_set_nistp224_fp(group)); | |
251 #else | |
252 group = | |
253 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, | |
254 &order, params->cofactor); | |
255 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
256 MP_CHECKOK(ec_group_set_gfp224(group, name)); | |
257 #endif | |
258 break; | |
259 #endif /* NSS_ECC_MORE_THAN_SUITE_B */ | |
260 case ECCurve_SECG_PRIME_256R1: | |
261 group = | |
262 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, | |
263 &order, params->cofactor); | |
264 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
265 MP_CHECKOK(ec_group_set_gfp256(group, name)); | |
266 MP_CHECKOK(ec_group_set_gfp256_32(group, name)); | |
267 break; | |
268 case ECCurve_SECG_PRIME_521R1: | |
269 group = | |
270 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, | |
271 &order, params->cofactor); | |
272 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
273 MP_CHECKOK(ec_group_set_gfp521(group, name)); | |
274 break; | |
275 default: | |
276 /* use generic arithmetic */ | |
277 group = | |
278 ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, | |
279 &order, params->cofactor); | |
280 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
281 } | |
282 #ifdef NSS_ECC_MORE_THAN_SUITE_B | |
283 } else if (params->field == ECField_GF2m) { | |
284 group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor); | |
285 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } | |
286 if ((name == ECCurve_NIST_K163) || | |
287 (name == ECCurve_NIST_B163) || | |
288 (name == ECCurve_SECG_CHAR2_163R1)) { | |
289 MP_CHECKOK(ec_group_set_gf2m163(group, name)); | |
290 } else if ((name == ECCurve_SECG_CHAR2_193R1) || | |
291 (name == ECCurve_SECG_CHAR2_193R2)) { | |
292 MP_CHECKOK(ec_group_set_gf2m193(group, name)); | |
293 } else if ((name == ECCurve_NIST_K233) || | |
294 (name == ECCurve_NIST_B233)) { | |
295 MP_CHECKOK(ec_group_set_gf2m233(group, name)); | |
296 } | |
297 #endif | |
298 } else { | |
299 res = MP_UNDEF; | |
300 goto CLEANUP; | |
301 } | |
302 | |
303 /* set name, if any */ | |
304 if ((group != NULL) && (params->text != NULL)) { | |
305 group->text = strdup(params->text); | |
306 if (group->text == NULL) { | |
307 res = MP_MEM; | |
308 } | |
309 } | |
310 | |
311 CLEANUP: | |
312 mp_clear(&irr); | |
313 mp_clear(&curvea); | |
314 mp_clear(&curveb); | |
315 mp_clear(&genx); | |
316 mp_clear(&geny); | |
317 mp_clear(&order); | |
318 if (res != MP_OKAY) { | |
319 ECGroup_free(group); | |
320 return NULL; | |
321 } | |
322 return group; | |
323 } | |
324 | |
325 /* Construct ECGroup from hexadecimal representations of parameters. */ | |
326 ECGroup * | |
327 ECGroup_fromHex(const ECCurveParams * params) | |
328 { | |
329 return ecgroup_fromNameAndHex(ECCurve_noName, params); | |
330 } | |
331 | |
332 /* Construct ECGroup from named parameters. */ | |
333 ECGroup * | |
334 ECGroup_fromName(const ECCurveName name) | |
335 { | |
336 ECGroup *group = NULL; | |
337 ECCurveParams *params = NULL; | |
338 mp_err res = MP_OKAY; | |
339 | |
340 params = EC_GetNamedCurveParams(name); | |
341 if (params == NULL) { | |
342 res = MP_UNDEF; | |
343 goto CLEANUP; | |
344 } | |
345 | |
346 /* construct actual group */ | |
347 group = ecgroup_fromNameAndHex(name, params); | |
348 if (group == NULL) { | |
349 res = MP_UNDEF; | |
350 goto CLEANUP; | |
351 } | |
352 | |
353 CLEANUP: | |
354 EC_FreeCurveParams(params); | |
355 if (res != MP_OKAY) { | |
356 ECGroup_free(group); | |
357 return NULL; | |
358 } | |
359 return group; | |
360 } | |
361 | |
362 /* Validates an EC public key as described in Section 5.2.2 of X9.62. */ | |
363 mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const | |
364 mp_int *py) | |
365 { | |
366 /* 1: Verify that publicValue is not the point at infinity */ | |
367 /* 2: Verify that the coordinates of publicValue are elements | |
368 * of the field. | |
369 */ | |
370 /* 3: Verify that publicValue is on the curve. */ | |
371 /* 4: Verify that the order of the curve times the publicValue | |
372 * is the point at infinity. | |
373 */ | |
374 return group->validate_point(px, py, group); | |
375 } | |
376 | |
377 /* Free the memory allocated (if any) to an ECGroup object. */ | |
378 void | |
379 ECGroup_free(ECGroup *group) | |
380 { | |
381 if (group == NULL) | |
382 return; | |
383 GFMethod_free(group->meth); | |
384 if (group->constructed == MP_NO) | |
385 return; | |
386 mp_clear(&group->curvea); | |
387 mp_clear(&group->curveb); | |
388 mp_clear(&group->genx); | |
389 mp_clear(&group->geny); | |
390 mp_clear(&group->order); | |
391 if (group->text != NULL) | |
392 free(group->text); | |
393 if (group->extra_free != NULL) | |
394 group->extra_free(group); | |
395 free(group); | |
396 } |