diff options
-rw-r--r-- | src/lib/libssl/Makefile | 6 | ||||
-rw-r--r-- | src/lib/libssl/tls13_internal.h | 32 | ||||
-rw-r--r-- | src/lib/libssl/tls13_record_layer.c | 758 |
3 files changed, 790 insertions, 6 deletions
diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index b835d3f5ae..d23aaa7249 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.48 2019/01/19 04:08:06 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.49 2019/01/20 10:31:54 jsing Exp $ |
2 | 2 | ||
3 | .include <bsd.own.mk> | 3 | .include <bsd.own.mk> |
4 | .ifndef NOMAN | 4 | .ifndef NOMAN |
@@ -16,7 +16,6 @@ CFLAGS+= -Wall -Wundef | |||
16 | CFLAGS+= -Werror | 16 | CFLAGS+= -Werror |
17 | .endif | 17 | .endif |
18 | CFLAGS+= -DLIBRESSL_INTERNAL | 18 | CFLAGS+= -DLIBRESSL_INTERNAL |
19 | |||
20 | CFLAGS+= -I${.CURDIR} | 19 | CFLAGS+= -I${.CURDIR} |
21 | 20 | ||
22 | LDADD+= -L${BSDOBJDIR}/lib/libcrypto -lcrypto | 21 | LDADD+= -L${BSDOBJDIR}/lib/libcrypto -lcrypto |
@@ -65,7 +64,8 @@ SRCS= \ | |||
65 | tls13_buffer.c \ | 64 | tls13_buffer.c \ |
66 | tls13_handshake.c \ | 65 | tls13_handshake.c \ |
67 | tls13_key_schedule.c \ | 66 | tls13_key_schedule.c \ |
68 | tls13_record.c | 67 | tls13_record.c \ |
68 | tls13_record_layer.c | ||
69 | 69 | ||
70 | HDRS= dtls1.h srtp.h ssl.h ssl2.h ssl23.h ssl3.h tls1.h | 70 | HDRS= dtls1.h srtp.h ssl.h ssl2.h ssl23.h ssl3.h tls1.h |
71 | 71 | ||
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index 876f339c80..496627c0cd 100644 --- a/src/lib/libssl/tls13_internal.h +++ b/src/lib/libssl/tls13_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_internal.h,v 1.8 2019/01/19 03:32:03 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.9 2019/01/20 10:31:54 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> |
4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> | 4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> |
@@ -31,8 +31,12 @@ __BEGIN_HIDDEN_DECLS | |||
31 | #define TLS13_IO_WANT_POLLIN -2 | 31 | #define TLS13_IO_WANT_POLLIN -2 |
32 | #define TLS13_IO_WANT_POLLOUT -3 | 32 | #define TLS13_IO_WANT_POLLOUT -3 |
33 | 33 | ||
34 | typedef int (*tls13_alert_cb)(uint8_t _alert_level, uint8_t _alert_desc, | ||
35 | void *_cb_arg); | ||
36 | typedef int (*tls13_post_handshake_cb)(void *_cb_arg); | ||
34 | typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg); | 37 | typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg); |
35 | typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen, void *_cb_arg); | 38 | typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen, |
39 | void *_cb_arg); | ||
36 | 40 | ||
37 | struct tls13_buffer; | 41 | struct tls13_buffer; |
38 | 42 | ||
@@ -41,7 +45,8 @@ void tls13_buffer_free(struct tls13_buffer *buf); | |||
41 | ssize_t tls13_buffer_extend(struct tls13_buffer *buf, size_t len, | 45 | ssize_t tls13_buffer_extend(struct tls13_buffer *buf, size_t len, |
42 | tls13_read_cb read_cb, void *cb_arg); | 46 | tls13_read_cb read_cb, void *cb_arg); |
43 | void tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs); | 47 | void tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs); |
44 | int tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out, size_t *out_len); | 48 | int tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out, |
49 | size_t *out_len); | ||
45 | 50 | ||
46 | struct tls13_secret { | 51 | struct tls13_secret { |
47 | uint8_t *data; | 52 | uint8_t *data; |
@@ -92,6 +97,27 @@ int tls13_derive_application_secrets(struct tls13_secrets *secrets, | |||
92 | 97 | ||
93 | struct tls13_ctx; | 98 | struct tls13_ctx; |
94 | 99 | ||
100 | struct tls13_record_layer; | ||
101 | |||
102 | struct tls13_record_layer *tls13_record_layer_new(tls13_read_cb wire_read, | ||
103 | tls13_write_cb wire_write, tls13_alert_cb alert_cb, | ||
104 | tls13_post_handshake_cb post_handshake_cb, void *cb_arg); | ||
105 | void tls13_record_layer_free(struct tls13_record_layer *rl); | ||
106 | void tls13_record_layer_set_aead(struct tls13_record_layer *rl, | ||
107 | const EVP_AEAD *aead); | ||
108 | void tls13_record_layer_set_hash(struct tls13_record_layer *rl, | ||
109 | const EVP_MD *hash); | ||
110 | void tls13_record_layer_handshake_completed(struct tls13_record_layer *rl); | ||
111 | int tls13_record_layer_set_traffic_keys(struct tls13_record_layer *rl, | ||
112 | struct tls13_secret *read_key, struct tls13_secret *write_key); | ||
113 | |||
114 | ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); | ||
115 | ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, | ||
116 | size_t n); | ||
117 | ssize_t tls13_read_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); | ||
118 | ssize_t tls13_write_application_data(struct tls13_record_layer *rl, const uint8_t *buf, | ||
119 | size_t n); | ||
120 | |||
95 | /* | 121 | /* |
96 | * RFC 8446, Section B.3 | 122 | * RFC 8446, Section B.3 |
97 | * | 123 | * |
diff --git a/src/lib/libssl/tls13_record_layer.c b/src/lib/libssl/tls13_record_layer.c new file mode 100644 index 0000000000..b70f9f174e --- /dev/null +++ b/src/lib/libssl/tls13_record_layer.c | |||
@@ -0,0 +1,758 @@ | |||
1 | /* $OpenBSD: tls13_record_layer.c,v 1.1 2019/01/20 10:31:54 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include "ssl_locl.h" | ||
19 | |||
20 | #include <openssl/curve25519.h> | ||
21 | |||
22 | #include "tls13_internal.h" | ||
23 | #include "tls13_record.h" | ||
24 | |||
25 | struct tls13_record_layer { | ||
26 | int change_cipher_spec_seen; | ||
27 | int handshake_completed; | ||
28 | |||
29 | struct tls13_record *rrec; | ||
30 | struct tls13_record *wrec; | ||
31 | |||
32 | /* Buffer containing plaintext from opened records. */ | ||
33 | uint8_t rbuf_content_type; | ||
34 | uint8_t *rbuf; | ||
35 | size_t rbuf_len; | ||
36 | CBS rbuf_cbs; | ||
37 | |||
38 | /* Record protection. */ | ||
39 | const EVP_MD *hash; | ||
40 | const EVP_AEAD *aead; | ||
41 | EVP_AEAD_CTX read_aead_ctx; | ||
42 | EVP_AEAD_CTX write_aead_ctx; | ||
43 | struct tls13_secret read_iv; | ||
44 | struct tls13_secret write_iv; | ||
45 | struct tls13_secret read_nonce; | ||
46 | struct tls13_secret write_nonce; | ||
47 | uint8_t read_seq_num[TLS13_RECORD_SEQ_NUM_LEN]; | ||
48 | uint8_t write_seq_num[TLS13_RECORD_SEQ_NUM_LEN]; | ||
49 | |||
50 | /* Record callbacks. */ | ||
51 | tls13_alert_cb alert_cb; | ||
52 | tls13_post_handshake_cb post_handshake_cb; | ||
53 | |||
54 | /* Wire read/write callbacks. */ | ||
55 | tls13_read_cb wire_read; | ||
56 | tls13_write_cb wire_write; | ||
57 | void *cb_arg; | ||
58 | }; | ||
59 | |||
60 | static void | ||
61 | tls13_record_layer_rbuf_free(struct tls13_record_layer *rl) | ||
62 | { | ||
63 | CBS_init(&rl->rbuf_cbs, NULL, 0); | ||
64 | freezero(rl->rbuf, rl->rbuf_len); | ||
65 | rl->rbuf = NULL; | ||
66 | rl->rbuf_len = 0; | ||
67 | rl->rbuf_content_type = 0; | ||
68 | } | ||
69 | |||
70 | static void | ||
71 | tls13_record_layer_rrec_free(struct tls13_record_layer *rl) | ||
72 | { | ||
73 | tls13_record_free(rl->rrec); | ||
74 | rl->rrec = NULL; | ||
75 | } | ||
76 | |||
77 | static void | ||
78 | tls13_record_layer_wrec_free(struct tls13_record_layer *rl) | ||
79 | { | ||
80 | tls13_record_free(rl->wrec); | ||
81 | rl->wrec = NULL; | ||
82 | } | ||
83 | |||
84 | struct tls13_record_layer * | ||
85 | tls13_record_layer_new(tls13_read_cb wire_read, tls13_write_cb wire_write, | ||
86 | tls13_alert_cb alert_cb, tls13_post_handshake_cb post_handshake_cb, | ||
87 | void *cb_arg) | ||
88 | { | ||
89 | struct tls13_record_layer *rl; | ||
90 | |||
91 | if ((rl = calloc(1, sizeof(struct tls13_record_layer))) == NULL) | ||
92 | return NULL; | ||
93 | |||
94 | rl->wire_read = wire_read; | ||
95 | rl->wire_write = wire_write; | ||
96 | rl->alert_cb = alert_cb; | ||
97 | rl->post_handshake_cb = post_handshake_cb; | ||
98 | rl->cb_arg = cb_arg; | ||
99 | |||
100 | return rl; | ||
101 | } | ||
102 | |||
103 | void | ||
104 | tls13_record_layer_free(struct tls13_record_layer *rl) | ||
105 | { | ||
106 | if (rl == NULL) | ||
107 | return; | ||
108 | |||
109 | tls13_record_layer_rbuf_free(rl); | ||
110 | |||
111 | tls13_record_layer_rrec_free(rl); | ||
112 | tls13_record_layer_wrec_free(rl); | ||
113 | |||
114 | EVP_AEAD_CTX_cleanup(&rl->read_aead_ctx); | ||
115 | EVP_AEAD_CTX_cleanup(&rl->write_aead_ctx); | ||
116 | |||
117 | freezero(rl->read_iv.data, rl->read_iv.len); | ||
118 | freezero(rl->write_iv.data, rl->write_iv.len); | ||
119 | freezero(rl->read_nonce.data, rl->read_nonce.len); | ||
120 | freezero(rl->write_nonce.data, rl->write_nonce.len); | ||
121 | |||
122 | freezero(rl, sizeof(struct tls13_record_layer)); | ||
123 | } | ||
124 | |||
125 | static int | ||
126 | tls13_record_layer_inc_seq_num(uint8_t *seq_num) | ||
127 | { | ||
128 | size_t i; | ||
129 | |||
130 | for (i = TLS13_RECORD_SEQ_NUM_LEN - 1; i > 0; i--) { | ||
131 | if (++seq_num[i] != 0) | ||
132 | break; | ||
133 | } | ||
134 | |||
135 | /* RFC 8446 section 5.3 - sequence numbers must not wrap. */ | ||
136 | return (i != 0 || seq_num[0] != 0); | ||
137 | } | ||
138 | |||
139 | static int | ||
140 | tls13_record_layer_update_nonce(struct tls13_secret *nonce, | ||
141 | struct tls13_secret *iv, uint8_t *seq_num) | ||
142 | { | ||
143 | ssize_t i, j; | ||
144 | |||
145 | if (nonce->len != iv->len) | ||
146 | return 0; | ||
147 | |||
148 | /* | ||
149 | * RFC 8446 section 5.3 - sequence number is zero padded and XOR'd | ||
150 | * with the IV to produce a per-record nonce. The IV will also be | ||
151 | * at least 8-bytes in length. | ||
152 | */ | ||
153 | for (i = nonce->len - 1, j = TLS13_RECORD_SEQ_NUM_LEN - 1; i >= 0; i--, j--) | ||
154 | nonce->data[i] = iv->data[i] ^ (j >= 0 ? seq_num[j] : 0); | ||
155 | |||
156 | return 1; | ||
157 | } | ||
158 | |||
159 | void | ||
160 | tls13_record_layer_set_aead(struct tls13_record_layer *rl, | ||
161 | const EVP_AEAD *aead) | ||
162 | { | ||
163 | rl->aead = aead; | ||
164 | } | ||
165 | |||
166 | void | ||
167 | tls13_record_layer_set_hash(struct tls13_record_layer *rl, | ||
168 | const EVP_MD *hash) | ||
169 | { | ||
170 | rl->hash = hash; | ||
171 | } | ||
172 | |||
173 | void | ||
174 | tls13_record_layer_handshake_completed(struct tls13_record_layer *rl) | ||
175 | { | ||
176 | rl->handshake_completed = 1; | ||
177 | } | ||
178 | |||
179 | static int | ||
180 | tls13_record_layer_process_alert(struct tls13_record_layer *rl) | ||
181 | { | ||
182 | uint8_t alert_level, alert_desc; | ||
183 | |||
184 | /* | ||
185 | * A TLSv1.3 alert record can only contain a single alert - this means | ||
186 | * that processing the alert must consume all of the record. The alert | ||
187 | * will result in one of three things - continuation (user_cancelled), | ||
188 | * read channel closure (close_notify) or termination (all others). | ||
189 | */ | ||
190 | if (rl->rbuf == NULL) | ||
191 | return -1; | ||
192 | if (rl->rbuf_content_type != SSL3_RT_ALERT) | ||
193 | return -1; | ||
194 | |||
195 | if (!CBS_get_u8(&rl->rbuf_cbs, &alert_level)) | ||
196 | return -1; /* XXX - decode error alert. */ | ||
197 | if (!CBS_get_u8(&rl->rbuf_cbs, &alert_desc)) | ||
198 | return -1; /* XXX - decode error alert. */ | ||
199 | |||
200 | if (CBS_len(&rl->rbuf_cbs) != 0) | ||
201 | return -1; | ||
202 | |||
203 | tls13_record_layer_rbuf_free(rl); | ||
204 | |||
205 | return rl->alert_cb(alert_level, alert_desc, rl->cb_arg); | ||
206 | } | ||
207 | |||
208 | int | ||
209 | tls13_record_layer_send_alert(struct tls13_record_layer *rl, | ||
210 | uint8_t alert_level, uint8_t alert_desc) | ||
211 | { | ||
212 | /* XXX - implement. */ | ||
213 | return -1; | ||
214 | } | ||
215 | |||
216 | static int | ||
217 | tls13_record_layer_set_traffic_key(const EVP_AEAD *aead, EVP_AEAD_CTX *aead_ctx, | ||
218 | const EVP_MD *hash, struct tls13_secret *iv, struct tls13_secret *nonce, | ||
219 | struct tls13_secret *traffic_key) | ||
220 | { | ||
221 | struct tls13_secret context = { .data = "", .len = 0 }; | ||
222 | struct tls13_secret key = { .data = NULL, .len = 0 }; | ||
223 | int ret = 0; | ||
224 | |||
225 | freezero(iv->data, iv->len); | ||
226 | iv->data = NULL; | ||
227 | iv->len = 0; | ||
228 | |||
229 | freezero(nonce->data, nonce->len); | ||
230 | nonce->data = NULL; | ||
231 | nonce->len = 0; | ||
232 | |||
233 | if ((iv->data = calloc(1, EVP_AEAD_nonce_length(aead))) == NULL) | ||
234 | goto err; | ||
235 | iv->len = EVP_AEAD_nonce_length(aead); | ||
236 | |||
237 | if ((nonce->data = calloc(1, EVP_AEAD_nonce_length(aead))) == NULL) | ||
238 | goto err; | ||
239 | nonce->len = EVP_AEAD_nonce_length(aead); | ||
240 | |||
241 | if ((key.data = calloc(1, EVP_AEAD_key_length(aead))) == NULL) | ||
242 | goto err; | ||
243 | key.len = EVP_AEAD_key_length(aead); | ||
244 | |||
245 | if (!tls13_hkdf_expand_label(iv, hash, traffic_key, "iv", &context)) | ||
246 | goto err; | ||
247 | if (!tls13_hkdf_expand_label(&key, hash, traffic_key, "key", &context)) | ||
248 | goto err; | ||
249 | |||
250 | if (!EVP_AEAD_CTX_init(aead_ctx, aead, key.data, key.len, | ||
251 | EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) | ||
252 | goto err; | ||
253 | |||
254 | ret = 1; | ||
255 | |||
256 | err: | ||
257 | freezero(key.data, key.len); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | int | ||
263 | tls13_record_layer_set_traffic_keys(struct tls13_record_layer *rl, | ||
264 | struct tls13_secret *read_key, struct tls13_secret *write_key) | ||
265 | { | ||
266 | memset(rl->read_seq_num, 0, TLS13_RECORD_SEQ_NUM_LEN); | ||
267 | memset(rl->write_seq_num, 0, TLS13_RECORD_SEQ_NUM_LEN); | ||
268 | |||
269 | if (!tls13_record_layer_set_traffic_key(rl->aead, &rl->read_aead_ctx, | ||
270 | rl->hash, &rl->read_iv, &rl->read_nonce, read_key)) | ||
271 | return 0; | ||
272 | |||
273 | if (!tls13_record_layer_set_traffic_key(rl->aead, &rl->write_aead_ctx, | ||
274 | rl->hash, &rl->write_iv, &rl->write_nonce, write_key)) | ||
275 | return 0; | ||
276 | |||
277 | return 1; | ||
278 | } | ||
279 | |||
280 | static int | ||
281 | tls13_record_layer_open_record_plaintext(struct tls13_record_layer *rl) | ||
282 | { | ||
283 | CBS cbs; | ||
284 | |||
285 | if (rl->aead != NULL) | ||
286 | return 0; | ||
287 | |||
288 | /* | ||
289 | * We're still operating in plaintext mode, so just copy the | ||
290 | * content from the record to the plaintext buffer. | ||
291 | */ | ||
292 | if (!tls13_record_content(rl->rrec, &cbs)) | ||
293 | return 0; | ||
294 | |||
295 | tls13_record_layer_rbuf_free(rl); | ||
296 | |||
297 | if (!CBS_stow(&cbs, &rl->rbuf, &rl->rbuf_len)) | ||
298 | return 0; | ||
299 | |||
300 | rl->rbuf_content_type = tls13_record_content_type(rl->rrec); | ||
301 | |||
302 | CBS_init(&rl->rbuf_cbs, rl->rbuf, rl->rbuf_len); | ||
303 | |||
304 | return 1; | ||
305 | } | ||
306 | |||
307 | static int | ||
308 | tls13_record_layer_open_record_protected(struct tls13_record_layer *rl) | ||
309 | { | ||
310 | CBS header, enc_record; | ||
311 | uint8_t *content = NULL; | ||
312 | ssize_t content_len = 0; | ||
313 | uint8_t content_type; | ||
314 | size_t out_len; | ||
315 | |||
316 | if (rl->aead == NULL) | ||
317 | goto err; | ||
318 | |||
319 | if (!tls13_record_header(rl->rrec, &header)) | ||
320 | goto err; | ||
321 | if (!tls13_record_content(rl->rrec, &enc_record)) | ||
322 | goto err; | ||
323 | |||
324 | if ((content = calloc(1, CBS_len(&enc_record))) == NULL) | ||
325 | goto err; | ||
326 | content_len = CBS_len(&enc_record); | ||
327 | |||
328 | if (!tls13_record_layer_update_nonce(&rl->read_nonce, &rl->read_iv, | ||
329 | rl->read_seq_num)) | ||
330 | goto err; | ||
331 | |||
332 | if (!EVP_AEAD_CTX_open(&rl->read_aead_ctx, | ||
333 | content, &out_len, content_len, | ||
334 | rl->read_nonce.data, rl->read_nonce.len, | ||
335 | CBS_data(&enc_record), CBS_len(&enc_record), | ||
336 | CBS_data(&header), CBS_len(&header))) | ||
337 | goto err; | ||
338 | |||
339 | if (!tls13_record_layer_inc_seq_num(rl->read_seq_num)) | ||
340 | goto err; | ||
341 | |||
342 | /* | ||
343 | * The real content type is hidden at the end of the record content and | ||
344 | * it may be followed by padding that consists of one or more zeroes. | ||
345 | * Time to hunt for that elusive content type! | ||
346 | */ | ||
347 | /* XXX - CBS from end? CBS_get_end_u8()? */ | ||
348 | content_len = out_len - 1; | ||
349 | while (content_len >= 0 && content[content_len] == 0) | ||
350 | content_len--; | ||
351 | if (content_len < 0) | ||
352 | goto err; | ||
353 | content_type = content[content_len]; | ||
354 | |||
355 | tls13_record_layer_rbuf_free(rl); | ||
356 | |||
357 | rl->rbuf_content_type = content_type; | ||
358 | rl->rbuf = content; | ||
359 | rl->rbuf_len = content_len; | ||
360 | |||
361 | CBS_init(&rl->rbuf_cbs, rl->rbuf, rl->rbuf_len); | ||
362 | |||
363 | return 1; | ||
364 | |||
365 | err: | ||
366 | freezero(content, content_len); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int | ||
372 | tls13_record_layer_open_record(struct tls13_record_layer *rl) | ||
373 | { | ||
374 | if (rl->aead == NULL) | ||
375 | return tls13_record_layer_open_record_plaintext(rl); | ||
376 | |||
377 | return tls13_record_layer_open_record_protected(rl); | ||
378 | } | ||
379 | |||
380 | static int | ||
381 | tls13_record_layer_seal_record_plaintext(struct tls13_record_layer *rl, | ||
382 | uint8_t content_type, const uint8_t *content, size_t content_len) | ||
383 | { | ||
384 | uint8_t *data = NULL; | ||
385 | size_t data_len = 0; | ||
386 | uint16_t version; | ||
387 | CBB cbb, body; | ||
388 | |||
389 | if (rl->aead != NULL) | ||
390 | return 0; | ||
391 | |||
392 | /* XXX - TLS1_VERSION for first client hello... */ | ||
393 | version = TLS1_2_VERSION; | ||
394 | |||
395 | /* | ||
396 | * We're still operating in plaintext mode, so just copy the | ||
397 | * content into the record. | ||
398 | */ | ||
399 | if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN + content_len)) | ||
400 | goto err; | ||
401 | |||
402 | if (!CBB_add_u8(&cbb, content_type)) | ||
403 | goto err; | ||
404 | if (!CBB_add_u16(&cbb, version)) | ||
405 | goto err; | ||
406 | if (!CBB_add_u16_length_prefixed(&cbb, &body)) | ||
407 | goto err; | ||
408 | if (!CBB_add_bytes(&body, content, content_len)) | ||
409 | goto err; | ||
410 | |||
411 | if (!CBB_finish(&cbb, &data, &data_len)) | ||
412 | goto err; | ||
413 | |||
414 | if (!tls13_record_set_data(rl->wrec, data, data_len)) | ||
415 | goto err; | ||
416 | |||
417 | return 1; | ||
418 | |||
419 | err: | ||
420 | CBB_cleanup(&cbb); | ||
421 | freezero(data, data_len); | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static int | ||
427 | tls13_record_layer_seal_record_protected(struct tls13_record_layer *rl, | ||
428 | uint8_t content_type, const uint8_t *content, size_t content_len) | ||
429 | { | ||
430 | uint8_t *data = NULL, *header = NULL, *inner = NULL; | ||
431 | size_t data_len = 0, header_len = 0, inner_len = 0; | ||
432 | uint8_t *enc_record; | ||
433 | size_t enc_record_len; | ||
434 | ssize_t ret = 0; | ||
435 | size_t out_len; | ||
436 | CBB cbb; | ||
437 | |||
438 | if (rl->aead == NULL) | ||
439 | return 0; | ||
440 | |||
441 | memset(&cbb, 0, sizeof(cbb)); | ||
442 | |||
443 | /* Build inner plaintext. */ | ||
444 | if (!CBB_init(&cbb, content_len + 1)) | ||
445 | goto err; | ||
446 | if (!CBB_add_bytes(&cbb, content, content_len)) | ||
447 | goto err; | ||
448 | if (!CBB_add_u8(&cbb, content_type)) | ||
449 | goto err; | ||
450 | /* XXX - padding? */ | ||
451 | if (!CBB_finish(&cbb, &inner, &inner_len)) | ||
452 | goto err; | ||
453 | |||
454 | if (inner_len > TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN) | ||
455 | goto err; | ||
456 | |||
457 | /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ | ||
458 | enc_record_len = inner_len + EVP_AEAD_max_tag_len(rl->aead); | ||
459 | if (enc_record_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN) | ||
460 | goto err; | ||
461 | |||
462 | /* Build the record header. */ | ||
463 | if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN)) | ||
464 | goto err; | ||
465 | if (!CBB_add_u8(&cbb, SSL3_RT_APPLICATION_DATA)) | ||
466 | goto err; | ||
467 | if (!CBB_add_u16(&cbb, TLS1_2_VERSION)) | ||
468 | goto err; | ||
469 | if (!CBB_add_u16(&cbb, enc_record_len)) | ||
470 | goto err; | ||
471 | if (!CBB_finish(&cbb, &header, &header_len)) | ||
472 | goto err; | ||
473 | |||
474 | /* Build the actual record. */ | ||
475 | if (!CBB_init(&cbb, TLS13_RECORD_HEADER_LEN + enc_record_len)) | ||
476 | goto err; | ||
477 | if (!CBB_add_bytes(&cbb, header, header_len)) | ||
478 | goto err; | ||
479 | if (!CBB_add_space(&cbb, &enc_record, enc_record_len)) | ||
480 | goto err; | ||
481 | if (!CBB_finish(&cbb, &data, &data_len)) | ||
482 | goto err; | ||
483 | |||
484 | if (!tls13_record_layer_update_nonce(&rl->write_nonce, | ||
485 | &rl->write_iv, rl->write_seq_num)) | ||
486 | goto err; | ||
487 | |||
488 | /* | ||
489 | * XXX - consider a EVP_AEAD_CTX_seal_iov() that takes an iovec... | ||
490 | * this would avoid a copy since the inner would be passed as two | ||
491 | * separate pieces. | ||
492 | */ | ||
493 | if (!EVP_AEAD_CTX_seal(&rl->write_aead_ctx, | ||
494 | enc_record, &out_len, enc_record_len, | ||
495 | rl->write_nonce.data, rl->write_nonce.len, | ||
496 | inner, inner_len, header, header_len)) | ||
497 | goto err; | ||
498 | |||
499 | if (out_len != enc_record_len) | ||
500 | goto err; | ||
501 | |||
502 | if (!tls13_record_layer_inc_seq_num(rl->write_seq_num)) | ||
503 | goto err; | ||
504 | |||
505 | if (!tls13_record_set_data(rl->wrec, data, data_len)) | ||
506 | goto err; | ||
507 | |||
508 | data = NULL; | ||
509 | data_len = 0; | ||
510 | |||
511 | ret = 1; | ||
512 | |||
513 | err: | ||
514 | CBB_cleanup(&cbb); | ||
515 | |||
516 | freezero(data, data_len); | ||
517 | freezero(header, header_len); | ||
518 | freezero(inner, inner_len); | ||
519 | |||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | static int | ||
524 | tls13_record_layer_seal_record(struct tls13_record_layer *rl, | ||
525 | uint8_t content_type, const uint8_t *content, size_t content_len) | ||
526 | { | ||
527 | tls13_record_layer_wrec_free(rl); | ||
528 | |||
529 | if ((rl->wrec = tls13_record_new()) == NULL) | ||
530 | return 0; | ||
531 | |||
532 | if (rl->aead == NULL) | ||
533 | return tls13_record_layer_seal_record_plaintext(rl, | ||
534 | content_type, content, content_len); | ||
535 | |||
536 | return tls13_record_layer_seal_record_protected(rl, content_type, | ||
537 | content, content_len); | ||
538 | } | ||
539 | |||
540 | static ssize_t | ||
541 | tls13_record_layer_read_record(struct tls13_record_layer *rl) | ||
542 | { | ||
543 | uint8_t content_type, ccs; | ||
544 | ssize_t ret; | ||
545 | CBS cbs; | ||
546 | |||
547 | again: /* XXX */ | ||
548 | |||
549 | if (rl->rrec == NULL) { | ||
550 | if ((rl->rrec = tls13_record_new()) == NULL) | ||
551 | goto err; | ||
552 | } | ||
553 | |||
554 | if ((ret = tls13_record_recv(rl->rrec, rl->wire_read, rl->cb_arg)) <= 0) | ||
555 | return ret; | ||
556 | |||
557 | /* XXX - record version checks. */ | ||
558 | |||
559 | content_type = tls13_record_content_type(rl->rrec); | ||
560 | |||
561 | /* | ||
562 | * Bag of hacks ahead... after the first ClientHello message has been | ||
563 | * sent or received and before the peer's Finished message has been | ||
564 | * received, we may receive an unencrypted ChangeCipherSpec record | ||
565 | * (see RFC 8446 section 5 and appendix D.4). This record must be | ||
566 | * ignored. | ||
567 | */ | ||
568 | if (content_type == SSL3_RT_CHANGE_CIPHER_SPEC) { | ||
569 | /* XXX - need to check after ClientHello, before Finished. */ | ||
570 | if (rl->handshake_completed || rl->change_cipher_spec_seen) { | ||
571 | /* XXX - unexpected message alert. */ | ||
572 | goto err; | ||
573 | } | ||
574 | if (!tls13_record_content(rl->rrec, &cbs)) { | ||
575 | /* XXX - decode error alert. */ | ||
576 | goto err; | ||
577 | } | ||
578 | if (!CBS_get_u8(&cbs, &ccs)) { | ||
579 | /* XXX - decode error alert. */ | ||
580 | goto err; | ||
581 | } | ||
582 | if (ccs != 1) { | ||
583 | /* XXX - something alert. */ | ||
584 | goto err; | ||
585 | } | ||
586 | rl->change_cipher_spec_seen = 1; | ||
587 | tls13_record_layer_rrec_free(rl); | ||
588 | goto again; /* XXX */ | ||
589 | } | ||
590 | |||
591 | /* | ||
592 | * Once record protection is engaged, we should only receive | ||
593 | * protected application data messages (aside from the | ||
594 | * dummy ChangeCipherSpec messages, handled above). | ||
595 | */ | ||
596 | if (rl->aead != NULL && content_type != SSL3_RT_APPLICATION_DATA) { | ||
597 | /* XXX - unexpected message alert. */ | ||
598 | goto err; | ||
599 | } | ||
600 | |||
601 | if (!tls13_record_layer_open_record(rl)) | ||
602 | goto err; | ||
603 | |||
604 | tls13_record_layer_rrec_free(rl); | ||
605 | |||
606 | switch (rl->rbuf_content_type) { | ||
607 | case SSL3_RT_ALERT: | ||
608 | return tls13_record_layer_process_alert(rl); | ||
609 | |||
610 | case SSL3_RT_HANDSHAKE: | ||
611 | break; | ||
612 | |||
613 | case SSL3_RT_APPLICATION_DATA: | ||
614 | if (!rl->handshake_completed) { | ||
615 | /* XXX - unexpected message alert. */ | ||
616 | goto err; | ||
617 | } | ||
618 | break; | ||
619 | |||
620 | default: | ||
621 | /* XXX - unexpected message alert. */ | ||
622 | goto err; | ||
623 | } | ||
624 | |||
625 | return TLS13_IO_SUCCESS; | ||
626 | |||
627 | err: | ||
628 | return TLS13_IO_FAILURE; | ||
629 | } | ||
630 | |||
631 | ssize_t | ||
632 | tls13_record_layer_read(struct tls13_record_layer *rl, uint8_t content_type, | ||
633 | uint8_t *buf, size_t n) | ||
634 | { | ||
635 | int ret; | ||
636 | |||
637 | /* XXX - loop here with record and byte limits. */ | ||
638 | /* XXX - send alert... */ | ||
639 | |||
640 | again: /* XXX */ | ||
641 | |||
642 | /* If necessary, pull up the next record. */ | ||
643 | if (CBS_len(&rl->rbuf_cbs) == 0) { | ||
644 | if ((ret = tls13_record_layer_read_record(rl)) <= 0) | ||
645 | return ret; | ||
646 | |||
647 | /* XXX - need to check record version. */ | ||
648 | } | ||
649 | if (rl->rbuf_content_type != content_type) { | ||
650 | /* | ||
651 | * Handshake content can appear as post-handshake messages (yup, | ||
652 | * the RFC reused the same content type...), which means we can | ||
653 | * be trying to read application data and need to handle a | ||
654 | * post-handshake handshake message instead... | ||
655 | */ | ||
656 | if (rl->rbuf_content_type == SSL3_RT_HANDSHAKE) { | ||
657 | if (rl->handshake_completed) { | ||
658 | /* XXX - call callback, drop for now... */ | ||
659 | tls13_record_layer_rbuf_free(rl); | ||
660 | goto again; | ||
661 | } | ||
662 | } | ||
663 | |||
664 | /* XXX - unexpected message alert. */ | ||
665 | goto err; | ||
666 | } | ||
667 | |||
668 | if (n > CBS_len(&rl->rbuf_cbs)) | ||
669 | n = CBS_len(&rl->rbuf_cbs); | ||
670 | |||
671 | /* XXX - CBS_memcpy? CBS_copy_bytes? */ | ||
672 | memcpy(buf, CBS_data(&rl->rbuf_cbs), n); | ||
673 | if (!CBS_skip(&rl->rbuf_cbs, n)) | ||
674 | goto err; | ||
675 | |||
676 | if (CBS_len(&rl->rbuf_cbs) == 0) | ||
677 | tls13_record_layer_rbuf_free(rl); | ||
678 | |||
679 | return n; | ||
680 | |||
681 | err: | ||
682 | return TLS13_IO_FAILURE; | ||
683 | } | ||
684 | |||
685 | static ssize_t | ||
686 | tls13_record_layer_write_record(struct tls13_record_layer *rl, | ||
687 | uint8_t content_type, const uint8_t *content, size_t content_len) | ||
688 | { | ||
689 | ssize_t ret; | ||
690 | |||
691 | /* See if there is an existing record and attempt to push it out... */ | ||
692 | if (rl->wrec != NULL) { | ||
693 | if ((ret = tls13_record_send(rl->wrec, rl->wire_write, | ||
694 | rl->cb_arg)) <= 0) | ||
695 | return ret; | ||
696 | |||
697 | tls13_record_layer_wrec_free(rl); | ||
698 | |||
699 | /* XXX - could be pushing out different data... */ | ||
700 | return content_len; | ||
701 | } | ||
702 | |||
703 | if (content_len > TLS13_RECORD_MAX_PLAINTEXT_LEN) | ||
704 | goto err; | ||
705 | |||
706 | if (!tls13_record_layer_seal_record(rl, content_type, content, content_len)) | ||
707 | goto err; | ||
708 | |||
709 | if ((ret = tls13_record_send(rl->wrec, rl->wire_write, rl->cb_arg)) <= 0) | ||
710 | return ret; | ||
711 | |||
712 | tls13_record_layer_wrec_free(rl); | ||
713 | |||
714 | return content_len; | ||
715 | |||
716 | err: | ||
717 | return TLS13_IO_FAILURE; | ||
718 | } | ||
719 | |||
720 | static ssize_t | ||
721 | tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type, | ||
722 | const uint8_t *buf, size_t n) | ||
723 | { | ||
724 | /* XXX - handle fragmenting... */ | ||
725 | return tls13_record_layer_write_record(rl, content_type, buf, n); | ||
726 | } | ||
727 | |||
728 | ssize_t | ||
729 | tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n) | ||
730 | { | ||
731 | return tls13_record_layer_read(rl, SSL3_RT_HANDSHAKE, buf, n); | ||
732 | } | ||
733 | |||
734 | ssize_t | ||
735 | tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, | ||
736 | size_t n) | ||
737 | { | ||
738 | return tls13_record_layer_write(rl, SSL3_RT_HANDSHAKE, buf, n); | ||
739 | } | ||
740 | |||
741 | ssize_t | ||
742 | tls13_read_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n) | ||
743 | { | ||
744 | if (!rl->handshake_completed) | ||
745 | return TLS13_IO_FAILURE; | ||
746 | |||
747 | return tls13_record_layer_read(rl, SSL3_RT_APPLICATION_DATA, buf, n); | ||
748 | } | ||
749 | |||
750 | ssize_t | ||
751 | tls13_write_application_data(struct tls13_record_layer *rl, const uint8_t *buf, | ||
752 | size_t n) | ||
753 | { | ||
754 | if (!rl->handshake_completed) | ||
755 | return TLS13_IO_FAILURE; | ||
756 | |||
757 | return tls13_record_layer_write(rl, SSL3_RT_APPLICATION_DATA, buf, n); | ||
758 | } | ||