1 /*
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is the Elliptic Curve Cryptography library.
16 *
17 * The Initial Developer of the Original Code is
18 * Sun Microsystems, Inc.
19 * Portions created by the Initial Developer are Copyright (C) 2003
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Dr Vipul Gupta <vipul.gupta@sun.com> and
24 * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39 /*
40 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
41 * Use is subject to license terms.
42 *
43 * Sun elects to use this software under the MPL license.
44 */
45
46 #pragma ident "%Z%%M% %I% %E% SMI"
47
48 #include <sys/types.h>
49 #include <sys/systm.h>
50 #include <sys/param.h>
51 #ifdef _KERNEL
52 #include <sys/kmem.h>
53 #else
54 #include <string.h>
55 #endif
56 #include "ec.h"
57 #include "ecl-curve.h"
58 #include "ecc_impl.h"
59
60 #define MAX_ECKEY_LEN 72
61 #define SEC_ASN1_OBJECT_ID 0x06
62
63 /*
64 * Initializes a SECItem from a hexadecimal string
65 *
66 * Warning: This function ignores leading 00's, so any leading 00's
67 * in the hexadecimal string must be optional.
68 */
69 static SECItem *
hexString2SECItem(PRArenaPool * arena,SECItem * item,const char * str,int kmflag)70 hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str,
71 int kmflag)
72 {
73 int i = 0;
74 int byteval = 0;
75 int tmp = strlen(str);
76
77 if ((tmp % 2) != 0) return NULL;
78
79 /* skip leading 00's unless the hex string is "00" */
80 while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
81 str += 2;
82 tmp -= 2;
83 }
84
85 item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2, kmflag);
86 if (item->data == NULL) return NULL;
87 item->len = tmp/2;
88
89 while (str[i]) {
90 if ((str[i] >= '0') && (str[i] <= '9'))
91 tmp = str[i] - '0';
92 else if ((str[i] >= 'a') && (str[i] <= 'f'))
93 tmp = str[i] - 'a' + 10;
94 else if ((str[i] >= 'A') && (str[i] <= 'F'))
95 tmp = str[i] - 'A' + 10;
96 else
97 return NULL;
98
99 byteval = byteval * 16 + tmp;
100 if ((i % 2) != 0) {
101 item->data[i/2] = byteval;
102 byteval = 0;
103 }
104 i++;
105 }
106
107 return item;
108 }
109
110 static SECStatus
gf_populate_params(ECCurveName name,ECFieldType field_type,ECParams * params,int kmflag)111 gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params,
112 int kmflag)
113 {
114 SECStatus rv = SECFailure;
115 const ECCurveParams *curveParams;
116 /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
117 char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
118
119 if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
120 params->name = name;
121 curveParams = ecCurve_map[params->name];
122 CHECK_OK(curveParams);
123 params->fieldID.size = curveParams->size;
124 params->fieldID.type = field_type;
125 if (field_type == ec_field_GFp) {
126 CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.prime,
127 curveParams->irr, kmflag));
128 } else {
129 CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.poly,
130 curveParams->irr, kmflag));
131 }
132 CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.a,
133 curveParams->curvea, kmflag));
134 CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.b,
135 curveParams->curveb, kmflag));
136 genenc[0] = '0';
137 genenc[1] = '4';
138 genenc[2] = '\0';
139 strcat(genenc, curveParams->genx);
140 strcat(genenc, curveParams->geny);
141 CHECK_OK(hexString2SECItem(NULL, ¶ms->base, genenc, kmflag));
142 CHECK_OK(hexString2SECItem(NULL, ¶ms->order,
143 curveParams->order, kmflag));
144 params->cofactor = curveParams->cofactor;
145
146 rv = SECSuccess;
147
148 cleanup:
149 return rv;
150 }
151
152 ECCurveName SECOID_FindOIDTag(const SECItem *);
153
154 SECStatus
EC_FillParams(PRArenaPool * arena,const SECItem * encodedParams,ECParams * params,int kmflag)155 EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
156 ECParams *params, int kmflag)
157 {
158 SECStatus rv = SECFailure;
159 ECCurveName tag;
160 SECItem oid = { siBuffer, NULL, 0};
161
162 #if EC_DEBUG
163 int i;
164
165 printf("Encoded params in EC_DecodeParams: ");
166 for (i = 0; i < encodedParams->len; i++) {
167 printf("%02x:", encodedParams->data[i]);
168 }
169 printf("\n");
170 #endif
171
172 if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
173 (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
174 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
175 return SECFailure;
176 };
177
178 oid.len = encodedParams->len - 2;
179 oid.data = encodedParams->data + 2;
180 if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
181 ((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) {
182 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
183 return SECFailure;
184 }
185
186 params->arena = arena;
187 params->cofactor = 0;
188 params->type = ec_params_named;
189 params->name = ECCurve_noName;
190
191 /* For named curves, fill out curveOID */
192 params->curveOID.len = oid.len;
193 params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len,
194 kmflag);
195 if (params->curveOID.data == NULL) goto cleanup;
196 memcpy(params->curveOID.data, oid.data, oid.len);
197
198 #if EC_DEBUG
199 printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
200 #endif
201
202 switch (tag) {
203
204 /* Binary curves */
205
206 case ECCurve_X9_62_CHAR2_PNB163V1:
207 /* Populate params for c2pnb163v1 */
208 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
209 params, kmflag) );
210 break;
211
212 case ECCurve_X9_62_CHAR2_PNB163V2:
213 /* Populate params for c2pnb163v2 */
214 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
215 params, kmflag) );
216 break;
217
218 case ECCurve_X9_62_CHAR2_PNB163V3:
219 /* Populate params for c2pnb163v3 */
220 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
221 params, kmflag) );
222 break;
223
224 case ECCurve_X9_62_CHAR2_PNB176V1:
225 /* Populate params for c2pnb176v1 */
226 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
227 params, kmflag) );
228 break;
229
230 case ECCurve_X9_62_CHAR2_TNB191V1:
231 /* Populate params for c2tnb191v1 */
232 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
233 params, kmflag) );
234 break;
235
236 case ECCurve_X9_62_CHAR2_TNB191V2:
237 /* Populate params for c2tnb191v2 */
238 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
239 params, kmflag) );
240 break;
241
242 case ECCurve_X9_62_CHAR2_TNB191V3:
243 /* Populate params for c2tnb191v3 */
244 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
245 params, kmflag) );
246 break;
247
248 case ECCurve_X9_62_CHAR2_PNB208W1:
249 /* Populate params for c2pnb208w1 */
250 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
251 params, kmflag) );
252 break;
253
254 case ECCurve_X9_62_CHAR2_TNB239V1:
255 /* Populate params for c2tnb239v1 */
256 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
257 params, kmflag) );
258 break;
259
260 case ECCurve_X9_62_CHAR2_TNB239V2:
261 /* Populate params for c2tnb239v2 */
262 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
263 params, kmflag) );
264 break;
265
266 case ECCurve_X9_62_CHAR2_TNB239V3:
267 /* Populate params for c2tnb239v3 */
268 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
269 params, kmflag) );
270 break;
271
272 case ECCurve_X9_62_CHAR2_PNB272W1:
273 /* Populate params for c2pnb272w1 */
274 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
275 params, kmflag) );
276 break;
277
278 case ECCurve_X9_62_CHAR2_PNB304W1:
279 /* Populate params for c2pnb304w1 */
280 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
281 params, kmflag) );
282 break;
283
284 case ECCurve_X9_62_CHAR2_TNB359V1:
285 /* Populate params for c2tnb359v1 */
286 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
287 params, kmflag) );
288 break;
289
290 case ECCurve_X9_62_CHAR2_PNB368W1:
291 /* Populate params for c2pnb368w1 */
292 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
293 params, kmflag) );
294 break;
295
296 case ECCurve_X9_62_CHAR2_TNB431R1:
297 /* Populate params for c2tnb431r1 */
298 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
299 params, kmflag) );
300 break;
301
302 case ECCurve_SECG_CHAR2_113R1:
303 /* Populate params for sect113r1 */
304 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
305 params, kmflag) );
306 break;
307
308 case ECCurve_SECG_CHAR2_113R2:
309 /* Populate params for sect113r2 */
310 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
311 params, kmflag) );
312 break;
313
314 case ECCurve_SECG_CHAR2_131R1:
315 /* Populate params for sect131r1 */
316 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
317 params, kmflag) );
318 break;
319
320 case ECCurve_SECG_CHAR2_131R2:
321 /* Populate params for sect131r2 */
322 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
323 params, kmflag) );
324 break;
325
326 case ECCurve_SECG_CHAR2_163K1:
327 /* Populate params for sect163k1
328 * (the NIST K-163 curve)
329 */
330 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
331 params, kmflag) );
332 break;
333
334 case ECCurve_SECG_CHAR2_163R1:
335 /* Populate params for sect163r1 */
336 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
337 params, kmflag) );
338 break;
339
340 case ECCurve_SECG_CHAR2_163R2:
341 /* Populate params for sect163r2
342 * (the NIST B-163 curve)
343 */
344 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
345 params, kmflag) );
346 break;
347
348 case ECCurve_SECG_CHAR2_193R1:
349 /* Populate params for sect193r1 */
350 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
351 params, kmflag) );
352 break;
353
354 case ECCurve_SECG_CHAR2_193R2:
355 /* Populate params for sect193r2 */
356 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
357 params, kmflag) );
358 break;
359
360 case ECCurve_SECG_CHAR2_233K1:
361 /* Populate params for sect233k1
362 * (the NIST K-233 curve)
363 */
364 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
365 params, kmflag) );
366 break;
367
368 case ECCurve_SECG_CHAR2_233R1:
369 /* Populate params for sect233r1
370 * (the NIST B-233 curve)
371 */
372 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
373 params, kmflag) );
374 break;
375
376 case ECCurve_SECG_CHAR2_239K1:
377 /* Populate params for sect239k1 */
378 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
379 params, kmflag) );
380 break;
381
382 case ECCurve_SECG_CHAR2_283K1:
383 /* Populate params for sect283k1
384 * (the NIST K-283 curve)
385 */
386 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
387 params, kmflag) );
388 break;
389
390 case ECCurve_SECG_CHAR2_283R1:
391 /* Populate params for sect283r1
392 * (the NIST B-283 curve)
393 */
394 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
395 params, kmflag) );
396 break;
397
398 case ECCurve_SECG_CHAR2_409K1:
399 /* Populate params for sect409k1
400 * (the NIST K-409 curve)
401 */
402 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
403 params, kmflag) );
404 break;
405
406 case ECCurve_SECG_CHAR2_409R1:
407 /* Populate params for sect409r1
408 * (the NIST B-409 curve)
409 */
410 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
411 params, kmflag) );
412 break;
413
414 case ECCurve_SECG_CHAR2_571K1:
415 /* Populate params for sect571k1
416 * (the NIST K-571 curve)
417 */
418 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
419 params, kmflag) );
420 break;
421
422 case ECCurve_SECG_CHAR2_571R1:
423 /* Populate params for sect571r1
424 * (the NIST B-571 curve)
425 */
426 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
427 params, kmflag) );
428 break;
429
430 /* Prime curves */
431
432 case ECCurve_X9_62_PRIME_192V1:
433 /* Populate params for prime192v1 aka secp192r1
434 * (the NIST P-192 curve)
435 */
436 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
437 params, kmflag) );
438 break;
439
440 case ECCurve_X9_62_PRIME_192V2:
441 /* Populate params for prime192v2 */
442 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
443 params, kmflag) );
444 break;
445
446 case ECCurve_X9_62_PRIME_192V3:
447 /* Populate params for prime192v3 */
448 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
449 params, kmflag) );
450 break;
451
452 case ECCurve_X9_62_PRIME_239V1:
453 /* Populate params for prime239v1 */
454 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
455 params, kmflag) );
456 break;
457
458 case ECCurve_X9_62_PRIME_239V2:
459 /* Populate params for prime239v2 */
460 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
461 params, kmflag) );
462 break;
463
464 case ECCurve_X9_62_PRIME_239V3:
465 /* Populate params for prime239v3 */
466 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
467 params, kmflag) );
468 break;
469
470 case ECCurve_X9_62_PRIME_256V1:
471 /* Populate params for prime256v1 aka secp256r1
472 * (the NIST P-256 curve)
473 */
474 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
475 params, kmflag) );
476 break;
477
478 case ECCurve_SECG_PRIME_112R1:
479 /* Populate params for secp112r1 */
480 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
481 params, kmflag) );
482 break;
483
484 case ECCurve_SECG_PRIME_112R2:
485 /* Populate params for secp112r2 */
486 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
487 params, kmflag) );
488 break;
489
490 case ECCurve_SECG_PRIME_128R1:
491 /* Populate params for secp128r1 */
492 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
493 params, kmflag) );
494 break;
495
496 case ECCurve_SECG_PRIME_128R2:
497 /* Populate params for secp128r2 */
498 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
499 params, kmflag) );
500 break;
501
502 case ECCurve_SECG_PRIME_160K1:
503 /* Populate params for secp160k1 */
504 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
505 params, kmflag) );
506 break;
507
508 case ECCurve_SECG_PRIME_160R1:
509 /* Populate params for secp160r1 */
510 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
511 params, kmflag) );
512 break;
513
514 case ECCurve_SECG_PRIME_160R2:
515 /* Populate params for secp160r1 */
516 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
517 params, kmflag) );
518 break;
519
520 case ECCurve_SECG_PRIME_192K1:
521 /* Populate params for secp192k1 */
522 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
523 params, kmflag) );
524 break;
525
526 case ECCurve_SECG_PRIME_224K1:
527 /* Populate params for secp224k1 */
528 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
529 params, kmflag) );
530 break;
531
532 case ECCurve_SECG_PRIME_224R1:
533 /* Populate params for secp224r1
534 * (the NIST P-224 curve)
535 */
536 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
537 params, kmflag) );
538 break;
539
540 case ECCurve_SECG_PRIME_256K1:
541 /* Populate params for secp256k1 */
542 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
543 params, kmflag) );
544 break;
545
546 case ECCurve_SECG_PRIME_384R1:
547 /* Populate params for secp384r1
548 * (the NIST P-384 curve)
549 */
550 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
551 params, kmflag) );
552 break;
553
554 case ECCurve_SECG_PRIME_521R1:
555 /* Populate params for secp521r1
556 * (the NIST P-521 curve)
557 */
558 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
559 params, kmflag) );
560 break;
561
562 default:
563 break;
564 };
565
566 cleanup:
567 if (!params->cofactor) {
568 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
569 #if EC_DEBUG
570 printf("Unrecognized curve, returning NULL params\n");
571 #endif
572 }
573
574 return rv;
575 }
576
577 SECStatus
EC_DecodeParams(const SECItem * encodedParams,ECParams ** ecparams,int kmflag)578 EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams, int kmflag)
579 {
580 PRArenaPool *arena;
581 ECParams *params;
582 SECStatus rv = SECFailure;
583
584 /* Initialize an arena for the ECParams structure */
585 if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
586 return SECFailure;
587
588 params = (ECParams *)PORT_ArenaZAlloc(NULL, sizeof(ECParams), kmflag);
589 if (!params) {
590 PORT_FreeArena(NULL, B_TRUE);
591 return SECFailure;
592 }
593
594 /* Copy the encoded params */
595 SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len,
596 kmflag);
597 memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
598
599 /* Fill out the rest of the ECParams structure based on
600 * the encoded params
601 */
602 rv = EC_FillParams(NULL, encodedParams, params, kmflag);
603 if (rv == SECFailure) {
604 PORT_FreeArena(NULL, B_TRUE);
605 return SECFailure;
606 } else {
607 *ecparams = params;;
608 return SECSuccess;
609 }
610 }
611