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