Source file
src/crypto/tls/key_schedule.go
1
2
3
4
5 package tls
6
7 import (
8 "crypto"
9 "crypto/ecdh"
10 "crypto/hmac"
11 "crypto/internal/fips140/tls13"
12 "crypto/mlkem"
13 "errors"
14 "hash"
15 "io"
16 )
17
18
19
20
21
22
23 func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte {
24 return tls13.ExpandLabel(c.hash.New, trafficSecret, "traffic upd", nil, c.hash.Size())
25 }
26
27
28 func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) {
29 key = tls13.ExpandLabel(c.hash.New, trafficSecret, "key", nil, c.keyLen)
30 iv = tls13.ExpandLabel(c.hash.New, trafficSecret, "iv", nil, aeadNonceLength)
31 return
32 }
33
34
35
36
37 func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte {
38 finishedKey := tls13.ExpandLabel(c.hash.New, baseKey, "finished", nil, c.hash.Size())
39 verifyData := hmac.New(c.hash.New, finishedKey)
40 verifyData.Write(transcript.Sum(nil))
41 return verifyData.Sum(nil)
42 }
43
44
45
46 func (c *cipherSuiteTLS13) exportKeyingMaterial(s *tls13.MasterSecret, transcript hash.Hash) func(string, []byte, int) ([]byte, error) {
47 expMasterSecret := s.ExporterMasterSecret(transcript)
48 return func(label string, context []byte, length int) ([]byte, error) {
49 return expMasterSecret.Exporter(label, context, length), nil
50 }
51 }
52
53 type keySharePrivateKeys struct {
54 ecdhe *ecdh.PrivateKey
55 mlkem crypto.Decapsulator
56 }
57
58
59 type keyExchange interface {
60
61
62
63
64
65 keyShares(rand io.Reader) (*keySharePrivateKeys, []keyShare, error)
66
67
68 serverSharedSecret(rand io.Reader, clientKeyShare []byte) ([]byte, keyShare, error)
69
70
71
72 clientSharedSecret(priv *keySharePrivateKeys, serverKeyShare []byte) ([]byte, error)
73 }
74
75 func keyExchangeForCurveID(id CurveID) (keyExchange, error) {
76 newMLKEMPrivateKey768 := func(b []byte) (crypto.Decapsulator, error) {
77 return mlkem.NewDecapsulationKey768(b)
78 }
79 newMLKEMPrivateKey1024 := func(b []byte) (crypto.Decapsulator, error) {
80 return mlkem.NewDecapsulationKey1024(b)
81 }
82 newMLKEMPublicKey768 := func(b []byte) (crypto.Encapsulator, error) {
83 return mlkem.NewEncapsulationKey768(b)
84 }
85 newMLKEMPublicKey1024 := func(b []byte) (crypto.Encapsulator, error) {
86 return mlkem.NewEncapsulationKey1024(b)
87 }
88 switch id {
89 case X25519:
90 return &ecdhKeyExchange{id, ecdh.X25519()}, nil
91 case CurveP256:
92 return &ecdhKeyExchange{id, ecdh.P256()}, nil
93 case CurveP384:
94 return &ecdhKeyExchange{id, ecdh.P384()}, nil
95 case CurveP521:
96 return &ecdhKeyExchange{id, ecdh.P521()}, nil
97 case X25519MLKEM768:
98 return &hybridKeyExchange{id, ecdhKeyExchange{X25519, ecdh.X25519()},
99 32, mlkem.EncapsulationKeySize768, mlkem.CiphertextSize768,
100 newMLKEMPrivateKey768, newMLKEMPublicKey768}, nil
101 case SecP256r1MLKEM768:
102 return &hybridKeyExchange{id, ecdhKeyExchange{CurveP256, ecdh.P256()},
103 65, mlkem.EncapsulationKeySize768, mlkem.CiphertextSize768,
104 newMLKEMPrivateKey768, newMLKEMPublicKey768}, nil
105 case SecP384r1MLKEM1024:
106 return &hybridKeyExchange{id, ecdhKeyExchange{CurveP384, ecdh.P384()},
107 97, mlkem.EncapsulationKeySize1024, mlkem.CiphertextSize1024,
108 newMLKEMPrivateKey1024, newMLKEMPublicKey1024}, nil
109 default:
110 return nil, errors.New("tls: unsupported key exchange")
111 }
112 }
113
114 type ecdhKeyExchange struct {
115 id CurveID
116 curve ecdh.Curve
117 }
118
119 func (ke *ecdhKeyExchange) keyShares(rand io.Reader) (*keySharePrivateKeys, []keyShare, error) {
120 priv, err := ke.curve.GenerateKey(rand)
121 if err != nil {
122 return nil, nil, err
123 }
124 return &keySharePrivateKeys{ecdhe: priv}, []keyShare{{ke.id, priv.PublicKey().Bytes()}}, nil
125 }
126
127 func (ke *ecdhKeyExchange) serverSharedSecret(rand io.Reader, clientKeyShare []byte) ([]byte, keyShare, error) {
128 key, err := ke.curve.GenerateKey(rand)
129 if err != nil {
130 return nil, keyShare{}, err
131 }
132 peerKey, err := ke.curve.NewPublicKey(clientKeyShare)
133 if err != nil {
134 return nil, keyShare{}, err
135 }
136 sharedKey, err := key.ECDH(peerKey)
137 if err != nil {
138 return nil, keyShare{}, err
139 }
140 return sharedKey, keyShare{ke.id, key.PublicKey().Bytes()}, nil
141 }
142
143 func (ke *ecdhKeyExchange) clientSharedSecret(priv *keySharePrivateKeys, serverKeyShare []byte) ([]byte, error) {
144 peerKey, err := ke.curve.NewPublicKey(serverKeyShare)
145 if err != nil {
146 return nil, err
147 }
148 sharedKey, err := priv.ecdhe.ECDH(peerKey)
149 if err != nil {
150 return nil, err
151 }
152 return sharedKey, nil
153 }
154
155 type hybridKeyExchange struct {
156 id CurveID
157 ecdh ecdhKeyExchange
158
159 ecdhElementSize int
160 mlkemPublicKeySize int
161 mlkemCiphertextSize int
162
163 newMLKEMPrivateKey func([]byte) (crypto.Decapsulator, error)
164 newMLKEMPublicKey func([]byte) (crypto.Encapsulator, error)
165 }
166
167 func (ke *hybridKeyExchange) keyShares(rand io.Reader) (*keySharePrivateKeys, []keyShare, error) {
168 priv, ecdhShares, err := ke.ecdh.keyShares(rand)
169 if err != nil {
170 return nil, nil, err
171 }
172 seed := make([]byte, mlkem.SeedSize)
173 if _, err := io.ReadFull(rand, seed); err != nil {
174 return nil, nil, err
175 }
176 priv.mlkem, err = ke.newMLKEMPrivateKey(seed)
177 if err != nil {
178 return nil, nil, err
179 }
180 var shareData []byte
181
182
183
184 if ke.id == X25519MLKEM768 {
185 shareData = append(priv.mlkem.Encapsulator().Bytes(), ecdhShares[0].data...)
186 } else {
187 shareData = append(ecdhShares[0].data, priv.mlkem.Encapsulator().Bytes()...)
188 }
189 return priv, []keyShare{{ke.id, shareData}, ecdhShares[0]}, nil
190 }
191
192 func (ke *hybridKeyExchange) serverSharedSecret(rand io.Reader, clientKeyShare []byte) ([]byte, keyShare, error) {
193 if len(clientKeyShare) != ke.ecdhElementSize+ke.mlkemPublicKeySize {
194 return nil, keyShare{}, errors.New("tls: invalid client key share length for hybrid key exchange")
195 }
196 var ecdhShareData, mlkemShareData []byte
197 if ke.id == X25519MLKEM768 {
198 mlkemShareData = clientKeyShare[:ke.mlkemPublicKeySize]
199 ecdhShareData = clientKeyShare[ke.mlkemPublicKeySize:]
200 } else {
201 ecdhShareData = clientKeyShare[:ke.ecdhElementSize]
202 mlkemShareData = clientKeyShare[ke.ecdhElementSize:]
203 }
204 ecdhSharedSecret, ks, err := ke.ecdh.serverSharedSecret(rand, ecdhShareData)
205 if err != nil {
206 return nil, keyShare{}, err
207 }
208 mlkemPeerKey, err := ke.newMLKEMPublicKey(mlkemShareData)
209 if err != nil {
210 return nil, keyShare{}, err
211 }
212 mlkemSharedSecret, mlkemKeyShare := mlkemPeerKey.Encapsulate()
213 var sharedKey []byte
214 if ke.id == X25519MLKEM768 {
215 sharedKey = append(mlkemSharedSecret, ecdhSharedSecret...)
216 ks.data = append(mlkemKeyShare, ks.data...)
217 } else {
218 sharedKey = append(ecdhSharedSecret, mlkemSharedSecret...)
219 ks.data = append(ks.data, mlkemKeyShare...)
220 }
221 ks.group = ke.id
222 return sharedKey, ks, nil
223 }
224
225 func (ke *hybridKeyExchange) clientSharedSecret(priv *keySharePrivateKeys, serverKeyShare []byte) ([]byte, error) {
226 if len(serverKeyShare) != ke.ecdhElementSize+ke.mlkemCiphertextSize {
227 return nil, errors.New("tls: invalid server key share length for hybrid key exchange")
228 }
229 var ecdhShareData, mlkemShareData []byte
230 if ke.id == X25519MLKEM768 {
231 mlkemShareData = serverKeyShare[:ke.mlkemCiphertextSize]
232 ecdhShareData = serverKeyShare[ke.mlkemCiphertextSize:]
233 } else {
234 ecdhShareData = serverKeyShare[:ke.ecdhElementSize]
235 mlkemShareData = serverKeyShare[ke.ecdhElementSize:]
236 }
237 ecdhSharedSecret, err := ke.ecdh.clientSharedSecret(priv, ecdhShareData)
238 if err != nil {
239 return nil, err
240 }
241 mlkemSharedSecret, err := priv.mlkem.Decapsulate(mlkemShareData)
242 if err != nil {
243 return nil, err
244 }
245 var sharedKey []byte
246 if ke.id == X25519MLKEM768 {
247 sharedKey = append(mlkemSharedSecret, ecdhSharedSecret...)
248 } else {
249 sharedKey = append(ecdhSharedSecret, mlkemSharedSecret...)
250 }
251 return sharedKey, nil
252 }
253
View as plain text