From d73cc256c8e256c32ed959456101b73ba9842f72 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 1 Dec 2015 09:00:32 +0100 Subject: [PATCH] bn/asm/x86_64-mont5.pl: fix carry propagating bug (CVE-2015-3193). Reviewed-by: Richard Levitte (cherry picked from commit e7c078db57908cbf16074c68034977565ffaf107) Upstream-Status: Backport This patch was imported from https://git.openssl.org/?p=openssl.git;a=commit;h=d73cc256c8e256c32ed959456101b73ba9842f72 Signed-off-by: Armin Kuster --- crypto/bn/asm/x86_64-mont5.pl | 22 +++++++++++++++++++--- crypto/bn/bntest.c | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) Index: openssl-1.0.2d/crypto/bn/asm/x86_64-mont5.pl =================================================================== --- openssl-1.0.2d.orig/crypto/bn/asm/x86_64-mont5.pl +++ openssl-1.0.2d/crypto/bn/asm/x86_64-mont5.pl @@ -1779,6 +1779,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 @@ -3125,6 +3134,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 @@ -3168,13 +3186,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 Index: openssl-1.0.2d/crypto/bn/bntest.c =================================================================== --- openssl-1.0.2d.orig/crypto/bn/bntest.c +++ openssl-1.0.2d/crypto/bn/bntest.c @@ -1027,6 +1027,24 @@ int test_mod_exp_mont_consttime(BIO *bp, 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);