1 /* 2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this library; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* ********************************************************************* 25 * 26 * The Original Code is the Elliptic Curve Cryptography library. 27 * 28 * The Initial Developer of the Original Code is 29 * Sun Microsystems, Inc. 30 * Portions created by the Initial Developer are Copyright (C) 2003 31 * the Initial Developer. All Rights Reserved. 32 * 33 * Contributor(s): 34 * Dr Vipul Gupta <vipul.gupta@sun.com> and 35 * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories 36 * 37 *********************************************************************** */ 38 39 #include "mplogic.h" 40 #include "ec.h" 41 #include "ecl.h" 42 43 #include <sys/types.h> 44 #ifndef _KERNEL 45 #include <stdlib.h> 46 #include <string.h> 47 48 #ifndef _WIN32 49 #include <stdio.h> 50 #include <strings.h> 51 #endif /* _WIN32 */ 52 53 #endif 54 #include "ecl-exp.h" 55 #include "mpi.h" 56 #include "ecc_impl.h" 57 58 /* 59 * Returns true if pointP is the point at infinity, false otherwise 60 */ 61 PRBool 62 ec_point_at_infinity(SECItem *pointP) 63 { 64 unsigned int i; 65 66 for (i = 1; i < pointP->len; i++) { 67 if (pointP->data[i] != 0x00) return PR_FALSE; 68 } 69 70 return PR_TRUE; 71 } 72 73 /* 74 * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for 75 * the curve whose parameters are encoded in params with base point G. 76 */ 77 SECStatus 78 ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2, 79 const SECItem *pointP, SECItem *pointQ, int kmflag) 80 { 81 mp_int Px, Py, Qx, Qy; 82 mp_int Gx, Gy, order, irreducible, a, b; 83 #if 0 /* currently don't support non-named curves */ 84 unsigned int irr_arr[5]; 85 #endif 86 ECGroup *group = NULL; 87 SECStatus rv = SECFailure; 88 mp_err err = MP_OKAY; 89 unsigned int len; 90 91 #if EC_DEBUG 92 int i; 93 char mpstr[256]; 94 95 printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len); 96 for (i = 0; i < params->DEREncoding.len; i++) 97 printf("%02x:", params->DEREncoding.data[i]); 98 printf("\n"); 99 100 if (k1 != NULL) { 101 mp_tohex(k1, mpstr); 102 printf("ec_points_mul: scalar k1: %s\n", mpstr); 103 mp_todecimal(k1, mpstr); 104 printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr); 105 } 106 107 if (k2 != NULL) { 108 mp_tohex(k2, mpstr); 109 printf("ec_points_mul: scalar k2: %s\n", mpstr); 110 mp_todecimal(k2, mpstr); 111 printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr); 112 } 113 114 if (pointP != NULL) { 115 printf("ec_points_mul: pointP [len=%d]:", pointP->len); 116 for (i = 0; i < pointP->len; i++) 117 printf("%02x:", pointP->data[i]); 118 printf("\n"); 119 } 120 #endif 121 122 /* NOTE: We only support uncompressed points for now */ 123 len = (params->fieldID.size + 7) >> 3; 124 if (pointP != NULL) { 125 if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) || 126 (pointP->len != (2 * len + 1))) { 127 return SECFailure; 128 }; 129 } 130 131 MP_DIGITS(&Px) = 0; 132 MP_DIGITS(&Py) = 0; 133 MP_DIGITS(&Qx) = 0; 134 MP_DIGITS(&Qy) = 0; 135 MP_DIGITS(&Gx) = 0; 136 MP_DIGITS(&Gy) = 0; 137 MP_DIGITS(&order) = 0; 138 MP_DIGITS(&irreducible) = 0; 139 MP_DIGITS(&a) = 0; 140 MP_DIGITS(&b) = 0; 141 CHECK_MPI_OK( mp_init(&Px, kmflag) ); 142 CHECK_MPI_OK( mp_init(&Py, kmflag) ); 143 CHECK_MPI_OK( mp_init(&Qx, kmflag) ); 144 CHECK_MPI_OK( mp_init(&Qy, kmflag) ); 145 CHECK_MPI_OK( mp_init(&Gx, kmflag) ); 146 CHECK_MPI_OK( mp_init(&Gy, kmflag) ); 147 CHECK_MPI_OK( mp_init(&order, kmflag) ); 148 CHECK_MPI_OK( mp_init(&irreducible, kmflag) ); 149 CHECK_MPI_OK( mp_init(&a, kmflag) ); 150 CHECK_MPI_OK( mp_init(&b, kmflag) ); 151 152 if ((k2 != NULL) && (pointP != NULL)) { 153 /* Initialize Px and Py */ 154 CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) ); 155 CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) ); 156 } 157 158 /* construct from named params, if possible */ 159 if (params->name != ECCurve_noName) { 160 group = ECGroup_fromName(params->name, kmflag); 161 } 162 163 #if 0 /* currently don't support non-named curves */ 164 if (group == NULL) { 165 /* Set up mp_ints containing the curve coefficients */ 166 CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1, 167 (mp_size) len) ); 168 CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len, 169 (mp_size) len) ); 170 SECITEM_TO_MPINT( params->order, &order ); 171 SECITEM_TO_MPINT( params->curve.a, &a ); 172 SECITEM_TO_MPINT( params->curve.b, &b ); 173 if (params->fieldID.type == ec_field_GFp) { 174 SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible ); 175 group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor); 176 } else { 177 SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible ); 178 irr_arr[0] = params->fieldID.size; 179 irr_arr[1] = params->fieldID.k1; 180 irr_arr[2] = params->fieldID.k2; 181 irr_arr[3] = params->fieldID.k3; 182 irr_arr[4] = 0; 183 group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor); 184 } 185 } 186 #endif 187 if (group == NULL) 188 goto cleanup; 189 190 if ((k2 != NULL) && (pointP != NULL)) { 191 CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) ); 192 } else { 193 CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) ); 194 } 195 196 /* Construct the SECItem representation of point Q */ 197 pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED; 198 CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1, 199 (mp_size) len) ); 200 CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len, 201 (mp_size) len) ); 202 203 rv = SECSuccess; 204 205 #if EC_DEBUG 206 printf("ec_points_mul: pointQ [len=%d]:", pointQ->len); 207 for (i = 0; i < pointQ->len; i++) 208 printf("%02x:", pointQ->data[i]); 209 printf("\n"); 210 #endif 211 212 cleanup: 213 ECGroup_free(group); 214 mp_clear(&Px); 215 mp_clear(&Py); 216 mp_clear(&Qx); 217 mp_clear(&Qy); 218 mp_clear(&Gx); 219 mp_clear(&Gy); 220 mp_clear(&order); 221 mp_clear(&irreducible); 222 mp_clear(&a); 223 mp_clear(&b); 224 if (err) { 225 MP_TO_SEC_ERROR(err); 226 rv = SECFailure; 227 } 228 229 return rv; 230 } 231 232 /* Generates a new EC key pair. The private key is a supplied 233 * value and the public key is the result of performing a scalar 234 * point multiplication of that value with the curve's base point. 235 */ 236 SECStatus 237 ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey, 238 const unsigned char *privKeyBytes, int privKeyLen, int kmflag) 239 { 240 SECStatus rv = SECFailure; 241 PRArenaPool *arena; 242 ECPrivateKey *key; 243 mp_int k; 244 mp_err err = MP_OKAY; 245 int len; 246 247 #if EC_DEBUG 248 printf("ec_NewKey called\n"); 249 #endif 250 251 if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) { 252 PORT_SetError(SEC_ERROR_INVALID_ARGS); 253 return SECFailure; 254 } 255 256 /* Initialize an arena for the EC key. */ 257 if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE))) 258 return SECFailure; 259 260 key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey), 261 kmflag); 262 if (!key) { 263 PORT_FreeArena(arena, PR_TRUE); 264 return SECFailure; 265 } 266 267 /* Set the version number (SEC 1 section C.4 says it should be 1) */ 268 SECITEM_AllocItem(arena, &key->version, 1, kmflag); 269 key->version.data[0] = 1; 270 271 /* Copy all of the fields from the ECParams argument to the 272 * ECParams structure within the private key. 273 */ 274 key->ecParams.arena = arena; 275 key->ecParams.type = ecParams->type; 276 key->ecParams.fieldID.size = ecParams->fieldID.size; 277 key->ecParams.fieldID.type = ecParams->fieldID.type; 278 if (ecParams->fieldID.type == ec_field_GFp) { 279 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime, 280 &ecParams->fieldID.u.prime, kmflag)); 281 } else { 282 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly, 283 &ecParams->fieldID.u.poly, kmflag)); 284 } 285 key->ecParams.fieldID.k1 = ecParams->fieldID.k1; 286 key->ecParams.fieldID.k2 = ecParams->fieldID.k2; 287 key->ecParams.fieldID.k3 = ecParams->fieldID.k3; 288 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a, 289 &ecParams->curve.a, kmflag)); 290 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b, 291 &ecParams->curve.b, kmflag)); 292 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed, 293 &ecParams->curve.seed, kmflag)); 294 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base, 295 &ecParams->base, kmflag)); 296 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order, 297 &ecParams->order, kmflag)); 298 key->ecParams.cofactor = ecParams->cofactor; 299 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding, 300 &ecParams->DEREncoding, kmflag)); 301 key->ecParams.name = ecParams->name; 302 CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID, 303 &ecParams->curveOID, kmflag)); 304 305 len = (ecParams->fieldID.size + 7) >> 3; 306 SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1, kmflag); 307 len = ecParams->order.len; 308 SECITEM_AllocItem(arena, &key->privateValue, len, kmflag); 309 310 /* Copy private key */ 311 if (privKeyLen >= len) { 312 memcpy(key->privateValue.data, privKeyBytes, len); 313 } else { 314 memset(key->privateValue.data, 0, (len - privKeyLen)); 315 memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen); 316 } 317 318 /* Compute corresponding public key */ 319 MP_DIGITS(&k) = 0; 320 CHECK_MPI_OK( mp_init(&k, kmflag) ); 321 CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data, 322 (mp_size) len) ); 323 324 rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag); 325 if (rv != SECSuccess) goto cleanup; 326 *privKey = key; 327 328 cleanup: 329 mp_clear(&k); 330 if (rv) { 331 PORT_FreeArena(arena, PR_TRUE); 332 } 333 334 #if EC_DEBUG 335 printf("ec_NewKey returning %s\n", 336 (rv == SECSuccess) ? "success" : "failure"); 337 #endif 338 339 return rv; 340 341 } 342 343 /* Generates a new EC key pair. The private key is a supplied 344 * random value (in seed) and the public key is the result of 345 * performing a scalar point multiplication of that value with 346 * the curve's base point. 347 */ 348 SECStatus 349 EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey, 350 const unsigned char *seed, int seedlen, int kmflag) 351 { 352 SECStatus rv = SECFailure; 353 rv = ec_NewKey(ecParams, privKey, seed, seedlen, kmflag); 354 return rv; 355 } 356 357 /* Generate a random private key using the algorithm A.4.1 of ANSI X9.62, 358 * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the 359 * random number generator. 360 * 361 * Parameters 362 * - order: a buffer that holds the curve's group order 363 * - len: the length in octets of the order buffer 364 * - random: a buffer of 2 * len random bytes 365 * - randomlen: the length in octets of the random buffer 366 * 367 * Return Value 368 * Returns a buffer of len octets that holds the private key. The caller 369 * is responsible for freeing the buffer with PORT_ZFree. 370 */ 371 static unsigned char * 372 ec_GenerateRandomPrivateKey(const unsigned char *order, int len, 373 const unsigned char *random, int randomlen, int kmflag) 374 { 375 SECStatus rv = SECSuccess; 376 mp_err err; 377 unsigned char *privKeyBytes = NULL; 378 mp_int privKeyVal, order_1, one; 379 380 MP_DIGITS(&privKeyVal) = 0; 381 MP_DIGITS(&order_1) = 0; 382 MP_DIGITS(&one) = 0; 383 CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) ); 384 CHECK_MPI_OK( mp_init(&order_1, kmflag) ); 385 CHECK_MPI_OK( mp_init(&one, kmflag) ); 386 387 /* 388 * Reduces the 2*len buffer of random bytes modulo the group order. 389 */ 390 if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup; 391 if (randomlen != 2 * len) { 392 randomlen = 2 * len; 393 } 394 /* No need to generate - random bytes are now supplied */ 395 /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/ 396 memcpy(privKeyBytes, random, randomlen); 397 398 CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) ); 399 CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) ); 400 CHECK_MPI_OK( mp_set_int(&one, 1) ); 401 CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) ); 402 CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) ); 403 CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) ); 404 CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) ); 405 memset(privKeyBytes+len, 0, len); 406 cleanup: 407 mp_clear(&privKeyVal); 408 mp_clear(&order_1); 409 mp_clear(&one); 410 if (err < MP_OKAY) { 411 MP_TO_SEC_ERROR(err); 412 rv = SECFailure; 413 } 414 if (rv != SECSuccess && privKeyBytes) { 415 PORT_ZFree(privKeyBytes, 2*len); 416 privKeyBytes = NULL; 417 } 418 return privKeyBytes; 419 } 420 421 /* Generates a new EC key pair. The private key is a random value and 422 * the public key is the result of performing a scalar point multiplication 423 * of that value with the curve's base point. 424 */ 425 SECStatus 426 EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey, 427 const unsigned char* random, int randomlen, int kmflag) 428 { 429 SECStatus rv = SECFailure; 430 int len; 431 unsigned char *privKeyBytes = NULL; 432 433 if (!ecParams) { 434 PORT_SetError(SEC_ERROR_INVALID_ARGS); 435 return SECFailure; 436 } 437 438 len = ecParams->order.len; 439 privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len, 440 random, randomlen, kmflag); 441 if (privKeyBytes == NULL) goto cleanup; 442 /* generate public key */ 443 CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len, kmflag) ); 444 445 cleanup: 446 if (privKeyBytes) { 447 PORT_ZFree(privKeyBytes, len * 2); 448 } 449 #if EC_DEBUG 450 printf("EC_NewKey returning %s\n", 451 (rv == SECSuccess) ? "success" : "failure"); 452 #endif 453 454 return rv; 455 } 456 457 /* Validates an EC public key as described in Section 5.2.2 of 458 * X9.62. The ECDH primitive when used without the cofactor does 459 * not address small subgroup attacks, which may occur when the 460 * public key is not valid. These attacks can be prevented by 461 * validating the public key before using ECDH. 462 */ 463 SECStatus 464 EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue, int kmflag) 465 { 466 mp_int Px, Py; 467 ECGroup *group = NULL; 468 SECStatus rv = SECFailure; 469 mp_err err = MP_OKAY; 470 unsigned int len; 471 472 if (!ecParams || !publicValue) { 473 PORT_SetError(SEC_ERROR_INVALID_ARGS); 474 return SECFailure; 475 } 476 477 /* NOTE: We only support uncompressed points for now */ 478 len = (ecParams->fieldID.size + 7) >> 3; 479 if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) { 480 PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); 481 return SECFailure; 482 } else if (publicValue->len != (2 * len + 1)) { 483 PORT_SetError(SEC_ERROR_BAD_KEY); 484 return SECFailure; 485 } 486 487 MP_DIGITS(&Px) = 0; 488 MP_DIGITS(&Py) = 0; 489 CHECK_MPI_OK( mp_init(&Px, kmflag) ); 490 CHECK_MPI_OK( mp_init(&Py, kmflag) ); 491 492 /* Initialize Px and Py */ 493 CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) ); 494 CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) ); 495 496 /* construct from named params */ 497 group = ECGroup_fromName(ecParams->name, kmflag); 498 if (group == NULL) { 499 /* 500 * ECGroup_fromName fails if ecParams->name is not a valid 501 * ECCurveName value, or if we run out of memory, or perhaps 502 * for other reasons. Unfortunately if ecParams->name is a 503 * valid ECCurveName value, we don't know what the right error 504 * code should be because ECGroup_fromName doesn't return an 505 * error code to the caller. Set err to MP_UNDEF because 506 * that's what ECGroup_fromName uses internally. 507 */ 508 if ((ecParams->name <= ECCurve_noName) || 509 (ecParams->name >= ECCurve_pastLastCurve)) { 510 err = MP_BADARG; 511 } else { 512 err = MP_UNDEF; 513 } 514 goto cleanup; 515 } 516 517 /* validate public point */ 518 if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) { 519 if (err == MP_NO) { 520 PORT_SetError(SEC_ERROR_BAD_KEY); 521 rv = SECFailure; 522 err = MP_OKAY; /* don't change the error code */ 523 } 524 goto cleanup; 525 } 526 527 rv = SECSuccess; 528 529 cleanup: 530 ECGroup_free(group); 531 mp_clear(&Px); 532 mp_clear(&Py); 533 if (err) { 534 MP_TO_SEC_ERROR(err); 535 rv = SECFailure; 536 } 537 return rv; 538 } 539 540 /* 541 ** Performs an ECDH key derivation by computing the scalar point 542 ** multiplication of privateValue and publicValue (with or without the 543 ** cofactor) and returns the x-coordinate of the resulting elliptic 544 ** curve point in derived secret. If successful, derivedSecret->data 545 ** is set to the address of the newly allocated buffer containing the 546 ** derived secret, and derivedSecret->len is the size of the secret 547 ** produced. It is the caller's responsibility to free the allocated 548 ** buffer containing the derived secret. 549 */ 550 SECStatus 551 ECDH_Derive(SECItem *publicValue, 552 ECParams *ecParams, 553 SECItem *privateValue, 554 PRBool withCofactor, 555 SECItem *derivedSecret, 556 int kmflag) 557 { 558 SECStatus rv = SECFailure; 559 unsigned int len = 0; 560 SECItem pointQ = {siBuffer, NULL, 0}; 561 mp_int k; /* to hold the private value */ 562 mp_int cofactor; 563 mp_err err = MP_OKAY; 564 #if EC_DEBUG 565 int i; 566 #endif 567 568 if (!publicValue || !ecParams || !privateValue || 569 !derivedSecret) { 570 PORT_SetError(SEC_ERROR_INVALID_ARGS); 571 return SECFailure; 572 } 573 574 memset(derivedSecret, 0, sizeof *derivedSecret); 575 len = (ecParams->fieldID.size + 7) >> 3; 576 pointQ.len = 2*len + 1; 577 if ((pointQ.data = PORT_Alloc(2*len + 1, kmflag)) == NULL) goto cleanup; 578 579 MP_DIGITS(&k) = 0; 580 CHECK_MPI_OK( mp_init(&k, kmflag) ); 581 CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data, 582 (mp_size) privateValue->len) ); 583 584 if (withCofactor && (ecParams->cofactor != 1)) { 585 /* multiply k with the cofactor */ 586 MP_DIGITS(&cofactor) = 0; 587 CHECK_MPI_OK( mp_init(&cofactor, kmflag) ); 588 mp_set(&cofactor, ecParams->cofactor); 589 CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) ); 590 } 591 592 /* Multiply our private key and peer's public point */ 593 if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag) != SECSuccess) || 594 ec_point_at_infinity(&pointQ)) 595 goto cleanup; 596 597 /* Allocate memory for the derived secret and copy 598 * the x co-ordinate of pointQ into it. 599 */ 600 SECITEM_AllocItem(NULL, derivedSecret, len, kmflag); 601 memcpy(derivedSecret->data, pointQ.data + 1, len); 602 603 rv = SECSuccess; 604 605 #if EC_DEBUG 606 printf("derived_secret:\n"); 607 for (i = 0; i < derivedSecret->len; i++) 608 printf("%02x:", derivedSecret->data[i]); 609 printf("\n"); 610 #endif 611 612 cleanup: 613 mp_clear(&k); 614 615 if (pointQ.data) { 616 PORT_ZFree(pointQ.data, 2*len + 1); 617 } 618 619 return rv; 620 } 621 622 /* Computes the ECDSA signature (a concatenation of two values r and s) 623 * on the digest using the given key and the random value kb (used in 624 * computing s). 625 */ 626 SECStatus 627 ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, 628 const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag) 629 { 630 SECStatus rv = SECFailure; 631 mp_int x1; 632 mp_int d, k; /* private key, random integer */ 633 mp_int r, s; /* tuple (r, s) is the signature */ 634 mp_int n; 635 mp_err err = MP_OKAY; 636 ECParams *ecParams = NULL; 637 SECItem kGpoint = { siBuffer, NULL, 0}; 638 int flen = 0; /* length in bytes of the field size */ 639 unsigned olen; /* length in bytes of the base point order */ 640 641 #if EC_DEBUG 642 char mpstr[256]; 643 #endif 644 645 /* Initialize MPI integers. */ 646 /* must happen before the first potential call to cleanup */ 647 MP_DIGITS(&x1) = 0; 648 MP_DIGITS(&d) = 0; 649 MP_DIGITS(&k) = 0; 650 MP_DIGITS(&r) = 0; 651 MP_DIGITS(&s) = 0; 652 MP_DIGITS(&n) = 0; 653 654 /* Check args */ 655 if (!key || !signature || !digest || !kb || (kblen < 0)) { 656 PORT_SetError(SEC_ERROR_INVALID_ARGS); 657 goto cleanup; 658 } 659 660 ecParams = &(key->ecParams); 661 flen = (ecParams->fieldID.size + 7) >> 3; 662 olen = ecParams->order.len; 663 if (signature->data == NULL) { 664 /* a call to get the signature length only */ 665 goto finish; 666 } 667 if (signature->len < 2*olen) { 668 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 669 rv = SECBufferTooSmall; 670 goto cleanup; 671 } 672 673 674 CHECK_MPI_OK( mp_init(&x1, kmflag) ); 675 CHECK_MPI_OK( mp_init(&d, kmflag) ); 676 CHECK_MPI_OK( mp_init(&k, kmflag) ); 677 CHECK_MPI_OK( mp_init(&r, kmflag) ); 678 CHECK_MPI_OK( mp_init(&s, kmflag) ); 679 CHECK_MPI_OK( mp_init(&n, kmflag) ); 680 681 SECITEM_TO_MPINT( ecParams->order, &n ); 682 SECITEM_TO_MPINT( key->privateValue, &d ); 683 CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) ); 684 /* Make sure k is in the interval [1, n-1] */ 685 if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) { 686 #if EC_DEBUG 687 printf("k is outside [1, n-1]\n"); 688 mp_tohex(&k, mpstr); 689 printf("k : %s \n", mpstr); 690 mp_tohex(&n, mpstr); 691 printf("n : %s \n", mpstr); 692 #endif 693 PORT_SetError(SEC_ERROR_NEED_RANDOM); 694 goto cleanup; 695 } 696 697 /* 698 ** ANSI X9.62, Section 5.3.2, Step 2 699 ** 700 ** Compute kG 701 */ 702 kGpoint.len = 2*flen + 1; 703 kGpoint.data = PORT_Alloc(2*flen + 1, kmflag); 704 if ((kGpoint.data == NULL) || 705 (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag) 706 != SECSuccess)) 707 goto cleanup; 708 709 /* 710 ** ANSI X9.62, Section 5.3.3, Step 1 711 ** 712 ** Extract the x co-ordinate of kG into x1 713 */ 714 CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1, 715 (mp_size) flen) ); 716 717 /* 718 ** ANSI X9.62, Section 5.3.3, Step 2 719 ** 720 ** r = x1 mod n NOTE: n is the order of the curve 721 */ 722 CHECK_MPI_OK( mp_mod(&x1, &n, &r) ); 723 724 /* 725 ** ANSI X9.62, Section 5.3.3, Step 3 726 ** 727 ** verify r != 0 728 */ 729 if (mp_cmp_z(&r) == 0) { 730 PORT_SetError(SEC_ERROR_NEED_RANDOM); 731 goto cleanup; 732 } 733 734 /* 735 ** ANSI X9.62, Section 5.3.3, Step 4 736 ** 737 ** s = (k**-1 * (HASH(M) + d*r)) mod n 738 */ 739 SECITEM_TO_MPINT(*digest, &s); /* s = HASH(M) */ 740 741 /* In the definition of EC signing, digests are truncated 742 * to the length of n in bits. 743 * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/ 744 if (digest->len*8 > (unsigned int)ecParams->fieldID.size) { 745 mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size); 746 } 747 748 #if EC_DEBUG 749 mp_todecimal(&n, mpstr); 750 printf("n : %s (dec)\n", mpstr); 751 mp_todecimal(&d, mpstr); 752 printf("d : %s (dec)\n", mpstr); 753 mp_tohex(&x1, mpstr); 754 printf("x1: %s\n", mpstr); 755 mp_todecimal(&s, mpstr); 756 printf("digest: %s (decimal)\n", mpstr); 757 mp_todecimal(&r, mpstr); 758 printf("r : %s (dec)\n", mpstr); 759 mp_tohex(&r, mpstr); 760 printf("r : %s\n", mpstr); 761 #endif 762 763 CHECK_MPI_OK( mp_invmod(&k, &n, &k) ); /* k = k**-1 mod n */ 764 CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) ); /* d = d * r mod n */ 765 CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) ); /* s = s + d mod n */ 766 CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) ); /* s = s * k mod n */ 767 768 #if EC_DEBUG 769 mp_todecimal(&s, mpstr); 770 printf("s : %s (dec)\n", mpstr); 771 mp_tohex(&s, mpstr); 772 printf("s : %s\n", mpstr); 773 #endif 774 775 /* 776 ** ANSI X9.62, Section 5.3.3, Step 5 777 ** 778 ** verify s != 0 779 */ 780 if (mp_cmp_z(&s) == 0) { 781 PORT_SetError(SEC_ERROR_NEED_RANDOM); 782 goto cleanup; 783 } 784 785 /* 786 ** 787 ** Signature is tuple (r, s) 788 */ 789 CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) ); 790 CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) ); 791 finish: 792 signature->len = 2*olen; 793 794 rv = SECSuccess; 795 err = MP_OKAY; 796 cleanup: 797 mp_clear(&x1); 798 mp_clear(&d); 799 mp_clear(&k); 800 mp_clear(&r); 801 mp_clear(&s); 802 mp_clear(&n); 803 804 if (kGpoint.data) { 805 PORT_ZFree(kGpoint.data, 2*flen + 1); 806 } 807 808 if (err) { 809 MP_TO_SEC_ERROR(err); 810 rv = SECFailure; 811 } 812 813 #if EC_DEBUG 814 printf("ECDSA signing with seed %s\n", 815 (rv == SECSuccess) ? "succeeded" : "failed"); 816 #endif 817 818 return rv; 819 } 820 821 /* 822 ** Computes the ECDSA signature on the digest using the given key 823 ** and a random seed. 824 */ 825 SECStatus 826 ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest, 827 const unsigned char* random, int randomLen, int kmflag) 828 { 829 SECStatus rv = SECFailure; 830 int len; 831 unsigned char *kBytes= NULL; 832 833 if (!key) { 834 PORT_SetError(SEC_ERROR_INVALID_ARGS); 835 return SECFailure; 836 } 837 838 /* Generate random value k */ 839 len = key->ecParams.order.len; 840 kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len, 841 random, randomLen, kmflag); 842 if (kBytes == NULL) goto cleanup; 843 844 /* Generate ECDSA signature with the specified k value */ 845 rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag); 846 847 cleanup: 848 if (kBytes) { 849 PORT_ZFree(kBytes, len * 2); 850 } 851 852 #if EC_DEBUG 853 printf("ECDSA signing %s\n", 854 (rv == SECSuccess) ? "succeeded" : "failed"); 855 #endif 856 857 return rv; 858 } 859 860 /* 861 ** Checks the signature on the given digest using the key provided. 862 */ 863 SECStatus 864 ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, 865 const SECItem *digest, int kmflag) 866 { 867 SECStatus rv = SECFailure; 868 mp_int r_, s_; /* tuple (r', s') is received signature) */ 869 mp_int c, u1, u2, v; /* intermediate values used in verification */ 870 mp_int x1; 871 mp_int n; 872 mp_err err = MP_OKAY; 873 ECParams *ecParams = NULL; 874 SECItem pointC = { siBuffer, NULL, 0 }; 875 int slen; /* length in bytes of a half signature (r or s) */ 876 int flen; /* length in bytes of the field size */ 877 unsigned olen; /* length in bytes of the base point order */ 878 879 #if EC_DEBUG 880 char mpstr[256]; 881 printf("ECDSA verification called\n"); 882 #endif 883 884 /* Initialize MPI integers. */ 885 /* must happen before the first potential call to cleanup */ 886 MP_DIGITS(&r_) = 0; 887 MP_DIGITS(&s_) = 0; 888 MP_DIGITS(&c) = 0; 889 MP_DIGITS(&u1) = 0; 890 MP_DIGITS(&u2) = 0; 891 MP_DIGITS(&x1) = 0; 892 MP_DIGITS(&v) = 0; 893 MP_DIGITS(&n) = 0; 894 895 /* Check args */ 896 if (!key || !signature || !digest) { 897 PORT_SetError(SEC_ERROR_INVALID_ARGS); 898 goto cleanup; 899 } 900 901 ecParams = &(key->ecParams); 902 flen = (ecParams->fieldID.size + 7) >> 3; 903 olen = ecParams->order.len; 904 if (signature->len == 0 || signature->len%2 != 0 || 905 signature->len > 2*olen) { 906 PORT_SetError(SEC_ERROR_INPUT_LEN); 907 goto cleanup; 908 } 909 slen = signature->len/2; 910 911 SECITEM_AllocItem(NULL, &pointC, 2*flen + 1, kmflag); 912 if (pointC.data == NULL) 913 goto cleanup; 914 915 CHECK_MPI_OK( mp_init(&r_, kmflag) ); 916 CHECK_MPI_OK( mp_init(&s_, kmflag) ); 917 CHECK_MPI_OK( mp_init(&c, kmflag) ); 918 CHECK_MPI_OK( mp_init(&u1, kmflag) ); 919 CHECK_MPI_OK( mp_init(&u2, kmflag) ); 920 CHECK_MPI_OK( mp_init(&x1, kmflag) ); 921 CHECK_MPI_OK( mp_init(&v, kmflag) ); 922 CHECK_MPI_OK( mp_init(&n, kmflag) ); 923 924 /* 925 ** Convert received signature (r', s') into MPI integers. 926 */ 927 CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) ); 928 CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) ); 929 930 /* 931 ** ANSI X9.62, Section 5.4.2, Steps 1 and 2 932 ** 933 ** Verify that 0 < r' < n and 0 < s' < n 934 */ 935 SECITEM_TO_MPINT(ecParams->order, &n); 936 if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 || 937 mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) { 938 PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 939 goto cleanup; /* will return rv == SECFailure */ 940 } 941 942 /* 943 ** ANSI X9.62, Section 5.4.2, Step 3 944 ** 945 ** c = (s')**-1 mod n 946 */ 947 CHECK_MPI_OK( mp_invmod(&s_, &n, &c) ); /* c = (s')**-1 mod n */ 948 949 /* 950 ** ANSI X9.62, Section 5.4.2, Step 4 951 ** 952 ** u1 = ((HASH(M')) * c) mod n 953 */ 954 SECITEM_TO_MPINT(*digest, &u1); /* u1 = HASH(M) */ 955 956 /* In the definition of EC signing, digests are truncated 957 * to the length of n in bits. 958 * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/ 959 /* u1 = HASH(M') */ 960 if (digest->len*8 > (unsigned int)ecParams->fieldID.size) { 961 mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size); 962 } 963 964 #if EC_DEBUG 965 mp_todecimal(&r_, mpstr); 966 printf("r_: %s (dec)\n", mpstr); 967 mp_todecimal(&s_, mpstr); 968 printf("s_: %s (dec)\n", mpstr); 969 mp_todecimal(&c, mpstr); 970 printf("c : %s (dec)\n", mpstr); 971 mp_todecimal(&u1, mpstr); 972 printf("digest: %s (dec)\n", mpstr); 973 #endif 974 975 CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) ); /* u1 = u1 * c mod n */ 976 977 /* 978 ** ANSI X9.62, Section 5.4.2, Step 4 979 ** 980 ** u2 = ((r') * c) mod n 981 */ 982 CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) ); 983 984 /* 985 ** ANSI X9.62, Section 5.4.3, Step 1 986 ** 987 ** Compute u1*G + u2*Q 988 ** Here, A = u1.G B = u2.Q and C = A + B 989 ** If the result, C, is the point at infinity, reject the signature 990 */ 991 if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag) 992 != SECSuccess) { 993 rv = SECFailure; 994 goto cleanup; 995 } 996 if (ec_point_at_infinity(&pointC)) { 997 PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 998 rv = SECFailure; 999 goto cleanup; 1000 } 1001 1002 CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) ); 1003 1004 /* 1005 ** ANSI X9.62, Section 5.4.4, Step 2 1006 ** 1007 ** v = x1 mod n 1008 */ 1009 CHECK_MPI_OK( mp_mod(&x1, &n, &v) ); 1010 1011 #if EC_DEBUG 1012 mp_todecimal(&r_, mpstr); 1013 printf("r_: %s (dec)\n", mpstr); 1014 mp_todecimal(&v, mpstr); 1015 printf("v : %s (dec)\n", mpstr); 1016 #endif 1017 1018 /* 1019 ** ANSI X9.62, Section 5.4.4, Step 3 1020 ** 1021 ** Verification: v == r' 1022 */ 1023 if (mp_cmp(&v, &r_)) { 1024 PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 1025 rv = SECFailure; /* Signature failed to verify. */ 1026 } else { 1027 rv = SECSuccess; /* Signature verified. */ 1028 } 1029 1030 #if EC_DEBUG 1031 mp_todecimal(&u1, mpstr); 1032 printf("u1: %s (dec)\n", mpstr); 1033 mp_todecimal(&u2, mpstr); 1034 printf("u2: %s (dec)\n", mpstr); 1035 mp_tohex(&x1, mpstr); 1036 printf("x1: %s\n", mpstr); 1037 mp_todecimal(&v, mpstr); 1038 printf("v : %s (dec)\n", mpstr); 1039 #endif 1040 1041 cleanup: 1042 mp_clear(&r_); 1043 mp_clear(&s_); 1044 mp_clear(&c); 1045 mp_clear(&u1); 1046 mp_clear(&u2); 1047 mp_clear(&x1); 1048 mp_clear(&v); 1049 mp_clear(&n); 1050 1051 if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE); 1052 if (err) { 1053 MP_TO_SEC_ERROR(err); 1054 rv = SECFailure; 1055 } 1056 1057 #if EC_DEBUG 1058 printf("ECDSA verification %s\n", 1059 (rv == SECSuccess) ? "succeeded" : "failed"); 1060 #endif 1061 1062 return rv; 1063 }