xref: /dflybsd-src/crypto/libressl/ssl/tls13_record_layer.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: tls13_record_layer.c,v 1.71 2022/09/11 13:50:41 jsing Exp $ */
2cca6fc52SDaniel Fojt /*
3cca6fc52SDaniel Fojt  * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4cca6fc52SDaniel Fojt  *
5cca6fc52SDaniel Fojt  * Permission to use, copy, modify, and distribute this software for any
6cca6fc52SDaniel Fojt  * purpose with or without fee is hereby granted, provided that the above
7cca6fc52SDaniel Fojt  * copyright notice and this permission notice appear in all copies.
8cca6fc52SDaniel Fojt  *
9cca6fc52SDaniel Fojt  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10cca6fc52SDaniel Fojt  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11cca6fc52SDaniel Fojt  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12cca6fc52SDaniel Fojt  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13cca6fc52SDaniel Fojt  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14cca6fc52SDaniel Fojt  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15cca6fc52SDaniel Fojt  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16cca6fc52SDaniel Fojt  */
17cca6fc52SDaniel Fojt 
18cca6fc52SDaniel Fojt #include "tls13_internal.h"
19cca6fc52SDaniel Fojt #include "tls13_record.h"
20*de0e0e4dSAntonio Huete Jimenez #include "tls_content.h"
21cca6fc52SDaniel Fojt 
22cca6fc52SDaniel Fojt static ssize_t tls13_record_layer_write_chunk(struct tls13_record_layer *rl,
23cca6fc52SDaniel Fojt     uint8_t content_type, const uint8_t *buf, size_t n);
24cca6fc52SDaniel Fojt static ssize_t tls13_record_layer_write_record(struct tls13_record_layer *rl,
25cca6fc52SDaniel Fojt     uint8_t content_type, const uint8_t *content, size_t content_len);
26cca6fc52SDaniel Fojt 
27*de0e0e4dSAntonio Huete Jimenez struct tls13_record_protection {
28*de0e0e4dSAntonio Huete Jimenez 	EVP_AEAD_CTX *aead_ctx;
29*de0e0e4dSAntonio Huete Jimenez 	struct tls13_secret iv;
30*de0e0e4dSAntonio Huete Jimenez 	struct tls13_secret nonce;
31*de0e0e4dSAntonio Huete Jimenez 	uint8_t seq_num[TLS13_RECORD_SEQ_NUM_LEN];
32*de0e0e4dSAntonio Huete Jimenez };
33*de0e0e4dSAntonio Huete Jimenez 
34*de0e0e4dSAntonio Huete Jimenez struct tls13_record_protection *
tls13_record_protection_new(void)35*de0e0e4dSAntonio Huete Jimenez tls13_record_protection_new(void)
36*de0e0e4dSAntonio Huete Jimenez {
37*de0e0e4dSAntonio Huete Jimenez 	return calloc(1, sizeof(struct tls13_record_protection));
38*de0e0e4dSAntonio Huete Jimenez }
39*de0e0e4dSAntonio Huete Jimenez 
40*de0e0e4dSAntonio Huete Jimenez void
tls13_record_protection_clear(struct tls13_record_protection * rp)41*de0e0e4dSAntonio Huete Jimenez tls13_record_protection_clear(struct tls13_record_protection *rp)
42*de0e0e4dSAntonio Huete Jimenez {
43*de0e0e4dSAntonio Huete Jimenez 	EVP_AEAD_CTX_free(rp->aead_ctx);
44*de0e0e4dSAntonio Huete Jimenez 
45*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&rp->iv);
46*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&rp->nonce);
47*de0e0e4dSAntonio Huete Jimenez 
48*de0e0e4dSAntonio Huete Jimenez 	memset(rp, 0, sizeof(*rp));
49*de0e0e4dSAntonio Huete Jimenez }
50*de0e0e4dSAntonio Huete Jimenez 
51*de0e0e4dSAntonio Huete Jimenez void
tls13_record_protection_free(struct tls13_record_protection * rp)52*de0e0e4dSAntonio Huete Jimenez tls13_record_protection_free(struct tls13_record_protection *rp)
53*de0e0e4dSAntonio Huete Jimenez {
54*de0e0e4dSAntonio Huete Jimenez 	if (rp == NULL)
55*de0e0e4dSAntonio Huete Jimenez 		return;
56*de0e0e4dSAntonio Huete Jimenez 
57*de0e0e4dSAntonio Huete Jimenez 	tls13_record_protection_clear(rp);
58*de0e0e4dSAntonio Huete Jimenez 
59*de0e0e4dSAntonio Huete Jimenez 	freezero(rp, sizeof(struct tls13_record_protection));
60*de0e0e4dSAntonio Huete Jimenez }
61*de0e0e4dSAntonio Huete Jimenez 
62cca6fc52SDaniel Fojt struct tls13_record_layer {
63cca6fc52SDaniel Fojt 	uint16_t legacy_version;
64cca6fc52SDaniel Fojt 
65cca6fc52SDaniel Fojt 	int ccs_allowed;
66cca6fc52SDaniel Fojt 	int ccs_seen;
678edacedfSDaniel Fojt 	int ccs_sent;
68cca6fc52SDaniel Fojt 	int handshake_completed;
69cca6fc52SDaniel Fojt 	int legacy_alerts_allowed;
70cca6fc52SDaniel Fojt 	int phh;
718edacedfSDaniel Fojt 	int phh_retry;
72cca6fc52SDaniel Fojt 
73cca6fc52SDaniel Fojt 	/*
74cca6fc52SDaniel Fojt 	 * Read and/or write channels are closed due to an alert being
75cca6fc52SDaniel Fojt 	 * sent or received. In the case of an error alert both channels
76cca6fc52SDaniel Fojt 	 * are closed, whereas in the case of a close notify only one
77cca6fc52SDaniel Fojt 	 * channel is closed.
78cca6fc52SDaniel Fojt 	 */
79cca6fc52SDaniel Fojt 	int read_closed;
80cca6fc52SDaniel Fojt 	int write_closed;
81cca6fc52SDaniel Fojt 
82cca6fc52SDaniel Fojt 	struct tls13_record *rrec;
83cca6fc52SDaniel Fojt 
84cca6fc52SDaniel Fojt 	struct tls13_record *wrec;
85cca6fc52SDaniel Fojt 	uint8_t wrec_content_type;
86cca6fc52SDaniel Fojt 	size_t wrec_appdata_len;
87cca6fc52SDaniel Fojt 	size_t wrec_content_len;
88cca6fc52SDaniel Fojt 
898edacedfSDaniel Fojt 	/* Alert to be sent on return from current read handler. */
908edacedfSDaniel Fojt 	uint8_t alert;
918edacedfSDaniel Fojt 
92cca6fc52SDaniel Fojt 	/* Pending alert messages. */
93cca6fc52SDaniel Fojt 	uint8_t *alert_data;
94cca6fc52SDaniel Fojt 	size_t alert_len;
95cca6fc52SDaniel Fojt 	uint8_t alert_level;
96cca6fc52SDaniel Fojt 	uint8_t alert_desc;
97cca6fc52SDaniel Fojt 
98cca6fc52SDaniel Fojt 	/* Pending post-handshake handshake messages (RFC 8446, section 4.6). */
99cca6fc52SDaniel Fojt 	CBS phh_cbs;
100cca6fc52SDaniel Fojt 	uint8_t *phh_data;
101cca6fc52SDaniel Fojt 	size_t phh_len;
102cca6fc52SDaniel Fojt 
103*de0e0e4dSAntonio Huete Jimenez 	/* Content from opened records. */
104*de0e0e4dSAntonio Huete Jimenez 	struct tls_content *rcontent;
105cca6fc52SDaniel Fojt 
106cca6fc52SDaniel Fojt 	/* Record protection. */
107cca6fc52SDaniel Fojt 	const EVP_MD *hash;
108cca6fc52SDaniel Fojt 	const EVP_AEAD *aead;
109*de0e0e4dSAntonio Huete Jimenez 	struct tls13_record_protection *read;
110*de0e0e4dSAntonio Huete Jimenez 	struct tls13_record_protection *write;
111cca6fc52SDaniel Fojt 
1128edacedfSDaniel Fojt 	/* Callbacks. */
1138edacedfSDaniel Fojt 	struct tls13_record_layer_callbacks cb;
114cca6fc52SDaniel Fojt 	void *cb_arg;
115cca6fc52SDaniel Fojt };
116cca6fc52SDaniel Fojt 
117cca6fc52SDaniel Fojt static void
tls13_record_layer_rrec_free(struct tls13_record_layer * rl)118cca6fc52SDaniel Fojt tls13_record_layer_rrec_free(struct tls13_record_layer *rl)
119cca6fc52SDaniel Fojt {
120cca6fc52SDaniel Fojt 	tls13_record_free(rl->rrec);
121cca6fc52SDaniel Fojt 	rl->rrec = NULL;
122cca6fc52SDaniel Fojt }
123cca6fc52SDaniel Fojt 
124cca6fc52SDaniel Fojt static void
tls13_record_layer_wrec_free(struct tls13_record_layer * rl)125cca6fc52SDaniel Fojt tls13_record_layer_wrec_free(struct tls13_record_layer *rl)
126cca6fc52SDaniel Fojt {
127cca6fc52SDaniel Fojt 	tls13_record_free(rl->wrec);
128cca6fc52SDaniel Fojt 	rl->wrec = NULL;
129cca6fc52SDaniel Fojt }
130cca6fc52SDaniel Fojt 
131cca6fc52SDaniel Fojt struct tls13_record_layer *
tls13_record_layer_new(const struct tls13_record_layer_callbacks * callbacks,void * cb_arg)1328edacedfSDaniel Fojt tls13_record_layer_new(const struct tls13_record_layer_callbacks *callbacks,
133cca6fc52SDaniel Fojt     void *cb_arg)
134cca6fc52SDaniel Fojt {
135cca6fc52SDaniel Fojt 	struct tls13_record_layer *rl;
136cca6fc52SDaniel Fojt 
137cca6fc52SDaniel Fojt 	if ((rl = calloc(1, sizeof(struct tls13_record_layer))) == NULL)
138*de0e0e4dSAntonio Huete Jimenez 		goto err;
139*de0e0e4dSAntonio Huete Jimenez 
140*de0e0e4dSAntonio Huete Jimenez 	if ((rl->rcontent = tls_content_new()) == NULL)
141*de0e0e4dSAntonio Huete Jimenez 		goto err;
142*de0e0e4dSAntonio Huete Jimenez 
143*de0e0e4dSAntonio Huete Jimenez 	if ((rl->read = tls13_record_protection_new()) == NULL)
144*de0e0e4dSAntonio Huete Jimenez 		goto err;
145*de0e0e4dSAntonio Huete Jimenez 	if ((rl->write = tls13_record_protection_new()) == NULL)
146*de0e0e4dSAntonio Huete Jimenez 		goto err;
147cca6fc52SDaniel Fojt 
148cca6fc52SDaniel Fojt 	rl->legacy_version = TLS1_2_VERSION;
149*de0e0e4dSAntonio Huete Jimenez 
150*de0e0e4dSAntonio Huete Jimenez 	tls13_record_layer_set_callbacks(rl, callbacks, cb_arg);
151cca6fc52SDaniel Fojt 
152cca6fc52SDaniel Fojt 	return rl;
153*de0e0e4dSAntonio Huete Jimenez 
154*de0e0e4dSAntonio Huete Jimenez  err:
155*de0e0e4dSAntonio Huete Jimenez 	tls13_record_layer_free(rl);
156*de0e0e4dSAntonio Huete Jimenez 
157*de0e0e4dSAntonio Huete Jimenez 	return NULL;
158cca6fc52SDaniel Fojt }
159cca6fc52SDaniel Fojt 
160cca6fc52SDaniel Fojt void
tls13_record_layer_free(struct tls13_record_layer * rl)161cca6fc52SDaniel Fojt tls13_record_layer_free(struct tls13_record_layer *rl)
162cca6fc52SDaniel Fojt {
163cca6fc52SDaniel Fojt 	if (rl == NULL)
164cca6fc52SDaniel Fojt 		return;
165cca6fc52SDaniel Fojt 
166cca6fc52SDaniel Fojt 	tls13_record_layer_rrec_free(rl);
167cca6fc52SDaniel Fojt 	tls13_record_layer_wrec_free(rl);
168cca6fc52SDaniel Fojt 
169*de0e0e4dSAntonio Huete Jimenez 	freezero(rl->alert_data, rl->alert_len);
170*de0e0e4dSAntonio Huete Jimenez 	freezero(rl->phh_data, rl->phh_len);
171cca6fc52SDaniel Fojt 
172*de0e0e4dSAntonio Huete Jimenez 	tls_content_free(rl->rcontent);
173*de0e0e4dSAntonio Huete Jimenez 
174*de0e0e4dSAntonio Huete Jimenez 	tls13_record_protection_free(rl->read);
175*de0e0e4dSAntonio Huete Jimenez 	tls13_record_protection_free(rl->write);
176cca6fc52SDaniel Fojt 
177cca6fc52SDaniel Fojt 	freezero(rl, sizeof(struct tls13_record_layer));
178cca6fc52SDaniel Fojt }
179cca6fc52SDaniel Fojt 
180cca6fc52SDaniel Fojt void
tls13_record_layer_set_callbacks(struct tls13_record_layer * rl,const struct tls13_record_layer_callbacks * callbacks,void * cb_arg)181*de0e0e4dSAntonio Huete Jimenez tls13_record_layer_set_callbacks(struct tls13_record_layer *rl,
182*de0e0e4dSAntonio Huete Jimenez     const struct tls13_record_layer_callbacks *callbacks, void *cb_arg)
183cca6fc52SDaniel Fojt {
184*de0e0e4dSAntonio Huete Jimenez 	rl->cb = *callbacks;
185*de0e0e4dSAntonio Huete Jimenez 	rl->cb_arg = cb_arg;
186*de0e0e4dSAntonio Huete Jimenez }
187*de0e0e4dSAntonio Huete Jimenez 
188*de0e0e4dSAntonio Huete Jimenez void
tls13_record_layer_rcontent(struct tls13_record_layer * rl,CBS * cbs)189*de0e0e4dSAntonio Huete Jimenez tls13_record_layer_rcontent(struct tls13_record_layer *rl, CBS *cbs)
190*de0e0e4dSAntonio Huete Jimenez {
191*de0e0e4dSAntonio Huete Jimenez 	CBS_dup(tls_content_cbs(rl->rcontent), cbs);
192cca6fc52SDaniel Fojt }
193cca6fc52SDaniel Fojt 
194cca6fc52SDaniel Fojt static const uint8_t tls13_max_seq_num[TLS13_RECORD_SEQ_NUM_LEN] = {
195cca6fc52SDaniel Fojt 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
196cca6fc52SDaniel Fojt };
197cca6fc52SDaniel Fojt 
198cca6fc52SDaniel Fojt int
tls13_record_layer_inc_seq_num(uint8_t * seq_num)199cca6fc52SDaniel Fojt tls13_record_layer_inc_seq_num(uint8_t *seq_num)
200cca6fc52SDaniel Fojt {
201cca6fc52SDaniel Fojt 	int i;
202cca6fc52SDaniel Fojt 
203cca6fc52SDaniel Fojt 	/* RFC 8446 section 5.3 - sequence numbers must not wrap. */
204cca6fc52SDaniel Fojt 	if (memcmp(seq_num, tls13_max_seq_num, TLS13_RECORD_SEQ_NUM_LEN) == 0)
205cca6fc52SDaniel Fojt 		return 0;
206cca6fc52SDaniel Fojt 
207cca6fc52SDaniel Fojt 	for (i = TLS13_RECORD_SEQ_NUM_LEN - 1; i >= 0; i--) {
208cca6fc52SDaniel Fojt 		if (++seq_num[i] != 0)
209cca6fc52SDaniel Fojt 			break;
210cca6fc52SDaniel Fojt 	}
211cca6fc52SDaniel Fojt 
212cca6fc52SDaniel Fojt 	return 1;
213cca6fc52SDaniel Fojt }
214cca6fc52SDaniel Fojt 
215cca6fc52SDaniel Fojt static int
tls13_record_layer_update_nonce(struct tls13_secret * nonce,struct tls13_secret * iv,uint8_t * seq_num)216cca6fc52SDaniel Fojt tls13_record_layer_update_nonce(struct tls13_secret *nonce,
217cca6fc52SDaniel Fojt     struct tls13_secret *iv, uint8_t *seq_num)
218cca6fc52SDaniel Fojt {
219cca6fc52SDaniel Fojt 	ssize_t i, j;
220cca6fc52SDaniel Fojt 
221cca6fc52SDaniel Fojt 	if (nonce->len != iv->len)
222cca6fc52SDaniel Fojt 		return 0;
223cca6fc52SDaniel Fojt 
224cca6fc52SDaniel Fojt 	/*
225cca6fc52SDaniel Fojt 	 * RFC 8446 section 5.3 - sequence number is zero padded and XOR'd
226cca6fc52SDaniel Fojt 	 * with the IV to produce a per-record nonce. The IV will also be
227cca6fc52SDaniel Fojt 	 * at least 8-bytes in length.
228cca6fc52SDaniel Fojt 	 */
229cca6fc52SDaniel Fojt 	for (i = nonce->len - 1, j = TLS13_RECORD_SEQ_NUM_LEN - 1; i >= 0; i--, j--)
230cca6fc52SDaniel Fojt 		nonce->data[i] = iv->data[i] ^ (j >= 0 ? seq_num[j] : 0);
231cca6fc52SDaniel Fojt 
232cca6fc52SDaniel Fojt 	return 1;
233cca6fc52SDaniel Fojt }
234cca6fc52SDaniel Fojt 
235cca6fc52SDaniel Fojt void
tls13_record_layer_allow_ccs(struct tls13_record_layer * rl,int allow)236cca6fc52SDaniel Fojt tls13_record_layer_allow_ccs(struct tls13_record_layer *rl, int allow)
237cca6fc52SDaniel Fojt {
238cca6fc52SDaniel Fojt 	rl->ccs_allowed = allow;
239cca6fc52SDaniel Fojt }
240cca6fc52SDaniel Fojt 
241cca6fc52SDaniel Fojt void
tls13_record_layer_allow_legacy_alerts(struct tls13_record_layer * rl,int allow)242cca6fc52SDaniel Fojt tls13_record_layer_allow_legacy_alerts(struct tls13_record_layer *rl, int allow)
243cca6fc52SDaniel Fojt {
244cca6fc52SDaniel Fojt 	rl->legacy_alerts_allowed = allow;
245cca6fc52SDaniel Fojt }
246cca6fc52SDaniel Fojt 
247cca6fc52SDaniel Fojt void
tls13_record_layer_set_aead(struct tls13_record_layer * rl,const EVP_AEAD * aead)248cca6fc52SDaniel Fojt tls13_record_layer_set_aead(struct tls13_record_layer *rl,
249cca6fc52SDaniel Fojt     const EVP_AEAD *aead)
250cca6fc52SDaniel Fojt {
251cca6fc52SDaniel Fojt 	rl->aead = aead;
252cca6fc52SDaniel Fojt }
253cca6fc52SDaniel Fojt 
254cca6fc52SDaniel Fojt void
tls13_record_layer_set_hash(struct tls13_record_layer * rl,const EVP_MD * hash)255cca6fc52SDaniel Fojt tls13_record_layer_set_hash(struct tls13_record_layer *rl,
256cca6fc52SDaniel Fojt     const EVP_MD *hash)
257cca6fc52SDaniel Fojt {
258cca6fc52SDaniel Fojt 	rl->hash = hash;
259cca6fc52SDaniel Fojt }
260cca6fc52SDaniel Fojt 
261cca6fc52SDaniel Fojt void
tls13_record_layer_set_legacy_version(struct tls13_record_layer * rl,uint16_t version)262cca6fc52SDaniel Fojt tls13_record_layer_set_legacy_version(struct tls13_record_layer *rl,
263cca6fc52SDaniel Fojt     uint16_t version)
264cca6fc52SDaniel Fojt {
265cca6fc52SDaniel Fojt 	rl->legacy_version = version;
266cca6fc52SDaniel Fojt }
267cca6fc52SDaniel Fojt 
268cca6fc52SDaniel Fojt void
tls13_record_layer_handshake_completed(struct tls13_record_layer * rl)269cca6fc52SDaniel Fojt tls13_record_layer_handshake_completed(struct tls13_record_layer *rl)
270cca6fc52SDaniel Fojt {
271cca6fc52SDaniel Fojt 	rl->handshake_completed = 1;
272cca6fc52SDaniel Fojt }
273cca6fc52SDaniel Fojt 
2748edacedfSDaniel Fojt void
tls13_record_layer_set_retry_after_phh(struct tls13_record_layer * rl,int retry)2758edacedfSDaniel Fojt tls13_record_layer_set_retry_after_phh(struct tls13_record_layer *rl, int retry)
2768edacedfSDaniel Fojt {
2778edacedfSDaniel Fojt 	rl->phh_retry = retry;
2788edacedfSDaniel Fojt }
2798edacedfSDaniel Fojt 
280cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_process_alert(struct tls13_record_layer * rl)281cca6fc52SDaniel Fojt tls13_record_layer_process_alert(struct tls13_record_layer *rl)
282cca6fc52SDaniel Fojt {
283cca6fc52SDaniel Fojt 	uint8_t alert_level, alert_desc;
284cca6fc52SDaniel Fojt 	ssize_t ret = TLS13_IO_FAILURE;
285cca6fc52SDaniel Fojt 
286cca6fc52SDaniel Fojt 	/*
287cca6fc52SDaniel Fojt 	 * RFC 8446 - sections 5.1 and 6.
288cca6fc52SDaniel Fojt 	 *
289cca6fc52SDaniel Fojt 	 * A TLSv1.3 alert record can only contain a single alert - this means
290cca6fc52SDaniel Fojt 	 * that processing the alert must consume all of the record. The alert
291cca6fc52SDaniel Fojt 	 * will result in one of three things - continuation (user_cancelled),
292cca6fc52SDaniel Fojt 	 * read channel closure (close_notify) or termination (all others).
293cca6fc52SDaniel Fojt 	 */
294*de0e0e4dSAntonio Huete Jimenez 	if (tls_content_type(rl->rcontent) != SSL3_RT_ALERT)
295cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
296cca6fc52SDaniel Fojt 
297*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u8(tls_content_cbs(rl->rcontent), &alert_level))
298*de0e0e4dSAntonio Huete Jimenez 		return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
299*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u8(tls_content_cbs(rl->rcontent), &alert_desc))
3008edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
301cca6fc52SDaniel Fojt 
302*de0e0e4dSAntonio Huete Jimenez 	if (tls_content_remaining(rl->rcontent) != 0)
3038edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
304cca6fc52SDaniel Fojt 
305*de0e0e4dSAntonio Huete Jimenez 	tls_content_clear(rl->rcontent);
306cca6fc52SDaniel Fojt 
307cca6fc52SDaniel Fojt 	/*
308cca6fc52SDaniel Fojt 	 * Alert level is ignored for closure alerts (RFC 8446 section 6.1),
309cca6fc52SDaniel Fojt 	 * however for error alerts (RFC 8446 section 6.2), the alert level
310cca6fc52SDaniel Fojt 	 * must be specified as fatal.
311cca6fc52SDaniel Fojt 	 */
3128edacedfSDaniel Fojt 	if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) {
313cca6fc52SDaniel Fojt 		rl->read_closed = 1;
314cca6fc52SDaniel Fojt 		ret = TLS13_IO_EOF;
3158edacedfSDaniel Fojt 	} else if (alert_desc == TLS13_ALERT_USER_CANCELED) {
316cca6fc52SDaniel Fojt 		/* Ignored at the record layer. */
317cca6fc52SDaniel Fojt 		ret = TLS13_IO_WANT_RETRY;
3188edacedfSDaniel Fojt 	} else if (alert_level == TLS13_ALERT_LEVEL_FATAL) {
319cca6fc52SDaniel Fojt 		rl->read_closed = 1;
320cca6fc52SDaniel Fojt 		rl->write_closed = 1;
321cca6fc52SDaniel Fojt 		ret = TLS13_IO_ALERT;
3228edacedfSDaniel Fojt 	} else if (rl->legacy_alerts_allowed &&
3238edacedfSDaniel Fojt 	    alert_level == TLS13_ALERT_LEVEL_WARNING) {
324cca6fc52SDaniel Fojt 		/* Ignored and not passed to the callback. */
325cca6fc52SDaniel Fojt 		return TLS13_IO_WANT_RETRY;
326cca6fc52SDaniel Fojt 	} else {
3278edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_ILLEGAL_PARAMETER);
328cca6fc52SDaniel Fojt 	}
329cca6fc52SDaniel Fojt 
3308edacedfSDaniel Fojt 	rl->cb.alert_recv(alert_desc, rl->cb_arg);
331cca6fc52SDaniel Fojt 
332cca6fc52SDaniel Fojt 	return ret;
333cca6fc52SDaniel Fojt }
334cca6fc52SDaniel Fojt 
335cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_send_alert(struct tls13_record_layer * rl)336cca6fc52SDaniel Fojt tls13_record_layer_send_alert(struct tls13_record_layer *rl)
337cca6fc52SDaniel Fojt {
338cca6fc52SDaniel Fojt 	ssize_t ret;
339cca6fc52SDaniel Fojt 
340cca6fc52SDaniel Fojt 	/* This has to fit into a single record, per RFC 8446 section 5.1. */
341cca6fc52SDaniel Fojt 	if ((ret = tls13_record_layer_write_record(rl, SSL3_RT_ALERT,
342cca6fc52SDaniel Fojt 	    rl->alert_data, rl->alert_len)) != rl->alert_len) {
343cca6fc52SDaniel Fojt 		if (ret == TLS13_IO_EOF)
344cca6fc52SDaniel Fojt 			ret = TLS13_IO_ALERT;
345cca6fc52SDaniel Fojt 		return ret;
346cca6fc52SDaniel Fojt 	}
347cca6fc52SDaniel Fojt 
348cca6fc52SDaniel Fojt 	freezero(rl->alert_data, rl->alert_len);
349cca6fc52SDaniel Fojt 	rl->alert_data = NULL;
350cca6fc52SDaniel Fojt 	rl->alert_len = 0;
351cca6fc52SDaniel Fojt 
3528edacedfSDaniel Fojt 	if (rl->alert_desc == TLS13_ALERT_CLOSE_NOTIFY) {
353cca6fc52SDaniel Fojt 		rl->write_closed = 1;
354cca6fc52SDaniel Fojt 		ret = TLS13_IO_SUCCESS;
3558edacedfSDaniel Fojt 	} else if (rl->alert_desc == TLS13_ALERT_USER_CANCELED) {
356cca6fc52SDaniel Fojt 		/* Ignored at the record layer. */
357cca6fc52SDaniel Fojt 		ret = TLS13_IO_SUCCESS;
358cca6fc52SDaniel Fojt 	} else {
359cca6fc52SDaniel Fojt 		rl->read_closed = 1;
360cca6fc52SDaniel Fojt 		rl->write_closed = 1;
361cca6fc52SDaniel Fojt 		ret = TLS13_IO_ALERT;
362cca6fc52SDaniel Fojt 	}
363cca6fc52SDaniel Fojt 
3648edacedfSDaniel Fojt 	rl->cb.alert_sent(rl->alert_desc, rl->cb_arg);
3658edacedfSDaniel Fojt 
366cca6fc52SDaniel Fojt 	return ret;
367cca6fc52SDaniel Fojt }
368cca6fc52SDaniel Fojt 
369cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_send_phh(struct tls13_record_layer * rl)370cca6fc52SDaniel Fojt tls13_record_layer_send_phh(struct tls13_record_layer *rl)
371cca6fc52SDaniel Fojt {
372cca6fc52SDaniel Fojt 	ssize_t ret;
373cca6fc52SDaniel Fojt 
374cca6fc52SDaniel Fojt 	/* Push out pending post-handshake handshake messages. */
375cca6fc52SDaniel Fojt 	if ((ret = tls13_record_layer_write_chunk(rl, SSL3_RT_HANDSHAKE,
3768edacedfSDaniel Fojt 	    CBS_data(&rl->phh_cbs), CBS_len(&rl->phh_cbs))) <= 0)
377cca6fc52SDaniel Fojt 		return ret;
378cca6fc52SDaniel Fojt 	if (!CBS_skip(&rl->phh_cbs, ret))
379cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
380cca6fc52SDaniel Fojt 	if (CBS_len(&rl->phh_cbs) != 0)
381cca6fc52SDaniel Fojt 		return TLS13_IO_WANT_RETRY;
382cca6fc52SDaniel Fojt 
383cca6fc52SDaniel Fojt 	freezero(rl->phh_data, rl->phh_len);
384cca6fc52SDaniel Fojt 	rl->phh_data = NULL;
385cca6fc52SDaniel Fojt 	rl->phh_len = 0;
386cca6fc52SDaniel Fojt 
387cca6fc52SDaniel Fojt 	CBS_init(&rl->phh_cbs, rl->phh_data, rl->phh_len);
388cca6fc52SDaniel Fojt 
3898edacedfSDaniel Fojt 	rl->cb.phh_sent(rl->cb_arg);
390cca6fc52SDaniel Fojt 
391cca6fc52SDaniel Fojt 	return TLS13_IO_SUCCESS;
392cca6fc52SDaniel Fojt }
393cca6fc52SDaniel Fojt 
394cca6fc52SDaniel Fojt ssize_t
tls13_record_layer_send_pending(struct tls13_record_layer * rl)395cca6fc52SDaniel Fojt tls13_record_layer_send_pending(struct tls13_record_layer *rl)
396cca6fc52SDaniel Fojt {
397cca6fc52SDaniel Fojt 	/*
398cca6fc52SDaniel Fojt 	 * If an alert is pending, then it needs to be sent. However,
399cca6fc52SDaniel Fojt 	 * if we're already part of the way through sending post-handshake
400cca6fc52SDaniel Fojt 	 * handshake messages, then we need to finish that first...
401cca6fc52SDaniel Fojt 	 */
402cca6fc52SDaniel Fojt 
403cca6fc52SDaniel Fojt 	if (rl->phh_data != NULL && CBS_len(&rl->phh_cbs) != rl->phh_len)
404cca6fc52SDaniel Fojt 		return tls13_record_layer_send_phh(rl);
405cca6fc52SDaniel Fojt 
406cca6fc52SDaniel Fojt 	if (rl->alert_data != NULL)
407cca6fc52SDaniel Fojt 		return tls13_record_layer_send_alert(rl);
408cca6fc52SDaniel Fojt 
409cca6fc52SDaniel Fojt 	if (rl->phh_data != NULL)
410cca6fc52SDaniel Fojt 		return tls13_record_layer_send_phh(rl);
411cca6fc52SDaniel Fojt 
412cca6fc52SDaniel Fojt 	return TLS13_IO_SUCCESS;
413cca6fc52SDaniel Fojt }
414cca6fc52SDaniel Fojt 
415cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_enqueue_alert(struct tls13_record_layer * rl,uint8_t alert_level,uint8_t alert_desc)416*de0e0e4dSAntonio Huete Jimenez tls13_record_layer_enqueue_alert(struct tls13_record_layer *rl,
417cca6fc52SDaniel Fojt     uint8_t alert_level, uint8_t alert_desc)
418cca6fc52SDaniel Fojt {
419cca6fc52SDaniel Fojt 	CBB cbb;
420cca6fc52SDaniel Fojt 
421cca6fc52SDaniel Fojt 	if (rl->alert_data != NULL)
422cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
423cca6fc52SDaniel Fojt 
424cca6fc52SDaniel Fojt 	if (!CBB_init(&cbb, 0))
425cca6fc52SDaniel Fojt 		goto err;
426cca6fc52SDaniel Fojt 
427cca6fc52SDaniel Fojt 	if (!CBB_add_u8(&cbb, alert_level))
428cca6fc52SDaniel Fojt 		goto err;
429cca6fc52SDaniel Fojt 	if (!CBB_add_u8(&cbb, alert_desc))
430cca6fc52SDaniel Fojt 		goto err;
431cca6fc52SDaniel Fojt 	if (!CBB_finish(&cbb, &rl->alert_data, &rl->alert_len))
432cca6fc52SDaniel Fojt 		goto err;
433cca6fc52SDaniel Fojt 
434cca6fc52SDaniel Fojt 	rl->alert_level = alert_level;
435cca6fc52SDaniel Fojt 	rl->alert_desc = alert_desc;
436cca6fc52SDaniel Fojt 
437cca6fc52SDaniel Fojt 	return tls13_record_layer_send_pending(rl);
438cca6fc52SDaniel Fojt 
439cca6fc52SDaniel Fojt  err:
440cca6fc52SDaniel Fojt 	CBB_cleanup(&cbb);
441cca6fc52SDaniel Fojt 
442cca6fc52SDaniel Fojt 	return TLS13_IO_FAILURE;
443cca6fc52SDaniel Fojt }
444cca6fc52SDaniel Fojt 
445cca6fc52SDaniel Fojt ssize_t
tls13_record_layer_phh(struct tls13_record_layer * rl,CBS * cbs)446cca6fc52SDaniel Fojt tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs)
447cca6fc52SDaniel Fojt {
448cca6fc52SDaniel Fojt 	if (rl->phh_data != NULL)
449cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
450cca6fc52SDaniel Fojt 
451cca6fc52SDaniel Fojt 	if (!CBS_stow(cbs, &rl->phh_data, &rl->phh_len))
452cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
453cca6fc52SDaniel Fojt 
454cca6fc52SDaniel Fojt 	CBS_init(&rl->phh_cbs, rl->phh_data, rl->phh_len);
455cca6fc52SDaniel Fojt 
456cca6fc52SDaniel Fojt 	return tls13_record_layer_send_pending(rl);
457cca6fc52SDaniel Fojt }
458cca6fc52SDaniel Fojt 
459cca6fc52SDaniel Fojt static int
tls13_record_layer_set_traffic_key(const EVP_AEAD * aead,const EVP_MD * hash,struct tls13_record_protection * rp,struct tls13_secret * traffic_key)460*de0e0e4dSAntonio Huete Jimenez tls13_record_layer_set_traffic_key(const EVP_AEAD *aead, const EVP_MD *hash,
461*de0e0e4dSAntonio Huete Jimenez     struct tls13_record_protection *rp, struct tls13_secret *traffic_key)
462cca6fc52SDaniel Fojt {
463cca6fc52SDaniel Fojt 	struct tls13_secret context = { .data = "", .len = 0 };
464cca6fc52SDaniel Fojt 	struct tls13_secret key = { .data = NULL, .len = 0 };
465cca6fc52SDaniel Fojt 	int ret = 0;
466cca6fc52SDaniel Fojt 
467*de0e0e4dSAntonio Huete Jimenez 	tls13_record_protection_clear(rp);
468f015dc58SDaniel Fojt 
469*de0e0e4dSAntonio Huete Jimenez 	if ((rp->aead_ctx = EVP_AEAD_CTX_new()) == NULL)
470*de0e0e4dSAntonio Huete Jimenez 		return 0;
471cca6fc52SDaniel Fojt 
472*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&rp->iv, EVP_AEAD_nonce_length(aead)))
473cca6fc52SDaniel Fojt 		goto err;
474*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&rp->nonce, EVP_AEAD_nonce_length(aead)))
475cca6fc52SDaniel Fojt 		goto err;
476*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&key, EVP_AEAD_key_length(aead)))
477cca6fc52SDaniel Fojt 		goto err;
478cca6fc52SDaniel Fojt 
479*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_hkdf_expand_label(&rp->iv, hash, traffic_key, "iv", &context))
480cca6fc52SDaniel Fojt 		goto err;
481cca6fc52SDaniel Fojt 	if (!tls13_hkdf_expand_label(&key, hash, traffic_key, "key", &context))
482cca6fc52SDaniel Fojt 		goto err;
483cca6fc52SDaniel Fojt 
484*de0e0e4dSAntonio Huete Jimenez 	if (!EVP_AEAD_CTX_init(rp->aead_ctx, aead, key.data, key.len,
485cca6fc52SDaniel Fojt 	    EVP_AEAD_DEFAULT_TAG_LENGTH, NULL))
486cca6fc52SDaniel Fojt 		goto err;
487cca6fc52SDaniel Fojt 
488cca6fc52SDaniel Fojt 	ret = 1;
489cca6fc52SDaniel Fojt 
490cca6fc52SDaniel Fojt  err:
491*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&key);
492cca6fc52SDaniel Fojt 
493cca6fc52SDaniel Fojt 	return ret;
494cca6fc52SDaniel Fojt }
495cca6fc52SDaniel Fojt 
496cca6fc52SDaniel Fojt int
tls13_record_layer_set_read_traffic_key(struct tls13_record_layer * rl,struct tls13_secret * read_key,enum ssl_encryption_level_t read_level)497cca6fc52SDaniel Fojt tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl,
498*de0e0e4dSAntonio Huete Jimenez     struct tls13_secret *read_key, enum ssl_encryption_level_t read_level)
499cca6fc52SDaniel Fojt {
500*de0e0e4dSAntonio Huete Jimenez 	if (rl->cb.set_read_traffic_key != NULL)
501*de0e0e4dSAntonio Huete Jimenez 		return rl->cb.set_read_traffic_key(read_key, read_level,
502*de0e0e4dSAntonio Huete Jimenez 		    rl->cb_arg);
503cca6fc52SDaniel Fojt 
504*de0e0e4dSAntonio Huete Jimenez 	return tls13_record_layer_set_traffic_key(rl->aead, rl->hash,
505*de0e0e4dSAntonio Huete Jimenez 	    rl->read, read_key);
506cca6fc52SDaniel Fojt }
507cca6fc52SDaniel Fojt 
508cca6fc52SDaniel Fojt int
tls13_record_layer_set_write_traffic_key(struct tls13_record_layer * rl,struct tls13_secret * write_key,enum ssl_encryption_level_t write_level)509cca6fc52SDaniel Fojt tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl,
510*de0e0e4dSAntonio Huete Jimenez     struct tls13_secret *write_key, enum ssl_encryption_level_t write_level)
511cca6fc52SDaniel Fojt {
512*de0e0e4dSAntonio Huete Jimenez 	if (rl->cb.set_write_traffic_key != NULL)
513*de0e0e4dSAntonio Huete Jimenez 		return rl->cb.set_write_traffic_key(write_key, write_level,
514*de0e0e4dSAntonio Huete Jimenez 		    rl->cb_arg);
515cca6fc52SDaniel Fojt 
516*de0e0e4dSAntonio Huete Jimenez 	return tls13_record_layer_set_traffic_key(rl->aead, rl->hash,
517*de0e0e4dSAntonio Huete Jimenez 	    rl->write, write_key);
518cca6fc52SDaniel Fojt }
519cca6fc52SDaniel Fojt 
520cca6fc52SDaniel Fojt static int
tls13_record_layer_open_record_plaintext(struct tls13_record_layer * rl)521cca6fc52SDaniel Fojt tls13_record_layer_open_record_plaintext(struct tls13_record_layer *rl)
522cca6fc52SDaniel Fojt {
523cca6fc52SDaniel Fojt 	CBS cbs;
524cca6fc52SDaniel Fojt 
525cca6fc52SDaniel Fojt 	if (rl->aead != NULL)
526cca6fc52SDaniel Fojt 		return 0;
527cca6fc52SDaniel Fojt 
528cca6fc52SDaniel Fojt 	/*
529cca6fc52SDaniel Fojt 	 * We're still operating in plaintext mode, so just copy the
530cca6fc52SDaniel Fojt 	 * content from the record to the plaintext buffer.
531cca6fc52SDaniel Fojt 	 */
532cca6fc52SDaniel Fojt 	if (!tls13_record_content(rl->rrec, &cbs))
533cca6fc52SDaniel Fojt 		return 0;
534cca6fc52SDaniel Fojt 
5358edacedfSDaniel Fojt 	if (CBS_len(&cbs) > TLS13_RECORD_MAX_PLAINTEXT_LEN) {
5368edacedfSDaniel Fojt 		rl->alert = TLS13_ALERT_RECORD_OVERFLOW;
5378edacedfSDaniel Fojt 		return 0;
5388edacedfSDaniel Fojt 	}
5398edacedfSDaniel Fojt 
540*de0e0e4dSAntonio Huete Jimenez 	if (!tls_content_dup_data(rl->rcontent,
541*de0e0e4dSAntonio Huete Jimenez 	    tls13_record_content_type(rl->rrec), CBS_data(&cbs), CBS_len(&cbs)))
542cca6fc52SDaniel Fojt 		return 0;
543cca6fc52SDaniel Fojt 
544cca6fc52SDaniel Fojt 	return 1;
545cca6fc52SDaniel Fojt }
546cca6fc52SDaniel Fojt 
547cca6fc52SDaniel Fojt static int
tls13_record_layer_open_record_protected(struct tls13_record_layer * rl)548cca6fc52SDaniel Fojt tls13_record_layer_open_record_protected(struct tls13_record_layer *rl)
549cca6fc52SDaniel Fojt {
550*de0e0e4dSAntonio Huete Jimenez 	CBS header, enc_record, inner;
551cca6fc52SDaniel Fojt 	uint8_t *content = NULL;
552f015dc58SDaniel Fojt 	size_t content_len = 0;
553cca6fc52SDaniel Fojt 	uint8_t content_type;
554cca6fc52SDaniel Fojt 	size_t out_len;
555cca6fc52SDaniel Fojt 
556cca6fc52SDaniel Fojt 	if (rl->aead == NULL)
557cca6fc52SDaniel Fojt 		goto err;
558cca6fc52SDaniel Fojt 
559cca6fc52SDaniel Fojt 	if (!tls13_record_header(rl->rrec, &header))
560cca6fc52SDaniel Fojt 		goto err;
561cca6fc52SDaniel Fojt 	if (!tls13_record_content(rl->rrec, &enc_record))
562cca6fc52SDaniel Fojt 		goto err;
563cca6fc52SDaniel Fojt 
564cca6fc52SDaniel Fojt 	if ((content = calloc(1, CBS_len(&enc_record))) == NULL)
565cca6fc52SDaniel Fojt 		goto err;
566cca6fc52SDaniel Fojt 	content_len = CBS_len(&enc_record);
567cca6fc52SDaniel Fojt 
568*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_record_layer_update_nonce(&rl->read->nonce, &rl->read->iv,
569*de0e0e4dSAntonio Huete Jimenez 	    rl->read->seq_num))
570cca6fc52SDaniel Fojt 		goto err;
571cca6fc52SDaniel Fojt 
572*de0e0e4dSAntonio Huete Jimenez 	if (!EVP_AEAD_CTX_open(rl->read->aead_ctx,
573cca6fc52SDaniel Fojt 	    content, &out_len, content_len,
574*de0e0e4dSAntonio Huete Jimenez 	    rl->read->nonce.data, rl->read->nonce.len,
575cca6fc52SDaniel Fojt 	    CBS_data(&enc_record), CBS_len(&enc_record),
576cca6fc52SDaniel Fojt 	    CBS_data(&header), CBS_len(&header)))
577cca6fc52SDaniel Fojt 		goto err;
578cca6fc52SDaniel Fojt 
5798edacedfSDaniel Fojt 	if (out_len > TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN) {
5808edacedfSDaniel Fojt 		rl->alert = TLS13_ALERT_RECORD_OVERFLOW;
5818edacedfSDaniel Fojt 		goto err;
5828edacedfSDaniel Fojt 	}
5838edacedfSDaniel Fojt 
584*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_record_layer_inc_seq_num(rl->read->seq_num))
585cca6fc52SDaniel Fojt 		goto err;
586cca6fc52SDaniel Fojt 
587cca6fc52SDaniel Fojt 	/*
588cca6fc52SDaniel Fojt 	 * The real content type is hidden at the end of the record content and
589cca6fc52SDaniel Fojt 	 * it may be followed by padding that consists of one or more zeroes.
590cca6fc52SDaniel Fojt 	 * Time to hunt for that elusive content type!
591cca6fc52SDaniel Fojt 	 */
592*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&inner, content, out_len);
593*de0e0e4dSAntonio Huete Jimenez 	content_type = 0;
594*de0e0e4dSAntonio Huete Jimenez 	while (CBS_get_last_u8(&inner, &content_type)) {
595*de0e0e4dSAntonio Huete Jimenez 		if (content_type != 0)
596*de0e0e4dSAntonio Huete Jimenez 			break;
597*de0e0e4dSAntonio Huete Jimenez 	}
598*de0e0e4dSAntonio Huete Jimenez 	if (content_type == 0) {
5998edacedfSDaniel Fojt 		/* Unexpected message per RFC 8446 section 5.4. */
6008edacedfSDaniel Fojt 		rl->alert = TLS13_ALERT_UNEXPECTED_MESSAGE;
601cca6fc52SDaniel Fojt 		goto err;
6028edacedfSDaniel Fojt 	}
603*de0e0e4dSAntonio Huete Jimenez 	if (CBS_len(&inner) > TLS13_RECORD_MAX_PLAINTEXT_LEN) {
6048edacedfSDaniel Fojt 		rl->alert = TLS13_ALERT_RECORD_OVERFLOW;
6058edacedfSDaniel Fojt 		goto err;
6068edacedfSDaniel Fojt 	}
607cca6fc52SDaniel Fojt 
608*de0e0e4dSAntonio Huete Jimenez 	tls_content_set_data(rl->rcontent, content_type, CBS_data(&inner),
609*de0e0e4dSAntonio Huete Jimenez 	    CBS_len(&inner));
610cca6fc52SDaniel Fojt 
611cca6fc52SDaniel Fojt 	return 1;
612cca6fc52SDaniel Fojt 
613cca6fc52SDaniel Fojt  err:
614cca6fc52SDaniel Fojt 	freezero(content, content_len);
615cca6fc52SDaniel Fojt 
616cca6fc52SDaniel Fojt 	return 0;
617cca6fc52SDaniel Fojt }
618cca6fc52SDaniel Fojt 
619cca6fc52SDaniel Fojt static int
tls13_record_layer_open_record(struct tls13_record_layer * rl)620cca6fc52SDaniel Fojt tls13_record_layer_open_record(struct tls13_record_layer *rl)
621cca6fc52SDaniel Fojt {
622cca6fc52SDaniel Fojt 	if (rl->handshake_completed && rl->aead == NULL)
623cca6fc52SDaniel Fojt 		return 0;
624cca6fc52SDaniel Fojt 
625cca6fc52SDaniel Fojt 	if (rl->aead == NULL)
626cca6fc52SDaniel Fojt 		return tls13_record_layer_open_record_plaintext(rl);
627cca6fc52SDaniel Fojt 
628cca6fc52SDaniel Fojt 	return tls13_record_layer_open_record_protected(rl);
629cca6fc52SDaniel Fojt }
630cca6fc52SDaniel Fojt 
631cca6fc52SDaniel Fojt static int
tls13_record_layer_seal_record_plaintext(struct tls13_record_layer * rl,uint8_t content_type,const uint8_t * content,size_t content_len)632cca6fc52SDaniel Fojt tls13_record_layer_seal_record_plaintext(struct tls13_record_layer *rl,
633cca6fc52SDaniel Fojt     uint8_t content_type, const uint8_t *content, size_t content_len)
634cca6fc52SDaniel Fojt {
635cca6fc52SDaniel Fojt 	uint8_t *data = NULL;
636cca6fc52SDaniel Fojt 	size_t data_len = 0;
637cca6fc52SDaniel Fojt 	CBB cbb, body;
638cca6fc52SDaniel Fojt 
6398edacedfSDaniel Fojt 	/*
6408edacedfSDaniel Fojt 	 * Allow dummy CCS messages to be sent in plaintext even when
6418edacedfSDaniel Fojt 	 * record protection has been engaged, as long as the handshake
6428edacedfSDaniel Fojt 	 * has not yet completed.
6438edacedfSDaniel Fojt 	 */
6448edacedfSDaniel Fojt 	if (rl->handshake_completed)
6458edacedfSDaniel Fojt 		return 0;
6468edacedfSDaniel Fojt 	if (rl->aead != NULL && content_type != SSL3_RT_CHANGE_CIPHER_SPEC)
647cca6fc52SDaniel Fojt 		return 0;
648cca6fc52SDaniel Fojt 
649cca6fc52SDaniel Fojt 	/*
650cca6fc52SDaniel Fojt 	 * We're still operating in plaintext mode, so just copy the
651cca6fc52SDaniel Fojt 	 * content into the record.
652cca6fc52SDaniel Fojt 	 */
653cca6fc52SDaniel Fojt 	if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN + content_len))
654cca6fc52SDaniel Fojt 		goto err;
655cca6fc52SDaniel Fojt 
656cca6fc52SDaniel Fojt 	if (!CBB_add_u8(&cbb, content_type))
657cca6fc52SDaniel Fojt 		goto err;
658cca6fc52SDaniel Fojt 	if (!CBB_add_u16(&cbb, rl->legacy_version))
659cca6fc52SDaniel Fojt 		goto err;
660cca6fc52SDaniel Fojt 	if (!CBB_add_u16_length_prefixed(&cbb, &body))
661cca6fc52SDaniel Fojt 		goto err;
662cca6fc52SDaniel Fojt 	if (!CBB_add_bytes(&body, content, content_len))
663cca6fc52SDaniel Fojt 		goto err;
664cca6fc52SDaniel Fojt 
665cca6fc52SDaniel Fojt 	if (!CBB_finish(&cbb, &data, &data_len))
666cca6fc52SDaniel Fojt 		goto err;
667cca6fc52SDaniel Fojt 
668cca6fc52SDaniel Fojt 	if (!tls13_record_set_data(rl->wrec, data, data_len))
669cca6fc52SDaniel Fojt 		goto err;
670cca6fc52SDaniel Fojt 
671cca6fc52SDaniel Fojt 	rl->wrec_content_len = content_len;
672cca6fc52SDaniel Fojt 	rl->wrec_content_type = content_type;
673cca6fc52SDaniel Fojt 
674cca6fc52SDaniel Fojt 	return 1;
675cca6fc52SDaniel Fojt 
676cca6fc52SDaniel Fojt  err:
677cca6fc52SDaniel Fojt 	CBB_cleanup(&cbb);
678cca6fc52SDaniel Fojt 	freezero(data, data_len);
679cca6fc52SDaniel Fojt 
680cca6fc52SDaniel Fojt 	return 0;
681cca6fc52SDaniel Fojt }
682cca6fc52SDaniel Fojt 
683cca6fc52SDaniel Fojt static int
tls13_record_layer_seal_record_protected(struct tls13_record_layer * rl,uint8_t content_type,const uint8_t * content,size_t content_len)684cca6fc52SDaniel Fojt tls13_record_layer_seal_record_protected(struct tls13_record_layer *rl,
685cca6fc52SDaniel Fojt     uint8_t content_type, const uint8_t *content, size_t content_len)
686cca6fc52SDaniel Fojt {
687cca6fc52SDaniel Fojt 	uint8_t *data = NULL, *header = NULL, *inner = NULL;
688cca6fc52SDaniel Fojt 	size_t data_len = 0, header_len = 0, inner_len = 0;
689cca6fc52SDaniel Fojt 	uint8_t *enc_record;
690cca6fc52SDaniel Fojt 	size_t enc_record_len;
691cca6fc52SDaniel Fojt 	ssize_t ret = 0;
692cca6fc52SDaniel Fojt 	size_t out_len;
693cca6fc52SDaniel Fojt 	CBB cbb;
694cca6fc52SDaniel Fojt 
695cca6fc52SDaniel Fojt 	if (rl->aead == NULL)
696cca6fc52SDaniel Fojt 		return 0;
697cca6fc52SDaniel Fojt 
698cca6fc52SDaniel Fojt 	memset(&cbb, 0, sizeof(cbb));
699cca6fc52SDaniel Fojt 
700cca6fc52SDaniel Fojt 	/* Build inner plaintext. */
701cca6fc52SDaniel Fojt 	if (!CBB_init(&cbb, content_len + 1))
702cca6fc52SDaniel Fojt 		goto err;
703cca6fc52SDaniel Fojt 	if (!CBB_add_bytes(&cbb, content, content_len))
704cca6fc52SDaniel Fojt 		goto err;
705cca6fc52SDaniel Fojt 	if (!CBB_add_u8(&cbb, content_type))
706cca6fc52SDaniel Fojt 		goto err;
707cca6fc52SDaniel Fojt 	/* XXX - padding? */
708cca6fc52SDaniel Fojt 	if (!CBB_finish(&cbb, &inner, &inner_len))
709cca6fc52SDaniel Fojt 		goto err;
710cca6fc52SDaniel Fojt 
711cca6fc52SDaniel Fojt 	if (inner_len > TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN)
712cca6fc52SDaniel Fojt 		goto err;
713cca6fc52SDaniel Fojt 
714cca6fc52SDaniel Fojt 	/* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */
715cca6fc52SDaniel Fojt 	enc_record_len = inner_len + EVP_AEAD_max_tag_len(rl->aead);
716cca6fc52SDaniel Fojt 	if (enc_record_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN)
717cca6fc52SDaniel Fojt 		goto err;
718cca6fc52SDaniel Fojt 
719cca6fc52SDaniel Fojt 	/* Build the record header. */
720cca6fc52SDaniel Fojt 	if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN))
721cca6fc52SDaniel Fojt 		goto err;
722cca6fc52SDaniel Fojt 	if (!CBB_add_u8(&cbb, SSL3_RT_APPLICATION_DATA))
723cca6fc52SDaniel Fojt 		goto err;
724cca6fc52SDaniel Fojt 	if (!CBB_add_u16(&cbb, TLS1_2_VERSION))
725cca6fc52SDaniel Fojt 		goto err;
726cca6fc52SDaniel Fojt 	if (!CBB_add_u16(&cbb, enc_record_len))
727cca6fc52SDaniel Fojt 		goto err;
728cca6fc52SDaniel Fojt 	if (!CBB_finish(&cbb, &header, &header_len))
729cca6fc52SDaniel Fojt 		goto err;
730cca6fc52SDaniel Fojt 
731cca6fc52SDaniel Fojt 	/* Build the actual record. */
732cca6fc52SDaniel Fojt 	if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN + enc_record_len))
733cca6fc52SDaniel Fojt 		goto err;
734cca6fc52SDaniel Fojt 	if (!CBB_add_bytes(&cbb, header, header_len))
735cca6fc52SDaniel Fojt 		goto err;
736cca6fc52SDaniel Fojt 	if (!CBB_add_space(&cbb, &enc_record, enc_record_len))
737cca6fc52SDaniel Fojt 		goto err;
738cca6fc52SDaniel Fojt 	if (!CBB_finish(&cbb, &data, &data_len))
739cca6fc52SDaniel Fojt 		goto err;
740cca6fc52SDaniel Fojt 
741*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_record_layer_update_nonce(&rl->write->nonce,
742*de0e0e4dSAntonio Huete Jimenez 	    &rl->write->iv, rl->write->seq_num))
743cca6fc52SDaniel Fojt 		goto err;
744cca6fc52SDaniel Fojt 
745cca6fc52SDaniel Fojt 	/*
746cca6fc52SDaniel Fojt 	 * XXX - consider a EVP_AEAD_CTX_seal_iov() that takes an iovec...
747cca6fc52SDaniel Fojt 	 * this would avoid a copy since the inner would be passed as two
748cca6fc52SDaniel Fojt 	 * separate pieces.
749cca6fc52SDaniel Fojt 	 */
750*de0e0e4dSAntonio Huete Jimenez 	if (!EVP_AEAD_CTX_seal(rl->write->aead_ctx,
751cca6fc52SDaniel Fojt 	    enc_record, &out_len, enc_record_len,
752*de0e0e4dSAntonio Huete Jimenez 	    rl->write->nonce.data, rl->write->nonce.len,
753cca6fc52SDaniel Fojt 	    inner, inner_len, header, header_len))
754cca6fc52SDaniel Fojt 		goto err;
755cca6fc52SDaniel Fojt 
756cca6fc52SDaniel Fojt 	if (out_len != enc_record_len)
757cca6fc52SDaniel Fojt 		goto err;
758cca6fc52SDaniel Fojt 
759*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_record_layer_inc_seq_num(rl->write->seq_num))
760cca6fc52SDaniel Fojt 		goto err;
761cca6fc52SDaniel Fojt 
762cca6fc52SDaniel Fojt 	if (!tls13_record_set_data(rl->wrec, data, data_len))
763cca6fc52SDaniel Fojt 		goto err;
764cca6fc52SDaniel Fojt 
765cca6fc52SDaniel Fojt 	rl->wrec_content_len = content_len;
766cca6fc52SDaniel Fojt 	rl->wrec_content_type = content_type;
767cca6fc52SDaniel Fojt 
768cca6fc52SDaniel Fojt 	data = NULL;
769cca6fc52SDaniel Fojt 	data_len = 0;
770cca6fc52SDaniel Fojt 
771cca6fc52SDaniel Fojt 	ret = 1;
772cca6fc52SDaniel Fojt 
773cca6fc52SDaniel Fojt  err:
774cca6fc52SDaniel Fojt 	CBB_cleanup(&cbb);
775cca6fc52SDaniel Fojt 
776cca6fc52SDaniel Fojt 	freezero(data, data_len);
777cca6fc52SDaniel Fojt 	freezero(header, header_len);
778cca6fc52SDaniel Fojt 	freezero(inner, inner_len);
779cca6fc52SDaniel Fojt 
780cca6fc52SDaniel Fojt 	return ret;
781cca6fc52SDaniel Fojt }
782cca6fc52SDaniel Fojt 
783cca6fc52SDaniel Fojt static int
tls13_record_layer_seal_record(struct tls13_record_layer * rl,uint8_t content_type,const uint8_t * content,size_t content_len)784cca6fc52SDaniel Fojt tls13_record_layer_seal_record(struct tls13_record_layer *rl,
785cca6fc52SDaniel Fojt     uint8_t content_type, const uint8_t *content, size_t content_len)
786cca6fc52SDaniel Fojt {
787cca6fc52SDaniel Fojt 	if (rl->handshake_completed && rl->aead == NULL)
788cca6fc52SDaniel Fojt 		return 0;
789cca6fc52SDaniel Fojt 
790cca6fc52SDaniel Fojt 	tls13_record_layer_wrec_free(rl);
791cca6fc52SDaniel Fojt 
792cca6fc52SDaniel Fojt 	if ((rl->wrec = tls13_record_new()) == NULL)
793cca6fc52SDaniel Fojt 		return 0;
794cca6fc52SDaniel Fojt 
7958edacedfSDaniel Fojt 	if (rl->aead == NULL || content_type == SSL3_RT_CHANGE_CIPHER_SPEC)
796cca6fc52SDaniel Fojt 		return tls13_record_layer_seal_record_plaintext(rl,
797cca6fc52SDaniel Fojt 		    content_type, content, content_len);
798cca6fc52SDaniel Fojt 
799cca6fc52SDaniel Fojt 	return tls13_record_layer_seal_record_protected(rl, content_type,
800cca6fc52SDaniel Fojt 	    content, content_len);
801cca6fc52SDaniel Fojt }
802cca6fc52SDaniel Fojt 
803cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_read_record(struct tls13_record_layer * rl)804cca6fc52SDaniel Fojt tls13_record_layer_read_record(struct tls13_record_layer *rl)
805cca6fc52SDaniel Fojt {
806cca6fc52SDaniel Fojt 	uint8_t content_type, ccs;
807cca6fc52SDaniel Fojt 	ssize_t ret;
808cca6fc52SDaniel Fojt 	CBS cbs;
809cca6fc52SDaniel Fojt 
810cca6fc52SDaniel Fojt 	if (rl->rrec == NULL) {
811cca6fc52SDaniel Fojt 		if ((rl->rrec = tls13_record_new()) == NULL)
812cca6fc52SDaniel Fojt 			goto err;
813cca6fc52SDaniel Fojt 	}
814cca6fc52SDaniel Fojt 
8158edacedfSDaniel Fojt 	if ((ret = tls13_record_recv(rl->rrec, rl->cb.wire_read, rl->cb_arg)) <= 0) {
8168edacedfSDaniel Fojt 		switch (ret) {
8178edacedfSDaniel Fojt 		case TLS13_IO_RECORD_VERSION:
8188edacedfSDaniel Fojt 			return tls13_send_alert(rl, TLS13_ALERT_PROTOCOL_VERSION);
8198edacedfSDaniel Fojt 		case TLS13_IO_RECORD_OVERFLOW:
8208edacedfSDaniel Fojt 			return tls13_send_alert(rl, TLS13_ALERT_RECORD_OVERFLOW);
8218edacedfSDaniel Fojt 		}
822cca6fc52SDaniel Fojt 		return ret;
8238edacedfSDaniel Fojt 	}
824cca6fc52SDaniel Fojt 
825cca6fc52SDaniel Fojt 	content_type = tls13_record_content_type(rl->rrec);
826cca6fc52SDaniel Fojt 
827cca6fc52SDaniel Fojt 	/*
828*de0e0e4dSAntonio Huete Jimenez 	 * In response to a client hello we may receive an alert in a
829*de0e0e4dSAntonio Huete Jimenez 	 * record with a legacy version. Otherwise enforce that the
830*de0e0e4dSAntonio Huete Jimenez 	 * legacy record version is 0x0303 per RFC 8446, section 5.1.
831*de0e0e4dSAntonio Huete Jimenez 	 */
832*de0e0e4dSAntonio Huete Jimenez 	if (rl->legacy_version == TLS1_2_VERSION &&
833*de0e0e4dSAntonio Huete Jimenez 	    tls13_record_version(rl->rrec) != TLS1_2_VERSION &&
834*de0e0e4dSAntonio Huete Jimenez 	    (content_type != SSL3_RT_ALERT || !rl->legacy_alerts_allowed))
835*de0e0e4dSAntonio Huete Jimenez 		return tls13_send_alert(rl, TLS13_ALERT_PROTOCOL_VERSION);
836*de0e0e4dSAntonio Huete Jimenez 
837*de0e0e4dSAntonio Huete Jimenez 	/*
838cca6fc52SDaniel Fojt 	 * Bag of hacks ahead... after the first ClientHello message has been
839cca6fc52SDaniel Fojt 	 * sent or received and before the peer's Finished message has been
840cca6fc52SDaniel Fojt 	 * received, we may receive an unencrypted ChangeCipherSpec record
841cca6fc52SDaniel Fojt 	 * (see RFC 8446 section 5 and appendix D.4). This record must be
842cca6fc52SDaniel Fojt 	 * ignored.
843cca6fc52SDaniel Fojt 	 */
844cca6fc52SDaniel Fojt 	if (content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
845cca6fc52SDaniel Fojt 		if (!rl->ccs_allowed || rl->ccs_seen >= 2)
8468edacedfSDaniel Fojt 			return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
847cca6fc52SDaniel Fojt 		if (!tls13_record_content(rl->rrec, &cbs))
8488edacedfSDaniel Fojt 			return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
849cca6fc52SDaniel Fojt 		if (!CBS_get_u8(&cbs, &ccs))
8508edacedfSDaniel Fojt 			return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
851cca6fc52SDaniel Fojt 		if (ccs != 1)
8528edacedfSDaniel Fojt 			return tls13_send_alert(rl, TLS13_ALERT_ILLEGAL_PARAMETER);
853*de0e0e4dSAntonio Huete Jimenez 		if (CBS_len(&cbs) != 0)
854*de0e0e4dSAntonio Huete Jimenez 			return tls13_send_alert(rl, TLS13_ALERT_DECODE_ERROR);
855cca6fc52SDaniel Fojt 		rl->ccs_seen++;
856cca6fc52SDaniel Fojt 		tls13_record_layer_rrec_free(rl);
857cca6fc52SDaniel Fojt 		return TLS13_IO_WANT_RETRY;
858cca6fc52SDaniel Fojt 	}
859cca6fc52SDaniel Fojt 
860cca6fc52SDaniel Fojt 	/*
861cca6fc52SDaniel Fojt 	 * Once record protection is engaged, we should only receive
862cca6fc52SDaniel Fojt 	 * protected application data messages (aside from the
863cca6fc52SDaniel Fojt 	 * dummy ChangeCipherSpec messages, handled above).
864cca6fc52SDaniel Fojt 	 */
865cca6fc52SDaniel Fojt 	if (rl->aead != NULL && content_type != SSL3_RT_APPLICATION_DATA)
8668edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
867cca6fc52SDaniel Fojt 
868cca6fc52SDaniel Fojt 	if (!tls13_record_layer_open_record(rl))
869cca6fc52SDaniel Fojt 		goto err;
870cca6fc52SDaniel Fojt 
871cca6fc52SDaniel Fojt 	tls13_record_layer_rrec_free(rl);
872cca6fc52SDaniel Fojt 
8738edacedfSDaniel Fojt 	/*
8748edacedfSDaniel Fojt 	 * On receiving a handshake or alert record with empty inner plaintext,
8758edacedfSDaniel Fojt 	 * we must terminate the connection with an unexpected_message alert.
8768edacedfSDaniel Fojt 	 * See RFC 8446 section 5.4.
8778edacedfSDaniel Fojt 	 */
878*de0e0e4dSAntonio Huete Jimenez 	if (tls_content_remaining(rl->rcontent) == 0 &&
879*de0e0e4dSAntonio Huete Jimenez 	    (tls_content_type(rl->rcontent) == SSL3_RT_ALERT ||
880*de0e0e4dSAntonio Huete Jimenez 	     tls_content_type(rl->rcontent) == SSL3_RT_HANDSHAKE))
8818edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
8828edacedfSDaniel Fojt 
883*de0e0e4dSAntonio Huete Jimenez 	switch (tls_content_type(rl->rcontent)) {
884cca6fc52SDaniel Fojt 	case SSL3_RT_ALERT:
885cca6fc52SDaniel Fojt 		return tls13_record_layer_process_alert(rl);
886cca6fc52SDaniel Fojt 
887cca6fc52SDaniel Fojt 	case SSL3_RT_HANDSHAKE:
888cca6fc52SDaniel Fojt 		break;
889cca6fc52SDaniel Fojt 
890cca6fc52SDaniel Fojt 	case SSL3_RT_APPLICATION_DATA:
891cca6fc52SDaniel Fojt 		if (!rl->handshake_completed)
8928edacedfSDaniel Fojt 			return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
893cca6fc52SDaniel Fojt 		break;
894cca6fc52SDaniel Fojt 
895cca6fc52SDaniel Fojt 	default:
8968edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
897cca6fc52SDaniel Fojt 	}
898cca6fc52SDaniel Fojt 
899cca6fc52SDaniel Fojt 	return TLS13_IO_SUCCESS;
900cca6fc52SDaniel Fojt 
901cca6fc52SDaniel Fojt  err:
902cca6fc52SDaniel Fojt 	return TLS13_IO_FAILURE;
903cca6fc52SDaniel Fojt }
904cca6fc52SDaniel Fojt 
905cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_pending(struct tls13_record_layer * rl,uint8_t content_type)906cca6fc52SDaniel Fojt tls13_record_layer_pending(struct tls13_record_layer *rl, uint8_t content_type)
907cca6fc52SDaniel Fojt {
908*de0e0e4dSAntonio Huete Jimenez 	if (tls_content_type(rl->rcontent) != content_type)
909cca6fc52SDaniel Fojt 		return 0;
910cca6fc52SDaniel Fojt 
911*de0e0e4dSAntonio Huete Jimenez 	return tls_content_remaining(rl->rcontent);
912cca6fc52SDaniel Fojt }
913cca6fc52SDaniel Fojt 
914cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_recv_phh(struct tls13_record_layer * rl)9158edacedfSDaniel Fojt tls13_record_layer_recv_phh(struct tls13_record_layer *rl)
9168edacedfSDaniel Fojt {
9178edacedfSDaniel Fojt 	ssize_t ret = TLS13_IO_FAILURE;
9188edacedfSDaniel Fojt 
9198edacedfSDaniel Fojt 	rl->phh = 1;
9208edacedfSDaniel Fojt 
9218edacedfSDaniel Fojt 	/*
9228edacedfSDaniel Fojt 	 * The post handshake handshake receive callback is allowed to return:
9238edacedfSDaniel Fojt 	 *
9248edacedfSDaniel Fojt 	 * TLS13_IO_WANT_POLLIN  need more handshake data.
9258edacedfSDaniel Fojt 	 * TLS13_IO_WANT_POLLOUT got whole handshake message, response enqueued.
9268edacedfSDaniel Fojt 	 * TLS13_IO_SUCCESS	 got the whole handshake, nothing more to do.
9278edacedfSDaniel Fojt 	 * TLS13_IO_FAILURE	 something broke.
9288edacedfSDaniel Fojt 	 */
9298edacedfSDaniel Fojt 	if (rl->cb.phh_recv != NULL)
930*de0e0e4dSAntonio Huete Jimenez 		ret = rl->cb.phh_recv(rl->cb_arg);
9318edacedfSDaniel Fojt 
932*de0e0e4dSAntonio Huete Jimenez 	tls_content_clear(rl->rcontent);
9338edacedfSDaniel Fojt 
9348edacedfSDaniel Fojt 	/* Leave post handshake handshake mode unless we need more data. */
9358edacedfSDaniel Fojt 	if (ret != TLS13_IO_WANT_POLLIN)
9368edacedfSDaniel Fojt 		rl->phh = 0;
9378edacedfSDaniel Fojt 
9388edacedfSDaniel Fojt 	if (ret == TLS13_IO_SUCCESS) {
9398edacedfSDaniel Fojt 		if (rl->phh_retry)
9408edacedfSDaniel Fojt 			return TLS13_IO_WANT_RETRY;
9418edacedfSDaniel Fojt 
9428edacedfSDaniel Fojt 		return TLS13_IO_WANT_POLLIN;
9438edacedfSDaniel Fojt 	}
9448edacedfSDaniel Fojt 
9458edacedfSDaniel Fojt 	return ret;
9468edacedfSDaniel Fojt }
9478edacedfSDaniel Fojt 
9488edacedfSDaniel Fojt static ssize_t
tls13_record_layer_read_internal(struct tls13_record_layer * rl,uint8_t content_type,uint8_t * buf,size_t n,int peek)949cca6fc52SDaniel Fojt tls13_record_layer_read_internal(struct tls13_record_layer *rl,
950cca6fc52SDaniel Fojt     uint8_t content_type, uint8_t *buf, size_t n, int peek)
951cca6fc52SDaniel Fojt {
952cca6fc52SDaniel Fojt 	ssize_t ret;
953cca6fc52SDaniel Fojt 
954cca6fc52SDaniel Fojt 	if ((ret = tls13_record_layer_send_pending(rl)) != TLS13_IO_SUCCESS)
955cca6fc52SDaniel Fojt 		return ret;
956cca6fc52SDaniel Fojt 
957cca6fc52SDaniel Fojt 	if (rl->read_closed)
958cca6fc52SDaniel Fojt 		return TLS13_IO_EOF;
959cca6fc52SDaniel Fojt 
960cca6fc52SDaniel Fojt 	/* If necessary, pull up the next record. */
961*de0e0e4dSAntonio Huete Jimenez 	if (tls_content_remaining(rl->rcontent) == 0) {
962cca6fc52SDaniel Fojt 		if ((ret = tls13_record_layer_read_record(rl)) <= 0)
963cca6fc52SDaniel Fojt 			return ret;
964cca6fc52SDaniel Fojt 
9658edacedfSDaniel Fojt 		/*
9668edacedfSDaniel Fojt 		 * We may have read a valid 0-byte application data record,
9678edacedfSDaniel Fojt 		 * in which case we need to read the next record.
9688edacedfSDaniel Fojt 		 */
969*de0e0e4dSAntonio Huete Jimenez 		if (tls_content_remaining(rl->rcontent) == 0)
9708edacedfSDaniel Fojt 			return TLS13_IO_WANT_POLLIN;
9718edacedfSDaniel Fojt 	}
972cca6fc52SDaniel Fojt 
973cca6fc52SDaniel Fojt 	/*
9748edacedfSDaniel Fojt 	 * If we are in post handshake handshake mode, we must not see
975cca6fc52SDaniel Fojt 	 * any record type that isn't a handshake until we are done.
976cca6fc52SDaniel Fojt 	 */
977*de0e0e4dSAntonio Huete Jimenez 	if (rl->phh && tls_content_type(rl->rcontent) != SSL3_RT_HANDSHAKE)
9788edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
979cca6fc52SDaniel Fojt 
980cca6fc52SDaniel Fojt 	/*
981cca6fc52SDaniel Fojt 	 * Handshake content can appear as post-handshake messages (yup,
982cca6fc52SDaniel Fojt 	 * the RFC reused the same content type...), which means we can
983cca6fc52SDaniel Fojt 	 * be trying to read application data and need to handle a
984cca6fc52SDaniel Fojt 	 * post-handshake handshake message instead...
985cca6fc52SDaniel Fojt 	 */
986*de0e0e4dSAntonio Huete Jimenez 	if (tls_content_type(rl->rcontent) != content_type) {
987*de0e0e4dSAntonio Huete Jimenez 		if (tls_content_type(rl->rcontent) == SSL3_RT_HANDSHAKE) {
9888edacedfSDaniel Fojt 			if (rl->handshake_completed)
9898edacedfSDaniel Fojt 				return tls13_record_layer_recv_phh(rl);
990cca6fc52SDaniel Fojt 		}
9918edacedfSDaniel Fojt 		return tls13_send_alert(rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
992cca6fc52SDaniel Fojt 	}
993cca6fc52SDaniel Fojt 
994*de0e0e4dSAntonio Huete Jimenez 	if (peek)
995*de0e0e4dSAntonio Huete Jimenez 		return tls_content_peek(rl->rcontent, buf, n);
996cca6fc52SDaniel Fojt 
997*de0e0e4dSAntonio Huete Jimenez 	return tls_content_read(rl->rcontent, buf, n);
998cca6fc52SDaniel Fojt }
999cca6fc52SDaniel Fojt 
1000cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_peek(struct tls13_record_layer * rl,uint8_t content_type,uint8_t * buf,size_t n)1001cca6fc52SDaniel Fojt tls13_record_layer_peek(struct tls13_record_layer *rl, uint8_t content_type,
1002cca6fc52SDaniel Fojt     uint8_t *buf, size_t n)
1003cca6fc52SDaniel Fojt {
1004cca6fc52SDaniel Fojt 	ssize_t ret;
1005cca6fc52SDaniel Fojt 
1006cca6fc52SDaniel Fojt 	do {
1007cca6fc52SDaniel Fojt 		ret = tls13_record_layer_read_internal(rl, content_type, buf, n, 1);
1008cca6fc52SDaniel Fojt 	} while (ret == TLS13_IO_WANT_RETRY);
1009cca6fc52SDaniel Fojt 
10108edacedfSDaniel Fojt 	if (rl->alert != 0)
10118edacedfSDaniel Fojt 		return tls13_send_alert(rl, rl->alert);
10128edacedfSDaniel Fojt 
1013cca6fc52SDaniel Fojt 	return ret;
1014cca6fc52SDaniel Fojt }
1015cca6fc52SDaniel Fojt 
1016cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_read(struct tls13_record_layer * rl,uint8_t content_type,uint8_t * buf,size_t n)1017cca6fc52SDaniel Fojt tls13_record_layer_read(struct tls13_record_layer *rl, uint8_t content_type,
1018cca6fc52SDaniel Fojt     uint8_t *buf, size_t n)
1019cca6fc52SDaniel Fojt {
1020cca6fc52SDaniel Fojt 	ssize_t ret;
1021cca6fc52SDaniel Fojt 
1022cca6fc52SDaniel Fojt 	do {
1023cca6fc52SDaniel Fojt 		ret = tls13_record_layer_read_internal(rl, content_type, buf, n, 0);
1024cca6fc52SDaniel Fojt 	} while (ret == TLS13_IO_WANT_RETRY);
1025cca6fc52SDaniel Fojt 
10268edacedfSDaniel Fojt 	if (rl->alert != 0)
10278edacedfSDaniel Fojt 		return tls13_send_alert(rl, rl->alert);
10288edacedfSDaniel Fojt 
1029cca6fc52SDaniel Fojt 	return ret;
1030cca6fc52SDaniel Fojt }
1031cca6fc52SDaniel Fojt 
1032cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_write_record(struct tls13_record_layer * rl,uint8_t content_type,const uint8_t * content,size_t content_len)1033cca6fc52SDaniel Fojt tls13_record_layer_write_record(struct tls13_record_layer *rl,
1034cca6fc52SDaniel Fojt     uint8_t content_type, const uint8_t *content, size_t content_len)
1035cca6fc52SDaniel Fojt {
1036cca6fc52SDaniel Fojt 	ssize_t ret;
1037cca6fc52SDaniel Fojt 
1038cca6fc52SDaniel Fojt 	if (rl->write_closed)
1039cca6fc52SDaniel Fojt 		return TLS13_IO_EOF;
1040cca6fc52SDaniel Fojt 
1041cca6fc52SDaniel Fojt 	/*
1042cca6fc52SDaniel Fojt 	 * If we pushed out application data while handling other messages,
1043cca6fc52SDaniel Fojt 	 * we need to return content length on the next call.
1044cca6fc52SDaniel Fojt 	 */
1045cca6fc52SDaniel Fojt 	if (content_type == SSL3_RT_APPLICATION_DATA &&
1046cca6fc52SDaniel Fojt 	    rl->wrec_appdata_len != 0) {
1047cca6fc52SDaniel Fojt 		ret = rl->wrec_appdata_len;
1048cca6fc52SDaniel Fojt 		rl->wrec_appdata_len = 0;
1049cca6fc52SDaniel Fojt 		return ret;
1050cca6fc52SDaniel Fojt 	}
1051cca6fc52SDaniel Fojt 
1052cca6fc52SDaniel Fojt 	/* See if there is an existing record and attempt to push it out... */
1053cca6fc52SDaniel Fojt 	if (rl->wrec != NULL) {
10548edacedfSDaniel Fojt 		if ((ret = tls13_record_send(rl->wrec, rl->cb.wire_write,
1055cca6fc52SDaniel Fojt 		    rl->cb_arg)) <= 0)
1056cca6fc52SDaniel Fojt 			return ret;
1057cca6fc52SDaniel Fojt 		tls13_record_layer_wrec_free(rl);
1058cca6fc52SDaniel Fojt 
1059cca6fc52SDaniel Fojt 		if (rl->wrec_content_type == content_type) {
1060cca6fc52SDaniel Fojt 			ret = rl->wrec_content_len;
1061cca6fc52SDaniel Fojt 			rl->wrec_content_len = 0;
1062cca6fc52SDaniel Fojt 			rl->wrec_content_type = 0;
1063cca6fc52SDaniel Fojt 			return ret;
1064cca6fc52SDaniel Fojt 		}
1065cca6fc52SDaniel Fojt 
1066cca6fc52SDaniel Fojt 		/*
1067cca6fc52SDaniel Fojt 		 * The only partial record type should be application data.
1068cca6fc52SDaniel Fojt 		 * All other cases are handled to completion.
1069cca6fc52SDaniel Fojt 		 */
1070cca6fc52SDaniel Fojt 		if (rl->wrec_content_type != SSL3_RT_APPLICATION_DATA)
1071cca6fc52SDaniel Fojt 			return TLS13_IO_FAILURE;
1072cca6fc52SDaniel Fojt 		rl->wrec_appdata_len = rl->wrec_content_len;
1073cca6fc52SDaniel Fojt 	}
1074cca6fc52SDaniel Fojt 
1075cca6fc52SDaniel Fojt 	if (content_len > TLS13_RECORD_MAX_PLAINTEXT_LEN)
1076cca6fc52SDaniel Fojt 		goto err;
1077cca6fc52SDaniel Fojt 
1078cca6fc52SDaniel Fojt 	if (!tls13_record_layer_seal_record(rl, content_type, content, content_len))
1079cca6fc52SDaniel Fojt 		goto err;
1080cca6fc52SDaniel Fojt 
10818edacedfSDaniel Fojt 	if ((ret = tls13_record_send(rl->wrec, rl->cb.wire_write, rl->cb_arg)) <= 0)
1082cca6fc52SDaniel Fojt 		return ret;
1083cca6fc52SDaniel Fojt 
1084cca6fc52SDaniel Fojt 	tls13_record_layer_wrec_free(rl);
1085cca6fc52SDaniel Fojt 
1086cca6fc52SDaniel Fojt 	return content_len;
1087cca6fc52SDaniel Fojt 
1088cca6fc52SDaniel Fojt  err:
1089cca6fc52SDaniel Fojt 	return TLS13_IO_FAILURE;
1090cca6fc52SDaniel Fojt }
1091cca6fc52SDaniel Fojt 
1092cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_write_chunk(struct tls13_record_layer * rl,uint8_t content_type,const uint8_t * buf,size_t n)1093cca6fc52SDaniel Fojt tls13_record_layer_write_chunk(struct tls13_record_layer *rl,
1094cca6fc52SDaniel Fojt     uint8_t content_type, const uint8_t *buf, size_t n)
1095cca6fc52SDaniel Fojt {
1096cca6fc52SDaniel Fojt 	if (n > TLS13_RECORD_MAX_PLAINTEXT_LEN)
1097cca6fc52SDaniel Fojt 		n = TLS13_RECORD_MAX_PLAINTEXT_LEN;
1098cca6fc52SDaniel Fojt 
1099cca6fc52SDaniel Fojt 	return tls13_record_layer_write_record(rl, content_type, buf, n);
1100cca6fc52SDaniel Fojt }
1101cca6fc52SDaniel Fojt 
1102cca6fc52SDaniel Fojt static ssize_t
tls13_record_layer_write(struct tls13_record_layer * rl,uint8_t content_type,const uint8_t * buf,size_t n)1103cca6fc52SDaniel Fojt tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type,
1104cca6fc52SDaniel Fojt     const uint8_t *buf, size_t n)
1105cca6fc52SDaniel Fojt {
1106cca6fc52SDaniel Fojt 	ssize_t ret;
1107cca6fc52SDaniel Fojt 
1108cca6fc52SDaniel Fojt 	do {
1109cca6fc52SDaniel Fojt 		ret = tls13_record_layer_send_pending(rl);
1110cca6fc52SDaniel Fojt 	} while (ret == TLS13_IO_WANT_RETRY);
1111cca6fc52SDaniel Fojt 	if (ret != TLS13_IO_SUCCESS)
1112cca6fc52SDaniel Fojt 		return ret;
1113cca6fc52SDaniel Fojt 
1114cca6fc52SDaniel Fojt 	do {
1115cca6fc52SDaniel Fojt 		ret = tls13_record_layer_write_chunk(rl, content_type, buf, n);
1116cca6fc52SDaniel Fojt 	} while (ret == TLS13_IO_WANT_RETRY);
1117cca6fc52SDaniel Fojt 
1118cca6fc52SDaniel Fojt 	return ret;
1119cca6fc52SDaniel Fojt }
1120cca6fc52SDaniel Fojt 
1121*de0e0e4dSAntonio Huete Jimenez ssize_t
tls13_record_layer_flush(struct tls13_record_layer * rl)1122*de0e0e4dSAntonio Huete Jimenez tls13_record_layer_flush(struct tls13_record_layer *rl)
1123*de0e0e4dSAntonio Huete Jimenez {
1124*de0e0e4dSAntonio Huete Jimenez 	return rl->cb.wire_flush(rl->cb_arg);
1125*de0e0e4dSAntonio Huete Jimenez }
1126*de0e0e4dSAntonio Huete Jimenez 
11278edacedfSDaniel Fojt static const uint8_t tls13_dummy_ccs[] = { 0x01 };
11288edacedfSDaniel Fojt 
11298edacedfSDaniel Fojt ssize_t
tls13_send_dummy_ccs(struct tls13_record_layer * rl)11308edacedfSDaniel Fojt tls13_send_dummy_ccs(struct tls13_record_layer *rl)
11318edacedfSDaniel Fojt {
11328edacedfSDaniel Fojt 	ssize_t ret;
11338edacedfSDaniel Fojt 
11348edacedfSDaniel Fojt 	if (rl->ccs_sent)
11358edacedfSDaniel Fojt 		return TLS13_IO_FAILURE;
11368edacedfSDaniel Fojt 
11378edacedfSDaniel Fojt 	if ((ret = tls13_record_layer_write(rl, SSL3_RT_CHANGE_CIPHER_SPEC,
11388edacedfSDaniel Fojt 	    tls13_dummy_ccs, sizeof(tls13_dummy_ccs))) <= 0)
11398edacedfSDaniel Fojt 		return ret;
11408edacedfSDaniel Fojt 
11418edacedfSDaniel Fojt 	rl->ccs_sent = 1;
11428edacedfSDaniel Fojt 
11438edacedfSDaniel Fojt 	return TLS13_IO_SUCCESS;
11448edacedfSDaniel Fojt }
11458edacedfSDaniel Fojt 
1146cca6fc52SDaniel Fojt ssize_t
tls13_read_handshake_data(struct tls13_record_layer * rl,uint8_t * buf,size_t n)1147cca6fc52SDaniel Fojt tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n)
1148cca6fc52SDaniel Fojt {
1149*de0e0e4dSAntonio Huete Jimenez 	if (rl->cb.handshake_read != NULL)
1150*de0e0e4dSAntonio Huete Jimenez 		return rl->cb.handshake_read(buf, n, rl->cb_arg);
1151*de0e0e4dSAntonio Huete Jimenez 
1152cca6fc52SDaniel Fojt 	return tls13_record_layer_read(rl, SSL3_RT_HANDSHAKE, buf, n);
1153cca6fc52SDaniel Fojt }
1154cca6fc52SDaniel Fojt 
1155cca6fc52SDaniel Fojt ssize_t
tls13_write_handshake_data(struct tls13_record_layer * rl,const uint8_t * buf,size_t n)1156cca6fc52SDaniel Fojt tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf,
1157cca6fc52SDaniel Fojt     size_t n)
1158cca6fc52SDaniel Fojt {
1159*de0e0e4dSAntonio Huete Jimenez 	if (rl->cb.handshake_write != NULL)
1160*de0e0e4dSAntonio Huete Jimenez 		return rl->cb.handshake_write(buf, n, rl->cb_arg);
1161*de0e0e4dSAntonio Huete Jimenez 
1162cca6fc52SDaniel Fojt 	return tls13_record_layer_write(rl, SSL3_RT_HANDSHAKE, buf, n);
1163cca6fc52SDaniel Fojt }
1164cca6fc52SDaniel Fojt 
1165cca6fc52SDaniel Fojt ssize_t
tls13_pending_application_data(struct tls13_record_layer * rl)1166cca6fc52SDaniel Fojt tls13_pending_application_data(struct tls13_record_layer *rl)
1167cca6fc52SDaniel Fojt {
1168cca6fc52SDaniel Fojt 	if (!rl->handshake_completed)
1169cca6fc52SDaniel Fojt 		return 0;
1170cca6fc52SDaniel Fojt 
1171cca6fc52SDaniel Fojt 	return tls13_record_layer_pending(rl, SSL3_RT_APPLICATION_DATA);
1172cca6fc52SDaniel Fojt }
1173cca6fc52SDaniel Fojt 
1174cca6fc52SDaniel Fojt ssize_t
tls13_peek_application_data(struct tls13_record_layer * rl,uint8_t * buf,size_t n)1175cca6fc52SDaniel Fojt tls13_peek_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n)
1176cca6fc52SDaniel Fojt {
1177cca6fc52SDaniel Fojt 	if (!rl->handshake_completed)
1178cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
1179cca6fc52SDaniel Fojt 
1180cca6fc52SDaniel Fojt 	return tls13_record_layer_peek(rl, SSL3_RT_APPLICATION_DATA, buf, n);
1181cca6fc52SDaniel Fojt }
1182cca6fc52SDaniel Fojt 
1183cca6fc52SDaniel Fojt ssize_t
tls13_read_application_data(struct tls13_record_layer * rl,uint8_t * buf,size_t n)1184cca6fc52SDaniel Fojt tls13_read_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n)
1185cca6fc52SDaniel Fojt {
1186cca6fc52SDaniel Fojt 	if (!rl->handshake_completed)
1187cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
1188cca6fc52SDaniel Fojt 
1189cca6fc52SDaniel Fojt 	return tls13_record_layer_read(rl, SSL3_RT_APPLICATION_DATA, buf, n);
1190cca6fc52SDaniel Fojt }
1191cca6fc52SDaniel Fojt 
1192cca6fc52SDaniel Fojt ssize_t
tls13_write_application_data(struct tls13_record_layer * rl,const uint8_t * buf,size_t n)1193cca6fc52SDaniel Fojt tls13_write_application_data(struct tls13_record_layer *rl, const uint8_t *buf,
1194cca6fc52SDaniel Fojt     size_t n)
1195cca6fc52SDaniel Fojt {
1196cca6fc52SDaniel Fojt 	if (!rl->handshake_completed)
1197cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
1198cca6fc52SDaniel Fojt 
1199cca6fc52SDaniel Fojt 	return tls13_record_layer_write(rl, SSL3_RT_APPLICATION_DATA, buf, n);
1200cca6fc52SDaniel Fojt }
1201cca6fc52SDaniel Fojt 
1202cca6fc52SDaniel Fojt ssize_t
tls13_send_alert(struct tls13_record_layer * rl,uint8_t alert_desc)1203cca6fc52SDaniel Fojt tls13_send_alert(struct tls13_record_layer *rl, uint8_t alert_desc)
1204cca6fc52SDaniel Fojt {
12058edacedfSDaniel Fojt 	uint8_t alert_level = TLS13_ALERT_LEVEL_FATAL;
1206cca6fc52SDaniel Fojt 	ssize_t ret;
1207cca6fc52SDaniel Fojt 
1208*de0e0e4dSAntonio Huete Jimenez 	if (rl->cb.alert_send != NULL)
1209*de0e0e4dSAntonio Huete Jimenez 		return rl->cb.alert_send(alert_desc, rl->cb_arg);
1210*de0e0e4dSAntonio Huete Jimenez 
12118edacedfSDaniel Fojt 	if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY ||
12128edacedfSDaniel Fojt 	    alert_desc == TLS13_ALERT_USER_CANCELED)
12138edacedfSDaniel Fojt 		alert_level = TLS13_ALERT_LEVEL_WARNING;
1214cca6fc52SDaniel Fojt 
1215cca6fc52SDaniel Fojt 	do {
1216*de0e0e4dSAntonio Huete Jimenez 		ret = tls13_record_layer_enqueue_alert(rl, alert_level,
1217*de0e0e4dSAntonio Huete Jimenez 		    alert_desc);
1218cca6fc52SDaniel Fojt 	} while (ret == TLS13_IO_WANT_RETRY);
1219cca6fc52SDaniel Fojt 
1220cca6fc52SDaniel Fojt 	return ret;
1221cca6fc52SDaniel Fojt }
1222