summaryrefslogtreecommitdiffstats
path: root/crypto/bn/bn_lib.c
diff options
context:
space:
mode:
authorNicola Tuveri <nic.tuv@gmail.com>2020-01-21 17:08:16 +0200
committerNicola Tuveri <nic.tuv@gmail.com>2020-02-18 19:11:10 +0200
commit2d9167ed0b588dacbdd0303fb6041ffe1d8b3a92 (patch)
treecf92949b383a5dbabed87bff96681f108e4e1131 /crypto/bn/bn_lib.c
parent0401d766afcd022748763f5614188301c9856c6e (diff)
[BN] harden `BN_copy()` against leaks from memory accesses
`BN_copy()` (and indirectly `BN_dup()`) do not propagate the `BN_FLG_CONSTTIME` flag: the propagation has been turned on and off a few times in the past years, because in some conditions it has shown unintended consequences in some code paths. Without turning the propagation on once more, we can still improve `BN_copy()` by avoiding to leak `src->top` in case `src` is flagged with `BN_FLG_CONSTTIME`. In this case we can instead use `src->dmax` as the number of words allocated for `dst` and for the `memcpy` operation. Barring compiler or runtime optimizations, if the caller provides `src` flagged as const time and preallocated to a public size, no leak should happen due to the copy operation. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/10631)
Diffstat (limited to 'crypto/bn/bn_lib.c')
-rw-r--r--crypto/bn/bn_lib.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 1e62b96874..e7ffce2875 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -322,15 +322,19 @@ BIGNUM *BN_dup(const BIGNUM *a)
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
{
+ int bn_words;
+
bn_check_top(b);
+ bn_words = BN_get_flags(b, BN_FLG_CONSTTIME) ? b->dmax : b->top;
+
if (a == b)
return a;
- if (bn_wexpand(a, b->top) == NULL)
+ if (bn_wexpand(a, bn_words) == NULL)
return NULL;
if (b->top > 0)
- memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
+ memcpy(a->d, b->d, sizeof(b->d[0]) * bn_words);
a->neg = b->neg;
a->top = b->top;