fix nonce usage in the AEAD, use the AEAD provided by qtls for Initials

This commit is contained in:
Marten Seemann 2019-01-06 10:56:33 +07:00
parent 2cb72ad098
commit b4356d7348
6 changed files with 23 additions and 49 deletions

View file

@ -8,7 +8,6 @@ import (
)
type sealer struct {
iv []byte
aead cipher.AEAD
hpEncrypter cipher.Block
@ -22,9 +21,8 @@ type sealer struct {
var _ Sealer = &sealer{}
func newSealer(aead cipher.AEAD, iv []byte, hpEncrypter cipher.Block, is1RTT bool) Sealer {
func newSealer(aead cipher.AEAD, hpEncrypter cipher.Block, is1RTT bool) Sealer {
return &sealer{
iv: iv,
aead: aead,
nonceBuf: make([]byte, aead.NonceSize()),
is1RTT: is1RTT,
@ -35,14 +33,9 @@ func newSealer(aead cipher.AEAD, iv []byte, hpEncrypter cipher.Block, is1RTT boo
func (s *sealer) Seal(dst, src []byte, pn protocol.PacketNumber, ad []byte) []byte {
binary.BigEndian.PutUint64(s.nonceBuf[len(s.nonceBuf)-8:], uint64(pn))
for i := 0; i < len(s.nonceBuf); i++ {
s.nonceBuf[i] ^= s.iv[i]
}
sealed := s.aead.Seal(dst, s.nonceBuf, src, ad)
for i := 0; i < len(s.nonceBuf); i++ {
s.nonceBuf[i] = 0
}
return sealed
// The AEAD we're using here will be the qtls.aeadAESGCM13.
// It uses the nonce provided here and XOR it with the IV.
return s.aead.Seal(dst, s.nonceBuf, src, ad)
}
func (s *sealer) EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) {
@ -65,7 +58,6 @@ func (s *sealer) Overhead() int {
}
type opener struct {
iv []byte
aead cipher.AEAD
pnDecrypter cipher.Block
@ -79,9 +71,8 @@ type opener struct {
var _ Opener = &opener{}
func newOpener(aead cipher.AEAD, iv []byte, pnDecrypter cipher.Block, is1RTT bool) Opener {
func newOpener(aead cipher.AEAD, pnDecrypter cipher.Block, is1RTT bool) Opener {
return &opener{
iv: iv,
aead: aead,
nonceBuf: make([]byte, aead.NonceSize()),
is1RTT: is1RTT,
@ -92,14 +83,9 @@ func newOpener(aead cipher.AEAD, iv []byte, pnDecrypter cipher.Block, is1RTT boo
func (o *opener) Open(dst, src []byte, pn protocol.PacketNumber, ad []byte) ([]byte, error) {
binary.BigEndian.PutUint64(o.nonceBuf[len(o.nonceBuf)-8:], uint64(pn))
for i := 0; i < len(o.nonceBuf); i++ {
o.nonceBuf[i] ^= o.iv[i]
}
opened, err := o.aead.Open(dst, o.nonceBuf, src, ad)
for i := 0; i < len(o.nonceBuf); i++ {
o.nonceBuf[i] = 0
}
return opened, err
// The AEAD we're using here will be the qtls.aeadAESGCM13.
// It uses the nonce provided here and XOR it with the IV.
return o.aead.Open(dst, o.nonceBuf, src, ad)
}
func (o *opener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) {

View file

@ -12,19 +12,19 @@ import (
var _ = Describe("AEAD", func() {
getSealerAndOpener := func(is1RTT bool) (Sealer, Opener) {
key := make([]byte, 16)
pnKey := make([]byte, 16)
hpKey := make([]byte, 16)
rand.Read(key)
rand.Read(pnKey)
rand.Read(hpKey)
block, err := aes.NewCipher(key)
Expect(err).ToNot(HaveOccurred())
aead, err := cipher.NewGCM(block)
Expect(err).ToNot(HaveOccurred())
pnBlock, err := aes.NewCipher(pnKey)
hpBlock, err := aes.NewCipher(hpKey)
Expect(err).ToNot(HaveOccurred())
iv := make([]byte, 12)
rand.Read(iv)
return newSealer(aead, iv, pnBlock, is1RTT), newOpener(aead, iv, pnBlock, is1RTT)
return newSealer(aead, hpBlock, is1RTT), newOpener(aead, hpBlock, is1RTT)
}
Context("message encryption", func() {

View file

@ -419,7 +419,6 @@ func (h *cryptoSetup) SetReadKey(suite *qtls.CipherSuite, trafficSecret []byte)
}
opener := newOpener(
suite.AEAD(key, iv),
iv,
hpDecrypter,
h.readEncLevel == protocol.Encryption1RTT,
)
@ -449,7 +448,6 @@ func (h *cryptoSetup) SetWriteKey(suite *qtls.CipherSuite, trafficSecret []byte)
}
sealer := newSealer(
suite.AEAD(key, iv),
iv,
hpEncrypter,
h.writeEncLevel == protocol.Encryption1RTT,
)

View file

@ -3,7 +3,6 @@ package handshake
import (
"crypto"
"crypto/aes"
"crypto/cipher"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/marten-seemann/qtls"
@ -25,31 +24,17 @@ func NewInitialAEAD(connID protocol.ConnectionID, pers protocol.Perspective) (Se
myKey, myHPKey, myIV := computeInitialKeyAndIV(mySecret)
otherKey, otherHPKey, otherIV := computeInitialKeyAndIV(otherSecret)
encrypterCipher, err := aes.NewCipher(myKey)
if err != nil {
return nil, nil, err
}
encrypter, err := cipher.NewGCM(encrypterCipher)
if err != nil {
return nil, nil, err
}
encrypter := qtls.AEADAESGCM13(myKey, myIV)
hpEncrypter, err := aes.NewCipher(myHPKey)
if err != nil {
return nil, nil, err
}
decrypterCipher, err := aes.NewCipher(otherKey)
if err != nil {
return nil, nil, err
}
decrypter, err := cipher.NewGCM(decrypterCipher)
if err != nil {
return nil, nil, err
}
decrypter := qtls.AEADAESGCM13(otherKey, otherIV)
hpDecrypter, err := aes.NewCipher(otherHPKey)
if err != nil {
return nil, nil, err
}
return newSealer(encrypter, myIV, hpEncrypter, false), newOpener(decrypter, otherIV, hpDecrypter, false), nil
return newSealer(encrypter, hpEncrypter, false), newOpener(decrypter, hpDecrypter, false), nil
}
func computeSecrets(connID protocol.ConnectionID) (clientSecret, serverSecret []byte) {

View file

@ -250,6 +250,11 @@ func aeadAESGCM12(key, fixedNonce []byte) cipher.AEAD {
return ret
}
// AEADAESGCM13 creates a new AES-GCM AEAD for TLS 1.3
func AEADAESGCM13(key, fixedNonce []byte) cipher.AEAD {
return aeadAESGCM13(key, fixedNonce)
}
func aeadAESGCM13(key, fixedNonce []byte) cipher.AEAD {
aes, err := aes.NewCipher(key)
if err != nil {

6
vendor/vendor.json vendored
View file

@ -45,10 +45,10 @@
"revisionTime": "2018-11-11T22:04:28Z"
},
{
"checksumSHA1": "FDYRKDgqEto8ahW65hY3RruQLmg=",
"checksumSHA1": "dpjM/eonkDPExO4QWg4+R0wZPCs=",
"path": "github.com/marten-seemann/qtls",
"revision": "061d608f3d22ea089c4c9039e1216eea999b9341",
"revisionTime": "2018-12-25T08:07:48Z"
"revision": "26b223ad36d4436ed3eeb843041b66ac21dcee34",
"revisionTime": "2019-01-06T03:45:47Z"
},
{
"checksumSHA1": "9TPZ7plxFmlYtMEv2LLXRCEQg7c=",