Make it more obvious that am and tmp's widths are accurate.

https://boringssl-review.googlesource.com/c/boringssl/+/52825 lost a
tmp.width = top line. Without it, tmp.width was set by
bn_one_to_montgomery. Since we always size modular arithmetic by the
modulus, tmp.width (and am.width) will actually always be top, and
there's actually no need to zero pad it.

We don't capture this in the type system or BIGNUM width convention, so
better to set the width explicitly. The original code did it at the end,
but I think doing it right when we zero pad it is better, as that's when
the size gets set.

But we can go a step further. The manual zero padding code came from
OpenSSL, which still had the bn_correct_top invariant. Our BIGNUMs are
resizable, so just call bn_resize_words, immediately after the
computation.

(bn_resize_words will not reallocate the data because the BIGNUMs have
the STATIC_DATA flag set. bn_wexpand will internally allow expanding up
to dmax, or top.)

Change-Id: I2403afa7381b8a407615c6730fba9edaa41125c6
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/52906
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
chromium-5359
David Benjamin 3 years ago committed by Boringssl LUCI CQ
parent 8ba90d1817
commit 77dc23983f
  1. 16
      crypto/fipsmodule/bn/exponentiation.c

@ -1016,14 +1016,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
tmp.neg = am.neg = 0;
tmp.flags = am.flags = BN_FLG_STATIC_DATA;
if (!bn_one_to_montgomery(&tmp, mont, ctx)) {
if (!bn_one_to_montgomery(&tmp, mont, ctx) ||
!bn_resize_words(&tmp, top)) {
goto err;
}
// prepare a^1 in Montgomery domain
// Prepare a^1 in the Montgomery domain.
assert(!a->neg);
assert(BN_ucmp(a, m) < 0);
if (!BN_to_montgomery(&am, a, mont, ctx)) {
if (!BN_to_montgomery(&am, a, mont, ctx) ||
!bn_resize_words(&am, top)) {
goto err;
}
@ -1047,14 +1049,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
// and its interaction with other parts of the project. Determine whether this
// is actually necessary for performance.
if (window == 5 && top > 1) {
// Ensure |am| and |tmp| are padded to the right width.
for (i = am.width; i < top; i++) {
am.d[i] = 0;
}
for (i = tmp.width; i < top; i++) {
tmp.d[i] = 0;
}
// Copy |mont->N| to improve cache locality.
BN_ULONG *np = am.d + top;
for (i = 0; i < top; i++) {

Loading…
Cancel
Save