[openssl] master update

Richard Levitte levitte at openssl.org
Fri Apr 2 14:40:05 UTC 2021


The branch master has been updated
       via  5ad3e6c56eb1c295a7de92de5bb2f54614d5c277 (commit)
       via  ef83daf4dadf9380a3b94618fb7aee75fcd9a6b1 (commit)
      from  baf02793fc5b5095ad8929b8e2aae679e113f457 (commit)


- Log -----------------------------------------------------------------
commit 5ad3e6c56eb1c295a7de92de5bb2f54614d5c277
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Apr 15 12:54:23 2020 +0200

    Include BN assembler alongside CPUID code
    
    It turns out that some CPUID code requires the presence of some BN
    assembler code, so we make sure it's included in the same manner as
    the CPUID code itself.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14755)

commit ef83daf4dadf9380a3b94618fb7aee75fcd9a6b1
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Mar 11 17:38:46 2020 +0100

    Refactor CPUID code
    
    We were using CPUID coded in several modules, but it was unclear how
    it actually got there, and could fail randomly.
    
    To remedy that, this change separates the CPUID C code from the rest
    of cryptlib.c, and ensures the right modules get both that and the
    assembler sources explicitly.
    
    Fixes #11281
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14755)

-----------------------------------------------------------------------

Summary of changes:
 crypto/bn/build.info |  10 ++-
 crypto/build.info    |  43 +++++++----
 crypto/cpuid.c       | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto/cryptlib.c    | 197 -----------------------------------------------
 4 files changed, 250 insertions(+), 214 deletions(-)
 create mode 100644 crypto/cpuid.c

diff --git a/crypto/bn/build.info b/crypto/bn/build.info
index 237d5e90ed..89ff0044f2 100644
--- a/crypto/bn/build.info
+++ b/crypto/bn/build.info
@@ -107,17 +107,21 @@ $COMMON=bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c \
         bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
         bn_intern.c bn_dh.c bn_rsa_fips186_4.c bn_const.c
 SOURCE[../../libcrypto]=$COMMON $BNASM bn_print.c bn_err.c bn_srp.c
+DEFINE[../../libcrypto]=$BNDEF
 IF[{- !$disabled{'deprecated-3.0'} -}]
   SOURCE[../../libcrypto]=bn_depr.c bn_x931p.c
 ENDIF
 SOURCE[../../providers/libfips.a]=$COMMON $BNASM
+DEFINE[../../providers/libfips.a]=$BNDEF
+# Because some CPUID implementations use some BN assembler (!!!), we
+# must include assembler code into the legacy provider under the same
+# conditions as CPUID code is included.  See ../build.info
 SOURCE[../../providers/liblegacy.a]=$BNASM
+DEFINE[../../providers/liblegacy.a]=$BNDEF
 # Implementations are now spread across several libraries, so the defines
 # need to be applied to all affected libraries and modules.
-DEFINE[../../libcrypto]=$BNDEF
-DEFINE[../../providers/libfips.a]=$BNDEF
-DEFINE[../../providers/liblegacy.a]=$BNDEF
 DEFINE[../../providers/libimplementations.a]=$BNDEF
+DEFINE[../../providers/libcommon.a]=$BNDEF
 
 INCLUDE[bn_exp.o]=..
 
diff --git a/crypto/build.info b/crypto/build.info
index dc180d0252..560f872ee2 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -59,6 +59,30 @@ IF[{- !$disabled{asm} && $config{processor} ne '386' -}]
   ENDIF
 ENDIF
 
+# CPUID support.  We need to add that explicitly in every shared library and
+# provider module that uses it.  ctype.c is included here because the CPUID
+# uses functions from there to parse magic environment variables.
+$CPUID_COMMON=$CPUIDASM cpuid.c ctype.c
+INCLUDE[cpuid.o]=..
+
+SOURCE[../libcrypto]=$CPUID_COMMON
+DEFINE[../libcrypto]=$CPUIDDEF
+SOURCE[../providers/libfips.a]=$CPUID_COMMON
+DEFINE[../providers/libfips.a]=$CPUIDDEF
+# We only need to include the CPUID stuff in the legacy provider when it's a
+# separate module and it's dynamically linked with libcrypto.  Otherwise, it
+# already gets everything that the static libcrypto.a has, and doesn't need it
+# added again.
+IF[{- !$disabled{module} && !$disabled{shared} -}]
+  SOURCE[../providers/liblegacy.a]=$CPUID_COMMON
+  DEFINE[../providers/liblegacy.a]=$CPUIDDEF
+ENDIF
+
+# Implementations are now spread across several libraries, so the CPUID define
+# need to be applied to all affected libraries and modules.
+DEFINE[../providers/libimplementations.a]=$CPUIDDEF
+DEFINE[../providers/libcommon.a]=$CPUIDDEF
+
 # The Core
 $CORE_COMMON=provider_core.c provider_predefined.c \
         core_fetch.c core_algorithm.c core_namemap.c self_test_core.c
@@ -69,28 +93,19 @@ SOURCE[../providers/libfips.a]=$CORE_COMMON
 # Central utilities
 $UTIL_COMMON=\
         cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \
