mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-09 12:05:14 +00:00
8175110: Higher quality ECDSA operations
Reviewed-by: jnimeh, valeriep, vinnie, xuelei
This commit is contained in:
parent
adcce8ff05
commit
d137e5465c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -370,9 +370,15 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
random.nextBytes(seed);
|
||||
|
||||
// random bits needed for timing countermeasures
|
||||
int timingArgument = random.nextInt();
|
||||
// values must be non-zero to enable countermeasures
|
||||
timingArgument |= 1;
|
||||
|
||||
byte[] sig;
|
||||
try {
|
||||
sig = signDigest(getDigestValue(), s, encodedParams, seed);
|
||||
sig = signDigest(getDigestValue(), s, encodedParams, seed,
|
||||
timingArgument);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new SignatureException("Could not sign data", e);
|
||||
}
|
||||
@ -509,11 +515,19 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
* @param s the private key's S value.
|
||||
* @param encodedParams the curve's DER encoded object identifier.
|
||||
* @param seed the random seed.
|
||||
* @param timing When non-zero, the implmentation will use timing
|
||||
* countermeasures to hide secrets from timing channels. The EC
|
||||
* implementation will disable the countermeasures when this value is
|
||||
* zero, because the underlying EC functions are shared by several
|
||||
* crypto operations, some of which do not use the countermeasures.
|
||||
* The high-order 31 bits must be uniformly random. The entropy from
|
||||
* these bits is used by the countermeasures.
|
||||
*
|
||||
* @return byte[] the signature.
|
||||
*/
|
||||
private static native byte[] signDigest(byte[] digest, byte[] s,
|
||||
byte[] encodedParams, byte[] seed) throws GeneralSecurityException;
|
||||
byte[] encodedParams, byte[] seed, int timing)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Verifies the signed digest using the public key.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -196,7 +196,7 @@ cleanup:
|
||||
*/
|
||||
JNIEXPORT jbyteArray
|
||||
JNICALL Java_sun_security_ec_ECDSASignature_signDigest
|
||||
(JNIEnv *env, jclass clazz, jbyteArray digest, jbyteArray privateKey, jbyteArray encodedParams, jbyteArray seed)
|
||||
(JNIEnv *env, jclass clazz, jbyteArray digest, jbyteArray privateKey, jbyteArray encodedParams, jbyteArray seed, jint timing)
|
||||
{
|
||||
jbyte* pDigestBuffer = NULL;
|
||||
jint jDigestLength = env->GetArrayLength(digest);
|
||||
@ -256,7 +256,7 @@ JNICALL Java_sun_security_ec_ECDSASignature_signDigest
|
||||
|
||||
// Sign the digest (using the supplied seed)
|
||||
if (ECDSA_SignDigest(&privKey, &signature_item, &digest_item,
|
||||
(unsigned char *) pSeedBuffer, jSeedLength, 0) != SECSuccess) {
|
||||
(unsigned char *) pSeedBuffer, jSeedLength, 0, timing) != SECSuccess) {
|
||||
ThrowException(env, KEY_EXCEPTION);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -34,7 +34,7 @@
|
||||
* Dr Vipul Gupta <vipul.gupta@sun.com> and
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: November 2016
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#include "mplogic.h"
|
||||
@ -87,7 +87,7 @@ ec_point_at_infinity(SECItem *pointP)
|
||||
*/
|
||||
SECStatus
|
||||
ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
|
||||
const SECItem *pointP, SECItem *pointQ, int kmflag)
|
||||
const SECItem *pointP, SECItem *pointQ, int kmflag, int timing)
|
||||
{
|
||||
mp_int Px, Py, Qx, Qy;
|
||||
mp_int Gx, Gy, order, irreducible, a, b;
|
||||
@ -199,9 +199,9 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
|
||||
goto cleanup;
|
||||
|
||||
if ((k2 != NULL) && (pointP != NULL)) {
|
||||
CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
|
||||
CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy, timing) );
|
||||
} else {
|
||||
CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
|
||||
CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy, timing) );
|
||||
}
|
||||
|
||||
/* Construct the SECItem representation of point Q */
|
||||
@ -333,7 +333,8 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
|
||||
CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
|
||||
(mp_size) len) );
|
||||
|
||||
rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag);
|
||||
/* key generation does not support timing mitigation */
|
||||
rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag, /*timing*/ 0);
|
||||
if (rv != SECSuccess) goto cleanup;
|
||||
*privKey = key;
|
||||
|
||||
@ -610,7 +611,8 @@ ECDH_Derive(SECItem *publicValue,
|
||||
}
|
||||
|
||||
/* Multiply our private key and peer's public point */
|
||||
if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag) != SECSuccess) ||
|
||||
/* ECDH doesn't support timing mitigation */
|
||||
if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag, /*timing*/ 0) != SECSuccess) ||
|
||||
ec_point_at_infinity(&pointQ))
|
||||
goto cleanup;
|
||||
|
||||
@ -645,7 +647,8 @@ cleanup:
|
||||
*/
|
||||
SECStatus
|
||||
ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
|
||||
const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag)
|
||||
const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag,
|
||||
int timing)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
mp_int x1;
|
||||
@ -714,16 +717,6 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using an equivalent exponent of fixed length (same as n or 1 bit less
|
||||
* than n) to keep the kG timing relatively constant.
|
||||
*
|
||||
* Note that this is an extra step on top of the approach defined in
|
||||
* ANSI X9.62 so as to make a fixed length K.
|
||||
*/
|
||||
CHECK_MPI_OK( mp_add(&k, &n, &k) );
|
||||
CHECK_MPI_OK( mp_div_2(&k, &k) );
|
||||
|
||||
/*
|
||||
** ANSI X9.62, Section 5.3.2, Step 2
|
||||
**
|
||||
@ -732,7 +725,7 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
|
||||
kGpoint.len = 2*flen + 1;
|
||||
kGpoint.data = PORT_Alloc(2*flen + 1, kmflag);
|
||||
if ((kGpoint.data == NULL) ||
|
||||
(ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag)
|
||||
(ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag, timing)
|
||||
!= SECSuccess))
|
||||
goto cleanup;
|
||||
|
||||
@ -854,7 +847,7 @@ cleanup:
|
||||
*/
|
||||
SECStatus
|
||||
ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest,
|
||||
const unsigned char* random, int randomLen, int kmflag)
|
||||
const unsigned char* random, int randomLen, int kmflag, int timing)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
int len;
|
||||
@ -872,7 +865,7 @@ ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest,
|
||||
if (kBytes == NULL) goto cleanup;
|
||||
|
||||
/* Generate ECDSA signature with the specified k value */
|
||||
rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag);
|
||||
rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag, timing);
|
||||
|
||||
cleanup:
|
||||
if (kBytes) {
|
||||
@ -1018,7 +1011,8 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
|
||||
** Here, A = u1.G B = u2.Q and C = A + B
|
||||
** If the result, C, is the point at infinity, reject the signature
|
||||
*/
|
||||
if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag)
|
||||
/* verification does not support timing mitigation */
|
||||
if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag, /*timing*/ 0)
|
||||
!= SECSuccess) {
|
||||
rv = SECFailure;
|
||||
goto cleanup;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -33,6 +33,7 @@
|
||||
* Contributor(s):
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#ifndef _EC2_H
|
||||
@ -79,7 +80,7 @@ mp_err ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px,
|
||||
* determines the field GF2m. Uses Montgomery projective coordinates. */
|
||||
mp_err ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px,
|
||||
const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
const ECGroup *group);
|
||||
const ECGroup *group, int timing);
|
||||
|
||||
#ifdef ECL_ENABLE_GF2M_PROJ
|
||||
/* Converts a point P(px, py) from affine coordinates to projective
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -33,6 +33,7 @@
|
||||
* Contributor(s):
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#include "ec2.h"
|
||||
@ -329,7 +330,8 @@ ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
|
||||
/* 4: Verify that the order of the curve times the publicValue
|
||||
* is the point at infinity.
|
||||
*/
|
||||
MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
|
||||
/* timing mitigation is not supported */
|
||||
MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt, /*timing*/ 0) );
|
||||
if (ec_GF2m_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
|
||||
res = MP_NO;
|
||||
goto CLEANUP;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -35,6 +35,7 @@
|
||||
* Stephen Fung <fungstep@hotmail.com>, and
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#include "ec2.h"
|
||||
@ -181,10 +182,12 @@ gf2m_Mxy(const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
|
||||
/* Computes R = nP based on algorithm 2P of Lopex, J. and Dahab, R. "Fast
|
||||
* multiplication on elliptic curves over GF(2^m) without
|
||||
* precomputation". Elliptic curve points P and R can be identical. Uses
|
||||
* Montgomery projective coordinates. */
|
||||
* Montgomery projective coordinates. The timing parameter is ignored
|
||||
* because this algorithm resists timing attacks by default. */
|
||||
mp_err
|
||||
ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px, const mp_int *py,
|
||||
mp_int *rx, mp_int *ry, const ECGroup *group)
|
||||
mp_int *rx, mp_int *ry, const ECGroup *group,
|
||||
int timing)
|
||||
{
|
||||
mp_err res = MP_OKAY;
|
||||
mp_int x1, x2, z1, z2;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -34,7 +34,7 @@
|
||||
* Dr Vipul Gupta <vipul.gupta@sun.com> and
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: November 2013
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#ifndef _ECC_IMPL_H
|
||||
@ -258,7 +258,7 @@ extern SECStatus EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
|
||||
const unsigned char* random, int randomlen, int);
|
||||
/* This function has been modified to accept an array of random bytes */
|
||||
extern SECStatus ECDSA_SignDigest(ECPrivateKey *, SECItem *, const SECItem *,
|
||||
const unsigned char* random, int randomlen, int);
|
||||
const unsigned char* random, int randomlen, int, int timing);
|
||||
extern SECStatus ECDSA_VerifyDigest(ECPublicKey *, const SECItem *,
|
||||
const SECItem *, int);
|
||||
extern SECStatus ECDH_Derive(SECItem *, ECParams *, SECItem *, boolean_t,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -34,6 +34,7 @@
|
||||
* Stephen Fung <fungstep@hotmail.com> and
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#ifndef _ECL_PRIV_H
|
||||
@ -193,12 +194,13 @@ struct ECGroupStr {
|
||||
mp_int *ry, const ECGroup *group);
|
||||
mp_err (*point_mul) (const mp_int *n, const mp_int *px,
|
||||
const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
const ECGroup *group);
|
||||
const ECGroup *group, int timing);
|
||||
mp_err (*base_point_mul) (const mp_int *n, mp_int *rx, mp_int *ry,
|
||||
const ECGroup *group);
|
||||
mp_err (*points_mul) (const mp_int *k1, const mp_int *k2,
|
||||
const mp_int *px, const mp_int *py, mp_int *rx,
|
||||
mp_int *ry, const ECGroup *group);
|
||||
mp_int *ry, const ECGroup *group,
|
||||
int timing);
|
||||
mp_err (*validate_point) (const mp_int *px, const mp_int *py, const ECGroup *group);
|
||||
/* Extra storage for implementation-specific data. Any memory
|
||||
* allocated to these extra fields will be cleared by extra_free. */
|
||||
@ -262,10 +264,12 @@ void ec_GFp_extra_free_mont(GFMethod *meth);
|
||||
/* point multiplication */
|
||||
mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
|
||||
const mp_int *px, const mp_int *py, mp_int *rx,
|
||||
mp_int *ry, const ECGroup *group);
|
||||
mp_int *ry, const ECGroup *group,
|
||||
int timing);
|
||||
mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
|
||||
const mp_int *px, const mp_int *py, mp_int *rx,
|
||||
mp_int *ry, const ECGroup *group);
|
||||
mp_int *ry, const ECGroup *group,
|
||||
int timing);
|
||||
|
||||
/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
|
||||
* be an array of signed char's to output to, bitsize should be the number
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -33,6 +33,7 @@
|
||||
* Contributor(s):
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#ifndef _ECL_H
|
||||
@ -70,7 +71,8 @@ void EC_FreeCurveParams(ECCurveParams * params);
|
||||
* of the group of points on the elliptic curve. Input and output values
|
||||
* are assumed to be NOT field-encoded. */
|
||||
mp_err ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
|
||||
const mp_int *py, mp_int *qx, mp_int *qy);
|
||||
const mp_int *py, mp_int *qx, mp_int *qy,
|
||||
int timing);
|
||||
|
||||
/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k1 * G +
|
||||
* k2 * P(x, y), where G is the generator (base point) of the group of
|
||||
@ -78,7 +80,7 @@ mp_err ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
|
||||
* be NOT field-encoded. */
|
||||
mp_err ECPoints_mul(const ECGroup *group, const mp_int *k1,
|
||||
const mp_int *k2, const mp_int *px, const mp_int *py,
|
||||
mp_int *qx, mp_int *qy);
|
||||
mp_int *qx, mp_int *qy, int timing);
|
||||
|
||||
/* Validates an EC public key as described in Section 5.2.2 of X9.62.
|
||||
* Returns MP_YES if the public key is valid, MP_NO if the public key
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -33,7 +33,7 @@
|
||||
* Contributor(s):
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: Nov 2016
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#include "mpi.h"
|
||||
@ -50,7 +50,8 @@
|
||||
* are assumed to be NOT field-encoded. */
|
||||
mp_err
|
||||
ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
|
||||
const mp_int *py, mp_int *rx, mp_int *ry)
|
||||
const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
int timing)
|
||||
{
|
||||
mp_err res = MP_OKAY;
|
||||
mp_int kt;
|
||||
@ -76,16 +77,16 @@ ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
|
||||
kt.flag = (mp_sign)0;
|
||||
MP_CHECKOK(group->
|
||||
point_mul(&kt, &group->genx, &group->geny, rx, ry,
|
||||
group));
|
||||
group, timing));
|
||||
}
|
||||
} else {
|
||||
if (group->meth->field_enc) {
|
||||
MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
|
||||
MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
|
||||
MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
|
||||
MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group, timing));
|
||||
} else {
|
||||
kt.flag = (mp_sign)0;
|
||||
MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
|
||||
MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group, timing));
|
||||
}
|
||||
}
|
||||
if (group->meth->field_dec) {
|
||||
@ -107,7 +108,7 @@ ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
|
||||
mp_err
|
||||
ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
const ECGroup *group)
|
||||
const ECGroup *group, int timing)
|
||||
{
|
||||
mp_err res = MP_OKAY;
|
||||
mp_int sx, sy;
|
||||
@ -119,9 +120,9 @@ ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
|
||||
/* if some arguments are not defined used ECPoint_mul */
|
||||
if (k1 == NULL) {
|
||||
return ECPoint_mul(group, k2, px, py, rx, ry);
|
||||
return ECPoint_mul(group, k2, px, py, rx, ry, timing);
|
||||
} else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
|
||||
return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
|
||||
return ECPoint_mul(group, k1, NULL, NULL, rx, ry, timing);
|
||||
}
|
||||
|
||||
MP_DIGITS(&sx) = 0;
|
||||
@ -129,8 +130,8 @@ ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
MP_CHECKOK(mp_init(&sx, FLAG(k1)));
|
||||
MP_CHECKOK(mp_init(&sy, FLAG(k1)));
|
||||
|
||||
MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy));
|
||||
MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry));
|
||||
MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy, timing));
|
||||
MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry, timing));
|
||||
|
||||
if (group->meth->field_enc) {
|
||||
MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth));
|
||||
@ -162,7 +163,7 @@ ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
mp_err
|
||||
ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
const ECGroup *group)
|
||||
const ECGroup *group, int timing)
|
||||
{
|
||||
mp_err res = MP_OKAY;
|
||||
mp_int precomp[4][4][2];
|
||||
@ -177,9 +178,9 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
|
||||
/* if some arguments are not defined used ECPoint_mul */
|
||||
if (k1 == NULL) {
|
||||
return ECPoint_mul(group, k2, px, py, rx, ry);
|
||||
return ECPoint_mul(group, k2, px, py, rx, ry, timing);
|
||||
} else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
|
||||
return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
|
||||
return ECPoint_mul(group, k1, NULL, NULL, rx, ry, timing);
|
||||
}
|
||||
|
||||
/* initialize precomputation table */
|
||||
@ -311,7 +312,8 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
* Input and output values are assumed to be NOT field-encoded. */
|
||||
mp_err
|
||||
ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
|
||||
const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry)
|
||||
const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
int timing)
|
||||
{
|
||||
mp_err res = MP_OKAY;
|
||||
mp_int k1t, k2t;
|
||||
@ -348,9 +350,9 @@ ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
|
||||
|
||||
/* if points_mul is defined, then use it */
|
||||
if (group->points_mul) {
|
||||
res = group->points_mul(k1p, k2p, px, py, rx, ry, group);
|
||||
res = group->points_mul(k1p, k2p, px, py, rx, ry, group, timing);
|
||||
} else {
|
||||
res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
|
||||
res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group, timing);
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -33,6 +33,7 @@
|
||||
* Contributor(s):
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#ifndef _ECP_H
|
||||
@ -122,7 +123,7 @@ mp_err ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px,
|
||||
mp_err
|
||||
ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
const ECGroup *group);
|
||||
const ECGroup *group, int timing);
|
||||
|
||||
/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
|
||||
* curve points P and R can be identical. Uses mixed Modified-Jacobian
|
||||
@ -131,9 +132,13 @@ mp_err
|
||||
* returns output that is still field-encoded. Uses 5-bit window NAF
|
||||
* method (algorithm 11) for scalar-point multiplication from Brown,
|
||||
* Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
|
||||
* Curves Over Prime Fields. */
|
||||
* Curves Over Prime Fields. The implementation includes a countermeasure
|
||||
* that attempts to hide the size of n from timing channels. This counter-
|
||||
* measure is enabled using the timing argument. The high-rder bits of timing
|
||||
* must be uniformly random in order for this countermeasure to work. */
|
||||
mp_err
|
||||
ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
|
||||
mp_int *rx, mp_int *ry, const ECGroup *group);
|
||||
mp_int *rx, mp_int *ry, const ECGroup *group,
|
||||
int timing);
|
||||
|
||||
#endif /* _ECP_H */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -38,6 +38,7 @@
|
||||
* Nils Larsch <nla@trustcenter.de>, and
|
||||
* Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#include "ecp.h"
|
||||
@ -340,7 +341,8 @@ ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
|
||||
/* 4: Verify that the order of the curve times the publicValue
|
||||
* is the point at infinity.
|
||||
*/
|
||||
MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
|
||||
/* timing mitigation is not supported */
|
||||
MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt, /*timing*/ 0) );
|
||||
if (ec_GFp_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
|
||||
res = MP_NO;
|
||||
goto CLEANUP;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -38,6 +38,7 @@
|
||||
* Nils Larsch <nla@trustcenter.de>, and
|
||||
* Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#include "ecp.h"
|
||||
@ -406,7 +407,7 @@ ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
|
||||
mp_err
|
||||
ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
const mp_int *py, mp_int *rx, mp_int *ry,
|
||||
const ECGroup *group)
|
||||
const ECGroup *group, int timing)
|
||||
{
|
||||
mp_err res = MP_OKAY;
|
||||
mp_int precomp[4][4][2];
|
||||
@ -430,9 +431,9 @@ ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
|
||||
|
||||
/* if some arguments are not defined used ECPoint_mul */
|
||||
if (k1 == NULL) {
|
||||
return ECPoint_mul(group, k2, px, py, rx, ry);
|
||||
return ECPoint_mul(group, k2, px, py, rx, ry, timing);
|
||||
} else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
|
||||
return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
|
||||
return ECPoint_mul(group, k1, NULL, NULL, rx, ry, timing);
|
||||
}
|
||||
|
||||
/* initialize precomputation table */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -33,6 +33,7 @@
|
||||
* Contributor(s):
|
||||
* Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Last Modified Date from the Original Code: May 2017
|
||||
*********************************************************************** */
|
||||
|
||||
#include "ecp.h"
|
||||
@ -213,19 +214,23 @@ CLEANUP:
|
||||
* Curves Over Prime Fields. */
|
||||
mp_err
|
||||
ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
|
||||
mp_int *rx, mp_int *ry, const ECGroup *group)
|
||||
mp_int *rx, mp_int *ry, const ECGroup *group,
|
||||
int timing)
|
||||
{
|
||||
mp_err res = MP_OKAY;
|
||||
mp_int precomp[16][2], rz, tpx, tpy;
|
||||
mp_int raz4;
|
||||
mp_int precomp[16][2], rz, tpx, tpy, tpz;
|
||||
mp_int raz4, tpaz4;
|
||||
mp_int scratch[MAX_SCRATCH];
|
||||
signed char *naf = NULL;
|
||||
int i, orderBitSize;
|
||||
int numDoubles, numAdds, extraDoubles, extraAdds;
|
||||
|
||||
MP_DIGITS(&rz) = 0;
|
||||
MP_DIGITS(&raz4) = 0;
|
||||
MP_DIGITS(&tpx) = 0;
|
||||
MP_DIGITS(&tpy) = 0;
|
||||
MP_DIGITS(&tpz) = 0;
|
||||
MP_DIGITS(&tpaz4) = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
MP_DIGITS(&precomp[i][0]) = 0;
|
||||
MP_DIGITS(&precomp[i][1]) = 0;
|
||||
@ -239,7 +244,9 @@ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
|
||||
|
||||
/* initialize precomputation table */
|
||||
MP_CHECKOK(mp_init(&tpx, FLAG(n)));
|
||||
MP_CHECKOK(mp_init(&tpy, FLAG(n)));;
|
||||
MP_CHECKOK(mp_init(&tpy, FLAG(n)));
|
||||
MP_CHECKOK(mp_init(&tpz, FLAG(n)));
|
||||
MP_CHECKOK(mp_init(&tpaz4, FLAG(n)));
|
||||
MP_CHECKOK(mp_init(&rz, FLAG(n)));
|
||||
MP_CHECKOK(mp_init(&raz4, FLAG(n)));
|
||||
|
||||
@ -295,19 +302,64 @@ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
|
||||
/* Compute 5NAF */
|
||||
ec_compute_wNAF(naf, orderBitSize, n, 5);
|
||||
|
||||
numAdds = 0;
|
||||
numDoubles = orderBitSize;
|
||||
/* wNAF method */
|
||||
for (i = orderBitSize; i >= 0; i--) {
|
||||
|
||||
if (ec_GFp_pt_is_inf_jac(rx, ry, &rz) == MP_YES) {
|
||||
numDoubles--;
|
||||
}
|
||||
|
||||
/* R = 2R */
|
||||
ec_GFp_pt_dbl_jm(rx, ry, &rz, &raz4, rx, ry, &rz,
|
||||
&raz4, scratch, group);
|
||||
|
||||
if (naf[i] != 0) {
|
||||
ec_GFp_pt_add_jm_aff(rx, ry, &rz, &raz4,
|
||||
&precomp[(naf[i] + 15) / 2][0],
|
||||
&precomp[(naf[i] + 15) / 2][1], rx, ry,
|
||||
&rz, &raz4, scratch, group);
|
||||
numAdds++;
|
||||
}
|
||||
}
|
||||
|
||||
/* extra operations to make timing less dependent on secrets */
|
||||
if (timing) {
|
||||
/* low-order bit of timing argument contains no entropy */
|
||||
timing >>= 1;
|
||||
|
||||
MP_CHECKOK(ec_GFp_pt_set_inf_jac(&tpx, &tpy, &tpz));
|
||||
mp_zero(&tpaz4);
|
||||
|
||||
/* Set the temp value to a non-infinite point */
|
||||
ec_GFp_pt_add_jm_aff(&tpx, &tpy, &tpz, &tpaz4,
|
||||
&precomp[8][0],
|
||||
&precomp[8][1], &tpx, &tpy,
|
||||
&tpz, &tpaz4, scratch, group);
|
||||
|
||||
/* two bits of extra adds */
|
||||
extraAdds = timing & 0x3;
|
||||
timing >>= 2;
|
||||
/* Window size is 5, so the maximum number of additions is ceil(orderBitSize/5) */
|
||||
/* This is the same as (orderBitSize + 4) / 5 */
|
||||
for(i = numAdds; i <= (orderBitSize + 4) / 5 + extraAdds; i++) {
|
||||
ec_GFp_pt_add_jm_aff(&tpx, &tpy, &tpz, &tpaz4,
|
||||
&precomp[9 + (i % 3)][0],
|
||||
&precomp[9 + (i % 3)][1], &tpx, &tpy,
|
||||
&tpz, &tpaz4, scratch, group);
|
||||
}
|
||||
|
||||
/* two bits of extra doubles */
|
||||
extraDoubles = timing & 0x3;
|
||||
timing >>= 2;
|
||||
for(i = numDoubles; i <= orderBitSize + extraDoubles; i++) {
|
||||
ec_GFp_pt_dbl_jm(&tpx, &tpy, &tpz, &tpaz4, &tpx, &tpy, &tpz,
|
||||
&tpaz4, scratch, group);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* convert result S to affine coordinates */
|
||||
MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
|
||||
|
||||
@ -321,6 +373,8 @@ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
|
||||
}
|
||||
mp_clear(&tpx);
|
||||
mp_clear(&tpy);
|
||||
mp_clear(&tpz);
|
||||
mp_clear(&tpaz4);
|
||||
mp_clear(&rz);
|
||||
mp_clear(&raz4);
|
||||
#ifdef _KERNEL
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user