diff options
author | Billy Brumley <bbrumley@gmail.com> | 2021-01-08 13:45:49 +0200 |
---|---|---|
committer | Nicola Tuveri <nic.tuv@gmail.com> | 2021-01-10 21:58:39 +0200 |
commit | 6e3ba20dc49ccbf12ff4c27a4d8b84dcbeb71654 (patch) | |
tree | d721be08df7f857c86e30e5788b83689db1f725d /crypto | |
parent | 212d7118a788e332dae4123d40f65ea6e24044d2 (diff) |
[crypto/dh] side channel hardening for computing DH shared keys (1.1.1)
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/13772)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/dh/dh_key.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index daffdf74dd..ccf51b3546 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -25,18 +25,45 @@ int DH_generate_key(DH *dh) return dh->meth->generate_key(dh); } +/*- + * NB: This function is inherently not constant time due to the + * RFC 5246 (8.1.2) padding style that strips leading zero bytes. + */ int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) { - return dh->meth->compute_key(key, pub_key, dh); + int ret = 0, i; + volatile size_t npad = 0, mask = 1; + + /* compute the key; ret is constant unless compute_key is external */ + if ((ret = dh->meth->compute_key(key, pub_key, dh)) <= 0) + return ret; + + /* count leading zero bytes, yet still touch all bytes */ + for (i = 0; i < ret; i++) { + mask &= !key[i]; + npad += mask; + } + + /* unpad key */ + ret -= npad; + /* key-dependent memory access, potentially leaking npad / ret */ + memmove(key, key + npad, ret); + /* key-dependent memory access, potentially leaking npad / ret */ + memset(key + ret, 0, npad); + + return ret; } int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) { int rv, pad; + + /* rv is constant unless compute_key is external */ rv = dh->meth->compute_key(key, pub_key, dh); if (rv <= 0) return rv; pad = BN_num_bytes(dh->p) - rv; + /* pad is constant (zero) unless compute_key is external */ if (pad > 0) { memmove(key + pad, key, rv); memset(key, 0, pad); @@ -212,7 +239,7 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) goto err; } - ret = BN_bn2bin(tmp, key); + ret = BN_bn2binpad(tmp, key, BN_num_bytes(dh->p)); err: BN_CTX_end(ctx); BN_CTX_free(ctx); |