Просмотр исходного кода

Make the rest of BIGNUM accept non-minimal values.

Test this by re-running bn_tests.txt tests a lot. For the most part,
this was done by scattering bn_minimal_width or bn_correct_top calls as
needed. We'll incrementally tease apart the functions that need to act
on non-minimal BIGNUMs in constant-time.

BN_sqr was switched to call bn_correct_top at the end, rather than
sample bn_minimal_width, in anticipation of later splitting it into
BN_sqr (for calculators) and BN_sqr_fixed (for BN_mod_mul_montgomery).

BN_div_word also uses bn_correct_top because it calls BN_lshift so
officially shouldn't rely on BN_lshift returning something
minimal-width, though I expect we'd want to split off a BN_lshift_fixed
than change that anyway?

The shifts sample bn_minimal_width rather than bn_correct_top because
they all seem to try to be very clever around the bit width. If we need
constant-time versions of them, we can adjust them later.

Bug: 232
Change-Id: Ie17b39034a713542dbe906cf8954c0c5483c7db7
Reviewed-on: https://boringssl-review.googlesource.com/25255
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 6 лет назад
committed by CQ bot account: commit-bot@chromium.org
Родитель
Сommit
226b4b51b5
7 измененных файлов: 158 добавлений и 114 удалений
  1. +3
    -3
      crypto/fipsmodule/bn/add.c
  2. +131
    -85
      crypto/fipsmodule/bn/bn_test.cc
  3. +13
    -12
      crypto/fipsmodule/bn/div.c
  4. +4
    -3
      crypto/fipsmodule/bn/exponentiation.c
  5. +1
    -1
      crypto/fipsmodule/bn/internal.h
  6. +2
    -7
      crypto/fipsmodule/bn/mul.c
  7. +4
    -3
      crypto/fipsmodule/bn/shift.c

+ 3
- 3
crypto/fipsmodule/bn/add.c Просмотреть файл

@@ -251,8 +251,8 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
register BN_ULONG t1, t2, *ap, *bp, *rp;
int i, carry;

max = a->top;
min = b->top;
max = bn_minimal_width(a);
min = bn_minimal_width(b);
dif = max - min;

if (dif < 0) // hmm... should not be happening
@@ -337,7 +337,7 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w) {
return i;
}

