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