• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2023 The BoringSSL Authors
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15package subprocess
16
17import (
18	"crypto/sha256"
19	"crypto/sha512"
20	"encoding/hex"
21	"encoding/json"
22	"fmt"
23)
24
25// The following structures reflect the JSON of TLS 1.3 tests. See
26// https://pages.nist.gov/ACVP/draft-hammett-acvp-kdf-tls-v1.3.html
27
28type tls13TestVectorSet struct {
29	Groups []tls13TestGroup `json:"testGroups"`
30}
31
32type tls13TestGroup struct {
33	ID       uint64      `json:"tgId"`
34	HashFunc string      `json:"hmacAlg"`
35	Tests    []tls13Test `json:"tests"`
36}
37
38type tls13Test struct {
39	ID uint64 `json:"tcId"`
40	// Although ACVP refers to these as client and server randoms, these
41	// fields are misnamed and really contain portions of the handshake
42	// transcript. Concatenated in order, they give the transcript up to
43	// the named message. In case of HelloRetryRequest, ClientHelloHex
44	// includes up to the second ClientHello.
45	ClientHelloHex    string `json:"helloClientRandom"`
46	ServerHelloHex    string `json:"helloServerRandom"`
47	ServerFinishedHex string `json:"finishedServerRandom"`
48	ClientFinishedHex string `json:"finishedClientRandom"`
49	DHEInputHex       string `json:"dhe"`
50	PSKInputHex       string `json:"psk"`
51}
52
53type tls13TestGroupResponse struct {
54	ID    uint64              `json:"tgId"`
55	Tests []tls13TestResponse `json:"tests"`
56}
57
58type tls13TestResponse struct {
59	ID                                uint64 `json:"tcId"`
60	ClientEarlyTrafficSecretHex       string `json:"clientEarlyTrafficSecret"`
61	EarlyExporterMasterSecretHex      string `json:"earlyExporterMasterSecret"`
62	ClientHandshakeTrafficSecretHex   string `json:"clientHandshakeTrafficSecret"`
63	ServerHandshakeTrafficSecretHex   string `json:"serverHandshakeTrafficSecret"`
64	ClientApplicationTrafficSecretHex string `json:"clientApplicationTrafficSecret"`
65	ServerApplicationTrafficSecretHex string `json:"serverApplicationTrafficSecret"`
66	ExporterMasterSecretHex           string `json:"exporterMasterSecret"`
67	ResumptionMasterSecretHex         string `json:"resumptionMasterSecret"`
68}
69
70type tls13 struct{}
71
72func (k *tls13) Process(vectorSet []byte, m Transactable) (any, error) {
73	var parsed tls13TestVectorSet
74	if err := json.Unmarshal(vectorSet, &parsed); err != nil {
75		return nil, err
76	}
77
78	var respGroups []tls13TestGroupResponse
79	for _, group := range parsed.Groups {
80		group := group
81		groupResp := tls13TestGroupResponse{ID: group.ID}
82
83		for _, test := range group.Tests {
84			test := test
85			testResp := tls13TestResponse{ID: test.ID}
86
87			clientHello, err := hex.DecodeString(test.ClientHelloHex)
88			if err != nil {
89				return nil, err
90			}
91			serverHello, err := hex.DecodeString(test.ServerHelloHex)
92			if err != nil {
93				return nil, err
94			}
95			serverFinished, err := hex.DecodeString(test.ServerFinishedHex)
96			if err != nil {
97				return nil, err
98			}
99			clientFinished, err := hex.DecodeString(test.ClientFinishedHex)
100			if err != nil {
101				return nil, err
102			}
103
104			// See https://www.rfc-editor.org/rfc/rfc8446#section-7.1
105			var hashLen int
106			var emptyHash []byte
107			switch group.HashFunc {
108			case "SHA2-256":
109				hashLen = 256 / 8
110				digest := sha256.Sum256(nil)
111				emptyHash = digest[:]
112			case "SHA2-384":
113				hashLen = 384 / 8
114				digest := sha512.Sum384(nil)
115				emptyHash = digest[:]
116			default:
117				return nil, fmt.Errorf("hash function %q is not supported for TLS v1.3", group.HashFunc)
118			}
119			hashLenBytes := uint32le(uint32(hashLen))
120
121			psk, err := hex.DecodeString(test.PSKInputHex)
122			if err != nil {
123				return nil, err
124			}
125			if len(psk) == 0 {
126				psk = make([]byte, hashLen)
127			}
128
129			dhe, err := hex.DecodeString(test.DHEInputHex)
130			if err != nil {
131				return nil, err
132			}
133			if len(dhe) == 0 {
134				dhe = make([]byte, hashLen)
135			}
136
137			zeros := make([]byte, hashLen)
138			earlySecret, err := m.Transact("HKDFExtract/"+group.HashFunc, 1, psk, zeros)
139			if err != nil {
140				return nil, fmt.Errorf("HKDFExtract operation failed: %s", err)
141			}
142
143			hashedToClientHello, err := m.Transact(group.HashFunc, 1, clientHello)
144			if err != nil {
145				return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err)
146			}
147			hashedToServerHello, err := m.Transact(group.HashFunc, 1, concat(clientHello, serverHello))
148			if err != nil {
149				return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err)
150			}
151			hashedToServerFinished, err := m.Transact(group.HashFunc, 1, concat(clientHello, serverHello, serverFinished))
152			if err != nil {
153				return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err)
154			}
155			hashedMessages, err := m.Transact(group.HashFunc, 1, concat(clientHello, serverHello, serverFinished, clientFinished))
156			if err != nil {
157				return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err)
158			}
159
160			clientEarlyTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, earlySecret[0], []byte("c e traffic"), hashedToClientHello[0])
161			if err != nil {
162				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
163			}
164			testResp.ClientEarlyTrafficSecretHex = hex.EncodeToString(clientEarlyTrafficSecret[0])
165
166			earlyExporter, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, earlySecret[0], []byte("e exp master"), hashedToClientHello[0])
167			if err != nil {
168				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
169			}
170			testResp.EarlyExporterMasterSecretHex = hex.EncodeToString(earlyExporter[0])
171
172			derivedSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, earlySecret[0], []byte("derived"), emptyHash[:])
173			if err != nil {
174				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
175			}
176
177			handshakeSecret, err := m.Transact("HKDFExtract/"+group.HashFunc, 1, dhe, derivedSecret[0])
178			if err != nil {
179				return nil, fmt.Errorf("HKDFExtract operation failed: %s", err)
180			}
181
182			clientHandshakeTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, handshakeSecret[0], []byte("c hs traffic"), hashedToServerHello[0])
183			if err != nil {
184				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
185			}
186			testResp.ClientHandshakeTrafficSecretHex = hex.EncodeToString(clientHandshakeTrafficSecret[0])
187
188			serverHandshakeTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, handshakeSecret[0], []byte("s hs traffic"), hashedToServerHello[0])
189			if err != nil {
190				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
191			}
192			testResp.ServerHandshakeTrafficSecretHex = hex.EncodeToString(serverHandshakeTrafficSecret[0])
193
194			derivedSecret, err = m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, handshakeSecret[0], []byte("derived"), emptyHash[:])
195			if err != nil {
196				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
197			}
198
199			masterSecret, err := m.Transact("HKDFExtract/"+group.HashFunc, 1, zeros, derivedSecret[0])
200			if err != nil {
201				return nil, fmt.Errorf("HKDFExtract operation failed: %s", err)
202			}
203
204			clientAppTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("c ap traffic"), hashedToServerFinished[0])
205			if err != nil {
206				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
207			}
208			testResp.ClientApplicationTrafficSecretHex = hex.EncodeToString(clientAppTrafficSecret[0])
209
210			serverAppTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("s ap traffic"), hashedToServerFinished[0])
211			if err != nil {
212				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
213			}
214			testResp.ServerApplicationTrafficSecretHex = hex.EncodeToString(serverAppTrafficSecret[0])
215
216			exporterSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("exp master"), hashedToServerFinished[0])
217			if err != nil {
218				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
219			}
220			testResp.ExporterMasterSecretHex = hex.EncodeToString(exporterSecret[0])
221
222			resumptionSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("res master"), hashedMessages[0])
223			if err != nil {
224				return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err)
225			}
226			testResp.ResumptionMasterSecretHex = hex.EncodeToString(resumptionSecret[0])
227
228			groupResp.Tests = append(groupResp.Tests, testResp)
229		}
230		respGroups = append(respGroups, groupResp)
231	}
232
233	return respGroups, nil
234}
235
236func concat(slices ...[]byte) []byte {
237	var ret []byte
238	for _, slice := range slices {
239		ret = append(ret, slice...)
240	}
241	return ret
242}
243