xref: /openbsd-src/regress/lib/libssl/record/recordtest.c (revision c0a6a244667a40f937c830ebe95ad69286382395)
1*c0a6a244Stb /* $OpenBSD: recordtest.c,v 1.5 2022/06/10 22:00:15 tb Exp $ */
2749904dfSjsing /*
3749904dfSjsing  * Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
4749904dfSjsing  *
5749904dfSjsing  * Permission to use, copy, modify, and distribute this software for any
6749904dfSjsing  * purpose with or without fee is hereby granted, provided that the above
7749904dfSjsing  * copyright notice and this permission notice appear in all copies.
8749904dfSjsing  *
9749904dfSjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10749904dfSjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11749904dfSjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12749904dfSjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13749904dfSjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14749904dfSjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15749904dfSjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16749904dfSjsing  */
17749904dfSjsing 
18749904dfSjsing #include <err.h>
19749904dfSjsing #include <string.h>
20749904dfSjsing 
21749904dfSjsing #include <openssl/ssl.h>
22749904dfSjsing 
23749904dfSjsing #include "tls13_internal.h"
24749904dfSjsing #include "tls13_record.h"
25749904dfSjsing 
26749904dfSjsing /* Valid record. */
27749904dfSjsing static uint8_t test_record_1[] = {
28749904dfSjsing 	0x16, 0x03, 0x03, 0x00, 0x7a, 0x02, 0x00, 0x00,
29749904dfSjsing 	0x76, 0x03, 0x03, 0x14, 0xae, 0x2b, 0x6d, 0x58,
30749904dfSjsing 	0xe9, 0x79, 0x9d, 0xd4, 0x90, 0x52, 0x90, 0x13,
31749904dfSjsing 	0x1c, 0x08, 0xaa, 0x3f, 0x5b, 0xfb, 0x64, 0xfe,
32749904dfSjsing 	0x9a, 0xca, 0x73, 0x6d, 0x87, 0x8d, 0x8b, 0x3b,
33749904dfSjsing 	0x70, 0x14, 0xa3, 0x20, 0xd7, 0x50, 0xa4, 0xe5,
34749904dfSjsing 	0x17, 0x42, 0x5d, 0xce, 0xe6, 0xfe, 0x1b, 0x59,
35749904dfSjsing 	0x27, 0x6b, 0xff, 0xc8, 0x40, 0xc7, 0xac, 0x16,
36749904dfSjsing 	0x32, 0xe6, 0x5b, 0xd2, 0xd9, 0xd4, 0xb5, 0x3f,
37749904dfSjsing 	0x8f, 0x74, 0x6e, 0x7d, 0x13, 0x02, 0x00, 0x00,
38749904dfSjsing 	0x2e, 0x00, 0x33, 0x00, 0x24, 0x00, 0x1d, 0x00,
39749904dfSjsing 	0x20, 0x72, 0xb0, 0xaf, 0x7f, 0xf5, 0x89, 0x0f,
40749904dfSjsing 	0xcd, 0x6e, 0x45, 0xb1, 0x51, 0xa0, 0xbd, 0x1e,
41749904dfSjsing 	0xee, 0x7e, 0xf1, 0xa5, 0xc5, 0xc6, 0x7e, 0x5f,
42749904dfSjsing 	0x6a, 0xca, 0xc9, 0xe4, 0xae, 0xb9, 0x50, 0x76,
43749904dfSjsing 	0x0a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
44749904dfSjsing };
45749904dfSjsing 
46749904dfSjsing /* Truncated record. */
47749904dfSjsing static uint8_t test_record_2[] = {
48b38431afSjsing 	0x17, 0x03, 0x03, 0x41, 0x00, 0x02, 0x00, 0x00,
49b38431afSjsing };
50b38431afSjsing 
51b38431afSjsing /* Oversized and truncated record. */
52b38431afSjsing static uint8_t test_record_3[] = {
53b38431afSjsing 	0x17, 0x03, 0x03, 0x41, 0x01, 0x02, 0x00, 0x00,
54749904dfSjsing };
55749904dfSjsing 
56749904dfSjsing static void
hexdump(const unsigned char * buf,size_t len)57749904dfSjsing hexdump(const unsigned char *buf, size_t len)
58749904dfSjsing {
59749904dfSjsing 	size_t i;
60749904dfSjsing 
61749904dfSjsing 	for (i = 1; i <= len; i++)
62749904dfSjsing 		fprintf(stderr, " 0x%02x,%s", buf[i - 1], i % 8 ? "" : "\n");
63749904dfSjsing 	if (len % 8 != 0)
64749904dfSjsing 		fprintf(stderr, "\n");
65749904dfSjsing }
66749904dfSjsing 
67749904dfSjsing struct rw_state {
68749904dfSjsing 	uint8_t *buf;
69749904dfSjsing 	size_t len;
70749904dfSjsing 	size_t offset;
71749904dfSjsing 	uint8_t eof;
72749904dfSjsing };
73749904dfSjsing 
74749904dfSjsing static ssize_t
read_cb(void * buf,size_t buflen,void * cb_arg)75749904dfSjsing read_cb(void *buf, size_t buflen, void *cb_arg)
76749904dfSjsing {
77749904dfSjsing 	struct rw_state *rs = cb_arg;
78749904dfSjsing 	ssize_t n;
79749904dfSjsing 
80749904dfSjsing 	if (rs->eof)
81749904dfSjsing 		return TLS13_IO_EOF;
82749904dfSjsing 
83749904dfSjsing 	if ((size_t)(n = buflen) > (rs->len - rs->offset))
84749904dfSjsing 		n = rs->len - rs->offset;
85749904dfSjsing 
86749904dfSjsing 	if (n == 0)
87749904dfSjsing 		return TLS13_IO_WANT_POLLIN;
88749904dfSjsing 
89749904dfSjsing 	memcpy(buf, &rs->buf[rs->offset], n);
90749904dfSjsing 	rs->offset += n;
91749904dfSjsing 
92749904dfSjsing 	return n;
93749904dfSjsing }
94749904dfSjsing 
95749904dfSjsing static ssize_t
write_cb(const void * buf,size_t buflen,void * cb_arg)96749904dfSjsing write_cb(const void *buf, size_t buflen, void *cb_arg)
97749904dfSjsing {
98749904dfSjsing 	struct rw_state *ws = cb_arg;
99749904dfSjsing 	ssize_t n;
100749904dfSjsing 
101749904dfSjsing 	if (ws->eof)
102749904dfSjsing 		return TLS13_IO_EOF;
103749904dfSjsing 
104749904dfSjsing 	if ((size_t)(n = buflen) > (ws->len - ws->offset))
105749904dfSjsing 		n = ws->len - ws->offset;
106749904dfSjsing 
107749904dfSjsing 	if (n == 0)
108749904dfSjsing 		return TLS13_IO_WANT_POLLOUT;
109749904dfSjsing 
110749904dfSjsing 	memcpy(&ws->buf[ws->offset], buf, n);
111749904dfSjsing 	ws->offset += n;
112749904dfSjsing 
113749904dfSjsing 	return n;
114749904dfSjsing }
115749904dfSjsing 
116749904dfSjsing struct record_test {
117749904dfSjsing 	size_t rw_len;
118749904dfSjsing 	int eof;
119749904dfSjsing 	ssize_t want_ret;
120749904dfSjsing };
121749904dfSjsing 
122749904dfSjsing struct record_recv_test {
123749904dfSjsing 	uint8_t *read_buf;
124749904dfSjsing 	struct record_test rt[10];
125749904dfSjsing 	uint8_t want_content_type;
126749904dfSjsing 	uint8_t *want_data;
127749904dfSjsing 	size_t want_len;
128749904dfSjsing };
129749904dfSjsing 
130749904dfSjsing struct record_recv_test record_recv_tests[] = {
131749904dfSjsing 	{
132749904dfSjsing 		.read_buf = test_record_1,
133749904dfSjsing 		.rt = {
134749904dfSjsing 			{
135749904dfSjsing 				.rw_len = sizeof(test_record_1),
136749904dfSjsing 				.want_ret = sizeof(test_record_1),
137749904dfSjsing 			},
138749904dfSjsing 		},
139749904dfSjsing 		.want_content_type = SSL3_RT_HANDSHAKE,
140749904dfSjsing 		.want_data = test_record_1,
141749904dfSjsing 		.want_len = sizeof(test_record_1),
142749904dfSjsing 	},
143749904dfSjsing 	{
144749904dfSjsing 		.read_buf = test_record_1,
145749904dfSjsing 		.rt = {
146749904dfSjsing 			{
147749904dfSjsing 				.rw_len = 0,
148749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
149749904dfSjsing 			},
150749904dfSjsing 			{
151749904dfSjsing 				.rw_len = sizeof(test_record_1),
152749904dfSjsing 				.want_ret = sizeof(test_record_1),
153749904dfSjsing 			},
154749904dfSjsing 		},
155749904dfSjsing 		.want_content_type = SSL3_RT_HANDSHAKE,
156749904dfSjsing 		.want_data = test_record_1,
157749904dfSjsing 		.want_len = sizeof(test_record_1),
158749904dfSjsing 	},
159749904dfSjsing 	{
160749904dfSjsing 		.read_buf = test_record_1,
161749904dfSjsing 		.rt = {
162749904dfSjsing 			{
163749904dfSjsing 				.rw_len = 0,
164749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
165749904dfSjsing 			},
166749904dfSjsing 			{
167749904dfSjsing 				.rw_len = 5,
168749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
169749904dfSjsing 			},
170749904dfSjsing 			{
171749904dfSjsing 				.rw_len = sizeof(test_record_1),
172749904dfSjsing 				.want_ret = sizeof(test_record_1),
173749904dfSjsing 			},
174749904dfSjsing 		},
175749904dfSjsing 		.want_content_type = SSL3_RT_HANDSHAKE,
176749904dfSjsing 		.want_data = test_record_1,
177749904dfSjsing 		.want_len = sizeof(test_record_1),
178749904dfSjsing 	},
179749904dfSjsing 	{
180749904dfSjsing 		.read_buf = test_record_1,
181749904dfSjsing 		.rt = {
182749904dfSjsing 			{
183749904dfSjsing 				.rw_len = 0,
184749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
185749904dfSjsing 			},
186749904dfSjsing 			{
187749904dfSjsing 				.rw_len = 2,
188749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
189749904dfSjsing 			},
190749904dfSjsing 			{
191749904dfSjsing 				.rw_len = 6,
192749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
193749904dfSjsing 			},
194749904dfSjsing 			{
195749904dfSjsing 				.rw_len = sizeof(test_record_1),
196749904dfSjsing 				.want_ret = sizeof(test_record_1),
197749904dfSjsing 			},
198749904dfSjsing 		},
199749904dfSjsing 		.want_content_type = SSL3_RT_HANDSHAKE,
200749904dfSjsing 		.want_data = test_record_1,
201749904dfSjsing 		.want_len = sizeof(test_record_1),
202749904dfSjsing 	},
203749904dfSjsing 	{
204749904dfSjsing 		.read_buf = test_record_1,
205749904dfSjsing 		.rt = {
206749904dfSjsing 			{
207749904dfSjsing 				.rw_len = 4,
208749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
209749904dfSjsing 			},
210749904dfSjsing 			{
211749904dfSjsing 				.eof = 1,
212749904dfSjsing 				.want_ret = TLS13_IO_EOF,
213749904dfSjsing 			},
214749904dfSjsing 		},
215749904dfSjsing 	},
216749904dfSjsing 	{
217749904dfSjsing 		.read_buf = test_record_1,
218749904dfSjsing 		.rt = {
219749904dfSjsing 			{
220749904dfSjsing 				.eof = 1,
221749904dfSjsing 				.want_ret = TLS13_IO_EOF,
222749904dfSjsing 			},
223749904dfSjsing 		},
224749904dfSjsing 	},
225749904dfSjsing 	{
226749904dfSjsing 		.read_buf = test_record_2,
227749904dfSjsing 		.rt = {
228749904dfSjsing 			{
229749904dfSjsing 				.rw_len = sizeof(test_record_2),
230749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLIN,
231749904dfSjsing 			},
232749904dfSjsing 			{
233749904dfSjsing 				.eof = 1,
234749904dfSjsing 				.want_ret = TLS13_IO_EOF,
235749904dfSjsing 			},
236749904dfSjsing 		},
237749904dfSjsing 		.want_content_type = SSL3_RT_APPLICATION_DATA,
238749904dfSjsing 	},
239b38431afSjsing 	{
240b38431afSjsing 		.read_buf = test_record_3,
241b38431afSjsing 		.rt = {
242b38431afSjsing 			{
243b38431afSjsing 				.rw_len = sizeof(test_record_3),
2448dd6eaf4Sjsing 				.want_ret = TLS13_IO_RECORD_OVERFLOW,
245b38431afSjsing 			},
246b38431afSjsing 		},
247b38431afSjsing 	},
248749904dfSjsing };
249749904dfSjsing 
250749904dfSjsing #define N_RECORD_RECV_TESTS (sizeof(record_recv_tests) / sizeof(record_recv_tests[0]))
251749904dfSjsing 
252749904dfSjsing struct record_send_test {
253749904dfSjsing 	uint8_t *data;
254749904dfSjsing 	size_t data_len;
255749904dfSjsing 	struct record_test rt[10];
256749904dfSjsing 	uint8_t *want_data;
257749904dfSjsing 	size_t want_len;
258749904dfSjsing };
259749904dfSjsing 
260749904dfSjsing struct record_send_test record_send_tests[] = {
261749904dfSjsing 	{
262749904dfSjsing 		.data = test_record_1,
263749904dfSjsing 		.data_len = sizeof(test_record_1),
264749904dfSjsing 		.rt = {
265749904dfSjsing 			{
266749904dfSjsing 				.rw_len = sizeof(test_record_1),
267749904dfSjsing 				.want_ret = sizeof(test_record_1),
268749904dfSjsing 			},
269749904dfSjsing 		},
270749904dfSjsing 		.want_data = test_record_1,
271749904dfSjsing 		.want_len = sizeof(test_record_1),
272749904dfSjsing 	},
273749904dfSjsing 	{
274749904dfSjsing 		.data = test_record_1,
275749904dfSjsing 		.data_len = sizeof(test_record_1),
276749904dfSjsing 		.rt = {
277749904dfSjsing 			{
278749904dfSjsing 				.rw_len = 0,
279749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
280749904dfSjsing 			},
281749904dfSjsing 			{
282749904dfSjsing 				.rw_len = sizeof(test_record_1),
283749904dfSjsing 				.want_ret = sizeof(test_record_1),
284749904dfSjsing 			},
285749904dfSjsing 		},
286749904dfSjsing 		.want_data = test_record_1,
287749904dfSjsing 		.want_len = sizeof(test_record_1),
288749904dfSjsing 	},
289749904dfSjsing 	{
290749904dfSjsing 		.data = test_record_1,
291749904dfSjsing 		.data_len = sizeof(test_record_1),
292749904dfSjsing 		.rt = {
293749904dfSjsing 			{
294749904dfSjsing 				.rw_len = 0,
295749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
296749904dfSjsing 			},
297749904dfSjsing 			{
298749904dfSjsing 				.rw_len = 5,
299749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
300749904dfSjsing 			},
301749904dfSjsing 			{
302749904dfSjsing 				.rw_len = sizeof(test_record_1),
303749904dfSjsing 				.want_ret = sizeof(test_record_1),
304749904dfSjsing 			},
305749904dfSjsing 		},
306749904dfSjsing 		.want_data = test_record_1,
307749904dfSjsing 		.want_len = sizeof(test_record_1),
308749904dfSjsing 	},
309749904dfSjsing 	{
310749904dfSjsing 		.data = test_record_1,
311749904dfSjsing 		.data_len = sizeof(test_record_1),
312749904dfSjsing 		.rt = {
313749904dfSjsing 			{
314749904dfSjsing 				.rw_len = 0,
315749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
316749904dfSjsing 			},
317749904dfSjsing 			{
318749904dfSjsing 				.rw_len = 2,
319749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
320749904dfSjsing 			},
321749904dfSjsing 			{
322749904dfSjsing 				.rw_len = 6,
323749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
324749904dfSjsing 			},
325749904dfSjsing 			{
326749904dfSjsing 				.rw_len = sizeof(test_record_1),
327749904dfSjsing 				.want_ret = sizeof(test_record_1),
328749904dfSjsing 			},
329749904dfSjsing 		},
330749904dfSjsing 		.want_data = test_record_1,
331749904dfSjsing 		.want_len = sizeof(test_record_1),
332749904dfSjsing 	},
333749904dfSjsing 	{
334749904dfSjsing 		.data = test_record_1,
335749904dfSjsing 		.data_len = sizeof(test_record_1),
336749904dfSjsing 		.rt = {
337749904dfSjsing 			{
338749904dfSjsing 				.rw_len = 4,
339749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
340749904dfSjsing 			},
341749904dfSjsing 			{
342749904dfSjsing 				.eof = 1,
343749904dfSjsing 				.want_ret = TLS13_IO_EOF,
344749904dfSjsing 			},
345749904dfSjsing 		},
346749904dfSjsing 		.want_data = test_record_1,
347749904dfSjsing 		.want_len = 4,
348749904dfSjsing 	},
349749904dfSjsing 	{
350749904dfSjsing 		.data = test_record_1,
351749904dfSjsing 		.data_len = sizeof(test_record_1),
352749904dfSjsing 		.rt = {
353749904dfSjsing 			{
354749904dfSjsing 				.rw_len = 0,
355749904dfSjsing 				.want_ret = TLS13_IO_WANT_POLLOUT,
356749904dfSjsing 			},
357749904dfSjsing 			{
358749904dfSjsing 				.eof = 1,
359749904dfSjsing 				.want_ret = TLS13_IO_EOF,
360749904dfSjsing 			},
361749904dfSjsing 		},
362749904dfSjsing 		.want_data = NULL,
363749904dfSjsing 		.want_len = 0,
364749904dfSjsing 	},
365749904dfSjsing };
366749904dfSjsing 
367749904dfSjsing #define N_RECORD_SEND_TESTS (sizeof(record_send_tests) / sizeof(record_send_tests[0]))
368749904dfSjsing 
369749904dfSjsing static int
test_record_recv(size_t test_no,struct record_recv_test * rrt)370749904dfSjsing test_record_recv(size_t test_no, struct record_recv_test *rrt)
371749904dfSjsing {
372749904dfSjsing 	struct tls13_record *rec;
373749904dfSjsing 	struct rw_state rs;
374749904dfSjsing 	int failed = 1;
375749904dfSjsing 	ssize_t ret;
376749904dfSjsing 	size_t i;
377749904dfSjsing 	CBS cbs;
378749904dfSjsing 
379749904dfSjsing 	rs.buf = rrt->read_buf;
380749904dfSjsing 	rs.offset = 0;
381749904dfSjsing 
382749904dfSjsing 	if ((rec = tls13_record_new()) == NULL)
383749904dfSjsing 		errx(1, "tls13_record_new");
384749904dfSjsing 
385749904dfSjsing 	for (i = 0; rrt->rt[i].rw_len != 0 || rrt->rt[i].want_ret != 0; i++) {
386749904dfSjsing 		rs.eof = rrt->rt[i].eof;
387749904dfSjsing 		rs.len = rrt->rt[i].rw_len;
388749904dfSjsing 
389749904dfSjsing 		ret = tls13_record_recv(rec, read_cb, &rs);
390749904dfSjsing 		if (ret != rrt->rt[i].want_ret) {
391749904dfSjsing 			fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_recv "
392*c0a6a244Stb 			    "returned %zd, want %zd\n", test_no, i, ret,
393749904dfSjsing 			    rrt->rt[i].want_ret);
394749904dfSjsing 			goto failure;
395749904dfSjsing 		}
396749904dfSjsing 	}
397749904dfSjsing 
398749904dfSjsing 	if (tls13_record_content_type(rec) != rrt->want_content_type) {
399749904dfSjsing 		fprintf(stderr, "FAIL: Test %zu - got content type %u, "
400749904dfSjsing 		    "want %u\n", test_no, tls13_record_content_type(rec),
401749904dfSjsing 		    rrt->want_content_type);
402749904dfSjsing 		goto failure;
403749904dfSjsing 	}
404749904dfSjsing 
405749904dfSjsing 	tls13_record_data(rec, &cbs);
406749904dfSjsing 	if (rrt->want_data == NULL) {
407749904dfSjsing 		if (CBS_data(&cbs) != NULL || CBS_len(&cbs) != 0) {
408749904dfSjsing 			fprintf(stderr, "FAIL: Test %zu - got CBS with data, "
409749904dfSjsing 			    "want NULL\n", test_no);
410749904dfSjsing 			goto failure;
411749904dfSjsing 		}
412749904dfSjsing 		goto done;
413749904dfSjsing 	}
414749904dfSjsing 	if (!CBS_mem_equal(&cbs, rrt->want_data, rrt->want_len)) {
415749904dfSjsing 		fprintf(stderr, "FAIL: Test %zu - data mismatch\n", test_no);
416749904dfSjsing 		fprintf(stderr, "Got record data:\n");
417749904dfSjsing 		hexdump(CBS_data(&cbs), CBS_len(&cbs));
418749904dfSjsing 		fprintf(stderr, "Want record data:\n");
419749904dfSjsing 		hexdump(rrt->want_data, rrt->want_len);
420749904dfSjsing 		goto failure;
421749904dfSjsing 	}
422b38431afSjsing 
423b38431afSjsing 	if (!tls13_record_header(rec, &cbs)) {
424b38431afSjsing 		fprintf(stderr, "FAIL: Test %zu - fail to get record "
425b38431afSjsing 		    "header", test_no);
426b38431afSjsing 		goto failure;
427b38431afSjsing 	}
428b38431afSjsing 	if (!CBS_mem_equal(&cbs, rrt->want_data, TLS13_RECORD_HEADER_LEN)) {
429b38431afSjsing 		fprintf(stderr, "FAIL: Test %zu - header mismatch\n", test_no);
430b38431afSjsing 		fprintf(stderr, "Got record header:\n");
431b38431afSjsing 		hexdump(CBS_data(&cbs), CBS_len(&cbs));
432b38431afSjsing 		fprintf(stderr, "Want record header:\n");
433b38431afSjsing 		hexdump(rrt->want_data, rrt->want_len);
434b38431afSjsing 		goto failure;
435b38431afSjsing 	}
436b38431afSjsing 
437749904dfSjsing 	if (!tls13_record_content(rec, &cbs)) {
438749904dfSjsing 		fprintf(stderr, "FAIL: Test %zu - fail to get record "
439749904dfSjsing 		    "content", test_no);
440749904dfSjsing 		goto failure;
441749904dfSjsing 	}
442749904dfSjsing 	if (!CBS_mem_equal(&cbs, rrt->want_data + TLS13_RECORD_HEADER_LEN,
443749904dfSjsing 	    rrt->want_len - TLS13_RECORD_HEADER_LEN)) {
444749904dfSjsing 		fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no);
445b38431afSjsing 		fprintf(stderr, "Got record content:\n");
446749904dfSjsing 		hexdump(CBS_data(&cbs), CBS_len(&cbs));
447b38431afSjsing 		fprintf(stderr, "Want record content:\n");
448749904dfSjsing 		hexdump(rrt->want_data, rrt->want_len);
449749904dfSjsing 		goto failure;
450749904dfSjsing 	}
451749904dfSjsing 
452749904dfSjsing  done:
453749904dfSjsing 	failed = 0;
454749904dfSjsing 
455749904dfSjsing  failure:
456749904dfSjsing 	tls13_record_free(rec);
457749904dfSjsing 
458749904dfSjsing 	return failed;
459749904dfSjsing }
460749904dfSjsing 
461749904dfSjsing static int
test_record_send(size_t test_no,struct record_send_test * rst)462749904dfSjsing test_record_send(size_t test_no, struct record_send_test *rst)
463749904dfSjsing {
464749904dfSjsing 	uint8_t *data = NULL;
465749904dfSjsing 	struct tls13_record *rec;
466749904dfSjsing 	struct rw_state ws;
467749904dfSjsing 	int failed = 1;
468749904dfSjsing 	ssize_t ret;
469749904dfSjsing 	size_t i;
470749904dfSjsing 
471749904dfSjsing 	if ((ws.buf = malloc(TLS13_RECORD_MAX_LEN)) == NULL)
472749904dfSjsing 		errx(1, "malloc");
473749904dfSjsing 
474749904dfSjsing 	ws.offset = 0;
475749904dfSjsing 
476749904dfSjsing 	if ((rec = tls13_record_new()) == NULL)
477749904dfSjsing 		errx(1, "tls13_record_new");
478749904dfSjsing 
479749904dfSjsing 	if ((data = malloc(rst->data_len)) == NULL)
480749904dfSjsing 		errx(1, "malloc");
481749904dfSjsing 	memcpy(data, rst->data, rst->data_len);
482749904dfSjsing 
483b38431afSjsing 	if (!tls13_record_set_data(rec, data, rst->data_len)) {
484b38431afSjsing 		fprintf(stderr, "FAIL: Test %zu - failed to set record data\n",
485b38431afSjsing 		    test_no);
486b38431afSjsing 		goto failure;
487b38431afSjsing 	}
488749904dfSjsing 	data = NULL;
489749904dfSjsing 
490749904dfSjsing 	for (i = 0; rst->rt[i].rw_len != 0 || rst->rt[i].want_ret != 0; i++) {
491749904dfSjsing 		ws.eof = rst->rt[i].eof;
492749904dfSjsing 		ws.len = rst->rt[i].rw_len;
493749904dfSjsing 
494749904dfSjsing 		ret = tls13_record_send(rec, write_cb, &ws);
495749904dfSjsing 		if (ret != rst->rt[i].want_ret) {
496749904dfSjsing 			fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_send "
497*c0a6a244Stb 			    "returned %zd, want %zd\n", test_no, i, ret,
498749904dfSjsing 			    rst->rt[i].want_ret);
499749904dfSjsing 			goto failure;
500749904dfSjsing 		}
501749904dfSjsing 	}
502749904dfSjsing 
503749904dfSjsing 	if (rst->want_data != NULL &&
504749904dfSjsing 	    memcmp(ws.buf, rst->want_data, rst->want_len) != 0) {
505749904dfSjsing 		fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no);
506749904dfSjsing 		fprintf(stderr, "Got record data:\n");
507749904dfSjsing 		hexdump(rst->data, rst->data_len);
508749904dfSjsing 		fprintf(stderr, "Want record data:\n");
509749904dfSjsing 		hexdump(rst->want_data, rst->want_len);
510749904dfSjsing 		goto failure;
511749904dfSjsing 	}
512749904dfSjsing 
513749904dfSjsing 	failed = 0;
514749904dfSjsing 
515749904dfSjsing  failure:
516749904dfSjsing 	tls13_record_free(rec);
517749904dfSjsing 	free(ws.buf);
518749904dfSjsing 
519749904dfSjsing 	return failed;
520749904dfSjsing }
521749904dfSjsing 
522749904dfSjsing static int
test_recv_records(void)523749904dfSjsing test_recv_records(void)
524749904dfSjsing {
525749904dfSjsing 	int failed = 0;
526749904dfSjsing 	size_t i;
527749904dfSjsing 
528749904dfSjsing 	for (i = 0; i < N_RECORD_RECV_TESTS; i++)
529749904dfSjsing 		failed |= test_record_recv(i, &record_recv_tests[i]);
530749904dfSjsing 
531749904dfSjsing 	return failed;
532749904dfSjsing }
533749904dfSjsing 
534749904dfSjsing static int
test_send_records(void)535749904dfSjsing test_send_records(void)
536749904dfSjsing {
537749904dfSjsing 	int failed = 0;
538749904dfSjsing 	size_t i;
539749904dfSjsing 
540749904dfSjsing 	for (i = 0; i < N_RECORD_SEND_TESTS; i++)
541749904dfSjsing 		failed |= test_record_send(i, &record_send_tests[i]);
542749904dfSjsing 
543749904dfSjsing 	return failed;
544749904dfSjsing }
545749904dfSjsing 
546749904dfSjsing int
main(int argc,char ** argv)547749904dfSjsing main(int argc, char **argv)
548749904dfSjsing {
549749904dfSjsing 	int failed = 0;
550749904dfSjsing 
551749904dfSjsing 	failed |= test_recv_records();
552749904dfSjsing 	failed |= test_send_records();
553749904dfSjsing 
554749904dfSjsing 	return failed;
555749904dfSjsing }
556