untrusted comment: verify with openbsd-64-base.pub RWQq6XmS4eDAcWqUmGX8ecmw/YFwnGf3wdbfi/3mUcXcUc6T36b7nkg3QlgYMPc0R47GHGq7MHsLx68Z1AvFt/Gr6T4bTwZ7/QI= OpenBSD 6.4 errata 003, November 17, 2018: The portsmash vulnerability allows exfiltration of elliptic curve keys. signify -Vep /etc/signify/openbsd-64-base.pub -x 003_portsmash.patch.sig \ -m - | (cd /usr/src && patch -p0) And then build and install libcrypto cd /usr/src/lib/libcrypto make obj make make install Index: lib/libcrypto/ec/ec2_smpl.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ec2_smpl.c,v retrieving revision 1.20 diff -u -p -r1.20 ec2_smpl.c --- lib/libcrypto/ec/ec2_smpl.c 16 Jul 2018 17:32:39 -0000 1.20 +++ lib/libcrypto/ec/ec2_smpl.c 15 Nov 2018 00:05:11 -0000 @@ -115,6 +115,7 @@ EC_GF2m_simple_method(void) .field_mul = ec_GF2m_simple_field_mul, .field_sqr = ec_GF2m_simple_field_sqr, .field_div = ec_GF2m_simple_field_div, + .blind_coordinates = NULL, }; return &ret; Index: lib/libcrypto/ec/ec_lcl.h =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ec_lcl.h,v retrieving revision 1.10 diff -u -p -r1.10 ec_lcl.h --- lib/libcrypto/ec/ec_lcl.h 16 Jul 2018 17:32:39 -0000 1.10 +++ lib/libcrypto/ec/ec_lcl.h 15 Nov 2018 00:05:11 -0000 @@ -182,6 +182,7 @@ struct ec_method_st { int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */ int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */ int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *); + int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); } /* EC_METHOD */; typedef struct ec_extra_data_st { @@ -339,6 +340,7 @@ int ec_GFp_simple_make_affine(const EC_G int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); 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); int ec_GFp_simple_mul_generator_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, BN_CTX *); int ec_GFp_simple_mul_single_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *); @@ -358,6 +360,7 @@ int ec_GFp_mont_field_encode(const EC_GR int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); +int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); /* method functions in ecp_nist.c */ int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); Index: lib/libcrypto/ec/ec_lib.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ec_lib.c,v retrieving revision 1.29 diff -u -p -r1.29 ec_lib.c --- lib/libcrypto/ec/ec_lib.c 16 Jul 2018 17:32:39 -0000 1.29 +++ lib/libcrypto/ec/ec_lib.c 15 Nov 2018 00:14:28 -0000 @@ -533,6 +533,23 @@ EC_GROUP_cmp(const EC_GROUP * a, const E return -1; } +/* + * 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; + + return group->meth->blind_coordinates(group, p, ctx); +} /* this has 'package' visibility */ int Index: lib/libcrypto/ec/ecp_mont.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ecp_mont.c,v retrieving revision 1.16 diff -u -p -r1.16 ecp_mont.c --- lib/libcrypto/ec/ecp_mont.c 16 Jul 2018 17:32:39 -0000 1.16 +++ lib/libcrypto/ec/ecp_mont.c 15 Nov 2018 00:05:11 -0000 @@ -109,7 +109,8 @@ EC_GFp_mont_method(void) .field_sqr = ec_GFp_mont_field_sqr, .field_encode = ec_GFp_mont_field_encode, .field_decode = ec_GFp_mont_field_decode, - .field_set_to_one = ec_GFp_mont_field_set_to_one + .field_set_to_one = ec_GFp_mont_field_set_to_one, + .blind_coordinates = ec_GFp_simple_blind_coordinates, }; return &ret; Index: lib/libcrypto/ec/ecp_nist.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ecp_nist.c,v retrieving revision 1.14 diff -u -p -r1.14 ecp_nist.c --- lib/libcrypto/ec/ecp_nist.c 16 Jul 2018 17:32:39 -0000 1.14 +++ lib/libcrypto/ec/ecp_nist.c 15 Nov 2018 00:05:11 -0000 @@ -107,7 +107,8 @@ EC_GFp_nist_method(void) .mul_single_ct = ec_GFp_simple_mul_single_ct, .mul_double_nonct = ec_GFp_simple_mul_double_nonct, .field_mul = ec_GFp_nist_field_mul, - .field_sqr = ec_GFp_nist_field_sqr + .field_sqr = ec_GFp_nist_field_sqr, + .blind_coordinates = ec_GFp_simple_blind_coordinates, }; return &ret; Index: lib/libcrypto/ec/ecp_nistp224.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ecp_nistp224.c,v retrieving revision 1.22 diff -u -p -r1.22 ecp_nistp224.c --- lib/libcrypto/ec/ecp_nistp224.c 15 Jul 2018 16:27:39 -0000 1.22 +++ lib/libcrypto/ec/ecp_nistp224.c 15 Nov 2018 00:05:11 -0000 @@ -270,7 +270,8 @@ EC_GFp_nistp224_method(void) .precompute_mult = ec_GFp_nistp224_precompute_mult, .have_precompute_mult = ec_GFp_nistp224_have_precompute_mult, .field_mul = ec_GFp_nist_field_mul, - .field_sqr = ec_GFp_nist_field_sqr + .field_sqr = ec_GFp_nist_field_sqr, + .blind_coordinates = NULL, }; return &ret; Index: lib/libcrypto/ec/ecp_nistp256.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ecp_nistp256.c,v retrieving revision 1.21 diff -u -p -r1.21 ecp_nistp256.c --- lib/libcrypto/ec/ecp_nistp256.c 15 Jul 2018 16:27:39 -0000 1.21 +++ lib/libcrypto/ec/ecp_nistp256.c 15 Nov 2018 00:05:11 -0000 @@ -1724,7 +1724,8 @@ EC_GFp_nistp256_method(void) .precompute_mult = ec_GFp_nistp256_precompute_mult, .have_precompute_mult = ec_GFp_nistp256_have_precompute_mult, .field_mul = ec_GFp_nist_field_mul, - .field_sqr = ec_GFp_nist_field_sqr + .field_sqr = ec_GFp_nist_field_sqr, + .blind_coordinates = NULL, }; return &ret; Index: lib/libcrypto/ec/ecp_nistp521.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ecp_nistp521.c,v retrieving revision 1.22 diff -u -p -r1.22 ecp_nistp521.c --- lib/libcrypto/ec/ecp_nistp521.c 15 Jul 2018 16:27:39 -0000 1.22 +++ lib/libcrypto/ec/ecp_nistp521.c 15 Nov 2018 00:05:11 -0000 @@ -1614,7 +1614,8 @@ EC_GFp_nistp521_method(void) .precompute_mult = ec_GFp_nistp521_precompute_mult, .have_precompute_mult = ec_GFp_nistp521_have_precompute_mult, .field_mul = ec_GFp_nist_field_mul, - .field_sqr = ec_GFp_nist_field_sqr + .field_sqr = ec_GFp_nist_field_sqr, + .blind_coordinates = NULL, }; return &ret; Index: lib/libcrypto/ec/ecp_nistz256.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ecp_nistz256.c,v retrieving revision 1.6 diff -u -p -r1.6 ecp_nistz256.c --- lib/libcrypto/ec/ecp_nistz256.c 15 Jul 2018 16:27:39 -0000 1.6 +++ lib/libcrypto/ec/ecp_nistz256.c 15 Nov 2018 00:05:11 -0000 @@ -1182,7 +1182,8 @@ EC_GFp_nistz256_method(void) .field_sqr = ec_GFp_mont_field_sqr, .field_encode = ec_GFp_mont_field_encode, .field_decode = ec_GFp_mont_field_decode, - .field_set_to_one = ec_GFp_mont_field_set_to_one + .field_set_to_one = ec_GFp_mont_field_set_to_one, + .blind_coordinates = NULL, }; return &ret; Index: lib/libcrypto/ec/ecp_smpl.c =================================================================== RCS file: /var/cvs/src/lib/libcrypto/ec/ecp_smpl.c,v retrieving revision 1.22 diff -u -p -r1.22 ecp_smpl.c --- lib/libcrypto/ec/ecp_smpl.c 16 Jul 2018 17:32:39 -0000 1.22 +++ lib/libcrypto/ec/ecp_smpl.c 15 Nov 2018 00:13:47 -0000 @@ -107,7 +107,8 @@ EC_GFp_simple_method(void) .mul_single_ct = ec_GFp_simple_mul_single_ct, .mul_double_nonct = ec_GFp_simple_mul_double_nonct, .field_mul = ec_GFp_simple_field_mul, - .field_sqr = ec_GFp_simple_field_sqr + .field_sqr = ec_GFp_simple_field_sqr, + .blind_coordinates = ec_GFp_simple_blind_coordinates, }; return &ret; @@ -1406,13 +1407,73 @@ ec_GFp_simple_field_mul(const EC_GROUP * return BN_mod_mul(r, a, b, &group->field, ctx); } - int ec_GFp_simple_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, BN_CTX * ctx) { 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) + * + * where lambda is in the interval [1, group->field). + */ +int +ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) +{ + BIGNUM *lambda = NULL; + BIGNUM *tmp = NULL; + int ret = 0; + + BN_CTX_start(ctx); + if ((lambda = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Generate lambda in [1, group->field - 1] */ + do { + if (!BN_rand_range(lambda, &group->field)) + goto err; + } while (BN_is_zero(lambda)); + + if (group->meth->field_encode != NULL && + !group->meth->field_encode(group, lambda, lambda, ctx)) + goto err; + + /* Z = lambda * Z */ + if (!group->meth->field_mul(group, &p->Z, lambda, &p->Z, ctx)) + goto err; + + /* tmp = lambda^2 */ + if (!group->meth->field_sqr(group, tmp, lambda, ctx)) + goto err; + + /* X = lambda^2 * X */ + if (!group->meth->field_mul(group, &p->X, tmp, &p->X, ctx)) + goto err; + + /* tmp = lambda^3 */ + if (!group->meth->field_mul(group, tmp, tmp, lambda, ctx)) + goto err; + + /* Y = lambda^3 * Y */ + if (!group->meth->field_mul(group, &p->Y, tmp, &p->Y, ctx)) + goto err; + + /* Disable optimized arithmetics after replacing Z by lambda * Z. */ + p->Z_is_one = 0; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + + #define EC_POINT_BN_set_flags(P, flags) do { \ BN_set_flags(&(P)->X, (flags)); \ BN_set_flags(&(P)->Y, (flags)); \ @@ -1535,6 +1596,13 @@ ec_GFp_simple_mul_ct(const EC_GROUP *gro (bn_wexpand(&r->X, group_top) == NULL) || (bn_wexpand(&r->Y, group_top) == NULL) || (bn_wexpand(&r->Z, group_top) == NULL)) + goto err; + + /* + * Apply coordinate blinding for EC_POINT if the underlying EC_METHOD + * implements it. + */ + if (!ec_point_blind_coordinates(group, s, ctx)) goto err; /* top bit is a 1, in a fixed pos */