1 /* $OpenBSD: exportertest.c,v 1.4 2024/03/01 03:46:54 tb Exp $ */
2 /*
3  * Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <openssl/err.h>
19 #include <openssl/ssl.h>
20 
21 #include <err.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "ssl_local.h"
26 
27 static void
hexdump(const unsigned char * buf,size_t len)28 hexdump(const unsigned char *buf, size_t len)
29 {
30 	size_t i;
31 
32 	for (i = 1; i <= len; i++)
33 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
34 
35 	fprintf(stderr, "\n");
36 }
37 
38 struct exporter_test {
39 	uint16_t tls_version;
40 	unsigned int cipher_id;
41 	const uint8_t *label;
42 	size_t label_len;
43 	const uint8_t context_value[64];
44 	size_t context_value_len;
45 	int use_context;
46 	const uint8_t client_random[SSL3_RANDOM_SIZE];
47 	const uint8_t server_random[SSL3_RANDOM_SIZE];
48 	const uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
49 	const uint8_t shared_key[64];
50 	size_t shared_key_len;
51 	const uint8_t export[64];
52 	size_t export_len;
53 	int want_error;
54 };
55 
56 static const struct exporter_test exporter_tests[] = {
57 	{
58 		/* Valid export, no context - 32 bytes. */
59 		.tls_version = TLS1_2_VERSION,
60 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
61 		.label = "EXPERIMENTAL testing",
62 		.label_len = 20,
63 		.use_context = 0,
64 		.client_random = {
65 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
66 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
67 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
68 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
69 		},
70 		.server_random = {
71 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
72 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
73 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
74 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
75 		},
76 		.master_key = {
77 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
78 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
79 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
80 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
81 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
82 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
83 		},
84 		.export = {
85 			0x14, 0x08, 0x00, 0x9e, 0x6a, 0x67, 0x75, 0x4c,
86 			0xc4, 0xf3, 0x51, 0x57, 0x2f, 0x75, 0x0b, 0xf8,
87 			0x16, 0xfa, 0x61, 0x74, 0xd2, 0x12, 0x8f, 0x78,
88 			0x77, 0xf9, 0x8a, 0x3e, 0x58, 0x70, 0xf3, 0xd8,
89 		},
90 		.export_len = 32,
91 	},
92 	{
93 		/* Valid export, no context - 32 bytes. */
94 		.tls_version = TLS1_3_VERSION,
95 		.label = "EXPERIMENTAL testing",
96 		.label_len = 20,
97 		.use_context = 0,
98 		.shared_key = {
99 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
100 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
101 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
102 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
103 		},
104 		.shared_key_len = 32,
105 		.export = {
106 			0x69, 0xf4, 0xac, 0xec, 0x80, 0x67, 0xac, 0x5c,
107 			0xa6, 0x24, 0x47, 0xb1, 0x0f, 0xc8, 0xa1, 0x13,
108 			0x3b, 0x91, 0x33, 0x82, 0x97, 0x0a, 0xc0, 0xbf,
109 			0xac, 0x6d, 0x6b, 0x34, 0x20, 0xd3, 0x3a, 0x02,
110 		},
111 		.export_len = 32,
112 	},
113 	{
114 		/* Valid export, no context - 64 bytes. */
115 		.tls_version = TLS1_2_VERSION,
116 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
117 		.label = "EXPERIMENTAL testing",
118 		.label_len = 20,
119 		.use_context = 0,
120 		.client_random = {
121 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
122 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
123 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
124 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
125 		},
126 		.server_random = {
127 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
128 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
129 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
130 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
131 		},
132 		.master_key = {
133 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
134 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
135 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
136 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
137 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
138 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
139 		},
140 		.export = {
141 			0x14, 0x08, 0x00, 0x9e, 0x6a, 0x67, 0x75, 0x4c,
142 			0xc4, 0xf3, 0x51, 0x57, 0x2f, 0x75, 0x0b, 0xf8,
143 			0x16, 0xfa, 0x61, 0x74, 0xd2, 0x12, 0x8f, 0x78,
144 			0x77, 0xf9, 0x8a, 0x3e, 0x58, 0x70, 0xf3, 0xd8,
145 			0xe8, 0xd2, 0xb7, 0xcd, 0xbc, 0x37, 0xdf, 0x16,
146 			0x12, 0xf1, 0xe8, 0xb2, 0x62, 0x79, 0x91, 0x45,
147 			0x77, 0xe0, 0x68, 0x6d, 0xd5, 0x31, 0x54, 0x55,
148 			0x22, 0x63, 0xc0, 0x36, 0x31, 0x07, 0xda, 0x33,
149 		},
150 		.export_len = 64,
151 	},
152 	{
153 		/* Valid export, no context - 64 bytes. */
154 		.tls_version = TLS1_3_VERSION,
155 		.label = "EXPERIMENTAL testing",
156 		.label_len = 20,
157 		.use_context = 0,
158 		.shared_key = {
159 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
160 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
161 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
162 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
163 		},
164 		.shared_key_len = 32,
165 		.export = {
166 			0x77, 0x15, 0xe2, 0x07, 0x65, 0x64, 0x3b, 0x14,
167 			0x38, 0xcb, 0x73, 0x93, 0xda, 0x70, 0xfa, 0x86,
168 			0x2c, 0x34, 0xcc, 0x94, 0x52, 0xc2, 0xd3, 0xb4,
169 			0x59, 0x2c, 0xc8, 0x05, 0x70, 0xfe, 0x48, 0x61,
170 			0xd3, 0xea, 0x57, 0x66, 0xa9, 0x66, 0x2f, 0x4a,
171 			0x35, 0xc9, 0x88, 0x86, 0x28, 0x52, 0xe3, 0x64,
172 			0x5e, 0xf9, 0x28, 0x53, 0x8a, 0x3a, 0x92, 0x92,
173 			0x40, 0x8c, 0x89, 0x17, 0x59, 0xd0, 0xd0, 0x82,
174 		},
175 		.export_len = 64,
176 	},
177 	{
178 		/* Valid export, zero length context - 32 bytes. */
179 		.tls_version = TLS1_2_VERSION,
180 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
181 		.label = "EXPERIMENTAL testing",
182 		.label_len = 20,
183 		.context_value_len = 0,
184 		.use_context = 1,
185 		.client_random = {
186 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
187 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
188 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
189 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
190 		},
191 		.server_random = {
192 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
193 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
194 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
195 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
196 		},
197 		.master_key = {
198 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
199 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
200 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
201 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
202 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
203 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
204 		},
205 		.export = {
206 			0xdb, 0xc9, 0xdf, 0x7c, 0x04, 0x39, 0xdd, 0x23,
207 			0xc3, 0x68, 0xdc, 0xf3, 0x04, 0xcf, 0x4c, 0x4d,
208 			0x86, 0x5b, 0xe6, 0x48, 0xc5, 0x6d, 0xe5, 0x1e,
209 			0xea, 0xc5, 0xe4, 0x00, 0x27, 0x72, 0xda, 0xb6,
210 		},
211 		.export_len = 32,
212 	},
213 	{
214 		/* Valid export, zero length context - 32 bytes. */
215 		.tls_version = TLS1_3_VERSION,
216 		.label = "EXPERIMENTAL testing",
217 		.label_len = 20,
218 		.context_value_len = 0,
219 		.use_context = 1,
220 		.shared_key = {
221 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
222 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
223 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
224 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
225 		},
226 		.shared_key_len = 32,
227 		.export = {
228 			0x69, 0xf4, 0xac, 0xec, 0x80, 0x67, 0xac, 0x5c,
229 			0xa6, 0x24, 0x47, 0xb1, 0x0f, 0xc8, 0xa1, 0x13,
230 			0x3b, 0x91, 0x33, 0x82, 0x97, 0x0a, 0xc0, 0xbf,
231 			0xac, 0x6d, 0x6b, 0x34, 0x20, 0xd3, 0x3a, 0x02,
232 		},
233 		.export_len = 32,
234 	},
235 	{
236 		/* Valid export, with context value - 32 bytes. */
237 		.tls_version = TLS1_2_VERSION,
238 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
239 		.label = "EXPERIMENTAL testing",
240 		.label_len = 20,
241 		.context_value = {
242 			0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
243 			0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
244 		},
245 		.context_value_len = 16,
246 		.use_context = 1,
247 		.client_random = {
248 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
249 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
250 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
251 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
252 		},
253 		.server_random = {
254 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
255 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
256 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
257 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
258 		},
259 		.master_key = {
260 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
261 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
262 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
263 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
264 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
265 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
266 		},
267 		.export = {
268 			0x0e, 0xb4, 0xd1, 0x3a, 0x0e, 0x24, 0xab, 0x0d,
269 			0x4c, 0x48, 0x35, 0x25, 0xf6, 0x4d, 0xa2, 0x9b,
270 			0xaa, 0x1d, 0xbc, 0x54, 0x7e, 0xb0, 0x3c, 0x4b,
271 			0x07, 0x04, 0x9c, 0x7c, 0x06, 0xa7, 0xea, 0x70,
272 		},
273 		.export_len = 32,
274 	},
275 	{
276 		/* Valid export, with context value - 32 bytes. */
277 		.tls_version = TLS1_3_VERSION,
278 		.label = "EXPERIMENTAL testing",
279 		.label_len = 20,
280 		.context_value = {
281 			0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
282 			0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
283 		},
284 		.context_value_len = 16,
285 		.use_context = 1,
286 		.shared_key = {
287 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
288 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
289 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
290 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
291 		},
292 		.shared_key_len = 32,
293 		.export = {
294 			0x34, 0xb8, 0x00, 0x6a, 0xb2, 0x62, 0xab, 0xea,
295 			0xc7, 0x2b, 0x15, 0xa0, 0x85, 0xda, 0xaa, 0xa5,
296 			0x12, 0x85, 0xbf, 0x4a, 0xa4, 0x71, 0x42, 0xc8,
297 			0xd4, 0xa6, 0x66, 0x18, 0xc6, 0xc9, 0x26, 0x6f,
298 		},
299 		.export_len = 32,
300 	},
301 	{
302 		/* Valid export, with different label - 32 bytes. */
303 		.tls_version = TLS1_2_VERSION,
304 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
305 		.label = "EXPERIMENTAL more testing",
306 		.label_len = 20,
307 		.context_value = {
308 			0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
309 			0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
310 		},
311 		.context_value_len = 16,
312 		.use_context = 1,
313 		.client_random = {
314 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
315 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
316 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
317 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
318 		},
319 		.server_random = {
320 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
321 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
322 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
323 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
324 		},
325 		.master_key = {
326 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
327 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
328 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
329 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
330 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
331 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
332 		},
333 		.export = {
334 			0xb0, 0xb6, 0x45, 0xdd, 0x30, 0x76, 0xf0, 0x57,
335 			0x22, 0x31, 0xbb, 0x8d, 0xe1, 0xf9, 0xe3, 0xed,
336 			0xae, 0x74, 0x6f, 0x40, 0x94, 0xf6, 0xc2, 0xfc,
337 			0x21, 0xff, 0xf7, 0x00, 0x86, 0x54, 0xb6, 0x06,
338 		},
339 		.export_len = 32,
340 	},
341 	{
342 		/* Valid export, with different label - 32 bytes. */
343 		.tls_version = TLS1_3_VERSION,
344 		.label = "EXPERIMENTAL more testing",
345 		.label_len = 20,
346 		.context_value = {
347 			0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
348 			0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
349 		},
350 		.context_value_len = 16,
351 		.use_context = 1,
352 		.shared_key = {
353 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
354 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
355 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
356 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
357 		},
358 		.shared_key_len = 32,
359 		.export = {
360 			0x18, 0x4e, 0x65, 0x3c, 0x91, 0x5d, 0x6a, 0xc3,
361 			0x25, 0x38, 0xbe, 0x6e, 0xca, 0x12, 0x54, 0x76,
362 			0x5a, 0x84, 0xf7, 0x19, 0x44, 0x78, 0xec, 0xc0,
363 			0x83, 0xf6, 0x22, 0xb8, 0x86, 0x31, 0xe9, 0x2e,
364 		},
365 		.export_len = 32,
366 	},
367 	{
368 		/* Invalid - illegal label. */
369 		.tls_version = TLS1_2_VERSION,
370 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
371 		.label = TLS_MD_CLIENT_FINISH_CONST,
372 		.label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE,
373 		.use_context = 0,
374 		.client_random = {
375 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
376 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
377 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
378 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
379 		},
380 		.server_random = {
381 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
382 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
383 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
384 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
385 		},
386 		.master_key = {
387 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
388 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
389 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
390 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
391 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
392 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
393 		},
394 		.export_len = 32,
395 		.want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL,
396 	},
397 	{
398 		/* Invalid - illegal label. */
399 		.tls_version = TLS1_2_VERSION,
400 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
401 		.label = TLS_MD_SERVER_FINISH_CONST,
402 		.label_len = TLS_MD_SERVER_FINISH_CONST_SIZE,
403 		.use_context = 0,
404 		.client_random = {
405 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
406 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
407 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
408 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
409 		},
410 		.server_random = {
411 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
412 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
413 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
414 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
415 		},
416 		.master_key = {
417 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
418 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
419 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
420 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
421 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
422 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
423 		},
424 		.export_len = 32,
425 		.want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL,
426 	},
427 	{
428 		/* Invalid - illegal label. */
429 		.tls_version = TLS1_2_VERSION,
430 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
431 		.label = TLS_MD_KEY_EXPANSION_CONST,
432 		.label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE,
433 		.use_context = 0,
434 		.client_random = {
435 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
436 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
437 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
438 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
439 		},
440 		.server_random = {
441 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
442 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
443 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
444 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
445 		},
446 		.master_key = {
447 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
448 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
449 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
450 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
451 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
452 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
453 		},
454 		.export_len = 32,
455 		.want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL,
456 	},
457 	{
458 		/* Invalid - illegal label. */
459 		.tls_version = TLS1_2_VERSION,
460 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
461 		.label = TLS_MD_MASTER_SECRET_CONST,
462 		.label_len = TLS_MD_MASTER_SECRET_CONST_SIZE,
463 		.use_context = 0,
464 		.client_random = {
465 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
466 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
467 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
468 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
469 		},
470 		.server_random = {
471 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
472 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
473 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
474 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
475 		},
476 		.master_key = {
477 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
478 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
479 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
480 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
481 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
482 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
483 		},
484 		.export_len = 32,
485 		.want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL,
486 	},
487 	{
488 		/* Invalid - illegal label, split over label and seed. */
489 		.tls_version = TLS1_2_VERSION,
490 		.cipher_id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
491 		.label = "master ",
492 		.label_len = 7,
493 		.use_context = 0,
494 		.client_random = {
495 			 's',  'e',  'c',  'r',  'e',  't', 0x06, 0x07,
496 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
497 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
498 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
499 		},
500 		.server_random = {
501 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
502 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
503 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
504 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
505 		},
506 		.master_key = {
507 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
508 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
509 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
510 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
511 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
512 			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
513 		},
514 		.export = {
515 			0x40, 0x70, 0xba, 0xfa, 0xba, 0x44, 0x74, 0x93,
516 			0xa2, 0x43, 0x18, 0x07, 0xa4, 0x4f, 0x3f, 0xda,
517 			0x88, 0x7b, 0x0e, 0x79, 0x70, 0xcf, 0xdb, 0x91,
518 			0xfc, 0x3f, 0x96, 0x78, 0x6b, 0x50, 0xe3, 0xa6,
519 		},
520 		.export_len = 32,
521 		.want_error = SSL_R_TLS_ILLEGAL_EXPORTER_LABEL,
522 	},
523 };
524 
525 #define N_EXPORTER_TESTS (sizeof(exporter_tests) / sizeof(exporter_tests[0]))
526 
527 static int
exporter_test(size_t test_no,const struct exporter_test * et)528 exporter_test(size_t test_no, const struct exporter_test *et)
529 {
530 	struct tls13_secret tls13_context = { .data = "", .len = 0 };
531 	struct tls13_ctx *tls13_ctx;
532 	struct tls13_secrets *tls13_secrets;
533 	SSL_SESSION *ssl_session = NULL;
534 	SSL_CTX *ssl_ctx = NULL;
535 	SSL *ssl = NULL;
536 	uint8_t export[256];
537 	unsigned char id[2];
538 	int err, ret;
539 	int failed = 1;
540 
541 	memset(export, 0, sizeof(export));
542 
543 	if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) {
544 		fprintf(stderr, "FAIL: SSL_CTX_new\n");
545 		goto failure;
546 	}
547 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
548 		fprintf(stderr, "FAIL: SSL_new\n");
549 		goto failure;
550 	}
551 	if ((ssl_session = SSL_SESSION_new()) == NULL) {
552 		fprintf(stderr, "FAIL: SSL_SESSION_new\n");
553 		goto failure;
554 	}
555 
556 	ssl_session->ssl_version = et->tls_version;
557 
558 	if (!SSL_set_session(ssl, ssl_session)) {
559 		fprintf(stderr, "FAIL: SSL_set_session\n");
560 		goto failure;
561 	}
562 
563 	memcpy(ssl_session->master_key, et->master_key,
564 	    sizeof(ssl_session->master_key));
565 	memcpy(ssl->s3->client_random, et->client_random,
566 	    sizeof(ssl->s3->client_random));
567 	memcpy(ssl->s3->server_random, et->server_random,
568 	    sizeof(ssl->s3->server_random));
569 
570 	if (et->tls_version >= TLS1_3_VERSION) {
571 		if ((tls13_ctx = tls13_ctx_new(TLS13_HS_CLIENT, ssl)) == NULL) {
572 			fprintf(stderr, "FAIL: tls13_ctx_new\n");
573 			goto failure;
574 		}
575 		ssl->tls13 = tls13_ctx;
576 
577 		if ((tls13_secrets = tls13_secrets_create(EVP_sha384(),
578 		    0)) == NULL) {
579 			fprintf(stderr, "FAIL: tls13_secrets_create\n");
580 			goto failure;
581 		}
582 		ssl->s3->hs.tls13.secrets = tls13_secrets;
583 
584 		if (!tls13_derive_early_secrets(tls13_secrets,
585 		    tls13_secrets->zeros.data, tls13_secrets->zeros.len,
586 		    &tls13_context)) {
587 			fprintf(stderr, "FAIL: tls13_derive_early_secrets\n");
588 			goto failure;
589 		}
590 		if (!tls13_derive_handshake_secrets(tls13_secrets, et->shared_key,
591 		    et->shared_key_len, &tls13_context)) {
592 			fprintf(stderr, "FAIL: tls13_derive_handshake_secrets\n");
593 			goto failure;
594 		}
595 		if (!tls13_derive_application_secrets(tls13_secrets,
596 		    &tls13_context)) {
597 			fprintf(stderr, "FAIL: tls13_derive_early_secrets\n");
598 			goto failure;
599 		}
600 
601 		tls13_ctx->handshake_completed = 1;
602 	}
603 
604 	ssl->s3->hs.state = SSL_ST_OK;
605 	ssl->s3->hs.negotiated_tls_version = et->tls_version;
606 	id[0] = (et->cipher_id >> 8) & 0xff;
607 	id[1] = et->cipher_id & 0xff;
608 	ssl->s3->hs.cipher = SSL_CIPHER_find(ssl, id);
609 
610 	ret = SSL_export_keying_material(ssl, export, et->export_len, et->label,
611 	    et->label_len, et->context_value, et->context_value_len,
612 	    et->use_context);
613 
614 	if (et->want_error != 0) {
615 		if (ret) {
616 			fprintf(stderr, "FAIL: test %zu - "
617 			    "SSL_export_keying_material() succeeded, want "
618 			    "error\n", test_no);
619 			goto failure;
620 		}
621 
622 		err = ERR_peek_error();
623 		if (ERR_GET_REASON(err) != et->want_error) {
624 			fprintf(stderr, "FAIL: %zu - got error reason %d, "
625 			    "want %d\n", test_no, ERR_GET_REASON(err),
626 			    et->want_error);
627 			goto failure;
628 		}
629 	} else {
630 		if (!ret) {
631 			fprintf(stderr, "FAIL: test %zu - "
632 			    "SSL_export_keying_material() failed\n", test_no);
633 			ERR_print_errors_fp(stderr);
634 			goto failure;
635 		}
636 
637 		if (memcmp(et->export, export, et->export_len) != 0) {
638 			fprintf(stderr, "FAIL: test %zu\n", test_no);
639 			fprintf(stderr, "Got export:\n");
640 			hexdump(export, et->export_len);
641 			fprintf(stderr, "Want export:\n");
642 			hexdump(et->export, et->export_len);
643 			goto failure;
644 		}
645 	}
646 
647 	failed = 0;
648 
649  failure:
650 	SSL_SESSION_free(ssl_session);
651 	SSL_CTX_free(ssl_ctx);
652 	SSL_free(ssl);
653 
654 	return failed;
655 }
656 
657 int
main(int argc,char ** argv)658 main(int argc, char **argv)
659 {
660 	int failed = 0;
661 	size_t i;
662 
663 	for (i = 0; i < N_EXPORTER_TESTS; i++)
664 		failed |= exporter_test(i, &exporter_tests[i]);
665 
666 	return (failed);
667 }
668