1 /* 2 * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this library; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* ********************************************************************* 25 * 26 * The Original Code is the Elliptic Curve Cryptography library. 27 * 28 * The Initial Developer of the Original Code is 29 * Sun Microsystems, Inc. 30 * Portions created by the Initial Developer are Copyright (C) 2003 31 * the Initial Developer. All Rights Reserved. 32 * 33 * Contributor(s): 34 * Dr Vipul Gupta <vipul.gupta@sun.com> and 35 * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories 36 * 37 * Last Modified Date from the Original Code: March 2012 38 *********************************************************************** */ 39 40 #include <sys/types.h> 41 42 #ifndef _WIN32 43 #if !defined(__linux__) && !defined(_ALLBSD_SOURCE) 44 #include <sys/systm.h> 45 #endif /* __linux__ || _ALLBSD_SOURCE */ 46 #include <sys/param.h> 47 #endif /* _WIN32 */ 48 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 = (int)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 (((int)name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) 118 goto cleanup; 119 params->name = name; 120 curveParams = ecCurve_map[params->name]; 121 CHECK_OK(curveParams); 122 params->fieldID.size = curveParams->size; 123 params->fieldID.type = field_type; 124 if (field_type == ec_field_GFp) { 125 CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.prime, 126 curveParams->irr, kmflag)); 127 } else { 128 CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.poly, 129 curveParams->irr, kmflag)); 130 } 131 CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.a, 132 curveParams->curvea, kmflag)); 133 CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.b, 134 curveParams->curveb, kmflag)); 135 genenc[0] = '0'; 136 genenc[1] = '4'; 137 genenc[2] = '\0'; 138 strcat(genenc, curveParams->genx); 139 strcat(genenc, curveParams->geny); 140 CHECK_OK(hexString2SECItem(NULL, ¶ms->base, genenc, kmflag)); 141 CHECK_OK(hexString2SECItem(NULL, ¶ms->order, 142 curveParams->order, kmflag)); 143 params->cofactor = curveParams->cofactor; 144 145 rv = SECSuccess; 146 147 cleanup: 148 return rv; 149 } 150 151 ECCurveName SECOID_FindOIDTag(const SECItem *); 152 153 SECStatus 154 EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams, 155 ECParams *params, int kmflag) 156 { 157 SECStatus rv = SECFailure; 158 ECCurveName tag; 159 SECItem oid = { siBuffer, NULL, 0}; 160 161 #if EC_DEBUG 162 int i; 163 164 printf("Encoded params in EC_DecodeParams: "); 165 for (i = 0; i < encodedParams->len; i++) { 166 printf("%02x:", encodedParams->data[i]); 167 } 168 printf("\n"); 169 #endif 170 171 if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) && 172 (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) { 173 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); 174 return SECFailure; 175 }; 176 177 oid.len = encodedParams->len - 2; 178 oid.data = encodedParams->data + 2; 179 if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) || 180 ((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) { 181 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); 182 return SECFailure; 183 } 184 185 params->arena = arena; 186 params->cofactor = 0; 187 params->type = ec_params_named; 188 params->name = ECCurve_noName; 189 190 /* For named curves, fill out curveOID */ 191 params->curveOID.len = oid.len; 192 params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len, 193 kmflag); 194 if (params->curveOID.data == NULL) goto cleanup; 195 memcpy(params->curveOID.data, oid.data, oid.len); 196 197 #if EC_DEBUG 198 #ifndef SECOID_FindOIDTagDescription 199 printf("Curve: %s\n", ecCurve_map[tag]->text); 200 #else 201 printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag)); 202 #endif 203 #endif 204 205 switch (tag) { 206 207 /* Binary curves */ 208 209 case ECCurve_X9_62_CHAR2_PNB163V1: 210 /* Populate params for c2pnb163v1 */ 211 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m, 212 params, kmflag) ); 213 break; 214 215 case ECCurve_X9_62_CHAR2_PNB163V2: 216 /* Populate params for c2pnb163v2 */ 217 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m, 218 params, kmflag) ); 219 break; 220 221 case ECCurve_X9_62_CHAR2_PNB163V3: 222 /* Populate params for c2pnb163v3 */ 223 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m, 224 params, kmflag) ); 225 break; 226 227 case ECCurve_X9_62_CHAR2_PNB176V1: 228 /* Populate params for c2pnb176v1 */ 229 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m, 230 params, kmflag) ); 231 break; 232 233 case ECCurve_X9_62_CHAR2_TNB191V1: 234 /* Populate params for c2tnb191v1 */ 235 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m, 236 params, kmflag) ); 237 break; 238 239 case ECCurve_X9_62_CHAR2_TNB191V2: 240 /* Populate params for c2tnb191v2 */ 241 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m, 242 params, kmflag) ); 243 break; 244 245 case ECCurve_X9_62_CHAR2_TNB191V3: 246 /* Populate params for c2tnb191v3 */ 247 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m, 248 params, kmflag) ); 249 break; 250 251 case ECCurve_X9_62_CHAR2_PNB208W1: 252 /* Populate params for c2pnb208w1 */ 253 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m, 254 params, kmflag) ); 255 break; 256 257 case ECCurve_X9_62_CHAR2_TNB239V1: 258 /* Populate params for c2tnb239v1 */ 259 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m, 260 params, kmflag) ); 261 break; 262 263 case ECCurve_X9_62_CHAR2_TNB239V2: 264 /* Populate params for c2tnb239v2 */ 265 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m, 266 params, kmflag) ); 267 break; 268 269 case ECCurve_X9_62_CHAR2_TNB239V3: 270 /* Populate params for c2tnb239v3 */ 271 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m, 272 params, kmflag) ); 273 break; 274 275 case ECCurve_X9_62_CHAR2_PNB272W1: 276 /* Populate params for c2pnb272w1 */ 277 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m, 278 params, kmflag) ); 279 break; 280 281 case ECCurve_X9_62_CHAR2_PNB304W1: 282 /* Populate params for c2pnb304w1 */ 283 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m, 284 params, kmflag) ); 285 break; 286 287 case ECCurve_X9_62_CHAR2_TNB359V1: 288 /* Populate params for c2tnb359v1 */ 289 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m, 290 params, kmflag) ); 291 break; 292 293 case ECCurve_X9_62_CHAR2_PNB368W1: 294 /* Populate params for c2pnb368w1 */ 295 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m, 296 params, kmflag) ); 297 break; 298 299 case ECCurve_X9_62_CHAR2_TNB431R1: 300 /* Populate params for c2tnb431r1 */ 301 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m, 302 params, kmflag) ); 303 break; 304 305 case ECCurve_SECG_CHAR2_113R1: 306 /* Populate params for sect113r1 */ 307 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m, 308 params, kmflag) ); 309 break; 310 311 case ECCurve_SECG_CHAR2_113R2: 312 /* Populate params for sect113r2 */ 313 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m, 314 params, kmflag) ); 315 break; 316 317 case ECCurve_SECG_CHAR2_131R1: 318 /* Populate params for sect131r1 */ 319 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m, 320 params, kmflag) ); 321 break; 322 323 case ECCurve_SECG_CHAR2_131R2: 324 /* Populate params for sect131r2 */ 325 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m, 326 params, kmflag) ); 327 break; 328 329 case ECCurve_SECG_CHAR2_163K1: 330 /* Populate params for sect163k1 331 * (the NIST K-163 curve) 332 */ 333 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m, 334 params, kmflag) ); 335 break; 336 337 case ECCurve_SECG_CHAR2_163R1: 338 /* Populate params for sect163r1 */ 339 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m, 340 params, kmflag) ); 341 break; 342 343 case ECCurve_SECG_CHAR2_163R2: 344 /* Populate params for sect163r2 345 * (the NIST B-163 curve) 346 */ 347 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m, 348 params, kmflag) ); 349 break; 350 351 case ECCurve_SECG_CHAR2_193R1: 352 /* Populate params for sect193r1 */ 353 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m, 354 params, kmflag) ); 355 break; 356 357 case ECCurve_SECG_CHAR2_193R2: 358 /* Populate params for sect193r2 */ 359 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m, 360 params, kmflag) ); 361 break; 362 363 case ECCurve_SECG_CHAR2_233K1: 364 /* Populate params for sect233k1 365 * (the NIST K-233 curve) 366 */ 367 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m, 368 params, kmflag) ); 369 break; 370 371 case ECCurve_SECG_CHAR2_233R1: 372 /* Populate params for sect233r1 373 * (the NIST B-233 curve) 374 */ 375 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m, 376 params, kmflag) ); 377 break; 378 379 case ECCurve_SECG_CHAR2_239K1: 380 /* Populate params for sect239k1 */ 381 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m, 382 params, kmflag) ); 383 break; 384 385 case ECCurve_SECG_CHAR2_283K1: 386 /* Populate params for sect283k1 387 * (the NIST K-283 curve) 388 */ 389 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m, 390 params, kmflag) ); 391 break; 392 393 case ECCurve_SECG_CHAR2_283R1: 394 /* Populate params for sect283r1 395 * (the NIST B-283 curve) 396 */ 397 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m, 398 params, kmflag) ); 399 break; 400 401 case ECCurve_SECG_CHAR2_409K1: 402 /* Populate params for sect409k1 403 * (the NIST K-409 curve) 404 */ 405 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m, 406 params, kmflag) ); 407 break; 408 409 case ECCurve_SECG_CHAR2_409R1: 410 /* Populate params for sect409r1 411 * (the NIST B-409 curve) 412 */ 413 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m, 414 params, kmflag) ); 415 break; 416 417 case ECCurve_SECG_CHAR2_571K1: 418 /* Populate params for sect571k1 419 * (the NIST K-571 curve) 420 */ 421 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m, 422 params, kmflag) ); 423 break; 424 425 case ECCurve_SECG_CHAR2_571R1: 426 /* Populate params for sect571r1 427 * (the NIST B-571 curve) 428 */ 429 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m, 430 params, kmflag) ); 431 break; 432 433 /* Prime curves */ 434 435 case ECCurve_X9_62_PRIME_192V1: 436 /* Populate params for prime192v1 aka secp192r1 437 * (the NIST P-192 curve) 438 */ 439 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp, 440 params, kmflag) ); 441 break; 442 443 case ECCurve_X9_62_PRIME_192V2: 444 /* Populate params for prime192v2 */ 445 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp, 446 params, kmflag) ); 447 break; 448 449 case ECCurve_X9_62_PRIME_192V3: 450 /* Populate params for prime192v3 */ 451 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp, 452 params, kmflag) ); 453 break; 454 455 case ECCurve_X9_62_PRIME_239V1: 456 /* Populate params for prime239v1 */ 457 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp, 458 params, kmflag) ); 459 break; 460 461 case ECCurve_X9_62_PRIME_239V2: 462 /* Populate params for prime239v2 */ 463 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp, 464 params, kmflag) ); 465 break; 466 467 case ECCurve_X9_62_PRIME_239V3: 468 /* Populate params for prime239v3 */ 469 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp, 470 params, kmflag) ); 471 break; 472 473 case ECCurve_X9_62_PRIME_256V1: 474 /* Populate params for prime256v1 aka secp256r1 475 * (the NIST P-256 curve) 476 */ 477 CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp, 478 params, kmflag) ); 479 break; 480 481 case ECCurve_SECG_PRIME_112R1: 482 /* Populate params for secp112r1 */ 483 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp, 484 params, kmflag) ); 485 break; 486 487 case ECCurve_SECG_PRIME_112R2: 488 /* Populate params for secp112r2 */ 489 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp, 490 params, kmflag) ); 491 break; 492 493 case ECCurve_SECG_PRIME_128R1: 494 /* Populate params for secp128r1 */ 495 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp, 496 params, kmflag) ); 497 break; 498 499 case ECCurve_SECG_PRIME_128R2: 500 /* Populate params for secp128r2 */ 501 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp, 502 params, kmflag) ); 503 break; 504 505 case ECCurve_SECG_PRIME_160K1: 506 /* Populate params for secp160k1 */ 507 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp, 508 params, kmflag) ); 509 break; 510 511 case ECCurve_SECG_PRIME_160R1: 512 /* Populate params for secp160r1 */ 513 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp, 514 params, kmflag) ); 515 break; 516 517 case ECCurve_SECG_PRIME_160R2: 518 /* Populate params for secp160r1 */ 519 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp, 520 params, kmflag) ); 521 break; 522 523 case ECCurve_SECG_PRIME_192K1: 524 /* Populate params for secp192k1 */ 525 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp, 526 params, kmflag) ); 527 break; 528 529 case ECCurve_SECG_PRIME_224K1: 530 /* Populate params for secp224k1 */ 531 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp, 532 params, kmflag) ); 533 break; 534 535 case ECCurve_SECG_PRIME_224R1: 536 /* Populate params for secp224r1 537 * (the NIST P-224 curve) 538 */ 539 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp, 540 params, kmflag) ); 541 break; 542 543 case ECCurve_SECG_PRIME_256K1: 544 /* Populate params for secp256k1 */ 545 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp, 546 params, kmflag) ); 547 break; 548 549 case ECCurve_SECG_PRIME_384R1: 550 /* Populate params for secp384r1 551 * (the NIST P-384 curve) 552 */ 553 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp, 554 params, kmflag) ); 555 break; 556 557 case ECCurve_SECG_PRIME_521R1: 558 /* Populate params for secp521r1 559 * (the NIST P-521 curve) 560 */ 561 CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp, 562 params, kmflag) ); 563 break; 564 565 default: 566 break; 567 }; 568 569 cleanup: 570 if (!params->cofactor) { 571 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); 572 #if EC_DEBUG 573 printf("Unrecognized curve, returning NULL params\n"); 574 #endif 575 } 576 577 return rv; 578 } 579 580 SECStatus 581 EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams, int kmflag) 582 { 583 PRArenaPool *arena; 584 ECParams *params; 585 SECStatus rv = SECFailure; 586 587 /* Initialize an arena for the ECParams structure */ 588 if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE))) 589 return SECFailure; 590 591 params = (ECParams *)PORT_ArenaZAlloc(NULL, sizeof(ECParams), kmflag); 592 if (!params) { 593 PORT_FreeArena(NULL, B_TRUE); 594 return SECFailure; 595 } 596 597 /* Copy the encoded params */ 598 SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len, 599 kmflag); 600 memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len); 601 602 /* Fill out the rest of the ECParams structure based on 603 * the encoded params 604 */ 605 rv = EC_FillParams(NULL, encodedParams, params, kmflag); 606 if (rv == SECFailure) { 607 PORT_FreeArena(NULL, B_TRUE); 608 return SECFailure; 609 } else { 610 *ecparams = params;; 611 return SECSuccess; 612 } 613 }