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