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 * 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 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 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 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