Commit d61ac0db8c

Frank Denis <124872+jedisct1@users.noreply.github.com>
2023-03-22 17:58:24
TLS: Favor ChaCha over AES-based ciphers on CPUs without AES support (#15034)
On CPUs without AES support, ChaCha is always faster and safer than software AES. Add `crypto.core.aes.has_hardware_support` to represent whether AES acceleration is available or not, and in `tls.Client`, favor AES-based ciphers only if hardware support is available. This matches what BoringSSL is doing.
1 parent 84b89d7
Changed files (2)
lib
std
lib/std/crypto/tls/Client.zig
@@ -1363,13 +1363,22 @@ fn limitVecs(iovecs: []std.os.iovec, len: usize) []std.os.iovec {
 ///        aegis-256:        461 MiB/s
 ///       aes128-gcm:        138 MiB/s
 ///       aes256-gcm:        120 MiB/s
-const cipher_suites = enum_array(tls.CipherSuite, &.{
-    .AEGIS_128L_SHA256,
-    .AEGIS_256_SHA384,
-    .AES_128_GCM_SHA256,
-    .AES_256_GCM_SHA384,
-    .CHACHA20_POLY1305_SHA256,
-});
+const cipher_suites = if (crypto.core.aes.has_hardware_support)
+    enum_array(tls.CipherSuite, &.{
+        .AEGIS_128L_SHA256,
+        .AEGIS_256_SHA384,
+        .AES_128_GCM_SHA256,
+        .AES_256_GCM_SHA384,
+        .CHACHA20_POLY1305_SHA256,
+    })
+else
+    enum_array(tls.CipherSuite, &.{
+        .CHACHA20_POLY1305_SHA256,
+        .AEGIS_128L_SHA256,
+        .AEGIS_256_SHA384,
+        .AES_128_GCM_SHA256,
+        .AES_256_GCM_SHA384,
+    });
 
 test {
     _ = StreamInterface;
lib/std/crypto/aes.zig
@@ -14,6 +14,12 @@ impl: {
     break :impl @import("aes/soft.zig");
 };
 
+/// `true` if AES is backed by hardware (AES-NI on x86_64, ARM Crypto Extensions on AArch64).
+/// Software implementations are much slower, and should be avoided if possible.
+pub const has_hardware_support =
+    (builtin.cpu.arch == .x86_64 and has_aesni and has_avx) or
+    (builtin.cpu.arch == .aarch64 and has_armaes);
+
 pub const Block = impl.Block;
 pub const AesEncryptCtx = impl.AesEncryptCtx;
 pub const AesDecryptCtx = impl.AesDecryptCtx;