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