Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP4
openssl-1_1.26613
openssl-CVE-2019-1547.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssl-CVE-2019-1547.patch of Package openssl-1_1.26613
From 7c1709c2da5414f5b6133d00a03fc8c5bf996c7a Mon Sep 17 00:00:00 2001 From: Billy Brumley <bbrumley@gmail.com> Date: Fri, 6 Sep 2019 19:34:53 +0300 Subject: [PATCH] [crypto/ec] for ECC parameters with NULL or zero cofactor, compute it The cofactor argument to EC_GROUP_set_generator is optional, and SCA mitigations for ECC currently use it. So the library currently falls back to very old SCA-vulnerable code if the cofactor is not present. This PR allows EC_GROUP_set_generator to compute the cofactor for all curves of cryptographic interest. Steering scalar multiplication to more SCA-robust code. This issue affects persisted private keys in explicit parameter form, where the (optional) cofactor field is zero or absent. It also affects curves not built-in to the library, but constructed programatically with explicit parameters, then calling EC_GROUP_set_generator with a nonsensical value (NULL, zero). The very old scalar multiplication code is known to be vulnerable to local uarch attacks, outside of the OpenSSL threat model. New results suggest the code path is also vulnerable to traditional wall clock timing attacks. CVE-2019-1547 Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9795) --- CHANGES | 8 +++- crypto/ec/ec_err.c | 1 + crypto/ec/ec_lib.c | 103 ++++++++++++++++++++++++++++++++++++++++--- include/openssl/ec.h | 1 + 4 files changed, 105 insertions(+), 8 deletions(-) Index: openssl-1.1.0i/crypto/ec/ec_err.c =================================================================== --- openssl-1.1.0i.orig/crypto/ec/ec_err.c +++ openssl-1.1.0i/crypto/ec/ec_err.c @@ -267,6 +267,7 @@ static ERR_STRING_DATA EC_str_reasons[] {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, + {ERR_REASON(EC_R_UNKNOWN_COFACTOR), "unknown cofactor"}, {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, Index: openssl-1.1.0i/crypto/ec/ec_lib.c =================================================================== --- openssl-1.1.0i.orig/crypto/ec/ec_lib.c +++ openssl-1.1.0i/crypto/ec/ec_lib.c @@ -257,6 +257,67 @@ int EC_METHOD_get_field_type(const EC_ME return meth->field_type; } +/*- + * Try computing cofactor from the generator order (n) and field cardinality (q). + * This works for all curves of cryptographic interest. + * + * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q) + * h_min = (q + 1 - 2*sqrt(q))/n + * h_max = (q + 1 + 2*sqrt(q))/n + * h_max - h_min = 4*sqrt(q)/n + * So if n > 4*sqrt(q) holds, there is only one possible value for h: + * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil + * + * Otherwise, zero cofactor and return success. + */ +static int ec_guess_cofactor(EC_GROUP *group) { + int ret = 0; + BN_CTX *ctx = NULL; + BIGNUM *q = NULL; + + /*- + * If the cofactor is too large, we cannot guess it. + * The RHS of below is a strict overestimate of lg(4 * sqrt(q)) + */ + if (BN_num_bits(group->order) <= (BN_num_bits(group->field) + 1) / 2 + 3) { + /* default to 0 */ + BN_zero(group->cofactor); + /* return success */ + return 1; + } + + if ((ctx = BN_CTX_new()) == NULL) + return 0; + + BN_CTX_start(ctx); + if ((q = BN_CTX_get(ctx)) == NULL) + goto err; + + /* set q = 2**m for binary fields; q = p otherwise */ + if (group->meth->field_type == NID_X9_62_characteristic_two_field) { + BN_zero(q); + if (!BN_set_bit(q, BN_num_bits(group->field) - 1)) + goto err; + } else { + if (!BN_copy(q, group->field)) + goto err; + } + + /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */ + if (!BN_rshift1(group->cofactor, group->order) /* n/2 */ + || !BN_add(group->cofactor, group->cofactor, q) /* q + n/2 */ + /* q + 1 + n/2 */ + || !BN_add(group->cofactor, group->cofactor, BN_value_one()) + /* (q + 1 + n/2)/n */ + || !BN_div(group->cofactor, NULL, group->cofactor, group->order, ctx)) + goto err; + ret = 1; + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) { @@ -265,6 +326,34 @@ int EC_GROUP_set_generator(EC_GROUP *gro return 0; } + /* require group->field >= 1 */ + if (group->field == NULL || BN_is_zero(group->field) + || BN_is_negative(group->field)) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD); + return 0; + } + + /*- + * - require order >= 1 + * - enforce upper bound due to Hasse thm: order can be no more than one bit + * longer than field cardinality + */ + if (order == NULL || BN_is_zero(order) || BN_is_negative(order) + || BN_num_bits(order) > BN_num_bits(group->field) + 1) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + /*- + * Unfortunately the cofactor is an optional field in many standards. + * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor". + * So accept cofactor == NULL or cofactor >= 0. + */ + if (cofactor != NULL && BN_is_negative(cofactor)) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR); + return 0; + } + if (group->generator == NULL) { group->generator = EC_POINT_new(group); if (group->generator == NULL) @@ -273,17 +362,17 @@ int EC_GROUP_set_generator(EC_GROUP *gro if (!EC_POINT_copy(group->generator, generator)) return 0; - if (order != NULL) { - if (!BN_copy(group->order, order)) - return 0; - } else - BN_zero(group->order); + if (!BN_copy(group->order, order)) + return 0; - if (cofactor != NULL) { + /* Either take the provided positive cofactor, or try to compute it */ + if (cofactor != NULL && !BN_is_zero(cofactor)) { if (!BN_copy(group->cofactor, cofactor)) return 0; - } else + } else if (!ec_guess_cofactor(group)) { BN_zero(group->cofactor); + return 0; + } /* * Some groups have an order with Index: openssl-1.1.0i/include/openssl/ec.h =================================================================== --- openssl-1.1.0i.orig/include/openssl/ec.h +++ openssl-1.1.0i/include/openssl/ec.h @@ -1563,6 +1563,7 @@ int ERR_load_EC_strings(void); # define EC_R_SLOT_FULL 108 # define EC_R_UNDEFINED_GENERATOR 113 # define EC_R_UNDEFINED_ORDER 128 +# define EC_R_UNKNOWN_COFACTOR 164 # define EC_R_UNKNOWN_GROUP 129 # define EC_R_UNKNOWN_ORDER 114 # define EC_R_UNSUPPORTED_FIELD 131
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor