security/nss/lib/freebl/ec.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial