summaryrefslogtreecommitdiffstats
path: root/crypto/bn
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2015-12-01 09:00:32 +0100
committerMatt Caswell <matt@openssl.org>2015-12-03 14:32:05 +0000
commitd73cc256c8e256c32ed959456101b73ba9842f72 (patch)
tree48002d1685f114e6faaca36e4f312deb7cfff6e9 /crypto/bn
parentcc598f321fbac9c04da5766243ed55d55948637d (diff)
bn/asm/x86_64-mont5.pl: fix carry propagating bug (CVE-2015-3193).
Reviewed-by: Richard Levitte <levitte@openssl.org> (cherry picked from commit e7c078db57908cbf16074c68034977565ffaf107)
Diffstat (limited to 'crypto/bn')
-rwxr-xr-xcrypto/bn/asm/x86_64-mont5.pl22
-rw-r--r--crypto/bn/bntest.c18
2 files changed, 37 insertions, 3 deletions
diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl
index 388e3c6911..64e668f140 100755
--- a/crypto/bn/asm/x86_64-mont5.pl
+++ b/crypto/bn/asm/x86_64-mont5.pl
@@ -1784,6 +1784,15 @@ sqr8x_reduction:
.align 32
.L8x_tail_done:
add (%rdx),%r8 # can this overflow?
+ adc \$0,%r9
+ adc \$0,%r10
+ adc \$0,%r11
+ adc \$0,%r12
+ adc \$0,%r13
+ adc \$0,%r14
+ adc \$0,%r15 # can't overflow, because we
+ # started with "overhung" part
+ # of multiplication
xor %rax,%rax
neg $carry
@@ -3130,6 +3139,15 @@ sqrx8x_reduction:
.align 32
.Lsqrx8x_tail_done:
add 24+8(%rsp),%r8 # can this overflow?
+ adc \$0,%r9
+ adc \$0,%r10
+ adc \$0,%r11
+ adc \$0,%r12
+ adc \$0,%r13
+ adc \$0,%r14
+ adc \$0,%r15 # can't overflow, because we
+ # started with "overhung" part
+ # of multiplication
mov $carry,%rax # xor %rax,%rax
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
@@ -3173,13 +3191,11 @@ my ($rptr,$nptr)=("%rdx","%rbp");
my @ri=map("%r$_",(10..13));
my @ni=map("%r$_",(14..15));
$code.=<<___;
- xor %rbx,%rbx
+ xor %ebx,%ebx
sub %r15,%rsi # compare top-most words
adc %rbx,%rbx
mov %rcx,%r10 # -$num
- .byte 0x67
or %rbx,%rax
- .byte 0x67
mov %rcx,%r9 # -$num
xor \$1,%rax
sar \$3+2,%rcx # cf=0
diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c
index 8b8a15220e..1e35988022 100644
--- a/crypto/bn/bntest.c
+++ b/crypto/bn/bntest.c
@@ -1016,6 +1016,24 @@ int test_mod_exp(BIO *bp, BN_CTX *ctx)
return 0;
}
}
+
+ /* Regression test for carry propagation bug in sqr8x_reduction */
+ BN_hex2bn(&a, "050505050505");
+ BN_hex2bn(&b, "02");
+ BN_hex2bn(&c,
+ "4141414141414141414141274141414141414141414141414141414141414141"
+ "4141414141414141414141414141414141414141414141414141414141414141"
+ "4141414141414141414141800000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000001");
+ BN_mod_exp(d, a, b, c, ctx);
+ BN_mul(e, a, a, ctx);
+ if (BN_cmp(d, e)) {
+ fprintf(stderr, "BN_mod_exp and BN_mul produce different results!\n");
+ return 0;
+ }
+
BN_free(a);
BN_free(b);
BN_free(c);