-        ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \
-        context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM \
+        threads_pthread.c threads_win.c threads_none.c initthread.c \
+        context.c sparse_array.c asn1_dsa.c packet.c param_build.c \
         param_build_set.c der_writer.c passphrase.c threads_lib.c
-$UTIL_DEFINE=$CPUIDDEF
 
 SOURCE[../libcrypto]=$UTIL_COMMON \
         mem.c mem_sec.c \
         cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \
         o_fopen.c getenv.c o_init.c init.c trace.c provider.c \
-        punycode.c \
-        $UPLINKSRC
+        punycode.c
 SOURCE[../providers/libfips.a]=$UTIL_COMMON
-SOURCE[../providers/liblegacy.a]=cryptlib.c $CPUIDASM ctype.c
 
-# Implementations are now spread across several libraries, so the defines
-# need to be applied to all affected libraries and modules.
-DEFINE[../libcrypto]=$UTIL_DEFINE $UPLINKDEF
-DEFINE[../providers/libfips.a]=$UTIL_DEFINE
-DEFINE[../providers/fips]=$UTIL_DEFINE
-DEFINE[../providers/libimplementations.a]=$UTIL_DEFINE
-DEFINE[../providers/liblegacy.a]=$UTIL_DEFINE
-DEFINE[../providers/libcommon.a]=$UTIL_DEFINE
+SOURCE[../libcrypto]=$UPLINKSRC
+DEFINE[../libcrypto]=$UPLINKDEF
 
 DEPEND[info.o]=buildinf.h
 DEPEND[cversion.o]=buildinf.h
diff --git a/crypto/cpuid.c b/crypto/cpuid.c
new file mode 100644
index 0000000000..090f6fe03e
--- /dev/null
+++ b/crypto/cpuid.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 1998-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "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];
+
+# if defined(OPENSSL_CPUID_OBJ)
+
+/*
+ * Purpose of these minimalistic and character-type-agnostic subroutines
+ * is to break dependency on MSVCRT (on Windows) and locale. This makes
+ * OPENSSL_cpuid_setup safe to use as "constructor". "Character-type-
+ * agnostic" means that they work with either wide or 8-bit characters,
+ * exploiting the fact that first 127 characters can be simply casted
+ * between the sets, while the rest would be simply rejected by ossl_is*
+ * subroutines.
+ */
+#  ifdef _WIN32
+typedef WCHAR variant_char;
+
+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.
+     * As well as to ignore excessively long values...
+     */
+    static WCHAR value[48];
+    DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48);
+
+    return (len > 0 && len < 48) ? value : NULL;
+}
+#  else
+typedef char variant_char;
+#   define ossl_getenv getenv
+#  endif
+
+#  include "crypto/ctype.h"
+
+static int todigit(variant_char c)
+{
+    if (ossl_isdigit(c))
+        return c - '0';
+    else if (ossl_isxdigit(c))
+        return ossl_tolower(c) - 'a' + 10;
+
+    /* return largest base value to make caller terminate the loop */
+    return 16;
+}
+
+static uint64_t ossl_strtouint64(const variant_char *str)
+{
+    uint64_t ret = 0;
+    unsigned int digit, base = 10;
+
+    if (*str == '0') {
+        base = 8, str++;
+        if (ossl_tolower(*str) == 'x')
+            base = 16, str++;
+    }
+
+    while((digit = todigit(*str++)) < base)
+        ret = ret * base + digit;
+
+    return ret;
+}
+
+static variant_char *ossl_strchr(const variant_char *str, char srch)
+{   variant_char c;
+
+    while((c = *str)) {
+        if (c == srch)
+            return (variant_char *)str;
+        str++;
+    }
+
+    return NULL;
+}
+
+#  define OPENSSL_CPUID_SETUP
+typedef uint64_t IA32CAP;
+
+void OPENSSL_cpuid_setup(void)
+{
+    static int trigger = 0;
+    IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
+    IA32CAP vec;
+    const variant_char *env;
+
+    if (trigger)
+        return;
+
+    trigger = 1;
+    if ((env = ossl_getenv("OPENSSL_ia32cap")) != NULL) {
+        int off = (env[0] == '~') ? 1 : 0;
+
+        vec = ossl_strtouint64(env + off);
+
+        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);
+        }
+
+        if ((env = ossl_strchr(env, ':')) != NULL) {
+            IA32CAP vecx;
+
+            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);
+            }
+        } else {
+            OPENSSL_ia32cap_P[2] = 0;
+            OPENSSL_ia32cap_P[3] = 0;
+        }
+    } else {
+        vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+    }
+
+    /*
+     * |(1<<10) sets a reserved bit to signal that variable
+     * was initialized already... This is to avoid interference
+     * with cpuid snippets in ELF .init segment.
+     */
+    OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
+    OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
+}
+# else
+unsigned int OPENSSL_ia32cap_P[4];
+# endif
+#endif
+
+#ifndef OPENSSL_CPUID_OBJ
+# ifndef OPENSSL_CPUID_SETUP
+void OPENSSL_cpuid_setup(void)
+{
+}
+# endif
+
+/*
+ * The rest are functions that are defined in the same assembler files as
+ * the CPUID functionality.
+ */
+
+/*
+ * The volatile is used to 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.
+ *
+ * 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)
+{
+    size_t i;
+    const volatile unsigned char *a = in_a;
+    const volatile unsigned char *b = in_b;
+    unsigned char x = 0;
+
+    for (i = 0; i < len; i++)
+        x |= a[i] ^ b[i];
+
+    return x;
+}
+
+/*
+ * For systems that don't provide an instruction counter register or equivalent.
+ */
+uint32_t OPENSSL_rdtsc(void)
+{
+    return 0;
+}
+
+size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
+{
+    return 0;
+}
+
+size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
+{
+    return 0;
+}
+#endif
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index 0b545af15a..46e2e31475 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -12,161 +12,6 @@
 #include "crypto/cryptlib.h"
 #include <openssl/safestack.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];
