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