add diversification to AEADs and conditionally include in public header

ref #51
This commit is contained in:
Lucas Clemente
2016-05-20 23:39:52 +02:00
parent c6a9e7e575
commit 2606b891e2
6 changed files with 56 additions and 4 deletions

View File

@@ -6,4 +6,5 @@ import "github.com/lucas-clemente/quic-go/protocol"
type AEAD interface {
Open(packetNumber protocol.PacketNumber, associatedData []byte, ciphertext []byte) ([]byte, error)
Seal(packetNumber protocol.PacketNumber, associatedData []byte, plaintext []byte) []byte
DiversificationNonce() []byte
}

View File

@@ -56,3 +56,5 @@ func makeNonce(iv []byte, packetNumber protocol.PacketNumber) []byte {
binary.LittleEndian.PutUint64(res[4:12], uint64(packetNumber))
return res
}
func (aeadChacha20Poly1305) DiversificationNonce() []byte { return nil }

View File

@@ -47,3 +47,5 @@ func (*NullAEAD) Seal(packetNumber protocol.PacketNumber, associatedData []byte,
copy(res[12:], plaintext)
return res
}
func (NullAEAD) DiversificationNonce() []byte { return nil }

View File

@@ -24,6 +24,7 @@ type CryptoSetup struct {
version protocol.VersionNumber
scfg *ServerConfig
nonce []byte
diversificationNonce []byte
secureAEAD crypto.AEAD
forwardSecureAEAD crypto.AEAD
@@ -49,11 +50,16 @@ func NewCryptoSetup(connID protocol.ConnectionID, version protocol.VersionNumber
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
diversificationNonce := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, diversificationNonce); err != nil {
return nil, err
}
return &CryptoSetup{
connID: connID,
version: version,
scfg: scfg,
nonce: nonce,
diversificationNonce: diversificationNonce,
keyDerivation: crypto.DeriveKeysChacha20,
keyExchange: crypto.NewCurve25519KEX,
cryptoStream: cryptoStream,
@@ -249,3 +255,14 @@ func (h *CryptoSetup) handleCHLO(sni string, data []byte, cryptoData map[Tag][]b
return reply.Bytes(), nil
}
// DiversificationNonce returns a diversification nonce if required in the next packet to be Seal'ed
func (h *CryptoSetup) DiversificationNonce() []byte {
if h.version < protocol.VersionNumber(33) {
return nil
}
if h.receivedForwardSecurePacket || h.secureAEAD == nil {
return nil
}
return h.diversificationNonce
}

View File

@@ -67,6 +67,8 @@ func (m *mockAEAD) Open(packetNumber protocol.PacketNumber, associatedData []byt
return nil, errors.New("authentication failed")
}
func (mockAEAD) DiversificationNonce() []byte { return nil }
var expectedInitialNonceLen int
var expectedFSNonceLen int
@@ -140,6 +142,33 @@ var _ = Describe("Crypto setup", func() {
Expect(s).ToNot(BeZero())
})
Context("diversification nonce", func() {
BeforeEach(func() {
cs.version = 33
cs.secureAEAD = &mockAEAD{}
cs.receivedForwardSecurePacket = false
})
It("returns diversification nonces", func() {
Expect(cs.DiversificationNonce()).To(HaveLen(32))
})
It("does not return nonce for version < 33", func() {
cs.version = 32
Expect(cs.DiversificationNonce()).To(BeEmpty())
})
It("does not return nonce for FS packets", func() {
cs.receivedForwardSecurePacket = true
Expect(cs.DiversificationNonce()).To(BeEmpty())
})
It("does not return nonce for unencrypted packets", func() {
cs.secureAEAD = nil
Expect(cs.DiversificationNonce()).To(BeEmpty())
})
})
Context("when responding to client messages", func() {
It("generates REJ messages", func() {
response, err := cs.handleInchoateCHLO("", bytes.Repeat([]byte{'a'}, protocol.ClientHelloMinimumSize), nil)

View File

@@ -94,6 +94,7 @@ func (p *packetPacker) packPacket(stopWaitingFrame *frames.StopWaitingFrame, con
PacketNumber: currentPacketNumber,
PacketNumberLen: packetNumberLen,
TruncateConnectionID: p.connectionParametersManager.TruncateConnectionID(),
DiversificationNonce: p.aead.DiversificationNonce(),
}
publicHeaderLength, err := responsePublicHeader.GetLength()