ssh: ignore MAC if AEAD ciphers negotiated
If the server/client cipher chosen is one of the two AEAD ciphers that we support (aes128-gcm@openssh.com and chacha20-poly1305@openssh.com), don't attempt to find a common MAC algorithm in findAgreedAlgorithms. Similarly in newPacketCipher, don't attempt to generate a MAC key if we are using a AEAD cipher. Fixes golang/go#51406 Change-Id: Id48ae72f052cb0a0c597b32e9901a0f218e4161f Reviewed-on: https://go-review.googlesource.com/c/crypto/+/389214 Trust: Roland Shoemaker <roland@golang.org> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
committed by
Filippo Valsorda
parent
efcb8507fb
commit
6068a2e6cf
+15
-6
@@ -152,6 +152,11 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
|
|||||||
return 1 << 30
|
return 1 << 30
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var aeadCiphers = map[string]bool{
|
||||||
|
gcmCipherID: true,
|
||||||
|
chacha20Poly1305ID: true,
|
||||||
|
}
|
||||||
|
|
||||||
type algorithms struct {
|
type algorithms struct {
|
||||||
kex string
|
kex string
|
||||||
hostKey string
|
hostKey string
|
||||||
@@ -187,14 +192,18 @@ func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMs
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
|
if !aeadCiphers[ctos.Cipher] {
|
||||||
if err != nil {
|
ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
|
||||||
return
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
|
if !aeadCiphers[stoc.Cipher] {
|
||||||
if err != nil {
|
stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
|
||||||
return
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
|
ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
|
||||||
|
|||||||
@@ -560,3 +560,26 @@ func TestHandshakeRekeyDefault(t *testing.T) {
|
|||||||
t.Errorf("got rekey after %dG write, want 64G", wgb)
|
t.Errorf("got rekey after %dG write, want 64G", wgb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandshakeAEADCipherNoMAC(t *testing.T) {
|
||||||
|
for _, cipher := range []string{chacha20Poly1305ID, gcmCipherID} {
|
||||||
|
checker := &syncChecker{
|
||||||
|
called: make(chan int, 1),
|
||||||
|
}
|
||||||
|
clientConf := &ClientConfig{
|
||||||
|
Config: Config{
|
||||||
|
Ciphers: []string{cipher},
|
||||||
|
MACs: []string{},
|
||||||
|
},
|
||||||
|
HostKeyCallback: checker.Check,
|
||||||
|
}
|
||||||
|
trC, trS, err := handshakePair(clientConf, "addr", false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("handshakePair: %v", err)
|
||||||
|
}
|
||||||
|
defer trC.Close()
|
||||||
|
defer trS.Close()
|
||||||
|
|
||||||
|
<-checker.called
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+7
-3
@@ -238,15 +238,19 @@ var (
|
|||||||
// (to setup server->client keys) or clientKeys (for client->server keys).
|
// (to setup server->client keys) or clientKeys (for client->server keys).
|
||||||
func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
|
func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
|
||||||
cipherMode := cipherModes[algs.Cipher]
|
cipherMode := cipherModes[algs.Cipher]
|
||||||
macMode := macModes[algs.MAC]
|
|
||||||
|
|
||||||
iv := make([]byte, cipherMode.ivSize)
|
iv := make([]byte, cipherMode.ivSize)
|
||||||
key := make([]byte, cipherMode.keySize)
|
key := make([]byte, cipherMode.keySize)
|
||||||
macKey := make([]byte, macMode.keySize)
|
|
||||||
|
|
||||||
generateKeyMaterial(iv, d.ivTag, kex)
|
generateKeyMaterial(iv, d.ivTag, kex)
|
||||||
generateKeyMaterial(key, d.keyTag, kex)
|
generateKeyMaterial(key, d.keyTag, kex)
|
||||||
generateKeyMaterial(macKey, d.macKeyTag, kex)
|
|
||||||
|
var macKey []byte
|
||||||
|
if !aeadCiphers[algs.Cipher] {
|
||||||
|
macMode := macModes[algs.MAC]
|
||||||
|
macKey = make([]byte, macMode.keySize)
|
||||||
|
generateKeyMaterial(macKey, d.macKeyTag, kex)
|
||||||
|
}
|
||||||
|
|
||||||
return cipherModes[algs.Cipher].create(key, iv, macKey, algs)
|
return cipherModes[algs.Cipher].create(key, iv, macKey, algs)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user