Source file
src/crypto/tls/key_schedule.go
1
2
3
4
5 package tls
6
7 import (
8 "crypto/elliptic"
9 "crypto/hmac"
10 "errors"
11 "hash"
12 "io"
13 "math/big"
14
15 "golang.org/x/crypto/cryptobyte"
16 "golang.org/x/crypto/curve25519"
17 "golang.org/x/crypto/hkdf"
18 )
19
20
21
22
23 const (
24 resumptionBinderLabel = "res binder"
25 clientHandshakeTrafficLabel = "c hs traffic"
26 serverHandshakeTrafficLabel = "s hs traffic"
27 clientApplicationTrafficLabel = "c ap traffic"
28 serverApplicationTrafficLabel = "s ap traffic"
29 exporterLabel = "exp master"
30 resumptionLabel = "res master"
31 trafficUpdateLabel = "traffic upd"
32 )
33
34
35 func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte {
36 var hkdfLabel cryptobyte.Builder
37 hkdfLabel.AddUint16(uint16(length))
38 hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
39 b.AddBytes([]byte("tls13 "))
40 b.AddBytes([]byte(label))
41 })
42 hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
43 b.AddBytes(context)
44 })
45 out := make([]byte, length)
46 n, err := hkdf.Expand(c.hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out)
47 if err != nil || n != length {
48 panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
49 }
50 return out
51 }
52
53
54 func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte {
55 if transcript == nil {
56 transcript = c.hash.New()
57 }
58 return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size())
59 }
60
61
62 func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte {
63 if newSecret == nil {
64 newSecret = make([]byte, c.hash.Size())
65 }
66 return hkdf.Extract(c.hash.New, newSecret, currentSecret)
67 }
68
69
70
71 func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte {
72 return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size())
73 }
74
75
76 func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) {
77 key = c.expandLabel(trafficSecret, "key", nil, c.keyLen)
78 iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength)
79 return
80 }
81
82
83
84
85 func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte {
86 finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size())
87 verifyData := hmac.New(c.hash.New, finishedKey)
88 verifyData.Write(transcript.Sum(nil))
89 return verifyData.Sum(nil)
90 }
91
92
93
94 func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) {
95 expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript)
96 return func(label string, context []byte, length int) ([]byte, error) {
97 secret := c.deriveSecret(expMasterSecret, label, nil)
98 h := c.hash.New()
99 h.Write(context)
100 return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil
101 }
102 }
103
104
105
106 type ecdheParameters interface {
107 CurveID() CurveID
108 PublicKey() []byte
109 SharedKey(peerPublicKey []byte) []byte
110 }
111
112 func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) {
113 if curveID == X25519 {
114 privateKey := make([]byte, curve25519.ScalarSize)
115 if _, err := io.ReadFull(rand, privateKey); err != nil {
116 return nil, err
117 }
118 publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint)
119 if err != nil {
120 return nil, err
121 }
122 return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil
123 }
124
125 curve, ok := curveForCurveID(curveID)
126 if !ok {
127 return nil, errors.New("tls: internal error: unsupported curve")
128 }
129
130 p := &nistParameters{curveID: curveID}
131 var err error
132 p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand)
133 if err != nil {
134 return nil, err
135 }
136 return p, nil
137 }
138
139 func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
140 switch id {
141 case CurveP256:
142 return elliptic.P256(), true
143 case CurveP384:
144 return elliptic.P384(), true
145 case CurveP521:
146 return elliptic.P521(), true
147 default:
148 return nil, false
149 }
150 }
151
152 type nistParameters struct {
153 privateKey []byte
154 x, y *big.Int
155 curveID CurveID
156 }
157
158 func (p *nistParameters) CurveID() CurveID {
159 return p.curveID
160 }
161
162 func (p *nistParameters) PublicKey() []byte {
163 curve, _ := curveForCurveID(p.curveID)
164 return elliptic.Marshal(curve, p.x, p.y)
165 }
166
167 func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte {
168 curve, _ := curveForCurveID(p.curveID)
169
170 x, y := elliptic.Unmarshal(curve, peerPublicKey)
171 if x == nil {
172 return nil
173 }
174
175 xShared, _ := curve.ScalarMult(x, y, p.privateKey)
176 sharedKey := make([]byte, (curve.Params().BitSize+7)/8)
177 return xShared.FillBytes(sharedKey)
178 }
179
180 type x25519Parameters struct {
181 privateKey []byte
182 publicKey []byte
183 }
184
185 func (p *x25519Parameters) CurveID() CurveID {
186 return X25519
187 }
188
189 func (p *x25519Parameters) PublicKey() []byte {
190 return p.publicKey[:]
191 }
192
193 func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte {
194 sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey)
195 if err != nil {
196 return nil
197 }
198 return sharedKey
199 }
200
View as plain text