aboutsummaryrefslogtreecommitdiff
path: root/crypto/cpuid.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/cpuid.c')
-rw-r--r--crypto/cpuid.c69
1 files changed, 42 insertions, 27 deletions
diff --git a/crypto/cpuid.c b/crypto/cpuid.c
index 090f6fe03ecc..538a5a039f20 100644
--- a/crypto/cpuid.c
+++ b/crypto/cpuid.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -7,14 +7,14 @@
* https://www.openssl.org/source/license.html
*/
-#include "e_os.h"
+#include "internal/e_os.h"
#include "crypto/cryptlib.h"
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64)
-extern unsigned int OPENSSL_ia32cap_P[4];
+extern unsigned int OPENSSL_ia32cap_P[OPENSSL_IA32CAP_P_MAX_INDEXES];
# if defined(OPENSSL_CPUID_OBJ)
@@ -29,18 +29,18 @@ extern unsigned int OPENSSL_ia32cap_P[4];
*/
# ifdef _WIN32
typedef WCHAR variant_char;
-
+# define OPENSSL_IA32CAP_P_MAX_CHAR_SIZE 256
static variant_char *ossl_getenv(const char *name)
{
/*
* Since we pull only one environment variable, it's simpler to
- * to just ignore |name| and use equivalent wide-char L-literal.
+ * just ignore |name| and use equivalent wide-char L-literal.
* As well as to ignore excessively long values...
*/
- static WCHAR value[48];
- DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48);
+ static WCHAR value[OPENSSL_IA32CAP_P_MAX_CHAR_SIZE];
+ DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, OPENSSL_IA32CAP_P_MAX_CHAR_SIZE);
- return (len > 0 && len < 48) ? value : NULL;
+ return (len > 0 && len < OPENSSL_IA32CAP_P_MAX_CHAR_SIZE) ? value : NULL;
}
# else
typedef char variant_char;
@@ -71,7 +71,7 @@ static uint64_t ossl_strtouint64(const variant_char *str)
base = 16, str++;
}
- while((digit = todigit(*str++)) < base)
+ while ((digit = todigit(*str++)) < base)
ret = ret * base + digit;
return ret;
@@ -80,7 +80,7 @@ static uint64_t ossl_strtouint64(const variant_char *str)
static variant_char *ossl_strchr(const variant_char *str, char srch)
{ variant_char c;
- while((c = *str)) {
+ while ((c = *str)) {
if (c == srch)
return (variant_char *)str;
str++;
@@ -98,6 +98,7 @@ void OPENSSL_cpuid_setup(void)
IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
IA32CAP vec;
const variant_char *env;
+ int index = 2;
if (trigger)
return;
@@ -126,23 +127,37 @@ void OPENSSL_cpuid_setup(void)
vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
}
- if ((env = ossl_strchr(env, ':')) != NULL) {
- IA32CAP vecx;
-
+ /* Processed indexes 0, 1 */
+ if ((env = ossl_strchr(env, ':')) != NULL)
env++;
- off = (env[0] == '~') ? 1 : 0;
- vecx = ossl_strtouint64(env + off);
- if (off) {
- OPENSSL_ia32cap_P[2] &= ~(unsigned int)vecx;
- OPENSSL_ia32cap_P[3] &= ~(unsigned int)(vecx >> 32);
- } else {
- OPENSSL_ia32cap_P[2] = (unsigned int)vecx;
- OPENSSL_ia32cap_P[3] = (unsigned int)(vecx >> 32);
+ for (; index < OPENSSL_IA32CAP_P_MAX_INDEXES; index += 2) {
+ if ((env != NULL) && (env[0] != '\0')) {
+ /* if env[0] == ':' current index is skipped */
+ if (env[0] != ':') {
+ IA32CAP vecx;
+
+ off = (env[0] == '~') ? 1 : 0;
+ vecx = ossl_strtouint64(env + off);
+ if (off) {
+ OPENSSL_ia32cap_P[index] &= ~(unsigned int)vecx;
+ OPENSSL_ia32cap_P[index + 1] &= ~(unsigned int)(vecx >> 32);
+ } else {
+ OPENSSL_ia32cap_P[index] = (unsigned int)vecx;
+ OPENSSL_ia32cap_P[index + 1] = (unsigned int)(vecx >> 32);
+ }
+ }
+ /* skip delimeter */
+ if ((env = ossl_strchr(env, ':')) != NULL)
+ env++;
+ } else { /* zeroize the next two indexes */
+ OPENSSL_ia32cap_P[index] = 0;
+ OPENSSL_ia32cap_P[index + 1] = 0;
}
- } else {
- OPENSSL_ia32cap_P[2] = 0;
- OPENSSL_ia32cap_P[3] = 0;
}
+
+ /* If AVX10 is disabled, zero out its detailed cap bits */
+ if (!(OPENSSL_ia32cap_P[6] & (1 << 19)))
+ OPENSSL_ia32cap_P[9] = 0;
} else {
vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
}
@@ -156,7 +171,7 @@ void OPENSSL_cpuid_setup(void)
OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
}
# else
-unsigned int OPENSSL_ia32cap_P[4];
+unsigned int OPENSSL_ia32cap_P[OPENSSL_IA32CAP_P_MAX_INDEXES];
# endif
#endif
@@ -173,7 +188,7 @@ void OPENSSL_cpuid_setup(void)
*/
/*
- * The volatile is used to to ensure that the compiler generates code that reads
+ * The volatile is used to ensure that the compiler generates code that reads
* all values from the array and doesn't try to optimize this away. The standard
* doesn't actually require this behavior if the original data pointed to is
* not volatile, but compilers do this in practice anyway.
@@ -181,7 +196,7 @@ void OPENSSL_cpuid_setup(void)
* There are also assembler versions of this function.
*/
# undef CRYPTO_memcmp
-int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len)
+int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
{
size_t i;
const volatile unsigned char *a = in_a;