Support detecting AVX512BW, AVX512VL, VAES, and VPCLMULQDQ

Add helper functions that check the AVX512BW, AVX512VL, VAES, and
VPCLMULQDQ feature bits in the CPU capability words.  Also, make sure
that OPENSSL_cpuid_setup() clears VAES and VPCLMULQDQ when they are
unsupported due to the operating system not supporting ymm registers.

Change-Id: I2d672556acc269ef09ab6f5e080d37cb9831e7ce
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/68908
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Auto-Submit: Eric Biggers <ebiggers@google.com>
diff --git a/crypto/cpu_intel.c b/crypto/cpu_intel.c
index 3453fa3..10e7871 100644
--- a/crypto/cpu_intel.c
+++ b/crypto/cpu_intel.c
@@ -228,6 +228,8 @@
     ecx &= ~(1u << 12);  // FMA
     ecx &= ~(1u << 11);  // AMD XOP
     extended_features[0] &= ~(1u << 5);   // AVX2
+    extended_features[1] &= ~(1u << 9);   // VAES
+    extended_features[1] &= ~(1u << 10);  // VPCLMULQDQ
   }
   // See Intel manual, volume 1, sections 15.2 ("Detection of AVX-512 Foundation
   // Instructions") through 15.4 ("Detection of Intel AVX-512 Instruction Groups
diff --git a/crypto/internal.h b/crypto/internal.h
index 209c85a..4ec12f5 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -1564,6 +1564,38 @@
   return !hardware_supports_xsave && CRYPTO_is_MOVBE_capable();
 }
 
+OPENSSL_INLINE int CRYPTO_is_AVX512BW_capable(void) {
+#if defined(__AVX512BW__)
+  return 1;
+#else
+  return (OPENSSL_get_ia32cap(2) & (1u << 30)) != 0;
+#endif
+}
+
+OPENSSL_INLINE int CRYPTO_is_AVX512VL_capable(void) {
+#if defined(__AVX512VL__)
+  return 1;
+#else
+  return (OPENSSL_get_ia32cap(2) & (1u << 31)) != 0;
+#endif
+}
+
+OPENSSL_INLINE int CRYPTO_is_VAES_capable(void) {
+#if defined(__VAES__)
+  return 1;
+#else
+  return (OPENSSL_get_ia32cap(3) & (1u << 9)) != 0;
+#endif
+}
+
+OPENSSL_INLINE int CRYPTO_is_VPCLMULQDQ_capable(void) {
+#if defined(__VPCLMULQDQ__)
+  return 1;
+#else
+  return (OPENSSL_get_ia32cap(3) & (1u << 10)) != 0;
+#endif
+}
+
 #endif  // OPENSSL_X86 || OPENSSL_X86_64
 
 #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)