forked from quic-go/quic-go
update the ChaCha implementation, remove 0xffffffff workaround
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package handshake
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
@@ -79,6 +80,24 @@ var _ = Describe("Long Header AEAD", func() {
|
||||
Expect(lastFourBitsDifferent).To(BeNumerically(">", 75))
|
||||
})
|
||||
|
||||
It("encrypts and encrypts the header, for a 0xfff..fff sample", func() {
|
||||
sealer, opener := getSealerAndOpener()
|
||||
var lastFourBitsDifferent int
|
||||
for i := 0; i < 100; i++ {
|
||||
sample := bytes.Repeat([]byte{0xff}, 16)
|
||||
header := []byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef}
|
||||
sealer.EncryptHeader(sample, &header[0], header[9:13])
|
||||
if header[0]&0xf != 0xb5&0xf {
|
||||
lastFourBitsDifferent++
|
||||
}
|
||||
Expect(header[0] & 0xf0).To(Equal(byte(0xb5 & 0xf0)))
|
||||
Expect(header[1:9]).To(Equal([]byte{1, 2, 3, 4, 5, 6, 7, 8}))
|
||||
Expect(header[9:13]).ToNot(Equal([]byte{0xde, 0xad, 0xbe, 0xef}))
|
||||
opener.DecryptHeader(sample, &header[0], header[9:13])
|
||||
Expect(header).To(Equal([]byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef}))
|
||||
}
|
||||
})
|
||||
|
||||
It("fails to decrypt the header when using a different sample", func() {
|
||||
sealer, opener := getSealerAndOpener()
|
||||
header := []byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef}
|
||||
|
||||
@@ -3,7 +3,6 @@ package handshake
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
@@ -93,27 +92,10 @@ func newChaChaHeaderProtector(suite *qtls.CipherSuiteTLS13, trafficSecret []byte
|
||||
}
|
||||
|
||||
func (p *chachaHeaderProtector) DecryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {
|
||||
// Workaround for https://github.com/lucas-clemente/quic-go/issues/2326.
|
||||
// The ChaCha20 implementation panics when the nonce is 0xffffffff.
|
||||
// Don't apply header protection in that case.
|
||||
// The packet will end up undecryptable, but it only applies to 1 in 2^32 packets.
|
||||
if sample[0] == 0xff && sample[1] == 0xff && sample[2] == 0xff && sample[3] == 0xff {
|
||||
return
|
||||
}
|
||||
p.apply(sample, firstByte, hdrBytes)
|
||||
}
|
||||
|
||||
func (p *chachaHeaderProtector) EncryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {
|
||||
// Workaround for https://github.com/lucas-clemente/quic-go/issues/2326.
|
||||
// The ChaCha20 implementation panics when the nonce is 0xffffffff.
|
||||
// Apply header protection with a random mask, in order to not leak any data.
|
||||
// The packet will end up undecryptable, but this only applies to 1 in 2^32 packets.
|
||||
if sample[0] == 0xff && sample[1] == 0xff && sample[2] == 0xff && sample[3] == 0xff {
|
||||
if _, err := rand.Read(p.mask[:]); err != nil {
|
||||
panic("couldn't get rand for ChaCha20 bug workaround")
|
||||
}
|
||||
p.applyMask(firstByte, hdrBytes)
|
||||
}
|
||||
p.apply(sample, firstByte, hdrBytes)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user