Commit 29851264 authored by Andy Polyakov's avatar Andy Polyakov Committed by Matt Caswell
Browse files

bn/asm/x86_64-mont5.pl: fix carry propagating bug (CVE-2015-3193).

parent b5516cfb
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -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
+18 −0
Original line number Diff line number Diff line
@@ -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);