forked from quic-go/quic-go
Merge pull request #2467 from lucas-clemente/optimize-initial-aead-creation
optimize initialization of the Initial AEAD
This commit is contained in:
@@ -38,7 +38,7 @@ type aesHeaderProtector struct {
|
|||||||
var _ headerProtector = &aesHeaderProtector{}
|
var _ headerProtector = &aesHeaderProtector{}
|
||||||
|
|
||||||
func newAESHeaderProtector(suite *qtls.CipherSuiteTLS13, trafficSecret []byte, isLongHeader bool) headerProtector {
|
func newAESHeaderProtector(suite *qtls.CipherSuiteTLS13, trafficSecret []byte, isLongHeader bool) headerProtector {
|
||||||
hpKey := qtls.HkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, "quic hp", suite.KeyLen)
|
hpKey := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, "quic hp", suite.KeyLen)
|
||||||
block, err := aes.NewCipher(hpKey)
|
block, err := aes.NewCipher(hpKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("error creating new AES cipher: %s", err))
|
panic(fmt.Sprintf("error creating new AES cipher: %s", err))
|
||||||
@@ -83,7 +83,7 @@ type chachaHeaderProtector struct {
|
|||||||
var _ headerProtector = &chachaHeaderProtector{}
|
var _ headerProtector = &chachaHeaderProtector{}
|
||||||
|
|
||||||
func newChaChaHeaderProtector(suite *qtls.CipherSuiteTLS13, trafficSecret []byte, isLongHeader bool) headerProtector {
|
func newChaChaHeaderProtector(suite *qtls.CipherSuiteTLS13, trafficSecret []byte, isLongHeader bool) headerProtector {
|
||||||
hpKey := qtls.HkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, "quic hp", suite.KeyLen)
|
hpKey := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, "quic hp", suite.KeyLen)
|
||||||
|
|
||||||
p := &chachaHeaderProtector{
|
p := &chachaHeaderProtector{
|
||||||
isLongHeader: isLongHeader,
|
isLongHeader: isLongHeader,
|
||||||
|
|||||||
29
internal/handshake/hkdf.go
Normal file
29
internal/handshake/hkdf.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package handshake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/hkdf"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hkdfExpandLabel HKDF expands a label.
|
||||||
|
// Since this implementation avoids using a cryptobyte.Builder, it is about 15% faster than the
|
||||||
|
// hkdfExpandLabel in the standard library.
|
||||||
|
func hkdfExpandLabel(hash crypto.Hash, secret, context []byte, label string, length int) []byte {
|
||||||
|
b := make([]byte, 3, 3+6+len(label)+1+len(context))
|
||||||
|
binary.BigEndian.PutUint16(b, uint16(length))
|
||||||
|
b[2] = uint8(6 + len(label))
|
||||||
|
b = append(b, []byte("tls13 ")...)
|
||||||
|
b = append(b, []byte(label)...)
|
||||||
|
b = b[:3+6+len(label)+1]
|
||||||
|
b[3+6+len(label)] = uint8(len(context))
|
||||||
|
b = append(b, context...)
|
||||||
|
|
||||||
|
out := make([]byte, length)
|
||||||
|
n, err := hkdf.Expand(hash.New, secret, b).Read(out)
|
||||||
|
if err != nil || n != length {
|
||||||
|
panic("quic: HKDF-Expand-Label invocation failed unexpectedly")
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
31
internal/handshake/hkdf_test.go
Normal file
31
internal/handshake/hkdf_test.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package handshake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/rand"
|
||||||
|
mrand "math/rand"
|
||||||
|
|
||||||
|
"github.com/marten-seemann/qtls"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Initial AEAD using AES-GCM", func() {
|
||||||
|
It("gets the same results as qtls", func() {
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
secret := make([]byte, 32)
|
||||||
|
rand.Read(secret)
|
||||||
|
context := make([]byte, mrand.Intn(100))
|
||||||
|
rand.Read(context)
|
||||||
|
labelB := make([]byte, mrand.Intn(100))
|
||||||
|
rand.Read(labelB)
|
||||||
|
label := string(labelB)
|
||||||
|
length := mrand.Intn(100)
|
||||||
|
|
||||||
|
expanded := hkdfExpandLabel(crypto.SHA256, secret, context, label, length)
|
||||||
|
expandedQTLS := qtls.HkdfExpandLabel(crypto.SHA256, secret, context, label, length)
|
||||||
|
Expect(expanded).To(Equal(expandedQTLS))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -39,13 +39,13 @@ func NewInitialAEAD(connID protocol.ConnectionID, pers protocol.Perspective) (Lo
|
|||||||
|
|
||||||
func computeSecrets(connID protocol.ConnectionID) (clientSecret, serverSecret []byte) {
|
func computeSecrets(connID protocol.ConnectionID) (clientSecret, serverSecret []byte) {
|
||||||
initialSecret := qtls.HkdfExtract(crypto.SHA256, connID, quicVersion1Salt)
|
initialSecret := qtls.HkdfExtract(crypto.SHA256, connID, quicVersion1Salt)
|
||||||
clientSecret = qtls.HkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "client in", crypto.SHA256.Size())
|
clientSecret = hkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "client in", crypto.SHA256.Size())
|
||||||
serverSecret = qtls.HkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "server in", crypto.SHA256.Size())
|
serverSecret = hkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "server in", crypto.SHA256.Size())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeInitialKeyAndIV(secret []byte) (key, iv []byte) {
|
func computeInitialKeyAndIV(secret []byte) (key, iv []byte) {
|
||||||
key = qtls.HkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic key", 16)
|
key = hkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic key", 16)
|
||||||
iv = qtls.HkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic iv", 12)
|
iv = hkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic iv", 12)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user