Prefer AES-GCM when hardware support is available.

BUG=396787

Change-Id: I72ddb0ec3c71dbc70054403163930cbbde4b6009
Reviewed-on: https://boringssl-review.googlesource.com/1581
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/cipher/e_aes.c b/crypto/cipher/e_aes.c
index 03f9e28..15a886c 100644
--- a/crypto/cipher/e_aes.c
+++ b/crypto/cipher/e_aes.c
@@ -1271,3 +1271,11 @@
 const EVP_AEAD *EVP_aead_aes_128_key_wrap() { return &aead_aes_128_key_wrap; }
 
 const EVP_AEAD *EVP_aead_aes_256_key_wrap() { return &aead_aes_256_key_wrap; }
+
+int EVP_has_aes_hardware(void) {
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
+  return aesni_capable() && crypto_gcm_clmul_enabled();
+#else
+  return 0;
+#endif
+}
diff --git a/crypto/modes/gcm.c b/crypto/modes/gcm.c
index 982f823..065c457 100644
--- a/crypto/modes/gcm.c
+++ b/crypto/modes/gcm.c
@@ -406,8 +406,7 @@
   }
 
 #if defined(GHASH_ASM_X86_OR_64)
-  if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */
-      OPENSSL_ia32cap_P[1] & (1 << 1)) {  /* check PCLMULQDQ bit */
+  if (crypto_gcm_clmul_enabled()) {
     if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */
       gcm_init_avx(ctx->Htable, ctx->H.u);
       ctx->gmult = gcm_gmult_avx;
@@ -1189,3 +1188,14 @@
     OPENSSL_free(ctx);
   }
 }
+
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
+int crypto_gcm_clmul_enabled(void) {
+#ifdef GHASH_ASM
+  return OPENSSL_ia32cap_P[0] & (1 << 24) &&  /* check FXSR bit */
+    OPENSSL_ia32cap_P[1] & (1 << 1);  /* check PCLMULQDQ bit */
+#else
+  return 0;
+#endif
+}
+#endif
diff --git a/crypto/modes/internal.h b/crypto/modes/internal.h
index 4fa0ec6..4659eab 100644
--- a/crypto/modes/internal.h
+++ b/crypto/modes/internal.h
@@ -194,6 +194,13 @@
 #endif
 
 
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
+/* crypto_gcm_clmul_enabled returns one if the CLMUL implementation of GCM is
+ * used. */
+int crypto_gcm_clmul_enabled(void);
+#endif
+
+
 #if defined(__cplusplus)
 } /* extern C */
 #endif
diff --git a/include/openssl/aead.h b/include/openssl/aead.h
index 7e4682c..6f66e9c 100644
--- a/include/openssl/aead.h
+++ b/include/openssl/aead.h
@@ -115,6 +115,10 @@
  * See |EVP_aead_aes_128_key_wrap| for details. */
 OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_key_wrap();
 
+/* EVP_has_aes_hardware returns one if we enable hardware support for fast and
+ * constant-time AES-GCM. */
+OPENSSL_EXPORT int EVP_has_aes_hardware(void);
+
 
 /* TLS specific AEAD algorithms.
  *
diff --git a/include/openssl/cpu.h b/include/openssl/cpu.h
index bec157f..3cc1e5e 100644
--- a/include/openssl/cpu.h
+++ b/include/openssl/cpu.h
@@ -79,7 +79,10 @@
  *   Index 1:
  *     ECX for CPUID where EAX = 1
  *   Index 2:
- *     EBX for CPUID where EAX = 7 */
+ *     EBX for CPUID where EAX = 7
+ *
+ * Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM
+ * bits in XCR0, so it is not necessary to check those. */
 extern uint32_t OPENSSL_ia32cap_P[4];
 #endif
 
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index d9a4def..0caed0b 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -1193,16 +1193,24 @@
 	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
 	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, &head, &tail);
 
-	/* Order the bulk ciphers.
-	 * 1. CHACHA20_POLY1305.
-	 * 2. AES_256_GCM and AES_128_GCM.
-	 * 3. Legacy non-AEAD ciphers. AES_256_CBC, AES-128_CBC, RC4_128_SHA,
-	 *    RC4_128_MD5, 3DES_EDE_CBC_SHA.
-	 * TODO(davidben): Prefer AES_GCM over CHACHA20 if there is hardware
-	 * support. */
-        ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
-        ssl_cipher_apply_rule(0, 0, 0, SSL_AES256GCM, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
-        ssl_cipher_apply_rule(0, 0, 0, SSL_AES128GCM, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
+	/* Order the bulk ciphers. First the preferred AEAD ciphers. We prefer
+	 * CHACHA20 unless there is hardware support for fast and constant-time
+	 * AES_GCM. */
+	if (EVP_has_aes_hardware())
+		{
+		ssl_cipher_apply_rule(0, 0, 0, SSL_AES256GCM, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
+		ssl_cipher_apply_rule(0, 0, 0, SSL_AES128GCM, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
+		ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
+		}
+	else
+		{
+		ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
+		ssl_cipher_apply_rule(0, 0, 0, SSL_AES256GCM, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
+		ssl_cipher_apply_rule(0, 0, 0, SSL_AES128GCM, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
+		}
+
+	/* Then the legacy non-AEAD ciphers: AES_256_CBC, AES-128_CBC,
+	 * RC4_128_SHA, RC4_128_MD5, 3DES_EDE_CBC_SHA. */
         ssl_cipher_apply_rule(0, 0, 0, SSL_AES256, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
         ssl_cipher_apply_rule(0, 0, 0, SSL_AES128, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
         ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, ~SSL_MD5, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);