diff options
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | crypto/ec/ec2_smpl.c | 4 | ||||
-rw-r--r-- | crypto/ec/ec_err.c | 2 | ||||
-rw-r--r-- | crypto/ec/ec_lcl.h | 5 | ||||
-rw-r--r-- | crypto/ec/ec_lib.c | 18 | ||||
-rw-r--r-- | crypto/ec/ec_mult.c | 11 | ||||
-rw-r--r-- | crypto/ec/ecp_mont.c | 4 | ||||
-rw-r--r-- | crypto/ec/ecp_nist.c | 4 | ||||
-rw-r--r-- | crypto/ec/ecp_nistp224.c | 4 | ||||
-rw-r--r-- | crypto/ec/ecp_nistp521.c | 4 | ||||
-rw-r--r-- | crypto/ec/ecp_nistz256.c | 3 | ||||
-rw-r--r-- | crypto/ec/ecp_smpl.c | 58 | ||||
-rw-r--r-- | crypto/err/openssl.txt | 1 | ||||
-rw-r--r-- | include/openssl/ecerr.h | 1 |
14 files changed, 117 insertions, 7 deletions
@@ -8,6 +8,11 @@ release branch. Changes between 1.1.0h and 1.1.1 [xx XXX xxxx] + *) Add coordinate blinding for EC_POINT and implement projective + coordinate blinding for generic prime curves as a countermeasure to + chosen point SCA attacks. + [Sohaib ul Hassan, Nicola Tuveri, Billy Bob Brumley] + *) Add blinding to an ECDSA signature to protect against side channel attacks discovered by Keegan Ryan (NCC Group). [Matt Caswell] diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index b79e60b8b5..cef6ba4c65 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -64,7 +64,9 @@ const EC_METHOD *EC_GF2m_simple_method(void) ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key + ecdh_simple_compute_key, + 0, /* field_inverse_mod_ord */ + 0 /* blind_coordinates */ }; return &ret; diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index 6a1be2eb3b..342b84fecb 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -116,6 +116,8 @@ static const ERR_STRING_DATA EC_str_functs[] = { "ec_GFp_nist_field_sqr"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_GROUP_SET_CURVE, 0), "ec_GFp_nist_group_set_curve"}, + {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0), + "ec_GFp_simple_blind_coordinates"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0), "ec_GFp_simple_group_check_discriminant"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0), diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index 5e14071aec..006e3b6e16 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -176,6 +176,7 @@ struct ec_method_st { /* Inverse modulo order */ int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r, BIGNUM *x, BN_CTX *ctx); + int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); }; /* @@ -382,6 +383,8 @@ int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); +int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, + BN_CTX *ctx); /* method functions in ecp_mont.c */ int ec_GFp_mont_group_init(EC_GROUP *); @@ -635,3 +638,5 @@ void X25519_public_from_private(uint8_t out_public_value[32], int EC_GROUP_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, BIGNUM *x, BN_CTX *ctx); + +int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 30b11f75e9..d0393e8bad 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -1025,3 +1025,21 @@ int EC_GROUP_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, else return 0; } + +/*- + * Coordinate blinding for EC_POINT. + * + * The underlying EC_METHOD can optionally implement this function: + * underlying implementations should return 0 on errors, or 1 on + * success. + * + * This wrapper returns 1 in case the underlying EC_METHOD does not + * support coordinate blinding. + */ +int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) +{ + if (group->meth->blind_coordinates == NULL) + return 1; /* ignore if not implemented */ + + return group->meth->blind_coordinates(group, p, ctx); +} diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 05a3aca0a4..b668e87ff7 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -211,6 +211,17 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r, || (bn_wexpand(r->Z, group_top) == NULL)) goto err; + /*- + * Apply coordinate blinding for EC_POINT. + * + * The underlying EC_METHOD can optionally implement this function: + * ec_point_blind_coordinates() returns 0 in case of errors or 1 on + * success or if coordinate blinding is not implemented for this + * group. + */ + if (!ec_point_blind_coordinates(group, s, ctx)) + goto err; + /* top bit is a 1, in a fixed pos */ if (!EC_POINT_copy(r, s)) goto err; diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index 1a760d1239..27ece3b43c 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -61,7 +61,9 @@ const EC_METHOD *EC_GFp_mont_method(void) ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key + ecdh_simple_compute_key, + 0, /* field_inverse_mod_ord */ + ec_GFp_simple_blind_coordinates }; return &ret; diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c index 16c4cce313..aaa73d62d7 100644 --- a/crypto/ec/ecp_nist.c +++ b/crypto/ec/ecp_nist.c @@ -63,7 +63,9 @@ const EC_METHOD *EC_GFp_nist_method(void) ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key + ecdh_simple_compute_key, + 0, /* field_inverse_mod_ord */ + ec_GFp_simple_blind_coordinates }; return &ret; diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index 364b7f246d..6e7c687c43 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -290,7 +290,9 @@ const EC_METHOD *EC_GFp_nistp224_method(void) ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key + ecdh_simple_compute_key, + 0, /* field_inverse_mod_ord */ + 0 /* blind_coordinates */ }; return &ret; diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c index 3f68ae3c1c..43f3e2d9ee 100644 --- a/crypto/ec/ecp_nistp521.c +++ b/crypto/ec/ecp_nistp521.c @@ -1658,7 +1658,9 @@ const EC_METHOD *EC_GFp_nistp521_method(void) ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key + ecdh_simple_compute_key, + 0, /* field_inverse_mod_ord */ + 0 /* blind_coordinates */ }; return &ret; diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index d3603fbbec..02925616b1 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -1730,7 +1730,8 @@ const EC_METHOD *EC_GFp_nistz256_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, - ecp_nistz256_inv_mod_ord /* can be #define-d NULL */ + ecp_nistz256_inv_mod_ord, /* can be #define-d NULL */ + 0 /* blind_coordinates */ }; return &ret; diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 35d15a6882..e0e4996cfd 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -62,7 +62,9 @@ const EC_METHOD *EC_GFp_simple_method(void) ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key + ecdh_simple_compute_key, + 0, /* field_inverse_mod_ord */ + ec_GFp_simple_blind_coordinates }; return &ret; @@ -1363,3 +1365,57 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, { return BN_mod_sqr(r, a, group->field, ctx); } + +/*- + * Apply randomization of EC point projective coordinates: + * + * (X, Y ,Z ) = (lambda^2*X, lambda^3*Y, lambda*Z) + * lambda = [1,group->field) + * + */ +int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, + BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *lambda = NULL; + BIGNUM *temp = NULL; + + BN_CTX_start(ctx); + lambda = BN_CTX_get(ctx); + temp = BN_CTX_get(ctx); + if (temp == NULL) { + ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* make sure lambda is not zero */ + do { + if (!BN_priv_rand_range(lambda, group->field)) { + ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_BN_LIB); + goto err; + } + } while (BN_is_zero(lambda)); + + /* if field_encode defined convert between representations */ + if (group->meth->field_encode != NULL + && !group->meth->field_encode(group, lambda, lambda, ctx)) + goto err; + if (!group->meth->field_mul(group, p->Z, p->Z, lambda, ctx)) + goto err; + if (!group->meth->field_sqr(group, temp, lambda, ctx)) + goto err; + if (!group->meth->field_mul(group, p->X, p->X, temp, ctx)) + goto err; + if (!group->meth->field_mul(group, temp, temp, lambda, ctx)) + goto err; + if (!group->meth->field_mul(group, p->Y, p->Y, temp, ctx)) + goto err; + p->Z_is_one = 0; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 23671a0f26..e0580a871d 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -550,6 +550,7 @@ EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES:235:\ EC_F_EC_GFP_NIST_FIELD_MUL:200:ec_GFp_nist_field_mul EC_F_EC_GFP_NIST_FIELD_SQR:201:ec_GFp_nist_field_sqr EC_F_EC_GFP_NIST_GROUP_SET_CURVE:202:ec_GFp_nist_group_set_curve +EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES:287:ec_GFp_simple_blind_coordinates EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT:165:\ ec_GFp_simple_group_check_discriminant EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE:166:ec_GFp_simple_group_set_curve diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h index 603efccaa3..8db7967697 100644 --- a/include/openssl/ecerr.h +++ b/include/openssl/ecerr.h @@ -87,6 +87,7 @@ int ERR_load_EC_strings(void); # define EC_F_EC_GFP_NIST_FIELD_MUL 200 # define EC_F_EC_GFP_NIST_FIELD_SQR 201 # define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +# define EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES 287 # define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 # define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 # define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 |