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 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)