From d61ac0db8c62f706ea65b70d2772cbb8c4efb416 Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Wed, 22 Mar 2023 17:58:24 +0100 Subject: [PATCH] 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. --- lib/std/crypto/aes.zig | 6 ++++++ lib/std/crypto/tls/Client.zig | 23 ++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/std/crypto/aes.zig b/lib/std/crypto/aes.zig index e2efa5bb90..f5d96a5fe8 100644 --- a/lib/std/crypto/aes.zig +++ b/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; diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig index 2b62d592ba..7c97a2ead0 100644 --- a/lib/std/crypto/tls/Client.zig +++ b/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;