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