diff --git a/crypto/key_derivation.go b/crypto/key_derivation.go index cbd48775..60648d8e 100644 --- a/crypto/key_derivation.go +++ b/crypto/key_derivation.go @@ -21,15 +21,15 @@ import ( // } // DeriveKeysAESGCM derives the client and server keys and creates a matching AES-GCM AEAD instance -func DeriveKeysAESGCM(version protocol.VersionNumber, forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte) (AEAD, error) { - otherKey, myKey, otherIV, myIV, err := deriveKeys(version, forwardSecure, sharedSecret, nonces, connID, chlo, scfg, cert, divNonce, 16) +func DeriveKeysAESGCM(forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte) (AEAD, error) { + otherKey, myKey, otherIV, myIV, err := deriveKeys(forwardSecure, sharedSecret, nonces, connID, chlo, scfg, cert, divNonce, 16) if err != nil { return nil, err } return NewAEADAESGCM(otherKey, myKey, otherIV, myIV) } -func deriveKeys(version protocol.VersionNumber, forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo, scfg, cert, divNonce []byte, keyLen int) ([]byte, []byte, []byte, []byte, error) { +func deriveKeys(forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo, scfg, cert, divNonce []byte, keyLen int) ([]byte, []byte, []byte, []byte, error) { var info bytes.Buffer if forwardSecure { info.Write([]byte("QUIC forward secure key expansion\x00")) @@ -52,7 +52,7 @@ func deriveKeys(version protocol.VersionNumber, forwardSecure bool, sharedSecret otherIV := s[2*keyLen : 2*keyLen+4] myIV := s[2*keyLen+4:] - if !forwardSecure && version >= protocol.Version33 { + if !forwardSecure { if err := diversify(myKey, myIV, divNonce); err != nil { return nil, nil, nil, nil, err } diff --git a/crypto/key_derivation_test.go b/crypto/key_derivation_test.go index e3a660c7..ca6e338d 100644 --- a/crypto/key_derivation_test.go +++ b/crypto/key_derivation_test.go @@ -89,64 +89,6 @@ var _ = Describe("KeyDerivation", func() { Context("AES-GCM", func() { It("derives non-fs keys", func() { aead, err := DeriveKeysAESGCM( - protocol.Version32, - false, - []byte("0123456789012345678901"), - []byte("nonce"), - protocol.ConnectionID(42), - []byte("chlo"), - []byte("scfg"), - []byte("cert"), - nil, - ) - Expect(err).ToNot(HaveOccurred()) - chacha := aead.(*aeadAESGCM) - // If the IVs match, the keys will match too, since the keys are read earlier - Expect(chacha.myIV).To(Equal([]byte{0x28, 0x71, 0x71, 0x16})) - Expect(chacha.otherIV).To(Equal([]byte{0x64, 0xef, 0x3c, 0x9})) - }) - - It("derives fs keys", func() { - aead, err := DeriveKeysAESGCM( - protocol.Version32, - true, - []byte("0123456789012345678901"), - []byte("nonce"), - protocol.ConnectionID(42), - []byte("chlo"), - []byte("scfg"), - []byte("cert"), - nil, - ) - Expect(err).ToNot(HaveOccurred()) - chacha := aead.(*aeadAESGCM) - // If the IVs match, the keys will match too, since the keys are read earlier - Expect(chacha.myIV).To(Equal([]byte{0x7, 0xad, 0xab, 0xb8})) - Expect(chacha.otherIV).To(Equal([]byte{0xf2, 0x7a, 0xcc, 0x42})) - }) - - It("does not use diversification nonces in FS key derivation", func() { - aead, err := DeriveKeysAESGCM( - protocol.Version33, - true, - []byte("0123456789012345678901"), - []byte("nonce"), - protocol.ConnectionID(42), - []byte("chlo"), - []byte("scfg"), - []byte("cert"), - []byte("divnonce"), - ) - Expect(err).ToNot(HaveOccurred()) - chacha := aead.(*aeadAESGCM) - // If the IVs match, the keys will match too, since the keys are read earlier - Expect(chacha.myIV).To(Equal([]byte{0x7, 0xad, 0xab, 0xb8})) - Expect(chacha.otherIV).To(Equal([]byte{0xf2, 0x7a, 0xcc, 0x42})) - }) - - It("uses diversification nonces in initial key derivation", func() { - aead, err := DeriveKeysAESGCM( - protocol.Version33, false, []byte("0123456789012345678901"), []byte("nonce"), @@ -162,5 +104,41 @@ var _ = Describe("KeyDerivation", func() { Expect(chacha.myIV).To(Equal([]byte{0x1c, 0xec, 0xac, 0x9b})) Expect(chacha.otherIV).To(Equal([]byte{0x64, 0xef, 0x3c, 0x9})) }) + + It("derives fs keys", func() { + aead, err := DeriveKeysAESGCM( + true, + []byte("0123456789012345678901"), + []byte("nonce"), + protocol.ConnectionID(42), + []byte("chlo"), + []byte("scfg"), + []byte("cert"), + nil, + ) + Expect(err).ToNot(HaveOccurred()) + chacha := aead.(*aeadAESGCM) + // If the IVs match, the keys will match too, since the keys are read earlier + Expect(chacha.myIV).To(Equal([]byte{0x7, 0xad, 0xab, 0xb8})) + Expect(chacha.otherIV).To(Equal([]byte{0xf2, 0x7a, 0xcc, 0x42})) + }) + + It("does not use div-nonce for FS key derivation", func() { + aead, err := DeriveKeysAESGCM( + true, + []byte("0123456789012345678901"), + []byte("nonce"), + protocol.ConnectionID(42), + []byte("chlo"), + []byte("scfg"), + []byte("cert"), + []byte("divnonce"), + ) + Expect(err).ToNot(HaveOccurred()) + chacha := aead.(*aeadAESGCM) + // If the IVs match, the keys will match too, since the keys are read earlier + Expect(chacha.myIV).To(Equal([]byte{0x7, 0xad, 0xab, 0xb8})) + Expect(chacha.otherIV).To(Equal([]byte{0xf2, 0x7a, 0xcc, 0x42})) + }) }) }) diff --git a/handshake/crypto_setup.go b/handshake/crypto_setup.go index 4db8b3be..900d58c2 100644 --- a/handshake/crypto_setup.go +++ b/handshake/crypto_setup.go @@ -13,7 +13,7 @@ import ( ) // KeyDerivationFunction is used for key derivation -type KeyDerivationFunction func(version protocol.VersionNumber, forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte) (crypto.AEAD, error) +type KeyDerivationFunction func(forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte) (crypto.AEAD, error) // KeyExchangeFunction is used to make a new KEX type KeyExchangeFunction func() crypto.KeyExchange @@ -248,7 +248,6 @@ func (h *CryptoSetup) handleCHLO(sni string, data []byte, cryptoData map[Tag][]b } h.secureAEAD, err = h.keyDerivation( - h.version, false, sharedSecret, cryptoData[TagNONC], @@ -271,7 +270,7 @@ func (h *CryptoSetup) handleCHLO(sni string, data []byte, cryptoData map[Tag][]b if err != nil { return nil, err } - h.forwardSecureAEAD, err = h.keyDerivation(h.version, + h.forwardSecureAEAD, err = h.keyDerivation( true, ephermalSharedSecret, fsNonce.Bytes(), @@ -306,9 +305,6 @@ func (h *CryptoSetup) handleCHLO(sni string, data []byte, cryptoData map[Tag][]b // DiversificationNonce returns a diversification nonce if required in the next packet to be Seal'ed. See LockForSealing()! func (h *CryptoSetup) DiversificationNonce() []byte { - if h.version < protocol.Version33 { - return nil - } if h.receivedForwardSecurePacket || h.secureAEAD == nil { return nil } diff --git a/handshake/crypto_setup_test.go b/handshake/crypto_setup_test.go index e289ed11..508cc9d5 100644 --- a/handshake/crypto_setup_test.go +++ b/handshake/crypto_setup_test.go @@ -81,7 +81,7 @@ func (mockAEAD) DiversificationNonce() []byte { return nil } var expectedInitialNonceLen int var expectedFSNonceLen int -func mockKeyDerivation(v protocol.VersionNumber, forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte) (crypto.AEAD, error) { +func mockKeyDerivation(forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte) (crypto.AEAD, error) { if forwardSecure { Expect(nonces).To(HaveLen(expectedFSNonceLen)) } else { @@ -183,11 +183,6 @@ var _ = Describe("Crypto setup", func() { Expect(cs.DiversificationNonce()).To(HaveLen(32)) }) - It("does not return nonce for version < 33", func() { - cs.version = protocol.Version32 - Expect(cs.DiversificationNonce()).To(BeEmpty()) - }) - It("does not return nonce for FS packets", func() { cs.receivedForwardSecurePacket = true Expect(cs.DiversificationNonce()).To(BeEmpty())