summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbcook <>2016-07-05 02:54:35 +0000
committerbcook <>2016-07-05 02:54:35 +0000
commit893dbf4e24a37a4ac3cf521b4c386df31e6edf21 (patch)
tree90c31bd2681496537a3d217c0819f837c5e8d8b4
parent25f89b1a60c16a8a6f6b2258cfebc4c8db737315 (diff)
downloadopenbsd-893dbf4e24a37a4ac3cf521b4c386df31e6edf21.tar.gz
openbsd-893dbf4e24a37a4ac3cf521b4c386df31e6edf21.tar.bz2
openbsd-893dbf4e24a37a4ac3cf521b4c386df31e6edf21.zip
On systems where we do not have BN_ULLONG defined (most 64-bit systems),
BN_mod_word() can return incorrect results if the supplied modulus is too big, so we need to fall back to BN_div_word. Now that BN_mod_word may fail, handle errors properly update the man page. Thanks to Brian Smith for pointing out these fixes from BoringSSL: https://boringssl.googlesource.com/boringssl/+/67cb49d045f04973ddba0f92fe8a8ad483c7da89 https://boringssl.googlesource.com/boringssl/+/44bedc348d9491e63c7ed1438db100a4b8a830be ok beck@
-rw-r--r--src/lib/libcrypto/bn/bn_prime.c30
-rw-r--r--src/lib/libcrypto/bn/bn_word.c16
-rw-r--r--src/lib/libcrypto/dh/dh_check.c6
-rw-r--r--src/lib/libcrypto/man/BN_add_word.35
-rw-r--r--src/lib/libssl/src/crypto/bn/bn_prime.c30
-rw-r--r--src/lib/libssl/src/crypto/bn/bn_word.c16
-rw-r--r--src/lib/libssl/src/crypto/dh/dh_check.c6
-rw-r--r--src/regress/lib/libcrypto/bn/general/bntest.c28
8 files changed, 111 insertions, 26 deletions
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c
index b1aba663df..fb39756de2 100644
--- a/src/lib/libcrypto/bn/bn_prime.c
+++ b/src/lib/libcrypto/bn/bn_prime.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_prime.c,v 1.14 2015/10/21 19:02:22 miod Exp $ */ 1/* $OpenBSD: bn_prime.c,v 1.15 2016/07/05 02:54:35 bcook Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -277,9 +277,13 @@ BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
277 /* a is even => a is prime if and only if a == 2 */ 277 /* a is even => a is prime if and only if a == 2 */
278 return BN_is_word(a, 2); 278 return BN_is_word(a, 2);
279 if (do_trial_division) { 279 if (do_trial_division) {
280 for (i = 1; i < NUMPRIMES; i++) 280 for (i = 1; i < NUMPRIMES; i++) {
281 if (BN_mod_word(a, primes[i]) == 0) 281 BN_ULONG mod = BN_mod_word(a, primes[i]);
282 if (mod == (BN_ULONG)-1)
283 goto err;
284 if (mod == 0)
282 return 0; 285 return 0;
286 }
283 if (!BN_GENCB_call(cb, 1, -1)) 287 if (!BN_GENCB_call(cb, 1, -1))
284 goto err; 288 goto err;
285 } 289 }
@@ -398,8 +402,12 @@ again:
398 if (!BN_rand(rnd, bits, 1, 1)) 402 if (!BN_rand(rnd, bits, 1, 1))
399 return (0); 403 return (0);
400 /* we now have a random number 'rand' to test. */ 404 /* we now have a random number 'rand' to test. */
401 for (i = 1; i < NUMPRIMES; i++) 405 for (i = 1; i < NUMPRIMES; i++) {
402 mods[i] = (prime_t)BN_mod_word(rnd, (BN_ULONG)primes[i]); 406 BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
407 if (mod == (BN_ULONG)-1)
408 return (0);
409 mods[i] = (prime_t)mod;
410 }
403 maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; 411 maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
404 delta = 0; 412 delta = 0;
405loop: 413loop:
@@ -452,7 +460,10 @@ probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem,
452loop: 460loop:
453 for (i = 1; i < NUMPRIMES; i++) { 461 for (i = 1; i < NUMPRIMES; i++) {
454 /* check that rnd is a prime */ 462 /* check that rnd is a prime */
455 if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { 463 BN_LONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
464 if (mod == (BN_ULONG)-1)
465 goto err;
466 if (mod <= 1) {
456 if (!BN_add(rnd, rnd, add)) 467 if (!BN_add(rnd, rnd, add))
457 goto err; 468 goto err;
458 goto loop; 469 goto loop;
@@ -514,8 +525,11 @@ loop:
514 /* check that p and q are prime */ 525 /* check that p and q are prime */
515 /* check that for p and q 526 /* check that for p and q
516 * gcd(p-1,primes) == 1 (except for 2) */ 527 * gcd(p-1,primes) == 1 (except for 2) */
517 if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) || 528 BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]);
518 (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) { 529 BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]);
530 if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1)
531 goto err;
532 if (pmod == 0 || qmod == 0) {
519 if (!BN_add(p, p, padd)) 533 if (!BN_add(p, p, padd))
520 goto err; 534 goto err;
521 if (!BN_add(q, q, qadd)) 535 if (!BN_add(q, q, qadd))
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c
index c4c6754c37..71654586a1 100644
--- a/src/lib/libcrypto/bn/bn_word.c
+++ b/src/lib/libcrypto/bn/bn_word.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_word.c,v 1.12 2014/07/11 08:44:48 jsing Exp $ */ 1/* $OpenBSD: bn_word.c,v 1.13 2016/07/05 02:54:35 bcook Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -73,6 +73,20 @@ BN_mod_word(const BIGNUM *a, BN_ULONG w)
73 if (w == 0) 73 if (w == 0)
74 return (BN_ULONG) - 1; 74 return (BN_ULONG) - 1;
75 75
76#ifndef BN_ULLONG
77 /* If |w| is too long and we don't have |BN_ULLONG| then we need to fall back
78 * to using |BN_div_word|. */
79 if (w > ((BN_ULONG)1 << BN_BITS4)) {
80 BIGNUM *tmp = BN_dup(a);
81 if (tmp == NULL) {
82 return (BN_ULONG)-1;
83 }
84 ret = BN_div_word(tmp, w);
85 BN_free(tmp);
86 return ret;
87 }
88#endif
89
76 bn_check_top(a); 90 bn_check_top(a);
77 w &= BN_MASK2; 91 w &= BN_MASK2;
78 for (i = a->top - 1; i >= 0; i--) { 92 for (i = a->top - 1; i >= 0; i--) {
diff --git a/src/lib/libcrypto/dh/dh_check.c b/src/lib/libcrypto/dh/dh_check.c
index 93e1003bd6..a6010f0a6d 100644
--- a/src/lib/libcrypto/dh/dh_check.c
+++ b/src/lib/libcrypto/dh/dh_check.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dh_check.c,v 1.15 2015/02/07 13:19:15 doug Exp $ */ 1/* $OpenBSD: dh_check.c,v 1.16 2016/07/05 02:54:35 bcook Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -89,10 +89,14 @@ DH_check(const DH *dh, int *ret)
89 89
90 if (BN_is_word(dh->g, DH_GENERATOR_2)) { 90 if (BN_is_word(dh->g, DH_GENERATOR_2)) {
91 l = BN_mod_word(dh->p, 24); 91 l = BN_mod_word(dh->p, 24);
92 if (l == (BN_ULONG)-1)
93 goto err;
92 if (l != 11) 94 if (l != 11)
93 *ret |= DH_NOT_SUITABLE_GENERATOR; 95 *ret |= DH_NOT_SUITABLE_GENERATOR;
94 } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { 96 } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
95 l = BN_mod_word(dh->p, 10); 97 l = BN_mod_word(dh->p, 10);
98 if (l == (BN_ULONG)-1)
99 goto err;
96 if (l != 3 && l != 7) 100 if (l != 3 && l != 7)
97 *ret |= DH_NOT_SUITABLE_GENERATOR; 101 *ret |= DH_NOT_SUITABLE_GENERATOR;
98 } else 102 } else
diff --git a/src/lib/libcrypto/man/BN_add_word.3 b/src/lib/libcrypto/man/BN_add_word.3
index 930aae4d32..16f2a17eb5 100644
--- a/src/lib/libcrypto/man/BN_add_word.3
+++ b/src/lib/libcrypto/man/BN_add_word.3
@@ -1,4 +1,4 @@
1.Dd $Mdocdate: February 23 2015 $ 1.Dd $Mdocdate: July 5 2016 $
2.Dt BN_ADD_WORD 3 2.Dt BN_ADD_WORD 3
3.Os 3.Os
4.Sh NAME 4.Sh NAME
@@ -75,7 +75,8 @@ returns the remainder of
75.Fa a 75.Fa a
76divided by 76divided by
77.Fa w 77.Fa w
78.Pq Li a%w . 78.Pq Li a%w
79or (BN_ULONG)-1 on error.
79.Pp 80.Pp
80For 81For
81.Fn BN_div_word 82.Fn BN_div_word
diff --git a/src/lib/libssl/src/crypto/bn/bn_prime.c b/src/lib/libssl/src/crypto/bn/bn_prime.c
index b1aba663df..fb39756de2 100644
--- a/src/lib/libssl/src/crypto/bn/bn_prime.c
+++ b/src/lib/libssl/src/crypto/bn/bn_prime.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_prime.c,v 1.14 2015/10/21 19:02:22 miod Exp $ */ 1/* $OpenBSD: bn_prime.c,v 1.15 2016/07/05 02:54:35 bcook Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -277,9 +277,13 @@ BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
277 /* a is even => a is prime if and only if a == 2 */ 277 /* a is even => a is prime if and only if a == 2 */
278 return BN_is_word(a, 2); 278 return BN_is_word(a, 2);
279 if (do_trial_division) { 279 if (do_trial_division) {
280 for (i = 1; i < NUMPRIMES; i++) 280 for (i = 1; i < NUMPRIMES; i++) {
281 if (BN_mod_word(a, primes[i]) == 0) 281 BN_ULONG mod = BN_mod_word(a, primes[i]);
282 if (mod == (BN_ULONG)-1)
283 goto err;
284 if (mod == 0)
282 return 0; 285 return 0;
286 }
283 if (!BN_GENCB_call(cb, 1, -1)) 287 if (!BN_GENCB_call(cb, 1, -1))
284 goto err; 288 goto err;
285 } 289 }
@@ -398,8 +402,12 @@ again:
398 if (!BN_rand(rnd, bits, 1, 1)) 402 if (!BN_rand(rnd, bits, 1, 1))
399 return (0); 403 return (0);
400 /* we now have a random number 'rand' to test. */ 404 /* we now have a random number 'rand' to test. */
401 for (i = 1; i < NUMPRIMES; i++) 405 for (i = 1; i < NUMPRIMES; i++) {
402 mods[i] = (prime_t)BN_mod_word(rnd, (BN_ULONG)primes[i]); 406 BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
407 if (mod == (BN_ULONG)-1)
408 return (0);
409 mods[i] = (prime_t)mod;
410 }
403 maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; 411 maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
404 delta = 0; 412 delta = 0;
405loop: 413loop:
@@ -452,7 +460,10 @@ probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem,
452loop: 460loop:
453 for (i = 1; i < NUMPRIMES; i++) { 461 for (i = 1; i < NUMPRIMES; i++) {
454 /* check that rnd is a prime */ 462 /* check that rnd is a prime */
455 if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { 463 BN_LONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
464 if (mod == (BN_ULONG)-1)
465 goto err;
466 if (mod <= 1) {
456 if (!BN_add(rnd, rnd, add)) 467 if (!BN_add(rnd, rnd, add))
457 goto err; 468 goto err;
458 goto loop; 469 goto loop;
@@ -514,8 +525,11 @@ loop:
514 /* check that p and q are prime */ 525 /* check that p and q are prime */
515 /* check that for p and q 526 /* check that for p and q
516 * gcd(p-1,primes) == 1 (except for 2) */ 527 * gcd(p-1,primes) == 1 (except for 2) */
517 if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) || 528 BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]);
518 (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) { 529 BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]);
530 if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1)
531 goto err;
532 if (pmod == 0 || qmod == 0) {
519 if (!BN_add(p, p, padd)) 533 if (!BN_add(p, p, padd))
520 goto err; 534 goto err;
521 if (!BN_add(q, q, qadd)) 535 if (!BN_add(q, q, qadd))
diff --git a/src/lib/libssl/src/crypto/bn/bn_word.c b/src/lib/libssl/src/crypto/bn/bn_word.c
index c4c6754c37..71654586a1 100644
--- a/src/lib/libssl/src/crypto/bn/bn_word.c
+++ b/src/lib/libssl/src/crypto/bn/bn_word.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_word.c,v 1.12 2014/07/11 08:44:48 jsing Exp $ */ 1/* $OpenBSD: bn_word.c,v 1.13 2016/07/05 02:54:35 bcook Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -73,6 +73,20 @@ BN_mod_word(const BIGNUM *a, BN_ULONG w)
73 if (w == 0) 73 if (w == 0)
74 return (BN_ULONG) - 1; 74 return (BN_ULONG) - 1;
75 75
76#ifndef BN_ULLONG
77 /* If |w| is too long and we don't have |BN_ULLONG| then we need to fall back
78 * to using |BN_div_word|. */
79 if (w > ((BN_ULONG)1 << BN_BITS4)) {
80 BIGNUM *tmp = BN_dup(a);
81 if (tmp == NULL) {
82 return (BN_ULONG)-1;
83 }
84 ret = BN_div_word(tmp, w);
85 BN_free(tmp);
86 return ret;
87 }
88#endif
89
76 bn_check_top(a); 90 bn_check_top(a);
77 w &= BN_MASK2; 91 w &= BN_MASK2;
78 for (i = a->top - 1; i >= 0; i--) { 92 for (i = a->top - 1; i >= 0; i--) {
diff --git a/src/lib/libssl/src/crypto/dh/dh_check.c b/src/lib/libssl/src/crypto/dh/dh_check.c
index 93e1003bd6..a6010f0a6d 100644
--- a/src/lib/libssl/src/crypto/dh/dh_check.c
+++ b/src/lib/libssl/src/crypto/dh/dh_check.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dh_check.c,v 1.15 2015/02/07 13:19:15 doug Exp $ */ 1/* $OpenBSD: dh_check.c,v 1.16 2016/07/05 02:54:35 bcook Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -89,10 +89,14 @@ DH_check(const DH *dh, int *ret)
89 89
90 if (BN_is_word(dh->g, DH_GENERATOR_2)) { 90 if (BN_is_word(dh->g, DH_GENERATOR_2)) {
91 l = BN_mod_word(dh->p, 24); 91 l = BN_mod_word(dh->p, 24);
92 if (l == (BN_ULONG)-1)
93 goto err;
92 if (l != 11) 94 if (l != 11)
93 *ret |= DH_NOT_SUITABLE_GENERATOR; 95 *ret |= DH_NOT_SUITABLE_GENERATOR;
94 } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { 96 } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
95 l = BN_mod_word(dh->p, 10); 97 l = BN_mod_word(dh->p, 10);
98 if (l == (BN_ULONG)-1)
99 goto err;
96 if (l != 3 && l != 7) 100 if (l != 3 && l != 7)
97 *ret |= DH_NOT_SUITABLE_GENERATOR; 101 *ret |= DH_NOT_SUITABLE_GENERATOR;
98 } else 102 } else
diff --git a/src/regress/lib/libcrypto/bn/general/bntest.c b/src/regress/lib/libcrypto/bn/general/bntest.c
index c6bd788b54..1d541778e3 100644
--- a/src/regress/lib/libcrypto/bn/general/bntest.c
+++ b/src/regress/lib/libcrypto/bn/general/bntest.c
@@ -514,7 +514,7 @@ int
514test_div_word(BIO *bp) 514test_div_word(BIO *bp)
515{ 515{
516 BIGNUM a, b; 516 BIGNUM a, b;
517 BN_ULONG r, s; 517 BN_ULONG r, rmod, s;
518 int i; 518 int i;
519 int rc = 1; 519 int rc = 1;
520 520
@@ -523,14 +523,34 @@ test_div_word(BIO *bp)
523 523
524 for (i = 0; i < num0; i++) { 524 for (i = 0; i < num0; i++) {
525 do { 525 do {
526 BN_bntest_rand(&a, 512, -1, 0); 526 if (!BN_bntest_rand(&a, 512, -1, 0) ||
527 BN_bntest_rand(&b, BN_BITS2, -1, 0); 527 !BN_bntest_rand(&b, BN_BITS2, -1, 0)) {
528 rc = 0;
529 break;
530 }
528 s = b.d[0]; 531 s = b.d[0];
529 } while (!s); 532 } while (!s);
530 533
531 BN_copy(&b, &a); 534 if (!BN_copy(&b, &a)) {
535 rc = 0;
536 break;
537 }
538
539 s = b.d[0];
540 rmod = BN_mod_word(&b, s);
532 r = BN_div_word(&b, s); 541 r = BN_div_word(&b, s);
533 542
543 if (r == (BN_ULONG)-1 || rmod == (BN_ULONG)-1) {
544 rc = 0;
545 break;
546 }
547
548 if (rmod != r) {
549 fprintf(stderr, "Mod (word) test failed!\n");
550 rc = 0;
551 break;
552 }
553
534 if (bp != NULL) { 554 if (bp != NULL) {
535 if (!results) { 555 if (!results) {
536 BN_print(bp, &a); 556 BN_print(bp, &a);