From 1ac9b9783b7ae184a5022ab0a09267593cc7f4b4 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Mon, 7 Nov 2016 10:25:57 -0800 Subject: [PATCH] crypto/{cipher,tls,internal/cryptohw}: prioritise AES-GCM when hardware support is present. Support for ChaCha20-Poly1305 ciphers was recently added to crypto/tls. These ciphers are preferable in software, but they cannot beat hardware support for AES-GCM, if present. This change moves detection for hardware AES-GCM support into cipher/internal/cipherhw so that it can be used from crypto/tls. Then, when AES-GCM hardware is present, the AES-GCM cipher suites are prioritised by default in crypto/tls. (Some servers, such as Google, respect the client's preference between AES-GCM and ChaCha20-Poly1305.) Fixes #17779. Change-Id: I50de2be486f0b0b8052c4628d3e3205a1d54a646 Reviewed-on: https://go-review.googlesource.com/32871 Run-TryBot: Adam Langley Reviewed-by: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- common.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/common.go b/common.go index 5b2c666..276d176 100644 --- a/common.go +++ b/common.go @@ -7,6 +7,7 @@ package tls import ( "container/list" "crypto" + "crypto/internal/cipherhw" "crypto/rand" "crypto/sha512" "crypto/x509" @@ -919,11 +920,46 @@ func defaultCipherSuites() []uint16 { } func initDefaultCipherSuites() { + var topCipherSuites []uint16 + if cipherhw.AESGCMSupport() { + // If AES-GCM hardware is provided then prioritise AES-GCM + // cipher suites. + topCipherSuites = []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + } + } else { + // Without AES-GCM hardware, we put the ChaCha20-Poly1305 + // cipher suites first. + topCipherSuites = []uint16{ + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + } + } + varDefaultCipherSuites = make([]uint16, 0, len(cipherSuites)) + for _, topCipher := range topCipherSuites { + varDefaultCipherSuites = append(varDefaultCipherSuites, topCipher) + } + +NextCipherSuite: for _, suite := range cipherSuites { if suite.flags&suiteDefaultOff != 0 { continue } + for _, existing := range varDefaultCipherSuites { + if existing == suite.id { + continue NextCipherSuite + } + } varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id) } }