[openssl-commits] [openssl] master update
Andy Polyakov
appro at openssl.org
Thu Jul 12 12:54:50 UTC 2018
The branch master has been updated
via 71883868ea5b33416ae8283bcc38dd2d97e5006b (commit)
via 305b68f1a2b6d4d0aa07a6ab47ac372f067a40bb (commit)
via 6c90182a5f87af1a1e462536e7123ad2afb84c43 (commit)
via 3c97e4121ecec20cfac433883cd4709580a05620 (commit)
via e42395e637c3507b80b25c7ed63236898822d2f1 (commit)
from 7da84e0f0088fc9d575039fb173f12af0ae25832 (commit)
- Log -----------------------------------------------------------------
commit 71883868ea5b33416ae8283bcc38dd2d97e5006b
Author: Andy Polyakov <appro at openssl.org>
Date: Fri Jul 6 15:13:15 2018 +0200
bn/bn_{mont|exp}.c: switch to zero-padded intermediate vectors.
Note that exported functions maintain original behaviour, so that
external callers won't observe difference. While internally we can
now perform Montogomery multiplication on fixed-length vectors, fixed
at modulus size. The new functions, bn_to_mont_fixed_top and
bn_mul_mont_fixed_top, are declared in bn_int.h, because one can use
them even outside bn, e.g. in RSA, DSA, ECDSA...
Reviewed-by: Rich Salz <rsalz at openssl.org>
Reviewed-by: David Benjamin <davidben at google.com>
(Merged from https://github.com/openssl/openssl/pull/6662)
commit 305b68f1a2b6d4d0aa07a6ab47ac372f067a40bb
Author: Andy Polyakov <appro at openssl.org>
Date: Fri Jul 6 15:02:29 2018 +0200
bn/bn_lib.c: add BN_FLG_FIXED_TOP flag.
The new flag marks vectors that were not treated with bn_correct_top,
in other words such vectors are permitted to be zero padded. For now
it's BN_DEBUG-only flag, as initial use case for zero-padded vectors
would be controlled Montgomery multiplication/exponentiation, not
general purpose. For general purpose use another type might be more
appropriate. Advantage of this suggestion is that it's possible to
back-port it...
bn/bn_div.c: fix memory sanitizer problem.
bn/bn_sqr.c: harmonize with BN_mul.
Reviewed-by: Rich Salz <rsalz at openssl.org>
Reviewed-by: David Benjamin <davidben at google.com>
(Merged from https://github.com/openssl/openssl/pull/6662)
commit 6c90182a5f87af1a1e462536e7123ad2afb84c43
Author: Andy Polyakov <appro at openssl.org>
Date: Fri Jul 6 14:54:34 2018 +0200
bn/bn_mont.c: improve readability of post-condition code.
Reviewed-by: Rich Salz <rsalz at openssl.org>
Reviewed-by: David Benjamin <davidben at google.com>
(Merged from https://github.com/openssl/openssl/pull/6662)
commit 3c97e4121ecec20cfac433883cd4709580a05620
Author: Andy Polyakov <appro at openssl.org>
Date: Fri Jul 6 13:46:07 2018 +0200
bn/bn_mont.c: move boundary condition check closer to caller.
Reviewed-by: Rich Salz <rsalz at openssl.org>
Reviewed-by: David Benjamin <davidben at google.com>
(Merged from https://github.com/openssl/openssl/pull/6662)
commit e42395e637c3507b80b25c7ed63236898822d2f1
Author: Andy Polyakov <appro at openssl.org>
Date: Fri Jul 6 13:16:40 2018 +0200
bn/bn_lib.c: remove bn_check_top from bn_expand2.
Trouble is that addition is postponing expansion till carry is
calculated, and if addition carries, top word can be zero, which
triggers assertion in bn_check_top.
Reviewed-by: Rich Salz <rsalz at openssl.org>
Reviewed-by: David Benjamin <davidben at google.com>
(Merged from https://github.com/openssl/openssl/pull/6662)
-----------------------------------------------------------------------
Summary of changes:
crypto/bn/bn_div.c | 1 +
crypto/bn/bn_exp.c | 47 ++++++++++++++++--------------
crypto/bn/bn_lcl.h | 20 +++++++++++--
crypto/bn/bn_lib.c | 20 +++++++------
crypto/bn/bn_mont.c | 63 +++++++++++++++++++++++++++-------------
crypto/bn/bn_sqr.c | 10 ++-----
crypto/include/internal/bn_int.h | 12 ++++++++
7 files changed, 112 insertions(+), 61 deletions(-)
diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c
index b9b85fd..464a444 100644
--- a/crypto/bn/bn_div.c
+++ b/crypto/bn/bn_div.c
@@ -234,6 +234,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
wnum.neg = 0;
wnum.d = &(snum->d[loop]);
wnum.top = div_n;
+ wnum.flags = BN_FLG_STATIC_DATA;
/*
* only needed when BN_ucmp messes up the values between top and max
*/
diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c
index 10d3912..4e24c94 100644
--- a/crypto/bn/bn_exp.c
+++ b/crypto/bn/bn_exp.c
@@ -361,17 +361,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
ret = 1;
goto err;
}
- if (!BN_to_montgomery(val[0], aa, mont, ctx))
+ if (!bn_to_mont_fixed_top(val[0], aa, mont, ctx))
goto err; /* 1 */
window = BN_window_bits_for_exponent_size(bits);
if (window > 1) {
- if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
+ if (!bn_mul_mont_fixed_top(d, val[0], val[0], mont, ctx))
goto err; /* 2 */
j = 1 << (window - 1);
for (i = 1; i < j; i++) {
if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
- !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
+ !bn_mul_mont_fixed_top(val[i], val[i - 1], d, mont, ctx))
goto err;
}
}
@@ -393,19 +393,15 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
for (i = 1; i < j; i++)
r->d[i] = (~m->d[i]) & BN_MASK2;
r->top = j;
- /*
- * Upper words will be zero if the corresponding words of 'm' were
- * 0xfff[...], so decrement r->top accordingly.
- */
- bn_correct_top(r);
+ r->flags |= BN_FLG_FIXED_TOP;
} else
#endif
- if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+ if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx))
goto err;
for (;;) {
if (BN_is_bit_set(p, wstart) == 0) {
if (!start) {
- if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
goto err;
}
if (wstart == 0)
@@ -436,12 +432,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* add the 'bytes above' */
if (!start)
for (i = 0; i < j; i++) {
- if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
goto err;
}
/* wvalue will be an odd number < 2^window */
- if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
+ if (!bn_mul_mont_fixed_top(r, r, val[wvalue >> 1], mont, ctx))
goto err;
/* move the 'window' down further */
@@ -451,6 +447,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
if (wstart < 0)
break;
}
+ /*
+ * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
+ * removes padding [if any] and makes return value suitable for public
+ * API consumer.
+ */
#if defined(SPARC_T4_MONT)
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
j = mont->N.top; /* borrow j */
@@ -575,7 +576,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
}
b->top = top;
- bn_correct_top(b);
+ b->flags |= BN_FLG_FIXED_TOP;
return 1;
}
@@ -747,16 +748,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
tmp.top = top;
} else
#endif
- if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
+ if (!bn_to_mont_fixed_top(&tmp, BN_value_one(), mont, ctx))
goto err;
/* prepare a^1 in Montgomery domain */
if (a->neg || BN_ucmp(a, m) >= 0) {
if (!BN_nnmod(&am, a, m, ctx))
goto err;
- if (!BN_to_montgomery(&am, &am, mont, ctx))
+ if (!bn_to_mont_fixed_top(&am, &am, mont, ctx))
goto err;
- } else if (!BN_to_montgomery(&am, a, mont, ctx))
+ } else if (!bn_to_mont_fixed_top(&am, a, mont, ctx))
goto err;
#if defined(SPARC_T4_MONT)
@@ -1034,14 +1035,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
* performance advantage of sqr over mul).
*/
if (window > 1) {
- if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &am, &am, mont, ctx))
goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
window))
goto err;
for (i = 3; i < numPowers; i++) {
/* Calculate a^i = a^(i-1) * a */
- if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &am, &tmp, mont, ctx))
goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
window))
@@ -1072,7 +1073,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* Square the result window-size times */
for (i = 0; i < window; i++)
- if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx))
goto err;
/*
@@ -1095,12 +1096,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
/* Multiply the result into the intermediate result */
- if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &tmp, &am, mont, ctx))
goto err;
}
}
- /* Convert the final result from montgomery to standard format */
+ /*
+ * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
+ * removes padding [if any] and makes return value suitable for public
+ * API consumer.
+ */
#if defined(SPARC_T4_MONT)
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
am.d[0] = 1; /* borrow am */
diff --git a/crypto/bn/bn_lcl.h b/crypto/bn/bn_lcl.h
index f57c87d..0d3a8bf 100644
--- a/crypto/bn/bn_lcl.h
+++ b/crypto/bn/bn_lcl.h
@@ -141,6 +141,16 @@
*/
# ifdef BN_DEBUG
+/*
+ * The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with
+ * bn_correct_top, in other words such vectors are permitted to have zeros
+ * in most significant limbs. Such vectors are used internally to achieve
+ * execution time invariance for critical operations with private keys.
+ * It's BN_DEBUG-only flag, because user application is not supposed to
+ * observe it anyway. Moreover, optimizing compiler would actually remove
+ * all operations manipulating the bit in question in non-BN_DEBUG build.
+ */
+# define BN_FLG_FIXED_TOP 0x10000
# include <assert.h>
# ifdef BN_DEBUG_RAND
# define bn_pollute(a) \
@@ -165,8 +175,10 @@
do { \
const BIGNUM *_bnum2 = (a); \
if (_bnum2 != NULL) { \
- assert(((_bnum2->top == 0) && !_bnum2->neg) || \
- (_bnum2->top && (_bnum2->d[_bnum2->top - 1] != 0))); \
+ int top = _bnum2->top; \
+ assert((top == 0 && !_bnum2->neg) || \
+ (top && ((_bnum2->flags & BN_FLG_FIXED_TOP) \
+ || _bnum2->d[top - 1] != 0))); \
bn_pollute(_bnum2); \
} \
} while(0)
@@ -185,6 +197,7 @@
# else /* !BN_DEBUG */
+# define BN_FLG_FIXED_TOP 0
# define bn_pollute(a)
# define bn_check_top(a)
# define bn_fix_top(a) bn_correct_top(a)
@@ -216,7 +229,8 @@ struct bignum_st {
/* Used for montgomery multiplication */
struct bn_mont_ctx_st {
int ri; /* number of bits in R */
- BIGNUM RR; /* used to convert to montgomery form */
+ BIGNUM RR; /* used to convert to montgomery form,
+ possibly zero-padded */
BIGNUM N; /* The modulus */
BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only
* stored for bignum algorithm) */
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 5bb996e..b42df82 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -209,8 +209,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
{
BN_ULONG *a = NULL;
- bn_check_top(b);
-
if (words > (INT_MAX / (4 * BN_BITS2))) {
BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
return NULL;
@@ -245,8 +243,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
- bn_check_top(b);
-
if (words > b->dmax) {
BN_ULONG *a = bn_expand_internal(b, words);
if (!a)
@@ -259,7 +255,6 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
b->dmax = words;
}
- bn_check_top(b);
return b;
}
@@ -294,15 +289,17 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
if (b->top > 0)
memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
- a->top = b->top;
a->neg = b->neg;
+ a->top = b->top;
+ a->flags |= b->flags & BN_FLG_FIXED_TOP;
bn_check_top(a);
return a;
}
#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \
| BN_FLG_CONSTTIME \
- | BN_FLG_SECURE))
+ | BN_FLG_SECURE \
+ | BN_FLG_FIXED_TOP))
#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED))
void BN_swap(BIGNUM *a, BIGNUM *b)
@@ -343,8 +340,9 @@ void BN_clear(BIGNUM *a)
bn_check_top(a);
if (a->d != NULL)
OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
- a->top = 0;
a->neg = 0;
+ a->top = 0;
+ a->flags &= ~BN_FLG_FIXED_TOP;
}
BN_ULONG BN_get_word(const BIGNUM *a)
@@ -365,6 +363,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
a->neg = 0;
a->d[0] = w;
a->top = (w ? 1 : 0);
+ a->flags &= ~BN_FLG_FIXED_TOP;
bn_check_top(a);
return 1;
}
@@ -601,6 +600,7 @@ int BN_set_bit(BIGNUM *a, int n)
for (k = a->top; k < i + 1; k++)
a->d[k] = 0;
a->top = i + 1;
+ a->flags &= ~BN_FLG_FIXED_TOP;
}
a->d[i] |= (((BN_ULONG)1) << j);
@@ -833,8 +833,9 @@ int BN_security_bits(int L, int N)
void BN_zero_ex(BIGNUM *a)
{
- a->top = 0;
a->neg = 0;
+ a->top = 0;
+ a->flags &= ~BN_FLG_FIXED_TOP;
}
int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
@@ -958,5 +959,6 @@ void bn_correct_top(BIGNUM *a)
}
if (a->top == 0)
a->neg = 0;
+ a->flags &= ~BN_FLG_FIXED_TOP;
bn_pollute(a);
}
diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c
index 5e068c4..683e8e9 100644
--- a/crypto/bn/bn_mont.c
+++ b/crypto/bn/bn_mont.c
@@ -20,29 +20,43 @@
#define MONT_WORD /* use the faster word-based algorithm */
#ifdef MONT_WORD
-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
+static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
#endif
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_MONT_CTX *mont, BN_CTX *ctx)
{
+ int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx);
+
+ bn_correct_top(r);
+ bn_check_top(r);
+
+ return ret;
+}
+
+int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx)
+{
BIGNUM *tmp;
int ret = 0;
-#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
int num = mont->N.top;
+#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
if (num > 1 && a->top == num && b->top == num) {
if (bn_wexpand(r, num) == NULL)
return 0;
if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
r->neg = a->neg ^ b->neg;
r->top = num;
- bn_correct_top(r);
+ r->flags |= BN_FLG_FIXED_TOP;
return 1;
}
}
#endif
+ if ((a->top + b->top) > 2 * num)
+ return 0;
+
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
if (tmp == NULL)
@@ -58,13 +72,12 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
}
/* reduce from aRR to aR */
#ifdef MONT_WORD
- if (!BN_from_montgomery_word(r, tmp, mont))
+ if (!bn_from_montgomery_word(r, tmp, mont))
goto err;
#else
if (!BN_from_montgomery(r, tmp, mont, ctx))
goto err;
#endif
- bn_check_top(r);
ret = 1;
err:
BN_CTX_end(ctx);
@@ -72,7 +85,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
}
#ifdef MONT_WORD
-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
+static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
{
BIGNUM *n;
BN_ULONG *ap, *np, *rp, n0, v, carry;
@@ -95,12 +108,11 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
/* clear the top words of T */
i = max - r->top;
- if (i < 0)
- return 0;
if (i)
memset(&rp[r->top], 0, sizeof(*rp) * i);
r->top = max;
+ r->flags |= BN_FLG_FIXED_TOP;
n0 = mont->n0[0];
/*
@@ -119,6 +131,7 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
if (bn_wexpand(ret, nl) == NULL)
return 0;
ret->top = nl;
+ ret->flags |= BN_FLG_FIXED_TOP;
ret->neg = r->neg;
rp = ret->d;
@@ -129,20 +142,16 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
*/
ap = &(r->d[nl]);
+ carry -= bn_sub_words(rp, ap, np, nl);
/*
- * |v| is one if |ap| - |np| underflowed or zero if it did not. Note |v|
- * cannot be -1. That would imply the subtraction did not fit in |nl| words,
- * and we know at most one subtraction is needed.
+ * |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note
+ * |carry| cannot be 1. That would imply the subtraction did not fit in
+ * |nl| words, and we know at most one subtraction is needed.
*/
- v = bn_sub_words(rp, ap, np, nl) - carry;
- v = 0 - v;
for (i = 0; i < nl; i++) {
- rp[i] = (v & ap[i]) | (~v & rp[i]);
+ rp[i] = (carry & ap[i]) | (~carry & rp[i]);
ap[i] = 0;
}
- bn_correct_top(r);
- bn_correct_top(ret);
- bn_check_top(ret);
return 1;
}
@@ -156,8 +165,11 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
BIGNUM *t;
BN_CTX_start(ctx);
- if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
- retn = BN_from_montgomery_word(ret, t, mont);
+ if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) {
+ retn = bn_from_montgomery_word(ret, t, mont);
+ bn_correct_top(ret);
+ bn_check_top(ret);
+ }
BN_CTX_end(ctx);
#else /* !MONT_WORD */
BIGNUM *t1, *t2;
@@ -195,6 +207,12 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
return retn;
}
+int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx)
+{
+ return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx);
+}
+
BN_MONT_CTX *BN_MONT_CTX_new(void)
{
BN_MONT_CTX *ret;
@@ -232,7 +250,7 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont)
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
- int ret = 0;
+ int i, ret = 0;
BIGNUM *Ri, *R;
if (BN_is_zero(mod))
@@ -367,6 +385,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
goto err;
+ for (i = mont->RR.top, ret = mont->N.top; i < ret; i++)
+ mont->RR.d[i] = 0;
+ mont->RR.top = ret;
+ mont->RR.flags |= BN_FLG_FIXED_TOP;
+
ret = 1;
err:
BN_CTX_end(ctx);
diff --git a/crypto/bn/bn_sqr.c b/crypto/bn/bn_sqr.c
index dbfe9b8..40f7b23 100644
--- a/crypto/bn/bn_sqr.c
+++ b/crypto/bn/bn_sqr.c
@@ -82,14 +82,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 (r != rr && BN_copy(r, rr) == NULL)
goto err;
diff --git a/crypto/include/internal/bn_int.h b/crypto/include/internal/bn_int.h
index 9379951..e7fd899 100644
--- a/crypto/include/internal/bn_int.h
+++ b/crypto/include/internal/bn_int.h
@@ -60,4 +60,16 @@ void bn_set_static_words(BIGNUM *a, BN_ULONG *words, int size);
*/
int bn_set_words(BIGNUM *a, BN_ULONG *words, int num_words);
+/*
+ * Some BIGNUM functions assume most significant limb to be non-zero, which
+ * is customarily arranged by bn_correct_top. Output from below functions
+ * is not processed with bn_correct_top, and for this reason it may not be
+ * returned out of public API. It may only be passed internally into other
+ * functions known to support non-minimal or zero-padded BIGNUMs.
+ */
+int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx);
+int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx);
+
#endif
More information about the openssl-commits
mailing list