From af0025fc40779cc98c06db7e29936f9d5de8cc9e Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 18 Oct 2023 15:50:30 +0200 Subject: bn: Properly error out if aliasing return value with modulus Test case amended from code initially written by Bernd Edlinger. Fixes #21110 Reviewed-by: Dmitry Belyavskiy Reviewed-by: Paul Dale Reviewed-by: Hugo Landau (Merged from https://github.com/openssl/openssl/pull/22421) --- crypto/bn/bn_exp.c | 21 +++++++++++++++++++++ crypto/bn/bn_mod.c | 10 ++++++++++ 2 files changed, 31 insertions(+) (limited to 'crypto') diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index cb6d19229f..b876edbfac 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -242,6 +242,14 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, wstart = bits - 1; /* The top bit of the window */ wend = 0; /* The bottom bit of the window */ + if (r == p) { + BIGNUM *p_dup = BN_CTX_get(ctx); + + if (p_dup == NULL || BN_copy(p_dup, p) == NULL) + goto err; + p = p_dup; + } + if (!BN_one(r)) goto err; @@ -1317,6 +1325,11 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, return 0; } + if (r == m) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + bits = BN_num_bits(p); if (bits == 0) { /* x**0 mod 1, or x**0 mod -1 is still zero. */ @@ -1361,6 +1374,14 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, wstart = bits - 1; /* The top bit of the window */ wend = 0; /* The bottom bit of the window */ + if (r == p) { + BIGNUM *p_dup = BN_CTX_get(ctx); + + if (p_dup == NULL || BN_copy(p_dup, p) == NULL) + goto err; + p = p_dup; + } + if (!BN_one(r)) goto err; diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c index 982e0e992c..d7c2f4bd5b 100644 --- a/crypto/bn/bn_mod.c +++ b/crypto/bn/bn_mod.c @@ -17,6 +17,11 @@ int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) * always holds) */ + if (r == d) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (!(BN_mod(r, m, d, ctx))) return 0; if (!r->neg) @@ -184,6 +189,11 @@ int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) { + if (r == m) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (!BN_sub(r, a, b)) return 0; if (r->neg) -- cgit v1.2.3