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