Commit 875ba8b2 authored by Sohaib ul Hassan's avatar Sohaib ul Hassan Committed by Nicola Tuveri
Browse files

Implement coordinate blinding for EC_POINT

This commit implements coordinate blinding, i.e., it randomizes the
representative of an elliptic curve point in its equivalence class, for
prime curves implemented through EC_GFp_simple_method,
EC_GFp_mont_method, and EC_GFp_nist_method.

This commit is derived from the patch
https://marc.info/?l=openssl-dev&m=131194808413635

 by Billy Brumley.

Coordinate blinding is a generally useful side-channel countermeasure
and is (mostly) free. The function itself takes a few field
multiplicationss, but is usually only necessary at the beginning of a
scalar multiplication (as implemented in the patch). When used this way,
it makes the values that variables take (i.e., field elements in an
algorithm state) unpredictable.

For instance, this mitigates chosen EC point side-channel attacks for
settings such as ECDH and EC private key decryption, for the
aforementioned curves.

For EC_METHODs using different coordinate representations this commit
does nothing, but the corresponding coordinate blinding function can be
easily added in the future to extend these changes to such curves.

Co-authored-by: default avatarNicola Tuveri <nic.tuv@gmail.com>
Co-authored-by: default avatarBilly Brumley <bbrumley@gmail.com>

Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
Reviewed-by: default avatarNicola Tuveri <nic.tuv@gmail.com>
Reviewed-by: default avatarAndy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6526)
parent e5d18257
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -9,7 +9,10 @@
 Changes between 1.1.0i and 1.1.0j [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]
 Changes between 1.1.0h and 1.1.0i [14 Aug 2018]
+2 −1
Original line number Diff line number Diff line
@@ -83,7 +83,8 @@ 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  /* blind_coordinates */
    };

    return &ret;
+3 −1
Original line number Diff line number Diff line
/*
 * Generated by util/mkerr.pl DO NOT EDIT
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
@@ -97,6 +97,8 @@ static ERR_STRING_DATA EC_str_functs[] = {
    {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
    {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),
     "ec_GFp_nist_group_set_curve"},
    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES),
     "ec_GFp_simple_blind_coordinates"},
    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),
     "ec_GFp_simple_group_check_discriminant"},
    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),
+5 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ struct ec_method_st {
    /* custom ECDH operation */
    int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen,
                            const EC_POINT *pub_key, const EC_KEY *ecdh);
    int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
};

/*
@@ -375,6 +376,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 *);
@@ -627,3 +630,5 @@ int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
           const uint8_t peer_public_value[32]);
void X25519_public_from_private(uint8_t out_public_value[32],
                                const uint8_t private_key[32]);

int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
+18 −0
Original line number Diff line number Diff line
@@ -1017,3 +1017,21 @@ int ec_group_simple_order_bits(const EC_GROUP *group)
        return 0;
    return BN_num_bits(group->order);
}

/*-
 * 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);
}
Loading