Expand OPENSSL_ia32cap_P to 64 bits. It might appear controversial, because
such operation can be considered as breaking binary compatibility. However! OPNESSL_ia32cap_P is accessed by application through pointer returned by OPENSSL_ia32cap_loc() and such change of *internal* OPENSSL_ia32cap_P declaration is possible specifically on little-endian platforms, such as x86[_64] ones in question. In addition, if 32-bit application calls OPENSSL_ia32cap_loc(), it clears upper half of capability vector maintaining the illusion that it's still 32 bits wide.
This commit is contained in:
parent
500007c9ed
commit
0ec55604c0
@ -665,28 +665,49 @@ const char *CRYPTO_get_lock_name(int type)
|
|||||||
defined(__INTEL__) || \
|
defined(__INTEL__) || \
|
||||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
|
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
|
||||||
|
|
||||||
unsigned long OPENSSL_ia32cap_P=0;
|
unsigned int OPENSSL_ia32cap_P[2];
|
||||||
unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
|
unsigned long *OPENSSL_ia32cap_loc(void)
|
||||||
|
{ if (sizeof(long)==4)
|
||||||
|
/*
|
||||||
|
* If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
|
||||||
|
* clear second element to maintain the illusion that vector
|
||||||
|
* is 32-bit.
|
||||||
|
*/
|
||||||
|
OPENSSL_ia32cap_P[1]=0;
|
||||||
|
return (unsigned long *)OPENSSL_ia32cap_P;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
|
#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
|
||||||
#define OPENSSL_CPUID_SETUP
|
#define OPENSSL_CPUID_SETUP
|
||||||
|
#if defined(_WIN32)
|
||||||
|
typedef unsigned __int64 IA32CAP;
|
||||||
|
#else
|
||||||
|
typedef unsigned long long IA32CAP;
|
||||||
|
#endif
|
||||||
void OPENSSL_cpuid_setup(void)
|
void OPENSSL_cpuid_setup(void)
|
||||||
{ static int trigger=0;
|
{ static int trigger=0;
|
||||||
unsigned long OPENSSL_ia32_cpuid(void);
|
IA32CAP OPENSSL_ia32_cpuid(void);
|
||||||
|
IA32CAP vec;
|
||||||
char *env;
|
char *env;
|
||||||
|
|
||||||
if (trigger) return;
|
if (trigger) return;
|
||||||
|
|
||||||
trigger=1;
|
trigger=1;
|
||||||
if ((env=getenv("OPENSSL_ia32cap")))
|
if ((env=getenv("OPENSSL_ia32cap")))
|
||||||
OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10);
|
#if defined(_WIN32)
|
||||||
|
{ if (!sscanf(env,"%I64i",&vec)) vec = strtoul(env,NULL,0); }
|
||||||
|
#else
|
||||||
|
vec = strtoull(env,NULL,0);
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10);
|
vec = OPENSSL_ia32_cpuid();
|
||||||
/*
|
/*
|
||||||
* |(1<<10) sets a reserved bit to signal that variable
|
* |(1<<10) sets a reserved bit to signal that variable
|
||||||
* was initialized already... This is to avoid interference
|
* was initialized already... This is to avoid interference
|
||||||
* with cpuid snippets in ELF .init segment.
|
* with cpuid snippets in ELF .init segment.
|
||||||
*/
|
*/
|
||||||
|
OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
|
||||||
|
OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ extern "C" {
|
|||||||
#define HEX_SIZE(type) (sizeof(type)*2)
|
#define HEX_SIZE(type) (sizeof(type)*2)
|
||||||
|
|
||||||
void OPENSSL_cpuid_setup(void);
|
void OPENSSL_cpuid_setup(void);
|
||||||
extern unsigned long OPENSSL_ia32cap_P;
|
extern unsigned int OPENSSL_ia32cap_P[];
|
||||||
void OPENSSL_showfatal(const char *,...);
|
void OPENSSL_showfatal(const char *,...);
|
||||||
void *OPENSSL_stderr(void);
|
void *OPENSSL_stderr(void);
|
||||||
extern int OPENSSL_NONPIC_relocated;
|
extern int OPENSSL_NONPIC_relocated;
|
||||||
|
@ -150,7 +150,7 @@ sub ::public_label
|
|||||||
|
|
||||||
sub ::file_end
|
sub ::file_end
|
||||||
{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
|
{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
|
||||||
my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,4";
|
my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,8";
|
||||||
if ($::elf) { push (@out,"$tmp,4\n"); }
|
if ($::elf) { push (@out,"$tmp,4\n"); }
|
||||||
else { push (@out,"$tmp\n"); }
|
else { push (@out,"$tmp\n"); }
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ ___
|
|||||||
if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
|
if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
|
||||||
{ my $comm=<<___;
|
{ my $comm=<<___;
|
||||||
.bss SEGMENT 'BSS'
|
.bss SEGMENT 'BSS'
|
||||||
COMM ${nmdecor}OPENSSL_ia32cap_P:DWORD
|
COMM ${nmdecor}OPENSSL_ia32cap_P:QWORD
|
||||||
.bss ENDS
|
.bss ENDS
|
||||||
___
|
___
|
||||||
# comment out OPENSSL_ia32cap_P declarations
|
# comment out OPENSSL_ia32cap_P declarations
|
||||||
|
@ -114,7 +114,7 @@ sub ::file_end
|
|||||||
{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
|
{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
|
||||||
{ my $comm=<<___;
|
{ my $comm=<<___;
|
||||||
${drdecor}segment .bss
|
${drdecor}segment .bss
|
||||||
${drdecor}common ${nmdecor}OPENSSL_ia32cap_P 4
|
${drdecor}common ${nmdecor}OPENSSL_ia32cap_P 8
|
||||||
___
|
___
|
||||||
# comment out OPENSSL_ia32cap_P declarations
|
# comment out OPENSSL_ia32cap_P declarations
|
||||||
grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
|
grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
|
||||||
|
@ -68,9 +68,9 @@ typedef unsigned long long u64;
|
|||||||
CPUs this is actually faster! */
|
CPUs this is actually faster! */
|
||||||
# endif
|
# endif
|
||||||
# define GO_FOR_MMX(ctx,inp,num) do { \
|
# define GO_FOR_MMX(ctx,inp,num) do { \
|
||||||
extern unsigned long OPENSSL_ia32cap_P; \
|
extern unsigned int OPENSSL_ia32cap_P[]; \
|
||||||
void whirlpool_block_mmx(void *,const void *,size_t); \
|
void whirlpool_block_mmx(void *,const void *,size_t); \
|
||||||
if (!(OPENSSL_ia32cap_P & (1<<23))) break; \
|
if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \
|
||||||
whirlpool_block_mmx(ctx->H.c,inp,num); return; \
|
whirlpool_block_mmx(ctx->H.c,inp,num); return; \
|
||||||
} while (0)
|
} while (0)
|
||||||
# endif
|
# endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user