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     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, &params->fieldID.u.prime,
 129             curveParams->irr, kmflag));
 130     } else {
 131         CHECK_OK(hexString2SECItem(NULL, &params->fieldID.u.poly,
 132             curveParams->irr, kmflag));
 133     }
 134     CHECK_OK(hexString2SECItem(NULL, &params->curve.a,
 135         curveParams->curvea, kmflag));
 136     CHECK_OK(hexString2SECItem(NULL, &params->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, &params->base, genenc, kmflag));
 144     CHECK_OK(hexString2SECItem(NULL, &params->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 }