mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
66 lines
2.1 KiB
Go
66 lines
2.1 KiB
Go
package handshake
|
|
|
|
import (
|
|
gocrypto "crypto"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
|
|
"github.com/lucas-clemente/quic-go/internal/crypto"
|
|
"github.com/lucas-clemente/quic-go/internal/protocol"
|
|
)
|
|
|
|
var quicVersion1Salt = []byte{0x9c, 0x10, 0x8f, 0x98, 0x52, 0x0a, 0x5c, 0x5c, 0x32, 0x96, 0x8e, 0x95, 0x0e, 0x8a, 0x2c, 0x5f, 0xe0, 0x6d, 0x6c, 0x38}
|
|
|
|
func newInitialAEAD(connID protocol.ConnectionID, pers protocol.Perspective) (Sealer, Opener, error) {
|
|
clientSecret, serverSecret := computeSecrets(connID)
|
|
var mySecret, otherSecret []byte
|
|
if pers == protocol.PerspectiveClient {
|
|
mySecret = clientSecret
|
|
otherSecret = serverSecret
|
|
} else {
|
|
mySecret = serverSecret
|
|
otherSecret = clientSecret
|
|
}
|
|
myKey, myPNKey, myIV := computeInitialKeyAndIV(mySecret)
|
|
otherKey, otherPNKey, 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
|
|
}
|
|
pnEncrypter, err := aes.NewCipher(myPNKey)
|
|
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
|
|
}
|
|
pnDecrypter, err := aes.NewCipher(otherPNKey)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return newSealer(encrypter, myIV, pnEncrypter, false), newOpener(decrypter, otherIV, pnDecrypter, false), nil
|
|
}
|
|
|
|
func computeSecrets(connID protocol.ConnectionID) (clientSecret, serverSecret []byte) {
|
|
initialSecret := crypto.HkdfExtract(gocrypto.SHA256, connID, quicVersion1Salt)
|
|
clientSecret = crypto.HkdfExpandLabel(gocrypto.SHA256, initialSecret, "client in", gocrypto.SHA256.Size())
|
|
serverSecret = crypto.HkdfExpandLabel(gocrypto.SHA256, initialSecret, "server in", gocrypto.SHA256.Size())
|
|
return
|
|
}
|
|
|
|
func computeInitialKeyAndIV(secret []byte) (key, pnKey, iv []byte) {
|
|
key = crypto.HkdfExpandLabel(gocrypto.SHA256, secret, "key", 16)
|
|
pnKey = crypto.HkdfExpandLabel(gocrypto.SHA256, secret, "pn", 16)
|
|
iv = crypto.HkdfExpandLabel(gocrypto.SHA256, secret, "iv", 12)
|
|
return
|
|
}
|