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