-
-# if defined(OPENSSL_CPUID_OBJ)
-
-/*
- * Purpose of these minimalistic and character-type-agnostic subroutines
- * is to break dependency on MSVCRT (on Windows) and locale. This makes
- * OPENSSL_cpuid_setup safe to use as "constructor". "Character-type-
- * agnostic" means that they work with either wide or 8-bit characters,
- * exploiting the fact that first 127 characters can be simply casted
- * between the sets, while the rest would be simply rejected by ossl_is*
- * subroutines.
- */
-#  ifdef _WIN32
-typedef WCHAR variant_char;
-
-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.
-     * As well as to ignore excessively long values...
-     */
-    static WCHAR value[48];
-    DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48);
-
-    return (len > 0 && len < 48) ? value : NULL;
-}
-#  else
-typedef char variant_char;
-#   define ossl_getenv getenv
-#  endif
-
-#  include "crypto/ctype.h"
-
-static int todigit(variant_char c)
-{
-    if (ossl_isdigit(c))
-        return c - '0';
-    else if (ossl_isxdigit(c))
-        return ossl_tolower(c) - 'a' + 10;
-
-    /* return largest base value to make caller terminate the loop */
-    return 16;
-}
-
-static uint64_t ossl_strtouint64(const variant_char *str)
-{
-    uint64_t ret = 0;
-    unsigned int digit, base = 10;
-
-    if (*str == '0') {
-        base = 8, str++;
-        if (ossl_tolower(*str) == 'x')
-            base = 16, str++;
-    }
-
-    while((digit = todigit(*str++)) < base)
-        ret = ret * base + digit;
-
-    return ret;
-}
-
-static variant_char *ossl_strchr(const variant_char *str, char srch)
-{   variant_char c;
-
-    while((c = *str)) {
-        if (c == srch)
-            return (variant_char *)str;
-        str++;
-    }
-
-    return NULL;
-}
-
-#  define OPENSSL_CPUID_SETUP
-typedef uint64_t IA32CAP;
-
-void OPENSSL_cpuid_setup(void)
-{
-    static int trigger = 0;
-    IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
-    IA32CAP vec;
-    const variant_char *env;
-
-    if (trigger)
-        return;
-
-    trigger = 1;
-    if ((env = ossl_getenv("OPENSSL_ia32cap")) != NULL) {
-        int off = (env[0] == '~') ? 1 : 0;
-
-        vec = ossl_strtouint64(env + off);
-
-        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);
-        }
-
-        if ((env = ossl_strchr(env, ':')) != NULL) {
-            IA32CAP vecx;
-
-            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);
-            }
-        } else {
-            OPENSSL_ia32cap_P[2] = 0;
-            OPENSSL_ia32cap_P[3] = 0;
-        }
-    } else {
-        vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
-    }
-
-    /*
-     * |(1<<10) sets a reserved bit to signal that variable
-     * was initialized already... This is to avoid interference
-     * with cpuid snippets in ELF .init segment.
-     */
-    OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
-    OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
-}
-# else
-unsigned int OPENSSL_ia32cap_P[4];
-# endif
-#endif
-#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
-void OPENSSL_cpuid_setup(void)
-{
-}
-#endif
-
 #if defined(_WIN32)
 # include <tchar.h>
 # include <signal.h>
@@ -430,48 +275,6 @@ void OPENSSL_die(const char *message, const char *file, int line)
 #endif
 }
 
-#if !defined(OPENSSL_CPUID_OBJ)
-/*
- * 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.
- *
- * 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)
-{
-    size_t i;
-    const volatile unsigned char *a = in_a;
-    const volatile unsigned char *b = in_b;
-    unsigned char x = 0;
-
-    for (i = 0; i < len; i++)
-        x |= a[i] ^ b[i];
-
-    return x;
-}
-
-/*
- * For systems that don't provide an instruction counter register or equivalent.
- */
-uint32_t OPENSSL_rdtsc(void)
-{
-    return 0;
-}
-
-size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
-{
-    return 0;
-}
-
-size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
-{
-    return 0;
-}
-#endif
-
 #if defined(__TANDEM) && defined(OPENSSL_VPROC)
 /*
  * Define a VPROC function for HP NonStop build crypto library.


More information about the openssl-commits mailing list