mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
tls: Prefer ChaCha20 if AES-NI instruction set is unavailable (#1675)
Fixes #1674
This commit is contained in:
parent
8d3f336971
commit
b0cf3f0d2d
3 changed files with 52 additions and 18 deletions
|
@ -9,6 +9,7 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/codahale/aesnicheck"
|
||||
"github.com/mholt/caddy"
|
||||
"github.com/xenolf/lego/acme"
|
||||
)
|
||||
|
@ -294,7 +295,7 @@ func (c *Config) buildStandardTLSConfig() error {
|
|||
|
||||
// default cipher suites
|
||||
if len(config.CipherSuites) == 0 {
|
||||
config.CipherSuites = defaultCiphers
|
||||
config.CipherSuites = getPreferredDefaultCiphers()
|
||||
}
|
||||
|
||||
// for security, ensure TLS_FALLBACK_SCSV is always included first
|
||||
|
@ -380,7 +381,7 @@ func RegisterConfigGetter(serverType string, fn ConfigGetter) {
|
|||
func SetDefaultTLSParams(config *Config) {
|
||||
// If no ciphers provided, use default list
|
||||
if len(config.Ciphers) == 0 {
|
||||
config.Ciphers = defaultCiphers
|
||||
config.Ciphers = getPreferredDefaultCiphers()
|
||||
}
|
||||
|
||||
// Not a cipher suite, but still important for mitigating protocol downgrade attacks
|
||||
|
@ -464,6 +465,35 @@ var defaultCiphers = []uint16{
|
|||
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
}
|
||||
|
||||
// List of ciphers we should prefer if native AESNI support is missing
|
||||
var defaultCiphersNonAESNI = []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
}
|
||||
|
||||
// getPreferredDefaultCiphers returns an appropriate cipher suite to use, depending on
|
||||
// the hardware support available for AES-NI.
|
||||
//
|
||||
// See https://github.com/mholt/caddy/issues/1674
|
||||
func getPreferredDefaultCiphers() []uint16 {
|
||||
if aesnicheck.HasAESNI() {
|
||||
return defaultCiphers
|
||||
}
|
||||
|
||||
// Return a cipher suite that prefers ChaCha20
|
||||
return defaultCiphersNonAESNI
|
||||
}
|
||||
|
||||
// Map of supported curves
|
||||
// https://golang.org/pkg/crypto/tls/#CurveID
|
||||
var supportedCurvesMap = map[string]tls.CurveID{
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/codahale/aesnicheck"
|
||||
)
|
||||
|
||||
func TestConvertTLSConfigProtocolVersions(t *testing.T) {
|
||||
|
@ -60,10 +62,11 @@ func TestConvertTLSConfigCipherSuites(t *testing.T) {
|
|||
{Enabled: true, Ciphers: nil},
|
||||
}
|
||||
|
||||
defaultCiphersExpected := getPreferredDefaultCiphers()
|
||||
expectedCiphers := [][]uint16{
|
||||
{tls.TLS_FALLBACK_SCSV, 0xc02c, 0xc030},
|
||||
{tls.TLS_FALLBACK_SCSV, 0xc012, 0xc030, 0xc00a},
|
||||
append([]uint16{tls.TLS_FALLBACK_SCSV}, defaultCiphers...),
|
||||
append([]uint16{tls.TLS_FALLBACK_SCSV}, defaultCiphersExpected...),
|
||||
}
|
||||
|
||||
for i, config := range configs {
|
||||
|
@ -79,6 +82,21 @@ func TestConvertTLSConfigCipherSuites(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetPreferredDefaultCiphers(t *testing.T) {
|
||||
expectedCiphers := defaultCiphers
|
||||
if !aesnicheck.HasAESNI() {
|
||||
expectedCiphers = defaultCiphersNonAESNI
|
||||
}
|
||||
|
||||
// Ensure ordering is correct and ciphers are what we expected.
|
||||
result := getPreferredDefaultCiphers()
|
||||
for i, actual := range result {
|
||||
if actual != expectedCiphers[i] {
|
||||
t.Errorf("Expected cipher in position %d to be %0x, got %0x", i, expectedCiphers[i], actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStorageForNoURL(t *testing.T) {
|
||||
c := &Config{}
|
||||
if _, err := c.StorageFor(""); err == nil {
|
||||
|
|
|
@ -58,21 +58,7 @@ func TestSetupParseBasic(t *testing.T) {
|
|||
}
|
||||
|
||||
// Cipher checks
|
||||
expectedCiphers := []uint16{
|
||||
tls.TLS_FALLBACK_SCSV,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
}
|
||||
expectedCiphers := append([]uint16{tls.TLS_FALLBACK_SCSV}, getPreferredDefaultCiphers()...)
|
||||
|
||||
// Ensure count is correct (plus one for TLS_FALLBACK_SCSV)
|
||||
if len(cfg.Ciphers) != len(expectedCiphers) {
|
||||
|
|
Loading…
Reference in a new issue