summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2015-05-19 15:19:30 +0100
committerMatt Caswell <matt@openssl.org>2015-05-22 23:15:02 +0100
commit7cc18d8158b5fc2676393d99b51c30c135502107 (patch)
tree45d10d9d5128ff63ade1d546f43e9b138aa9fa6e /crypto
parent2c55a0bc93bf578757ec5c85bdb3abe9cf3f4893 (diff)
Reject negative shifts for BN_rshift and BN_lshift
The functions BN_rshift and BN_lshift shift their arguments to the right or left by a specified number of bits. Unpredicatable results (including crashes) can occur if a negative number is supplied for the shift value. Thanks to Mateusz Kocielski (LogicalTrust), Marek Kroemeke and Filip Palian for discovering and reporting this issue. Reviewed-by: Kurt Roeckx <kurt@openssl.org>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/bn/bn_err.c3
-rw-r--r--crypto/bn/bn_shift.c10
2 files changed, 13 insertions, 0 deletions
diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c
index 13742ff181..1096ec7621 100644
--- a/crypto/bn/bn_err.c
+++ b/crypto/bn/bn_err.c
@@ -98,6 +98,7 @@ static ERR_STRING_DATA BN_str_functs[] = {
{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"},
{ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"},
{ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"},
+ {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"},
{ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"},
{ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"},
{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"},
@@ -113,6 +114,7 @@ static ERR_STRING_DATA BN_str_functs[] = {
{ERR_FUNC(BN_F_BN_NEW), "BN_new"},
{ERR_FUNC(BN_F_BN_RAND), "BN_rand"},
{ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"},
+ {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"},
{ERR_FUNC(BN_F_BN_SET_WORDS), "bn_set_words"},
{ERR_FUNC(BN_F_BN_USUB), "BN_usub"},
{0, NULL}
@@ -131,6 +133,7 @@ static ERR_STRING_DATA BN_str_reasons[] = {
{ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"},
{ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"},
{ERR_REASON(BN_R_INVALID_RANGE), "invalid range"},
+ {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"},
{ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"},
{ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"},
{ERR_REASON(BN_R_NO_INVERSE), "no inverse"},
diff --git a/crypto/bn/bn_shift.c b/crypto/bn/bn_shift.c
index 1b38bd861a..4e43a60b22 100644
--- a/crypto/bn/bn_shift.c
+++ b/crypto/bn/bn_shift.c
@@ -136,6 +136,11 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
bn_check_top(r);
bn_check_top(a);
+ if (n < 0) {
+ BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT);
+ return 0;
+ }
+
r->neg = a->neg;
nw = n / BN_BITS2;
if (bn_wexpand(r, a->top + nw + 1) == NULL)
@@ -170,6 +175,11 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
bn_check_top(r);
bn_check_top(a);
+ if (n < 0) {
+ BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT);
+ return 0;
+ }
+
nw = n / BN_BITS2;
rb = n % BN_BITS2;
lb = BN_BITS2 - rb;