bn/asm/x86_64-mont5.pl: fix carry propagating bug (CVE-2015-3193).
authorAndy Polyakov <appro@openssl.org>
Tue, 1 Dec 2015 08:00:32 +0000 (09:00 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 3 Dec 2015 13:12:01 +0000 (13:12 +0000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
crypto/bn/asm/x86_64-mont5.pl
test/bntest.c

index 388e3c691184acf4f1245f3be607e8ca9890a66c..64e668f140c24eca9fe56364c49458cad6b2c812 100755 (executable)
@@ -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
index 9caa2c904ba879e75ddae8642c97143adb248efd..9542800444579bfb15fd095059cfde8a37503623 100644 (file)
@@ -1023,6 +1023,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);