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