security/nss/lib/freebl/ecdecode.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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, &params->fieldID.u.prime,
michael@0 128 curveParams->irr));
michael@0 129 } else {
michael@0 130 CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.poly,
michael@0 131 curveParams->irr));
michael@0 132 }
michael@0 133 CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
michael@0 134 curveParams->curvea));
michael@0 135 CHECK_OK(hexString2SECItem(params->arena, &params->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, &params->base, genenc));
michael@0 143 CHECK_OK(hexString2SECItem(params->arena, &params->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 */

mercurial