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