[openssl-commits] [openssl] master update
Matt Caswell
matt at openssl.org
Tue Jun 7 21:03:04 UTC 2016
The branch master has been updated
via f44310e9ce2cdab64a9269ad8014be978e333db6 (commit)
via 37258dadaa9e36db4b96a3aa54aa6c67136160cc (commit)
from 4692340e31985681f95008d409483d5761b6c213 (commit)
- Log -----------------------------------------------------------------
commit f44310e9ce2cdab64a9269ad8014be978e333db6
Author: Matt Caswell <matt at openssl.org>
Date: Tue May 31 11:38:52 2016 +0100
Add a BN_mod_word test()
The previous commit fixed a bug with BN_mod_word() which would have been
caught if we had a test for it. This commit adds one.
Reviewed-by: Andy Polyakov <appro at openssl.org>
commit 37258dadaa9e36db4b96a3aa54aa6c67136160cc
Author: Matt Caswell <matt at openssl.org>
Date: Tue May 31 11:28:14 2016 +0100
Fix BN_mod_word bug
On systems where we do not have BN_ULLONG (e.g. typically 64 bit systems)
then BN_mod_word() can return incorrect results if the supplied modulus is
too big.
RT#4501
Reviewed-by: Andy Polyakov <appro at openssl.org>
-----------------------------------------------------------------------
Summary of changes:
crypto/bn/bn_word.c | 22 ++++++++++++++++++++++
test/bntest.c | 8 +++++++-
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/crypto/bn/bn_word.c b/crypto/bn/bn_word.c
index fd28298..a34244c 100644
--- a/crypto/bn/bn_word.c
+++ b/crypto/bn/bn_word.c
@@ -22,10 +22,32 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
if (w == 0)
return (BN_ULONG)-1;
+#ifndef BN_LLONG
+ /*
+ * If |w| is too long and we don't have BN_ULLONG then we need to fall
+ * back to using BN_div_word
+ */
+ if (w > ((BN_ULONG)1 << BN_BITS4)) {
+ BIGNUM *tmp = BN_dup(a);
+ if (tmp == NULL)
+ return (BN_ULONG)-1;
+
+ ret = BN_div_word(tmp, w);
+ BN_free(tmp);
+
+ return ret;
+ }
+#endif
+
bn_check_top(a);
w &= BN_MASK2;
for (i = a->top - 1; i >= 0; i--) {
#ifndef BN_LLONG
+ /*
+ * We can assume here that | w <= ((BN_ULONG)1 << BN_BITS4) | and so
+ * | ret < ((BN_ULONG)1 << BN_BITS4) | and therefore the shifts here are
+ * safe and will not overflow
+ */
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
#else
diff --git a/test/bntest.c b/test/bntest.c
index 804406c..763a8c2 100644
--- a/test/bntest.c
+++ b/test/bntest.c
@@ -504,7 +504,7 @@ static void print_word(BIO *bp, BN_ULONG w)
int test_div_word(BIO *bp)
{
BIGNUM *a, *b;
- BN_ULONG r, s;
+ BN_ULONG r, rmod, s;
int i;
a = BN_new();
@@ -518,8 +518,14 @@ int test_div_word(BIO *bp)
s = b->d[0];
BN_copy(b, a);
+ rmod = BN_mod_word(b, s);
r = BN_div_word(b, s);
+ if (rmod != r) {
+ fprintf(stderr, "Mod (word) test failed!\n");
+ return 0;
+ }
+
if (bp != NULL) {
if (!results) {
BN_print(bp, a);
More information about the openssl-commits
mailing list