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 <agl@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Adam Langley 2016-11-07 10:25:57 -08:00 committed by Brad Fitzpatrick
parent 3dc6b2757e
commit 1ac9b9783b

View File

@ -7,6 +7,7 @@ package tls
import ( import (
"container/list" "container/list"
"crypto" "crypto"
"crypto/internal/cipherhw"
"crypto/rand" "crypto/rand"
"crypto/sha512" "crypto/sha512"
"crypto/x509" "crypto/x509"
@ -919,11 +920,46 @@ func defaultCipherSuites() []uint16 {
} }
func initDefaultCipherSuites() { 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)) varDefaultCipherSuites = make([]uint16, 0, len(cipherSuites))
for _, topCipher := range topCipherSuites {
varDefaultCipherSuites = append(varDefaultCipherSuites, topCipher)
}
NextCipherSuite:
for _, suite := range cipherSuites { for _, suite := range cipherSuites {
if suite.flags&suiteDefaultOff != 0 { if suite.flags&suiteDefaultOff != 0 {
continue continue
} }
for _, existing := range varDefaultCipherSuites {
if existing == suite.id {
continue NextCipherSuite
}
}
varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id) varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id)
} }
} }