github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/internal/handshake/initial_aead.go (about) 1 package handshake 2 3 import ( 4 "crypto" 5 "crypto/tls" 6 7 "golang.org/x/crypto/hkdf" 8 9 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/protocol" 10 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/qtls" 11 ) 12 13 var ( 14 quicSaltOld = []byte{0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99} 15 quicSalt = []byte{0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a} 16 ) 17 18 func getSalt(v protocol.VersionNumber) []byte { 19 if v == protocol.Version1 { 20 return quicSalt 21 } 22 return quicSaltOld 23 } 24 25 var initialSuite = &qtls.CipherSuiteTLS13{ 26 ID: tls.TLS_AES_128_GCM_SHA256, 27 KeyLen: 16, 28 AEAD: qtls.AEADAESGCMTLS13, 29 Hash: crypto.SHA256, 30 } 31 32 // NewInitialAEAD creates a new AEAD for Initial encryption / decryption. 33 func NewInitialAEAD(connID protocol.ConnectionID, pers protocol.Perspective, v protocol.VersionNumber) (LongHeaderSealer, LongHeaderOpener) { 34 clientSecret, serverSecret := computeSecrets(connID, v) 35 var mySecret, otherSecret []byte 36 if pers == protocol.PerspectiveClient { 37 mySecret = clientSecret 38 otherSecret = serverSecret 39 } else { 40 mySecret = serverSecret 41 otherSecret = clientSecret 42 } 43 myKey, myIV := computeInitialKeyAndIV(mySecret) 44 otherKey, otherIV := computeInitialKeyAndIV(otherSecret) 45 46 encrypter := qtls.AEADAESGCMTLS13(myKey, myIV) 47 decrypter := qtls.AEADAESGCMTLS13(otherKey, otherIV) 48 49 return newLongHeaderSealer(encrypter, newHeaderProtector(initialSuite, mySecret, true)), 50 newLongHeaderOpener(decrypter, newAESHeaderProtector(initialSuite, otherSecret, true)) 51 } 52 53 func computeSecrets(connID protocol.ConnectionID, v protocol.VersionNumber) (clientSecret, serverSecret []byte) { 54 initialSecret := hkdf.Extract(crypto.SHA256.New, connID, getSalt(v)) 55 clientSecret = hkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "client in", crypto.SHA256.Size()) 56 serverSecret = hkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "server in", crypto.SHA256.Size()) 57 return 58 } 59 60 func computeInitialKeyAndIV(secret []byte) (key, iv []byte) { 61 key = hkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic key", 16) 62 iv = hkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic iv", 12) 63 return 64 }