Reenable AES-NI in libcrypto
authortb <tb@openbsd.org>
Fri, 6 Sep 2024 09:57:32 +0000 (09:57 +0000)
committertb <tb@openbsd.org>
Fri, 6 Sep 2024 09:57:32 +0000 (09:57 +0000)
The OPENSSL_cpu_caps() change after the last bump missed a crucial bit:
there is more MD mess in the MI code than anticipated, with the result
that AES is now used without AES-NI on amd64 and i386, hurting machines
that previously greatly benefitted from it.

Temporarily add an internal crypto_cpu_caps_ia32() API that returns the
OPENSSL_ia32cap_P or 0 like OPENSSL_cpu_caps() previously did. This can
be improved after the release.

Regression reported and fix tested by Mark Patruck.
No impact on public ABI or API.

with/ok jsing

PS: Next time my pkg_add feels very slow, I should perhaps not mechanically
blame IEEE 802.11...

lib/libcrypto/cryptlib.c
lib/libcrypto/crypto_internal.h
lib/libcrypto/evp/e_aes.c
lib/libcrypto/modes/gcm128.c

index d929b0d..59e6456 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptlib.c,v 1.53 2024/08/31 12:43:58 jsing Exp $ */
+/* $OpenBSD: cryptlib.c,v 1.54 2024/09/06 09:57:32 tb Exp $ */
 /* ====================================================================
  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
  *
@@ -334,6 +334,12 @@ CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
 
 uint64_t OPENSSL_ia32cap_P;
 
+uint64_t
+crypto_cpu_caps_ia32(void)
+{
+       return OPENSSL_ia32cap_P;
+}
+
 #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM)
 #define OPENSSL_CPUID_SETUP
 void
@@ -352,6 +358,12 @@ OPENSSL_cpuid_setup(void)
 }
 #endif
 
+#else
+uint64_t
+crypto_cpu_caps_ia32(void)
+{
+       return 0;
+}
 #endif
 
 #if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
index 7676076..fc61747 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: crypto_internal.h,v 1.11 2024/08/11 13:02:39 jsing Exp $ */
+/*     $OpenBSD: crypto_internal.h,v 1.12 2024/09/06 09:57:32 tb Exp $ */
 /*
  * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
  *
@@ -220,4 +220,6 @@ crypto_ror_u64(uint64_t v, size_t shift)
 }
 #endif
 
+uint64_t crypto_cpu_caps_ia32(void);
+
 #endif
index 6135c7d..7753c18 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_aes.c,v 1.58 2024/04/09 13:52:41 beck Exp $ */
+/* $OpenBSD: e_aes.c,v 1.59 2024/09/06 09:57:32 tb Exp $ */
 /* ====================================================================
  * Copyright (c) 2001-2011 The OpenSSL Project.  All rights reserved.
  *
@@ -55,6 +55,8 @@
 
 #include <openssl/opensslconf.h>
 
+#include "crypto_internal.h"
+
 #ifndef OPENSSL_NO_AES
 #include <openssl/aes.h>
 #include <openssl/err.h>
@@ -154,7 +156,7 @@ void AES_xts_decrypt(const char *inp, char *out, size_t len,
 #include "x86_arch.h"
 
 #ifdef VPAES_ASM
-#define VPAES_CAPABLE  (OPENSSL_cpu_caps() & CPUCAP_MASK_SSSE3)
+#define VPAES_CAPABLE  (crypto_cpu_caps_ia32() & CPUCAP_MASK_SSSE3)
 #endif
 #ifdef BSAES_ASM
 #define BSAES_CAPABLE  VPAES_CAPABLE
@@ -162,7 +164,7 @@ void AES_xts_decrypt(const char *inp, char *out, size_t len,
 /*
  * AES-NI section
  */
-#define        AESNI_CAPABLE   (OPENSSL_cpu_caps() & CPUCAP_MASK_AESNI)
+#define        AESNI_CAPABLE   (crypto_cpu_caps_ia32() & CPUCAP_MASK_AESNI)
 
 int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
     AES_KEY *key);
index cbda8ad..6c89bd4 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: gcm128.c,v 1.26 2023/08/10 07:18:43 jsing Exp $ */
+/* $OpenBSD: gcm128.c,v 1.27 2024/09/06 09:57:32 tb Exp $ */
 /* ====================================================================
  * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
  *
 
 #define OPENSSL_FIPSAPI
 
+#include <string.h>
+
 #include <openssl/crypto.h>
+
+#include "crypto_internal.h"
 #include "modes_local.h"
-#include <string.h>
 
 #ifndef MODES_DEBUG
 # ifndef NDEBUG
@@ -660,7 +663,7 @@ CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block)
 # if   defined(GHASH_ASM_X86_OR_64)
 #  if  !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
        /* check FXSR and PCLMULQDQ bits */
-       if ((OPENSSL_cpu_caps() & (CPUCAP_MASK_FXSR | CPUCAP_MASK_PCLMUL)) ==
+       if ((crypto_cpu_caps_ia32() & (CPUCAP_MASK_FXSR | CPUCAP_MASK_PCLMUL)) ==
            (CPUCAP_MASK_FXSR | CPUCAP_MASK_PCLMUL)) {
                gcm_init_clmul(ctx->Htable, ctx->H.u);
                ctx->gmult = gcm_gmult_clmul;
@@ -671,9 +674,9 @@ CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block)
        gcm_init_4bit(ctx->Htable, ctx->H.u);
 #  if  defined(GHASH_ASM_X86)                  /* x86 only */
 #   if defined(OPENSSL_IA32_SSE2)
-       if (OPENSSL_cpu_caps() & CPUCAP_MASK_SSE) {     /* check SSE bit */
+       if (crypto_cpu_caps_ia32() & CPUCAP_MASK_SSE) { /* check SSE bit */
 #   else
-       if (OPENSSL_cpu_caps() & CPUCAP_MASK_MMX) {     /* check MMX bit */
+       if (crypto_cpu_caps_ia32() & CPUCAP_MASK_MMX) { /* check MMX bit */
 #   endif
                ctx->gmult = gcm_gmult_4bit_mmx;
                ctx->ghash = gcm_ghash_4bit_mmx;