aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/cryptlib.c
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2017-08-31 01:09:48 +0200
committerAndy Polyakov <appro@openssl.org>2017-09-01 08:48:32 +0200
commit6e5a853bda24e8aece325ecf5aa68b8ea832e414 (patch)
tree270c82691b064492838700aff24933c2c44f7aed /crypto/cryptlib.c
parent89bc9cf682e833d44fe135c901fe75f600d871ef (diff)
downloadopenssl-6e5a853bda24e8aece325ecf5aa68b8ea832e414.tar.gz
crypto/cryptlib.c: mask more capability bits upon FXSR bit flip.
OPENSSL_ia32cap.pod discusses possibility to disable operations on XMM register bank. This formally means that this flag has to be checked in combination with other flags. But it customarily isn't. But instead of chasing all the cases we can flip more bits together with FXSR one. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/4303)
Diffstat (limited to 'crypto/cryptlib.c')
-rw-r--r--crypto/cryptlib.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index 6e45b0d8ba..eb24b27808 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -42,12 +42,24 @@ void OPENSSL_cpuid_setup(void)
if (!sscanf(env + off, "%lli", (long long *)&vec))
vec = strtoul(env + off, NULL, 0);
# endif
- if (off)
- vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
- else if (env[0] == ':')
+ if (off) {
+ IA32CAP mask = vec;
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~mask;
+ if (mask & (1<<24)) {
+ /*
+ * User disables FXSR bit, mask even other capabilities
+ * that operate exclusively on XMM, so we don't have to
+ * double-check all the time. We mask PCLMULQDQ, AMD XOP,
+ * AES-NI and AVX. Formally speaking we don't have to
+ * do it in x86_64 case, but we can safely assume that
+ * x86_64 users won't actually flip this flag.
+ */
+ vec &= ~((IA32CAP)(1<<1|1<<11|1<<25|1<<28) << 32);
+ }
+ } else if (env[0] == ':') {
vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+ }
- OPENSSL_ia32cap_P[2] = 0;
if ((env = strchr(env, ':'))) {
unsigned int vecx;
env++;
@@ -57,9 +69,12 @@ void OPENSSL_cpuid_setup(void)
OPENSSL_ia32cap_P[2] &= ~vecx;
else
OPENSSL_ia32cap_P[2] = vecx;
+ } else {
+ OPENSSL_ia32cap_P[2] = 0;
}
- } else
+ } else {
vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+ }
/*
* |(1<<10) sets a reserved bit to signal that variable