| From d73cc256c8e256c32ed959456101b73ba9842f72 Mon Sep 17 00:00:00 2001 |
| From: Andy Polyakov <appro@openssl.org> |
| 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 <levitte@openssl.org> |
| (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 <akuster@mvista.com> |
| |
| --- |
| 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); |