OLD | NEW |
| (Empty) |
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 #ifdef NSS_ENABLE_ECC | |
6 | |
7 #include "blapi.h" | |
8 #include "secoid.h" | |
9 #include "secitem.h" | |
10 #include "secerr.h" | |
11 #include "ec.h" | |
12 #include "ecl-curve.h" | |
13 | |
14 #define CHECK_OK(func) if (func == NULL) goto cleanup | |
15 #define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup | |
16 | |
17 /* | |
18 * Initializes a SECItem from a hexadecimal string | |
19 * | |
20 * Warning: This function ignores leading 00's, so any leading 00's | |
21 * in the hexadecimal string must be optional. | |
22 */ | |
23 static SECItem * | |
24 hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str) | |
25 { | |
26 int i = 0; | |
27 int byteval = 0; | |
28 int tmp = PORT_Strlen(str); | |
29 | |
30 if ((tmp % 2) != 0) return NULL; | |
31 | |
32 /* skip leading 00's unless the hex string is "00" */ | |
33 while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { | |
34 str += 2; | |
35 tmp -= 2; | |
36 } | |
37 | |
38 item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2); | |
39 if (item->data == NULL) return NULL; | |
40 item->len = tmp/2; | |
41 | |
42 while (str[i]) { | |
43 if ((str[i] >= '0') && (str[i] <= '9')) | |
44 tmp = str[i] - '0'; | |
45 else if ((str[i] >= 'a') && (str[i] <= 'f')) | |
46 tmp = str[i] - 'a' + 10; | |
47 else if ((str[i] >= 'A') && (str[i] <= 'F')) | |
48 tmp = str[i] - 'A' + 10; | |
49 else | |
50 return NULL; | |
51 | |
52 byteval = byteval * 16 + tmp; | |
53 if ((i % 2) != 0) { | |
54 item->data[i/2] = byteval; | |
55 byteval = 0; | |
56 } | |
57 i++; | |
58 } | |
59 | |
60 return item; | |
61 } | |
62 | |
63 /* Copy all of the fields from srcParams into dstParams | |
64 */ | |
65 SECStatus | |
66 EC_CopyParams(PRArenaPool *arena, ECParams *dstParams, | |
67 const ECParams *srcParams) | |
68 { | |
69 SECStatus rv = SECFailure; | |
70 | |
71 dstParams->arena = arena; | |
72 dstParams->type = srcParams->type; | |
73 dstParams->fieldID.size = srcParams->fieldID.size; | |
74 dstParams->fieldID.type = srcParams->fieldID.type; | |
75 if (srcParams->fieldID.type == ec_field_GFp) { | |
76 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime, | |
77 &srcParams->fieldID.u.prime)); | |
78 } else { | |
79 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.poly, | |
80 &srcParams->fieldID.u.poly)); | |
81 } | |
82 dstParams->fieldID.k1 = srcParams->fieldID.k1; | |
83 dstParams->fieldID.k2 = srcParams->fieldID.k2; | |
84 dstParams->fieldID.k3 = srcParams->fieldID.k3; | |
85 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.a, | |
86 &srcParams->curve.a)); | |
87 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.b, | |
88 &srcParams->curve.b)); | |
89 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.seed, | |
90 &srcParams->curve.seed)); | |
91 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->base, | |
92 &srcParams->base)); | |
93 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->order, | |
94 &srcParams->order)); | |
95 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->DEREncoding, | |
96 &srcParams->DEREncoding)); | |
97 dstParams->name = srcParams->name; | |
98 CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curveOID, | |
99 &srcParams->curveOID)); | |
100 dstParams->cofactor = srcParams->cofactor; | |
101 | |
102 return SECSuccess; | |
103 | |
104 cleanup: | |
105 return SECFailure; | |
106 } | |
107 | |
108 static SECStatus | |
109 gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params) | |
110 { | |
111 SECStatus rv = SECFailure; | |
112 const ECCurveParams *curveParams; | |
113 /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */ | |
114 char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; | |
115 | |
116 if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup; | |
117 params->name = name; | |
118 curveParams = ecCurve_map[params->name]; | |
119 CHECK_OK(curveParams); | |
120 params->fieldID.size = curveParams->size; | |
121 params->fieldID.type = field_type; | |
122 if (field_type == ec_field_GFp) { | |
123 CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.prime, | |
124 curveParams->irr)); | |
125 } else { | |
126 CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.poly, | |
127 curveParams->irr)); | |
128 } | |
129 CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, | |
130 curveParams->curvea)); | |
131 CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, | |
132 curveParams->curveb)); | |
133 genenc[0] = '0'; | |
134 genenc[1] = '4'; | |
135 genenc[2] = '\0'; | |
136 strcat(genenc, curveParams->genx); | |
137 strcat(genenc, curveParams->geny); | |
138 CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, genenc)); | |
139 CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, | |
140 curveParams->order)); | |
141 params->cofactor = curveParams->cofactor; | |
142 | |
143 rv = SECSuccess; | |
144 | |
145 cleanup: | |
146 return rv; | |
147 } | |
148 | |
149 SECStatus | |
150 EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams, | |
151 ECParams *params) | |
152 { | |
153 SECStatus rv = SECFailure; | |
154 SECOidTag tag; | |
155 SECItem oid = { siBuffer, NULL, 0}; | |
156 | |
157 #if EC_DEBUG | |
158 int i; | |
159 | |
160 printf("Encoded params in EC_DecodeParams: "); | |
161 for (i = 0; i < encodedParams->len; i++) { | |
162 printf("%02x:", encodedParams->data[i]); | |
163 } | |
164 printf("\n"); | |
165 #endif | |
166 | |
167 if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) && | |
168 (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) { | |
169 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | |
170 return SECFailure; | |
171 }; | |
172 | |
173 oid.len = encodedParams->len - 2; | |
174 oid.data = encodedParams->data + 2; | |
175 if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) || | |
176 ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) { | |
177 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | |
178 return SECFailure; | |
179 } | |
180 | |
181 params->arena = arena; | |
182 params->cofactor = 0; | |
183 params->type = ec_params_named; | |
184 params->name = ECCurve_noName; | |
185 | |
186 /* For named curves, fill out curveOID */ | |
187 params->curveOID.len = oid.len; | |
188 params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len); | |
189 if (params->curveOID.data == NULL) goto cleanup; | |
190 memcpy(params->curveOID.data, oid.data, oid.len); | |
191 | |
192 #if EC_DEBUG | |
193 printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag)); | |
194 #endif | |
195 | |
196 switch (tag) { | |
197 | |
198 /* Binary curves */ | |
199 | |
200 case SEC_OID_ANSIX962_EC_C2PNB163V1: | |
201 /* Populate params for c2pnb163v1 */ | |
202 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_
GF2m, | |
203 params) ); | |
204 break; | |
205 | |
206 case SEC_OID_ANSIX962_EC_C2PNB163V2: | |
207 /* Populate params for c2pnb163v2 */ | |
208 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_
GF2m, | |
209 params) ); | |
210 break; | |
211 | |
212 case SEC_OID_ANSIX962_EC_C2PNB163V3: | |
213 /* Populate params for c2pnb163v3 */ | |
214 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_
GF2m, | |
215 params) ); | |
216 break; | |
217 | |
218 case SEC_OID_ANSIX962_EC_C2PNB176V1: | |
219 /* Populate params for c2pnb176v1 */ | |
220 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_
GF2m, | |
221 params) ); | |
222 break; | |
223 | |
224 case SEC_OID_ANSIX962_EC_C2TNB191V1: | |
225 /* Populate params for c2tnb191v1 */ | |
226 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_
GF2m, | |
227 params) ); | |
228 break; | |
229 | |
230 case SEC_OID_ANSIX962_EC_C2TNB191V2: | |
231 /* Populate params for c2tnb191v2 */ | |
232 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_
GF2m, | |
233 params) ); | |
234 break; | |
235 | |
236 case SEC_OID_ANSIX962_EC_C2TNB191V3: | |
237 /* Populate params for c2tnb191v3 */ | |
238 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_
GF2m, | |
239 params) ); | |
240 break; | |
241 | |
242 case SEC_OID_ANSIX962_EC_C2PNB208W1: | |
243 /* Populate params for c2pnb208w1 */ | |
244 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_
GF2m, | |
245 params) ); | |
246 break; | |
247 | |
248 case SEC_OID_ANSIX962_EC_C2TNB239V1: | |
249 /* Populate params for c2tnb239v1 */ | |
250 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_
GF2m, | |
251 params) ); | |
252 break; | |
253 | |
254 case SEC_OID_ANSIX962_EC_C2TNB239V2: | |
255 /* Populate params for c2tnb239v2 */ | |
256 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_
GF2m, | |
257 params) ); | |
258 break; | |
259 | |
260 case SEC_OID_ANSIX962_EC_C2TNB239V3: | |
261 /* Populate params for c2tnb239v3 */ | |
262 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_
GF2m, | |
263 params) ); | |
264 break; | |
265 | |
266 case SEC_OID_ANSIX962_EC_C2PNB272W1: | |
267 /* Populate params for c2pnb272w1 */ | |
268 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_
GF2m, | |
269 params) ); | |
270 break; | |
271 | |
272 case SEC_OID_ANSIX962_EC_C2PNB304W1: | |
273 /* Populate params for c2pnb304w1 */ | |
274 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_
GF2m, | |
275 params) ); | |
276 break; | |
277 | |
278 case SEC_OID_ANSIX962_EC_C2TNB359V1: | |
279 /* Populate params for c2tnb359v1 */ | |
280 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_
GF2m, | |
281 params) ); | |
282 break; | |
283 | |
284 case SEC_OID_ANSIX962_EC_C2PNB368W1: | |
285 /* Populate params for c2pnb368w1 */ | |
286 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_
GF2m, | |
287 params) ); | |
288 break; | |
289 | |
290 case SEC_OID_ANSIX962_EC_C2TNB431R1: | |
291 /* Populate params for c2tnb431r1 */ | |
292 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_
GF2m, | |
293 params) ); | |
294 break; | |
295 | |
296 case SEC_OID_SECG_EC_SECT113R1: | |
297 /* Populate params for sect113r1 */ | |
298 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m
, | |
299 params) ); | |
300 break; | |
301 | |
302 case SEC_OID_SECG_EC_SECT113R2: | |
303 /* Populate params for sect113r2 */ | |
304 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m
, | |
305 params) ); | |
306 break; | |
307 | |
308 case SEC_OID_SECG_EC_SECT131R1: | |
309 /* Populate params for sect131r1 */ | |
310 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m
, | |
311 params) ); | |
312 break; | |
313 | |
314 case SEC_OID_SECG_EC_SECT131R2: | |
315 /* Populate params for sect131r2 */ | |
316 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m
, | |
317 params) ); | |
318 break; | |
319 | |
320 case SEC_OID_SECG_EC_SECT163K1: | |
321 /* Populate params for sect163k1 | |
322 * (the NIST K-163 curve) | |
323 */ | |
324 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m
, | |
325 params) ); | |
326 break; | |
327 | |
328 case SEC_OID_SECG_EC_SECT163R1: | |
329 /* Populate params for sect163r1 */ | |
330 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m
, | |
331 params) ); | |
332 break; | |
333 | |
334 case SEC_OID_SECG_EC_SECT163R2: | |
335 /* Populate params for sect163r2 | |
336 * (the NIST B-163 curve) | |
337 */ | |
338 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m
, | |
339 params) ); | |
340 break; | |
341 | |
342 case SEC_OID_SECG_EC_SECT193R1: | |
343 /* Populate params for sect193r1 */ | |
344 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m
, | |
345 params) ); | |
346 break; | |
347 | |
348 case SEC_OID_SECG_EC_SECT193R2: | |
349 /* Populate params for sect193r2 */ | |
350 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m
, | |
351 params) ); | |
352 break; | |
353 | |
354 case SEC_OID_SECG_EC_SECT233K1: | |
355 /* Populate params for sect233k1 | |
356 * (the NIST K-233 curve) | |
357 */ | |
358 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m
, | |
359 params) ); | |
360 break; | |
361 | |
362 case SEC_OID_SECG_EC_SECT233R1: | |
363 /* Populate params for sect233r1 | |
364 * (the NIST B-233 curve) | |
365 */ | |
366 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m
, | |
367 params) ); | |
368 break; | |
369 | |
370 case SEC_OID_SECG_EC_SECT239K1: | |
371 /* Populate params for sect239k1 */ | |
372 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m
, | |
373 params) ); | |
374 break; | |
375 | |
376 case SEC_OID_SECG_EC_SECT283K1: | |
377 /* Populate params for sect283k1 | |
378 * (the NIST K-283 curve) | |
379 */ | |
380 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m
, | |
381 params) ); | |
382 break; | |
383 | |
384 case SEC_OID_SECG_EC_SECT283R1: | |
385 /* Populate params for sect283r1 | |
386 * (the NIST B-283 curve) | |
387 */ | |
388 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m
, | |
389 params) ); | |
390 break; | |
391 | |
392 case SEC_OID_SECG_EC_SECT409K1: | |
393 /* Populate params for sect409k1 | |
394 * (the NIST K-409 curve) | |
395 */ | |
396 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m
, | |
397 params) ); | |
398 break; | |
399 | |
400 case SEC_OID_SECG_EC_SECT409R1: | |
401 /* Populate params for sect409r1 | |
402 * (the NIST B-409 curve) | |
403 */ | |
404 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m
, | |
405 params) ); | |
406 break; | |
407 | |
408 case SEC_OID_SECG_EC_SECT571K1: | |
409 /* Populate params for sect571k1 | |
410 * (the NIST K-571 curve) | |
411 */ | |
412 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m
, | |
413 params) ); | |
414 break; | |
415 | |
416 case SEC_OID_SECG_EC_SECT571R1: | |
417 /* Populate params for sect571r1 | |
418 * (the NIST B-571 curve) | |
419 */ | |
420 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m
, | |
421 params) ); | |
422 break; | |
423 | |
424 /* Prime curves */ | |
425 | |
426 case SEC_OID_ANSIX962_EC_PRIME192V1: | |
427 /* Populate params for prime192v1 aka secp192r1 | |
428 * (the NIST P-192 curve) | |
429 */ | |
430 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp
, | |
431 params) ); | |
432 break; | |
433 | |
434 case SEC_OID_ANSIX962_EC_PRIME192V2: | |
435 /* Populate params for prime192v2 */ | |
436 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp
, | |
437 params) ); | |
438 break; | |
439 | |
440 case SEC_OID_ANSIX962_EC_PRIME192V3: | |
441 /* Populate params for prime192v3 */ | |
442 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp
, | |
443 params) ); | |
444 break; | |
445 | |
446 case SEC_OID_ANSIX962_EC_PRIME239V1: | |
447 /* Populate params for prime239v1 */ | |
448 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp
, | |
449 params) ); | |
450 break; | |
451 | |
452 case SEC_OID_ANSIX962_EC_PRIME239V2: | |
453 /* Populate params for prime239v2 */ | |
454 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp
, | |
455 params) ); | |
456 break; | |
457 | |
458 case SEC_OID_ANSIX962_EC_PRIME239V3: | |
459 /* Populate params for prime239v3 */ | |
460 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp
, | |
461 params) ); | |
462 break; | |
463 | |
464 case SEC_OID_ANSIX962_EC_PRIME256V1: | |
465 /* Populate params for prime256v1 aka secp256r1 | |
466 * (the NIST P-256 curve) | |
467 */ | |
468 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp
, | |
469 params) ); | |
470 break; | |
471 | |
472 case SEC_OID_SECG_EC_SECP112R1: | |
473 /* Populate params for secp112r1 */ | |
474 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp, | |
475 params) ); | |
476 break; | |
477 | |
478 case SEC_OID_SECG_EC_SECP112R2: | |
479 /* Populate params for secp112r2 */ | |
480 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp, | |
481 params) ); | |
482 break; | |
483 | |
484 case SEC_OID_SECG_EC_SECP128R1: | |
485 /* Populate params for secp128r1 */ | |
486 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp, | |
487 params) ); | |
488 break; | |
489 | |
490 case SEC_OID_SECG_EC_SECP128R2: | |
491 /* Populate params for secp128r2 */ | |
492 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp, | |
493 params) ); | |
494 break; | |
495 | |
496 case SEC_OID_SECG_EC_SECP160K1: | |
497 /* Populate params for secp160k1 */ | |
498 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp, | |
499 params) ); | |
500 break; | |
501 | |
502 case SEC_OID_SECG_EC_SECP160R1: | |
503 /* Populate params for secp160r1 */ | |
504 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp, | |
505 params) ); | |
506 break; | |
507 | |
508 case SEC_OID_SECG_EC_SECP160R2: | |
509 /* Populate params for secp160r1 */ | |
510 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp, | |
511 params) ); | |
512 break; | |
513 | |
514 case SEC_OID_SECG_EC_SECP192K1: | |
515 /* Populate params for secp192k1 */ | |
516 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp, | |
517 params) ); | |
518 break; | |
519 | |
520 case SEC_OID_SECG_EC_SECP224K1: | |
521 /* Populate params for secp224k1 */ | |
522 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp, | |
523 params) ); | |
524 break; | |
525 | |
526 case SEC_OID_SECG_EC_SECP224R1: | |
527 /* Populate params for secp224r1 | |
528 * (the NIST P-224 curve) | |
529 */ | |
530 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp, | |
531 params) ); | |
532 break; | |
533 | |
534 case SEC_OID_SECG_EC_SECP256K1: | |
535 /* Populate params for secp256k1 */ | |
536 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp, | |
537 params) ); | |
538 break; | |
539 | |
540 case SEC_OID_SECG_EC_SECP384R1: | |
541 /* Populate params for secp384r1 | |
542 * (the NIST P-384 curve) | |
543 */ | |
544 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp, | |
545 params) ); | |
546 break; | |
547 | |
548 case SEC_OID_SECG_EC_SECP521R1: | |
549 /* Populate params for secp521r1 | |
550 * (the NIST P-521 curve) | |
551 */ | |
552 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp, | |
553 params) ); | |
554 break; | |
555 | |
556 default: | |
557 break; | |
558 }; | |
559 | |
560 cleanup: | |
561 if (!params->cofactor) { | |
562 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | |
563 #if EC_DEBUG | |
564 printf("Unrecognized curve, returning NULL params\n"); | |
565 #endif | |
566 } | |
567 | |
568 return rv; | |
569 } | |
570 | |
571 SECStatus | |
572 EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams) | |
573 { | |
574 PRArenaPool *arena; | |
575 ECParams *params; | |
576 SECStatus rv = SECFailure; | |
577 | |
578 /* Initialize an arena for the ECParams structure */ | |
579 if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE))) | |
580 return SECFailure; | |
581 | |
582 params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams)); | |
583 if (!params) { | |
584 PORT_FreeArena(arena, PR_TRUE); | |
585 return SECFailure; | |
586 } | |
587 | |
588 /* Copy the encoded params */ | |
589 SECITEM_AllocItem(arena, &(params->DEREncoding), | |
590 encodedParams->len); | |
591 memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len); | |
592 | |
593 /* Fill out the rest of the ECParams structure based on | |
594 * the encoded params | |
595 */ | |
596 rv = EC_FillParams(arena, encodedParams, params); | |
597 if (rv == SECFailure) { | |
598 PORT_FreeArena(arena, PR_TRUE); | |
599 return SECFailure; | |
600 } else { | |
601 *ecparams = params;; | |
602 return SECSuccess; | |
603 } | |
604 } | |
605 | |
606 #endif /* NSS_ENABLE_ECC */ | |
OLD | NEW |