if ((a->top == 1) && (a->d[0] < w)) {
if ((bn_minimal_width(a) == 1) && (a->d[0] < w)) {
a->d[0] = w - a->d[0];
a->neg = 1;
return 1;


+ 131
- 85
crypto/fipsmodule/bn/bn_test.cc Просмотреть файл

@@ -107,34 +107,62 @@ static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
return ret;
}

static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *attribute) {
std::string hex;
if (!t->GetAttribute(&hex, attribute)) {
return nullptr;
}
// A BIGNUMFileTest wraps a FileTest to give |BIGNUM| values and also allows
// injecting oversized |BIGNUM|s.
class BIGNUMFileTest {
public:
BIGNUMFileTest(FileTest *t, unsigned large_mask)
: t_(t), large_mask_(large_mask), num_bignums_(0) {}

bssl::UniquePtr<BIGNUM> ret;
if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
t->PrintLine("Could not decode '%s'.", hex.c_str());
return nullptr;
unsigned num_bignums() const { return num_bignums_; }
bssl::UniquePtr<BIGNUM> GetBIGNUM(const char *attribute) {
return GetBIGNUMImpl(attribute, true /* resize */);
}
return ret;
}

static bool GetInt(FileTest *t, int *out, const char *attribute) {
bssl::UniquePtr<BIGNUM> ret = GetBIGNUM(t, attribute);
if (!ret) {
return false;
bool GetInt(int *out, const char *attribute) {
bssl::UniquePtr<BIGNUM> ret =
GetBIGNUMImpl(attribute, false /* don't resize */);
if (!ret) {
return false;
}

BN_ULONG word = BN_get_word(ret.get());
if (word > INT_MAX) {
return false;
}

*out = static_cast<int>(word);
return true;
}

BN_ULONG word = BN_get_word(ret.get());
if (word > INT_MAX) {
return false;
private:
bssl::UniquePtr<BIGNUM> GetBIGNUMImpl(const char *attribute, bool resize) {
std::string hex;
if (!t_->GetAttribute(&hex, attribute)) {
return nullptr;
}

bssl::UniquePtr<BIGNUM> ret;
if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
t_->PrintLine("Could not decode '%s'.", hex.c_str());
return nullptr;
}
if (resize) {
// Test with an oversized |BIGNUM| if necessary.
if ((large_mask_ & (1 << num_bignums_)) &&
!bn_resize_words(ret.get(), ret->top * 2 + 1)) {
return nullptr;
}
num_bignums_++;
}
return ret;
}

*out = static_cast<int>(word);
return true;
}
FileTest *t_;
unsigned large_mask_;
unsigned num_bignums_;
};

static testing::AssertionResult AssertBIGNUMSEqual(
const char *operation_expr, const char *expected_expr,
@@ -160,10 +188,10 @@ static testing::AssertionResult AssertBIGNUMSEqual(
#define EXPECT_BIGNUMS_EQUAL(op, a, b) \
EXPECT_PRED_FORMAT3(AssertBIGNUMSEqual, op, a, b)

static void TestSum(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
bssl::UniquePtr<BIGNUM> sum = GetBIGNUM(t, "Sum");
static void TestSum(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> b = t->GetBIGNUM("B");
bssl::UniquePtr<BIGNUM> sum = t->GetBIGNUM("Sum");
ASSERT_TRUE(a);
ASSERT_TRUE(b);
ASSERT_TRUE(sum);
@@ -262,9 +290,9 @@ static void TestSum(FileTest *t, BN_CTX *ctx) {
}
}

static void TestLShift1(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> lshift1 = GetBIGNUM(t, "LShift1");
static void TestLShift1(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> lshift1 = t->GetBIGNUM("LShift1");
bssl::UniquePtr<BIGNUM> zero(BN_new());
ASSERT_TRUE(a);
ASSERT_TRUE(lshift1);
@@ -308,13 +336,13 @@ static void TestLShift1(FileTest *t, BN_CTX *ctx) {
EXPECT_BIGNUMS_EQUAL("(LShift | 1) >> 1", a.get(), ret.get());
}

static void TestLShift(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> lshift = GetBIGNUM(t, "LShift");
static void TestLShift(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> lshift = t->GetBIGNUM("LShift");
ASSERT_TRUE(a);
ASSERT_TRUE(lshift);
int n = 0;
ASSERT_TRUE(GetInt(t, &n, "N"));
ASSERT_TRUE(t->GetInt(&n, "N"));

bssl::UniquePtr<BIGNUM> ret(BN_new());
ASSERT_TRUE(ret);
@@ -325,13 +353,13 @@ static void TestLShift(FileTest *t, BN_CTX *ctx) {
EXPECT_BIGNUMS_EQUAL("A >> N", a.get(), ret.get());
}

static void TestRShift(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> rshift = GetBIGNUM(t, "RShift");
static void TestRShift(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> rshift = t->GetBIGNUM("RShift");
ASSERT_TRUE(a);
ASSERT_TRUE(rshift);
int n = 0;
ASSERT_TRUE(GetInt(t, &n, "N"));
ASSERT_TRUE(t->GetInt(&n, "N"));

bssl::UniquePtr<BIGNUM> ret(BN_new());
ASSERT_TRUE(ret);
@@ -339,9 +367,9 @@ static void TestRShift(FileTest *t, BN_CTX *ctx) {
EXPECT_BIGNUMS_EQUAL("A >> N", rshift.get(), ret.get());
}

static void TestSquare(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> square = GetBIGNUM(t, "Square");
static void TestSquare(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> square = t->GetBIGNUM("Square");
bssl::UniquePtr<BIGNUM> zero(BN_new());
ASSERT_TRUE(a);
ASSERT_TRUE(square);
@@ -412,10 +440,10 @@ static void TestSquare(FileTest *t, BN_CTX *ctx) {
#endif
}

static void TestProduct(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
bssl::UniquePtr<BIGNUM> product = GetBIGNUM(t, "Product");
static void TestProduct(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> b = t->GetBIGNUM("B");
bssl::UniquePtr<BIGNUM> product = t->GetBIGNUM("Product");
bssl::UniquePtr<BIGNUM> zero(BN_new());
ASSERT_TRUE(a);
ASSERT_TRUE(b);
@@ -475,11 +503,11 @@ static void TestProduct(FileTest *t, BN_CTX *ctx) {
#endif
}

static void TestQuotient(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
bssl::UniquePtr<BIGNUM> quotient = GetBIGNUM(t, "Quotient");
bssl::UniquePtr<BIGNUM> remainder = GetBIGNUM(t, "Remainder");
static void TestQuotient(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> b = t->GetBIGNUM("B");
bssl::UniquePtr<BIGNUM> quotient = t->GetBIGNUM("Quotient");
bssl::UniquePtr<BIGNUM> remainder = t->GetBIGNUM("Remainder");
ASSERT_TRUE(a);
ASSERT_TRUE(b);
ASSERT_TRUE(quotient);
@@ -523,11 +551,11 @@ static void TestQuotient(FileTest *t, BN_CTX *ctx) {
}
}

static void TestModMul(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
bssl::UniquePtr<BIGNUM> mod_mul = GetBIGNUM(t, "ModMul");
static void TestModMul(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> b = t->GetBIGNUM("B");
bssl::UniquePtr<BIGNUM> m = t->GetBIGNUM("M");
bssl::UniquePtr<BIGNUM> mod_mul = t->GetBIGNUM("ModMul");
ASSERT_TRUE(a);
ASSERT_TRUE(b);
ASSERT_TRUE(m);
@@ -581,10 +609,10 @@ static void TestModMul(FileTest *t, BN_CTX *ctx) {
}
}

static void TestModSquare(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
bssl::UniquePtr<BIGNUM> mod_square = GetBIGNUM(t, "ModSquare");
static void TestModSquare(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> m = t->GetBIGNUM("M");
bssl::UniquePtr<BIGNUM> mod_square = t->GetBIGNUM("ModSquare");
ASSERT_TRUE(a);
ASSERT_TRUE(m);
ASSERT_TRUE(mod_square);
@@ -658,11 +686,11 @@ static void TestModSquare(FileTest *t, BN_CTX *ctx) {
}
}

static void TestModExp(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
bssl::UniquePtr<BIGNUM> mod_exp = GetBIGNUM(t, "ModExp");
static void TestModExp(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> e = t->GetBIGNUM("E");
bssl::UniquePtr<BIGNUM> m = t->GetBIGNUM("M");
bssl::UniquePtr<BIGNUM> mod_exp = t->GetBIGNUM("ModExp");
ASSERT_TRUE(a);
ASSERT_TRUE(e);
ASSERT_TRUE(m);
@@ -708,10 +736,10 @@ static void TestModExp(FileTest *t, BN_CTX *ctx) {
}
}

static void TestExp(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
bssl::UniquePtr<BIGNUM> exp = GetBIGNUM(t, "Exp");
static void TestExp(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> e = t->GetBIGNUM("E");
bssl::UniquePtr<BIGNUM> exp = t->GetBIGNUM("Exp");
ASSERT_TRUE(a);
ASSERT_TRUE(e);
ASSERT_TRUE(exp);
@@ -722,10 +750,10 @@ static void TestExp(FileTest *t, BN_CTX *ctx) {
EXPECT_BIGNUMS_EQUAL("A ^ E", exp.get(), ret.get());
}

static void TestModSqrt(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
bssl::UniquePtr<BIGNUM> mod_sqrt = GetBIGNUM(t, "ModSqrt");
static void TestModSqrt(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> p = t->GetBIGNUM("P");
bssl::UniquePtr<BIGNUM> mod_sqrt = t->GetBIGNUM("ModSqrt");
bssl::UniquePtr<BIGNUM> mod_sqrt2(BN_new());
ASSERT_TRUE(a);
ASSERT_TRUE(p);
@@ -747,9 +775,9 @@ static void TestModSqrt(FileTest *t, BN_CTX *ctx) {
}
}

static void TestNotModSquare(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> not_mod_square = GetBIGNUM(t, "NotModSquare");
bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
static void TestNotModSquare(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> not_mod_square = t->GetBIGNUM("NotModSquare");
bssl::UniquePtr<BIGNUM> p = t->GetBIGNUM("P");
bssl::UniquePtr<BIGNUM> ret(BN_new());
ASSERT_TRUE(not_mod_square);
ASSERT_TRUE(p);
@@ -764,10 +792,10 @@ static void TestNotModSquare(FileTest *t, BN_CTX *ctx) {
ERR_clear_error();
}

static void TestModInv(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
bssl::UniquePtr<BIGNUM> mod_inv = GetBIGNUM(t, "ModInv");
static void TestModInv(BIGNUMFileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = t->GetBIGNUM("A");
bssl::UniquePtr<BIGNUM> m = t->GetBIGNUM("M");
bssl::UniquePtr<BIGNUM> mod_inv = t->GetBIGNUM("ModInv");
ASSERT_TRUE(a);
ASSERT_TRUE(m);
ASSERT_TRUE(mod_inv);
@@ -794,7 +822,7 @@ class BNTest : public testing::Test {
TEST_F(BNTest, TestVectors) {
static const struct {
const char *name;
void (*func)(FileTest *t, BN_CTX *ctx);
void (*func)(BIGNUMFileTest *t, BN_CTX *ctx);
} kTests[] = {
{"Sum", TestSum},
{"LShift1", TestLShift1},
@@ -813,13 +841,34 @@ TEST_F(BNTest, TestVectors) {
};

FileTestGTest("crypto/fipsmodule/bn/bn_tests.txt", [&](FileTest *t) {
void (*func)(BIGNUMFileTest *t, BN_CTX *ctx) = nullptr;
for (const auto &test : kTests) {
if (t->GetType() == test.name) {
test.func(t, ctx());
return;
func = test.func;
break;
}
}
FAIL() << "Unknown test type: " << t->GetType();
if (!func) {
FAIL() << "Unknown test type: " << t->GetType();
return;
}

// Run the test with normalize-sized |BIGNUM|s.
BIGNUMFileTest bn_test(t, 0);
BN_CTX_start(ctx());
func(&bn_test, ctx());
BN_CTX_end(ctx());
unsigned num_bignums = bn_test.num_bignums();

// Repeat the test with all combinations of large and small |BIGNUM|s.
for (unsigned large_mask = 1; large_mask < (1u << num_bignums);
large_mask++) {
SCOPED_TRACE(large_mask);
BIGNUMFileTest bn_test2(t, large_mask);
BN_CTX_start(ctx());
func(&bn_test2, ctx());
BN_CTX_end(ctx());
}
});
}

@@ -865,7 +914,6 @@ TEST_F(BNTest, BN2BinPadded) {
Bytes(out, sizeof(out) - bytes));
EXPECT_EQ(Bytes(reference, bytes), Bytes(out + sizeof(out) - bytes, bytes));

#if !defined(BORINGSSL_SHARED_LIBRARY)
// Repeat some tests with a non-minimal |BIGNUM|.
EXPECT_TRUE(bn_resize_words(n.get(), 32));

@@ -874,7 +922,6 @@ TEST_F(BNTest, BN2BinPadded) {
ASSERT_TRUE(BN_bn2bin_padded(out, bytes + 1, n.get()));
EXPECT_EQ(0u, out[0]);
EXPECT_EQ(Bytes(reference, bytes), Bytes(out + 1, bytes));
#endif
}
}

@@ -1897,6 +1944,7 @@ TEST_F(BNTest, LessThanWords) {
EXPECT_EQ(0, bn_less_than_words(NULL, NULL, 0));
EXPECT_EQ(0, bn_in_range_words(NULL, 0, NULL, 0));
}
#endif // !BORINGSSL_SHARED_LIBRARY

TEST_F(BNTest, NonMinimal) {
bssl::UniquePtr<BIGNUM> ten(BN_new());
@@ -1992,5 +2040,3 @@ TEST_F(BNTest, NonMinimal) {
EXPECT_EQ(mont->N.top, mont2->N.top);
EXPECT_EQ(0, BN_cmp(&mont->RR, &mont2->RR));
}

#endif // !BORINGSSL_SHARED_LIBRARY

+ 13
- 12
crypto/fipsmodule/bn/div.c Просмотреть файл

@@ -202,10 +202,16 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
BN_ULONG d0, d1;
int num_n, div_n;

// Invalid zero-padding would have particularly bad consequences
// so don't just rely on bn_check_top() here
if ((numerator->top > 0 && numerator->d[numerator->top - 1] == 0) ||
(divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
// This function relies on the historical minimal-width |BIGNUM| invariant.
// It is already not constant-time (constant-time reductions should use
// Montgomery logic), so we shrink all inputs and intermediate values to
// retain the previous behavior.

// Invalid zero-padding would have particularly bad consequences.
int numerator_width = bn_minimal_width(numerator);
int divisor_width = bn_minimal_width(divisor);
if ((numerator_width > 0 && numerator->d[numerator_width - 1] == 0) ||
(divisor_width > 0 && divisor->d[divisor_width - 1] == 0)) {
OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED);
return 0;
}
@@ -234,11 +240,13 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
if (!BN_lshift(sdiv, divisor, norm_shift)) {
goto err;
}
bn_correct_top(sdiv);
sdiv->neg = 0;
norm_shift += BN_BITS2;
if (!BN_lshift(snum, numerator, norm_shift)) {
goto err;
}
bn_correct_top(snum);
snum->neg = 0;

// Since we don't want to have special-case logic for the case where snum is
@@ -604,14 +612,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
a->d[i] = d;
}

if ((a->top > 0) && (a->d[a->top - 1] == 0)) {
a->top--;
}

if (a->top == 0) {
a->neg = 0;
}

bn_correct_top(a);
ret >>= j;
return ret;
}


+ 4
- 3
crypto/fipsmodule/bn/exponentiation.c Просмотреть файл

@@ -982,7 +982,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
const BN_MONT_CTX *mont) {
int i, ret = 0, window, wvalue;
int top;
BN_MONT_CTX *new_mont = NULL;

int numPowers;
@@ -997,8 +996,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
return 0;
}

top = m->top;

// Use all bits stored in |p|, rather than |BN_num_bits|, so we do not leak
// whether the top bits are zero.
int max_bits = p->top * BN_BITS2;
@@ -1021,6 +1018,10 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
mont = new_mont;
}

// Use the width in |mont->N|, rather than the copy in |m|. The assembly
// implementation assumes it can use |top| to size R.
int top = mont->N.top;

if (a->neg || BN_ucmp(a, m) >= 0) {
new_a = BN_new();
if (new_a == NULL ||


+ 1
- 1
crypto/fipsmodule/bn/internal.h Просмотреть файл

@@ -220,7 +220,7 @@ int bn_expand(BIGNUM *bn, size_t bits);
// Do not call this function outside of unit tests. Most functions currently
// require |BIGNUM|s be minimal. This function breaks that invariant. It is
// introduced early so the invariant may be relaxed incrementally.
int bn_resize_words(BIGNUM *bn, size_t words);
OPENSSL_EXPORT int bn_resize_words(BIGNUM *bn, size_t words);

// bn_set_words sets |bn| to the value encoded in the |num| words in |words|,
// least significant word first.


+ 2
- 7
crypto/fipsmodule/bn/mul.c Просмотреть файл

@@ -866,13 +866,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) {
}

rr->neg = 0;
// If the most-significant half of the top word of 'a' is zero, then
// the square of 'a' will max-1 words.
if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l)) {
rr->top = max - 1;
} else {
rr->top = max;
}
rr->top = max;
bn_correct_top(rr);

if (rr != r && !BN_copy(r, rr)) {
goto err;


+ 4
- 3
crypto/fipsmodule/bn/shift.c Просмотреть файл

@@ -142,10 +142,11 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {
return 0;
}

int a_width = bn_minimal_width(a);
nw = n / BN_BITS2;
rb = n % BN_BITS2;
lb = BN_BITS2 - rb;
if (nw >= a->top || a->top == 0) {
if (nw >= a_width || a_width == 0) {
BN_zero(r);
return 1;
}
@@ -163,7 +164,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {

f = &(a->d[nw]);
t = r->d;
j = a->top - nw;
j = a_width - nw;
r->top = i;

if (rb == 0) {
@@ -198,7 +199,7 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a) {
BN_zero(r);
return 1;
}
i = a->top;
i = bn_minimal_width(a);
ap = a->d;
j = i - (ap[i - 1] == 1);
if (a != r) {


Загрузка…
Отмена
Сохранить