From 15ecb1a4dc4f75d6c33e8cd9089ca5cfc78d28dc Mon Sep 17 00:00:00 2001
From: Todd Short <tshort@akamai.com>
Date: Tue, 19 May 2015 14:46:40 -0400
Subject: [PATCH 1/3] RT3885 OpenSSL fails to cross-compile on 32-bit->64-bit

Older 32-bit versions of perl cannot handle 64-bit numbers, so when
the x86_64-xlate.pl script encounters a 64-bit number, the oct()
function munges it into a double-precision rather than a 64-bit
integer. In this case, we know it's either a hex number or an octal
number. So, if 64-bit hex, just pass through as hex string, otherwise
allow oct() to handle it. There are some cases where immediate constants
are multiplied together. The script assumes decimal numbers during mul,
div, mod operations, so by handling only 64-bit numbers in this manner,
the impact of this patch is minimized.

This is a problem in ghash-x86_64.pl (ghash-x86_64.s), and the solution
has an impact all 64-bit platforms. Ran the unit tests to make sure it's
OK. During development, AES-GCM on some Xeon processors exhibited a
failure trying to encrypt more than 384 bytes due to calculated
constants.

(cherry picked from commit d7caa2d1663b50e20dfe0a19735c192f84f7730f)
(cherry picked from commit c09e807dff4017a0c73d3ed43748ebf881fa10d4)
---
 crypto/perlasm/x86_64-xlate.pl | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index aae8288..35dd501 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -192,13 +192,19 @@ my %globals;
 	}
 	$ret;
     }
+    sub myoct {
+        my $v = shift;
+	return $v if ($v =~ /^0x[0-9a-f]{9,16}/i); # if 64-bit hex leave as-is
+        use integer;
+        return oct($v);
+    }
     sub out {
     	my $self = shift;
 
 	if ($gas) {
 	    # Solaris /usr/ccs/bin/as can't handle multiplications
 	    # in $self->{value}
-	    $self->{value} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
+	    $self->{value} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/myoct($1)/egi;
 	    $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
 	    sprintf "\$%s",$self->{value};
 	} else {
-- 
1.9.1

