xref: /openbsd-src/lib/libssl/tls12_record_layer.c (revision 11d1e10cf947d07b2ad0e8ea8c9732afda9ded9d)
1*11d1e10cSjsing /* $OpenBSD: tls12_record_layer.c,v 1.2 2020/09/15 15:11:58 jsing Exp $ */
2acef91a0Sjsing /*
3acef91a0Sjsing  * Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
4acef91a0Sjsing  *
5acef91a0Sjsing  * Permission to use, copy, modify, and distribute this software for any
6acef91a0Sjsing  * purpose with or without fee is hereby granted, provided that the above
7acef91a0Sjsing  * copyright notice and this permission notice appear in all copies.
8acef91a0Sjsing  *
9acef91a0Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10acef91a0Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11acef91a0Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12acef91a0Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13acef91a0Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14acef91a0Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15acef91a0Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16acef91a0Sjsing  */
17acef91a0Sjsing 
18acef91a0Sjsing #include <stdlib.h>
19acef91a0Sjsing 
20acef91a0Sjsing #include <openssl/evp.h>
21acef91a0Sjsing 
22acef91a0Sjsing #include "ssl_locl.h"
23acef91a0Sjsing 
24acef91a0Sjsing struct tls12_record_layer {
25acef91a0Sjsing 	uint16_t version;
26acef91a0Sjsing 	int dtls;
27acef91a0Sjsing 
28acef91a0Sjsing 	uint16_t read_epoch;
29acef91a0Sjsing 	uint16_t write_epoch;
30acef91a0Sjsing 
31acef91a0Sjsing 	int read_stream_mac;
32acef91a0Sjsing 	int write_stream_mac;
33acef91a0Sjsing 
34acef91a0Sjsing 	/*
35acef91a0Sjsing 	 * XXX - for now these are just pointers to externally managed
36acef91a0Sjsing 	 * structs/memory. These should eventually be owned by the record layer.
37acef91a0Sjsing 	 */
38acef91a0Sjsing 	SSL_AEAD_CTX *read_aead_ctx;
39acef91a0Sjsing 	SSL_AEAD_CTX *write_aead_ctx;
40acef91a0Sjsing 
41acef91a0Sjsing 	EVP_CIPHER_CTX *read_cipher_ctx;
42acef91a0Sjsing 	EVP_MD_CTX *read_hash_ctx;
43acef91a0Sjsing 	EVP_CIPHER_CTX *write_cipher_ctx;
44acef91a0Sjsing 	EVP_MD_CTX *write_hash_ctx;
45acef91a0Sjsing 
46acef91a0Sjsing 	uint8_t *read_seq_num;
47acef91a0Sjsing 	uint8_t *write_seq_num;
48acef91a0Sjsing };
49acef91a0Sjsing 
50acef91a0Sjsing struct tls12_record_layer *
51acef91a0Sjsing tls12_record_layer_new(void)
52acef91a0Sjsing {
53acef91a0Sjsing 	struct tls12_record_layer *rl;
54acef91a0Sjsing 
55acef91a0Sjsing 	if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL)
56acef91a0Sjsing 		return NULL;
57acef91a0Sjsing 
58acef91a0Sjsing 	return rl;
59acef91a0Sjsing }
60acef91a0Sjsing 
61acef91a0Sjsing void
62acef91a0Sjsing tls12_record_layer_free(struct tls12_record_layer *rl)
63acef91a0Sjsing {
64acef91a0Sjsing 	freezero(rl, sizeof(struct tls12_record_layer));
65acef91a0Sjsing }
66acef91a0Sjsing 
67acef91a0Sjsing void
68acef91a0Sjsing tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version)
69acef91a0Sjsing {
70acef91a0Sjsing 	rl->version = version;
71acef91a0Sjsing 	rl->dtls = (version == DTLS1_VERSION);
72acef91a0Sjsing }
73acef91a0Sjsing 
74acef91a0Sjsing void
75acef91a0Sjsing tls12_record_layer_set_read_epoch(struct tls12_record_layer *rl, uint16_t epoch)
76acef91a0Sjsing {
77acef91a0Sjsing 	rl->read_epoch = epoch;
78acef91a0Sjsing }
79acef91a0Sjsing 
80acef91a0Sjsing void
81acef91a0Sjsing tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, uint16_t epoch)
82acef91a0Sjsing {
83acef91a0Sjsing 	rl->write_epoch = epoch;
84acef91a0Sjsing }
85acef91a0Sjsing 
86acef91a0Sjsing static void
87acef91a0Sjsing tls12_record_layer_set_read_state(struct tls12_record_layer *rl,
88acef91a0Sjsing     SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx,
89acef91a0Sjsing     int stream_mac)
90acef91a0Sjsing {
91acef91a0Sjsing 	rl->read_aead_ctx = aead_ctx;
92acef91a0Sjsing 
93acef91a0Sjsing 	rl->read_cipher_ctx = cipher_ctx;
94acef91a0Sjsing 	rl->read_hash_ctx = hash_ctx;
95acef91a0Sjsing 	rl->read_stream_mac = stream_mac;
96acef91a0Sjsing }
97acef91a0Sjsing 
98acef91a0Sjsing static void
99acef91a0Sjsing tls12_record_layer_set_write_state(struct tls12_record_layer *rl,
100acef91a0Sjsing     SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx,
101acef91a0Sjsing     int stream_mac)
102acef91a0Sjsing {
103acef91a0Sjsing 	rl->write_aead_ctx = aead_ctx;
104acef91a0Sjsing 
105acef91a0Sjsing 	rl->write_cipher_ctx = cipher_ctx;
106acef91a0Sjsing 	rl->write_hash_ctx = hash_ctx;
107acef91a0Sjsing 	rl->write_stream_mac = stream_mac;
108acef91a0Sjsing }
109acef91a0Sjsing 
110acef91a0Sjsing void
111acef91a0Sjsing tls12_record_layer_clear_read_state(struct tls12_record_layer *rl)
112acef91a0Sjsing {
113acef91a0Sjsing 	tls12_record_layer_set_read_state(rl, NULL, NULL, NULL, 0);
114acef91a0Sjsing 	rl->read_seq_num = NULL;
115acef91a0Sjsing }
116acef91a0Sjsing 
117acef91a0Sjsing void
118acef91a0Sjsing tls12_record_layer_clear_write_state(struct tls12_record_layer *rl)
119acef91a0Sjsing {
120acef91a0Sjsing 	tls12_record_layer_set_write_state(rl, NULL, NULL, NULL, 0);
121acef91a0Sjsing 	rl->write_seq_num = NULL;
122acef91a0Sjsing }
123acef91a0Sjsing 
124acef91a0Sjsing void
125acef91a0Sjsing tls12_record_layer_set_read_seq_num(struct tls12_record_layer *rl,
126acef91a0Sjsing     uint8_t *seq_num)
127acef91a0Sjsing {
128acef91a0Sjsing 	rl->read_seq_num = seq_num;
129acef91a0Sjsing }
130acef91a0Sjsing 
131acef91a0Sjsing void
132acef91a0Sjsing tls12_record_layer_set_write_seq_num(struct tls12_record_layer *rl,
133acef91a0Sjsing     uint8_t *seq_num)
134acef91a0Sjsing {
135acef91a0Sjsing 	rl->write_seq_num = seq_num;
136acef91a0Sjsing }
137acef91a0Sjsing 
138acef91a0Sjsing int
139acef91a0Sjsing tls12_record_layer_set_read_aead(struct tls12_record_layer *rl,
140acef91a0Sjsing     SSL_AEAD_CTX *aead_ctx)
141acef91a0Sjsing {
142acef91a0Sjsing 	tls12_record_layer_set_read_state(rl, aead_ctx, NULL, NULL, 0);
143acef91a0Sjsing 
144acef91a0Sjsing 	return 1;
145acef91a0Sjsing }
146acef91a0Sjsing 
147acef91a0Sjsing int
148acef91a0Sjsing tls12_record_layer_set_write_aead(struct tls12_record_layer *rl,
149acef91a0Sjsing     SSL_AEAD_CTX *aead_ctx)
150acef91a0Sjsing {
151acef91a0Sjsing 	tls12_record_layer_set_write_state(rl, aead_ctx, NULL, NULL, 0);
152acef91a0Sjsing 
153acef91a0Sjsing 	return 1;
154acef91a0Sjsing }
155acef91a0Sjsing 
156acef91a0Sjsing int
157acef91a0Sjsing tls12_record_layer_set_read_cipher_hash(struct tls12_record_layer *rl,
158acef91a0Sjsing     EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac)
159acef91a0Sjsing {
160acef91a0Sjsing 	tls12_record_layer_set_read_state(rl, NULL, cipher_ctx, hash_ctx,
161acef91a0Sjsing 	    stream_mac);
162acef91a0Sjsing 
163acef91a0Sjsing 	return 1;
164acef91a0Sjsing }
165acef91a0Sjsing 
166acef91a0Sjsing int
167acef91a0Sjsing tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl,
168acef91a0Sjsing     EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac)
169acef91a0Sjsing {
170acef91a0Sjsing 	tls12_record_layer_set_write_state(rl, NULL, cipher_ctx, hash_ctx,
171acef91a0Sjsing 	    stream_mac);
172acef91a0Sjsing 
173acef91a0Sjsing 	return 1;
174acef91a0Sjsing }
175acef91a0Sjsing 
176acef91a0Sjsing static int
177acef91a0Sjsing tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb,
178acef91a0Sjsing     uint16_t epoch, uint8_t *seq_num, size_t seq_num_len)
179acef91a0Sjsing {
180acef91a0Sjsing 	CBS seq;
181acef91a0Sjsing 
182acef91a0Sjsing 	CBS_init(&seq, seq_num, seq_num_len);
183acef91a0Sjsing 
184acef91a0Sjsing 	if (rl->dtls) {
185acef91a0Sjsing 		if (!CBB_add_u16(cbb, epoch))
186acef91a0Sjsing 			return 0;
187acef91a0Sjsing 		if (!CBS_skip(&seq, 2))
188acef91a0Sjsing 			return 0;
189acef91a0Sjsing 	}
190acef91a0Sjsing 
191acef91a0Sjsing 	return CBB_add_bytes(cbb, CBS_data(&seq), CBS_len(&seq));
192acef91a0Sjsing }
193acef91a0Sjsing 
194acef91a0Sjsing static int
195acef91a0Sjsing tls12_record_layer_pseudo_header(struct tls12_record_layer *rl,
196acef91a0Sjsing     uint8_t content_type, uint16_t record_len, uint16_t epoch, uint8_t *seq_num,
197acef91a0Sjsing     size_t seq_num_len, uint8_t **out, size_t *out_len)
198acef91a0Sjsing {
199acef91a0Sjsing 	CBB cbb;
200acef91a0Sjsing 
201acef91a0Sjsing 	*out = NULL;
202acef91a0Sjsing 	*out_len = 0;
203acef91a0Sjsing 
204acef91a0Sjsing 	/* Build the pseudo-header used for MAC/AEAD. */
205acef91a0Sjsing 	if (!CBB_init(&cbb, 13))
206acef91a0Sjsing 		goto err;
207acef91a0Sjsing 
208acef91a0Sjsing 	if (!tls12_record_layer_build_seq_num(rl, &cbb, epoch,
209acef91a0Sjsing 	    seq_num, seq_num_len))
210acef91a0Sjsing 		goto err;
211acef91a0Sjsing 	if (!CBB_add_u8(&cbb, content_type))
212acef91a0Sjsing 		goto err;
213acef91a0Sjsing 	if (!CBB_add_u16(&cbb, rl->version))
214acef91a0Sjsing 		goto err;
215acef91a0Sjsing 	if (!CBB_add_u16(&cbb, record_len))
216acef91a0Sjsing 		goto err;
217acef91a0Sjsing 
218acef91a0Sjsing 	if (!CBB_finish(&cbb, out, out_len))
219acef91a0Sjsing 		goto err;
220acef91a0Sjsing 
221acef91a0Sjsing 	return 1;
222acef91a0Sjsing 
223acef91a0Sjsing  err:
224acef91a0Sjsing 	CBB_cleanup(&cbb);
225acef91a0Sjsing 
226acef91a0Sjsing 	return 0;
227acef91a0Sjsing }
228acef91a0Sjsing 
229acef91a0Sjsing static int
230acef91a0Sjsing tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb,
231acef91a0Sjsing     uint8_t content_type, const uint8_t *content, size_t content_len,
232acef91a0Sjsing     size_t *out_len)
233acef91a0Sjsing {
234acef91a0Sjsing 	EVP_MD_CTX *mac_ctx = NULL;
235acef91a0Sjsing 	uint8_t *header = NULL;
236acef91a0Sjsing 	size_t header_len;
237acef91a0Sjsing 	size_t mac_len;
238acef91a0Sjsing 	uint8_t *mac;
239acef91a0Sjsing 	int ret = 0;
240acef91a0Sjsing 
241acef91a0Sjsing 	if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
242acef91a0Sjsing 		goto err;
243acef91a0Sjsing 	if (!EVP_MD_CTX_copy(mac_ctx, rl->write_hash_ctx))
244acef91a0Sjsing 		goto err;
245acef91a0Sjsing 
246acef91a0Sjsing 	if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
247acef91a0Sjsing 	    rl->write_epoch, rl->write_seq_num, SSL3_SEQUENCE_SIZE,
248acef91a0Sjsing 	    &header, &header_len))
249acef91a0Sjsing 		goto err;
250acef91a0Sjsing 
251acef91a0Sjsing 	if (EVP_DigestSignUpdate(mac_ctx, header, header_len) <= 0)
252acef91a0Sjsing 		goto err;
253acef91a0Sjsing 	if (EVP_DigestSignUpdate(mac_ctx, content, content_len) <= 0)
254acef91a0Sjsing 		goto err;
255acef91a0Sjsing 	if (EVP_DigestSignFinal(mac_ctx, NULL, &mac_len) <= 0)
256acef91a0Sjsing 		goto err;
257acef91a0Sjsing 	if (!CBB_add_space(cbb, &mac, mac_len))
258acef91a0Sjsing 		goto err;
259acef91a0Sjsing 	if (EVP_DigestSignFinal(mac_ctx, mac, &mac_len) <= 0)
260acef91a0Sjsing 		goto err;
261acef91a0Sjsing 
262acef91a0Sjsing 	if (rl->write_stream_mac) {
263acef91a0Sjsing 		if (!EVP_MD_CTX_copy(rl->write_hash_ctx, mac_ctx))
264acef91a0Sjsing 			goto err;
265acef91a0Sjsing 	}
266acef91a0Sjsing 
267acef91a0Sjsing 	*out_len = mac_len;
268acef91a0Sjsing 
269acef91a0Sjsing 	ret = 1;
270acef91a0Sjsing 
271acef91a0Sjsing  err:
272acef91a0Sjsing 	EVP_MD_CTX_free(mac_ctx);
273acef91a0Sjsing 	free(header);
274acef91a0Sjsing 
275acef91a0Sjsing 	return ret;
276acef91a0Sjsing }
277acef91a0Sjsing 
278acef91a0Sjsing static int
279acef91a0Sjsing tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl,
280acef91a0Sjsing     uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
281acef91a0Sjsing {
282acef91a0Sjsing 	if (rl->write_aead_ctx != NULL || rl->write_cipher_ctx != NULL)
283acef91a0Sjsing 		return 0;
284acef91a0Sjsing 
285acef91a0Sjsing 	return CBB_add_bytes(out, content, content_len);
286acef91a0Sjsing }
287acef91a0Sjsing 
288acef91a0Sjsing static int
289acef91a0Sjsing tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl,
290acef91a0Sjsing     const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len)
291acef91a0Sjsing {
292acef91a0Sjsing 	CBB cbb;
293acef91a0Sjsing 
294acef91a0Sjsing 	if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE)
295acef91a0Sjsing 		return 0;
296acef91a0Sjsing 
297acef91a0Sjsing 	/* Fixed nonce and variable nonce (sequence number) are concatenated. */
298acef91a0Sjsing 	if (!CBB_init(&cbb, 16))
299acef91a0Sjsing 		goto err;
300acef91a0Sjsing 	if (!CBB_add_bytes(&cbb, aead->fixed_nonce,
301acef91a0Sjsing 	    aead->fixed_nonce_len))
302acef91a0Sjsing 		goto err;
303acef91a0Sjsing 	if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len))
304acef91a0Sjsing 		goto err;
305acef91a0Sjsing 	if (!CBB_finish(&cbb, out, out_len))
306acef91a0Sjsing 		goto err;
307acef91a0Sjsing 
308acef91a0Sjsing 	return 1;
309acef91a0Sjsing 
310acef91a0Sjsing  err:
311acef91a0Sjsing 	CBB_cleanup(&cbb);
312acef91a0Sjsing 
313acef91a0Sjsing 	return 0;
314acef91a0Sjsing }
315acef91a0Sjsing 
316acef91a0Sjsing static int
317acef91a0Sjsing tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl,
318acef91a0Sjsing     const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len)
319acef91a0Sjsing {
320acef91a0Sjsing 	uint8_t *nonce = NULL;
321acef91a0Sjsing 	size_t nonce_len = 0;
322acef91a0Sjsing 	uint8_t *pad;
323acef91a0Sjsing 	CBB cbb;
324acef91a0Sjsing 	int i;
325acef91a0Sjsing 
326acef91a0Sjsing 	if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE)
327acef91a0Sjsing 		return 0;
328acef91a0Sjsing 	if (aead->fixed_nonce_len < aead->variable_nonce_len)
329acef91a0Sjsing 		return 0;
330acef91a0Sjsing 
331acef91a0Sjsing 	/*
332acef91a0Sjsing 	 * Variable nonce (sequence number) is right padded, before the fixed
333acef91a0Sjsing 	 * nonce is XOR'd in.
334acef91a0Sjsing 	 */
335acef91a0Sjsing 	if (!CBB_init(&cbb, 16))
336acef91a0Sjsing 		goto err;
337acef91a0Sjsing 	if (!CBB_add_space(&cbb, &pad,
338acef91a0Sjsing 	    aead->fixed_nonce_len - aead->variable_nonce_len))
339acef91a0Sjsing 		goto err;
340acef91a0Sjsing 	if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len))
341acef91a0Sjsing 		goto err;
342acef91a0Sjsing 	if (!CBB_finish(&cbb, &nonce, &nonce_len))
343acef91a0Sjsing 		goto err;
344acef91a0Sjsing 
345acef91a0Sjsing 	for (i = 0; i < aead->fixed_nonce_len; i++)
346acef91a0Sjsing 		nonce[i] ^= aead->fixed_nonce[i];
347acef91a0Sjsing 
348acef91a0Sjsing 	*out = nonce;
349acef91a0Sjsing 	*out_len = nonce_len;
350acef91a0Sjsing 
351acef91a0Sjsing 	return 1;
352acef91a0Sjsing 
353acef91a0Sjsing  err:
354acef91a0Sjsing 	CBB_cleanup(&cbb);
355acef91a0Sjsing 	freezero(nonce, nonce_len);
356acef91a0Sjsing 
357acef91a0Sjsing 	return 0;
358acef91a0Sjsing }
359acef91a0Sjsing 
360acef91a0Sjsing static int
361acef91a0Sjsing tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl,
362acef91a0Sjsing     uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
363acef91a0Sjsing {
364acef91a0Sjsing 	const SSL_AEAD_CTX *aead = rl->write_aead_ctx;
365acef91a0Sjsing 	uint8_t *header = NULL, *nonce = NULL;
366acef91a0Sjsing 	size_t header_len = 0, nonce_len = 0;
367acef91a0Sjsing 	size_t enc_record_len, out_len;
368acef91a0Sjsing 	uint16_t epoch = 0;
369acef91a0Sjsing 	uint8_t *enc_data;
370acef91a0Sjsing 	int ret = 0;
371acef91a0Sjsing 
372acef91a0Sjsing 	/* XXX - move to nonce allocated in record layer, matching TLSv1.3 */
373acef91a0Sjsing 	if (aead->xor_fixed_nonce) {
374acef91a0Sjsing 		if (!tls12_record_layer_aead_xored_nonce(rl, aead,
375acef91a0Sjsing 		    rl->write_seq_num, &nonce, &nonce_len))
376acef91a0Sjsing 			goto err;
377acef91a0Sjsing 	} else {
378acef91a0Sjsing 		if (!tls12_record_layer_aead_concat_nonce(rl, aead,
379acef91a0Sjsing 		    rl->write_seq_num, &nonce, &nonce_len))
380acef91a0Sjsing 			goto err;
381acef91a0Sjsing 	}
382acef91a0Sjsing 
383acef91a0Sjsing 	if (aead->variable_nonce_in_record) {
384acef91a0Sjsing 		/* XXX - length check? */
385acef91a0Sjsing 		if (!CBB_add_bytes(out, rl->write_seq_num, aead->variable_nonce_len))
386acef91a0Sjsing 			goto err;
387acef91a0Sjsing 	}
388acef91a0Sjsing 
389acef91a0Sjsing 	if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
390acef91a0Sjsing 	    epoch, rl->write_seq_num, SSL3_SEQUENCE_SIZE, &header, &header_len))
391acef91a0Sjsing 		goto err;
392acef91a0Sjsing 
393acef91a0Sjsing 	/* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */
394acef91a0Sjsing 	enc_record_len = content_len + aead->tag_len;
395acef91a0Sjsing 	if (enc_record_len > SSL3_RT_MAX_ENCRYPTED_LENGTH)
396acef91a0Sjsing 		goto err;
397acef91a0Sjsing 	if (!CBB_add_space(out, &enc_data, enc_record_len))
398acef91a0Sjsing 		goto err;
399acef91a0Sjsing 
400acef91a0Sjsing 	if (!EVP_AEAD_CTX_seal(&aead->ctx, enc_data, &out_len, enc_record_len,
401acef91a0Sjsing 	    nonce, nonce_len, content, content_len, header, header_len))
402acef91a0Sjsing 		goto err;
403acef91a0Sjsing 
404acef91a0Sjsing 	if (out_len != enc_record_len)
405acef91a0Sjsing 		goto err;
406acef91a0Sjsing 
407acef91a0Sjsing 	ret = 1;
408acef91a0Sjsing 
409acef91a0Sjsing  err:
410acef91a0Sjsing 	freezero(header, header_len);
411acef91a0Sjsing 	freezero(nonce, nonce_len);
412acef91a0Sjsing 
413acef91a0Sjsing 	return ret;
414acef91a0Sjsing }
415acef91a0Sjsing 
416acef91a0Sjsing static int
417acef91a0Sjsing tls12_record_layer_seal_record_protected_cipher(struct tls12_record_layer *rl,
418acef91a0Sjsing     uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
419acef91a0Sjsing {
420acef91a0Sjsing 	EVP_CIPHER_CTX *enc = rl->write_cipher_ctx;
421acef91a0Sjsing 	size_t mac_len, pad_len;
422acef91a0Sjsing 	int block_size, eiv_len;
423acef91a0Sjsing 	uint8_t *enc_data, *eiv, *pad, pad_val;
424acef91a0Sjsing 	uint8_t *plain = NULL;
425acef91a0Sjsing 	size_t plain_len = 0;
426acef91a0Sjsing 	int ret = 0;
427acef91a0Sjsing 	CBB cbb;
428acef91a0Sjsing 
429acef91a0Sjsing 	if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
430acef91a0Sjsing 		goto err;
431acef91a0Sjsing 
432acef91a0Sjsing 	/* Add explicit IV if necessary. */
433acef91a0Sjsing 	eiv_len = 0;
434acef91a0Sjsing 	if (rl->version != TLS1_VERSION &&
435acef91a0Sjsing 	    EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE)
436acef91a0Sjsing 		eiv_len = EVP_CIPHER_CTX_iv_length(enc);
437acef91a0Sjsing 	if (eiv_len < 0 || eiv_len > EVP_MAX_IV_LENGTH)
438acef91a0Sjsing 		goto err;
439acef91a0Sjsing 	if (eiv_len > 0) {
440acef91a0Sjsing 		if (!CBB_add_space(&cbb, &eiv, eiv_len))
441acef91a0Sjsing 			goto err;
442acef91a0Sjsing 		arc4random_buf(eiv, eiv_len);
443acef91a0Sjsing 	}
444acef91a0Sjsing 
445acef91a0Sjsing 	if (!CBB_add_bytes(&cbb, content, content_len))
446acef91a0Sjsing 		goto err;
447acef91a0Sjsing 
448acef91a0Sjsing 	mac_len = 0;
449acef91a0Sjsing 	if (rl->write_hash_ctx != NULL) {
450acef91a0Sjsing 		if (!tls12_record_layer_write_mac(rl, &cbb, content_type,
451acef91a0Sjsing 		    content, content_len, &mac_len))
452acef91a0Sjsing 			goto err;
453acef91a0Sjsing 	}
454acef91a0Sjsing 
455acef91a0Sjsing 	plain_len = (size_t)eiv_len + content_len + mac_len;
456acef91a0Sjsing 
457acef91a0Sjsing 	/* Add padding to block size, if necessary. */
458acef91a0Sjsing 	block_size = EVP_CIPHER_CTX_block_size(enc);
459acef91a0Sjsing 	if (block_size < 0 || block_size > EVP_MAX_BLOCK_LENGTH)
460*11d1e10cSjsing 		goto err;
461acef91a0Sjsing 	if (block_size > 1) {
462acef91a0Sjsing 		pad_len = block_size - (plain_len % block_size);
463acef91a0Sjsing 		pad_val = pad_len - 1;
464acef91a0Sjsing 
465acef91a0Sjsing 		if (pad_len > 255)
466acef91a0Sjsing 			goto err;
467acef91a0Sjsing 		if (!CBB_add_space(&cbb, &pad, pad_len))
468acef91a0Sjsing 			goto err;
469acef91a0Sjsing 		memset(pad, pad_val, pad_len);
470acef91a0Sjsing 	}
471acef91a0Sjsing 
472acef91a0Sjsing 	if (!CBB_finish(&cbb, &plain, &plain_len))
473acef91a0Sjsing 		goto err;
474acef91a0Sjsing 
475acef91a0Sjsing 	if (plain_len % block_size != 0)
476acef91a0Sjsing 		goto err;
477acef91a0Sjsing 	if (plain_len > SSL3_RT_MAX_ENCRYPTED_LENGTH)
478acef91a0Sjsing 		goto err;
479acef91a0Sjsing 
480acef91a0Sjsing 	if (!CBB_add_space(out, &enc_data, plain_len))
481acef91a0Sjsing 		goto err;
482acef91a0Sjsing 	if (!EVP_Cipher(enc, enc_data, plain, plain_len))
483acef91a0Sjsing 		goto err;
484acef91a0Sjsing 
485acef91a0Sjsing 	ret = 1;
486acef91a0Sjsing 
487acef91a0Sjsing  err:
488acef91a0Sjsing 	CBB_cleanup(&cbb);
489acef91a0Sjsing 	freezero(plain, plain_len);
490acef91a0Sjsing 
491acef91a0Sjsing 	return ret;
492acef91a0Sjsing }
493acef91a0Sjsing 
494acef91a0Sjsing int
495acef91a0Sjsing tls12_record_layer_seal_record(struct tls12_record_layer *rl,
496acef91a0Sjsing     uint8_t content_type, const uint8_t *content, size_t content_len, CBB *cbb)
497acef91a0Sjsing {
498acef91a0Sjsing 	CBB fragment;
499acef91a0Sjsing 
500acef91a0Sjsing 	if (!CBB_add_u8(cbb, content_type))
501acef91a0Sjsing 		return 0;
502acef91a0Sjsing 	if (!CBB_add_u16(cbb, rl->version))
503acef91a0Sjsing 		return 0;
504acef91a0Sjsing 	if (rl->dtls) {
505acef91a0Sjsing 		if (!tls12_record_layer_build_seq_num(rl, cbb,
506acef91a0Sjsing 		    rl->write_epoch, rl->write_seq_num,
507acef91a0Sjsing 		    SSL3_SEQUENCE_SIZE))
508acef91a0Sjsing 			return 0;
509acef91a0Sjsing 	}
510acef91a0Sjsing 	if (!CBB_add_u16_length_prefixed(cbb, &fragment))
511acef91a0Sjsing 		return 0;
512acef91a0Sjsing 
513acef91a0Sjsing 	if (rl->write_aead_ctx != NULL) {
514acef91a0Sjsing 		if (!tls12_record_layer_seal_record_protected_aead(rl,
515acef91a0Sjsing 		    content_type, content, content_len, &fragment))
516acef91a0Sjsing 			return 0;
517acef91a0Sjsing 	} else if (rl->write_cipher_ctx != NULL) {
518acef91a0Sjsing 		if (!tls12_record_layer_seal_record_protected_cipher(rl,
519acef91a0Sjsing 		    content_type, content, content_len, &fragment))
520acef91a0Sjsing 			return 0;
521acef91a0Sjsing 	} else {
522acef91a0Sjsing 		if (!tls12_record_layer_seal_record_plaintext(rl,
523acef91a0Sjsing 		    content_type, content, content_len, &fragment))
524acef91a0Sjsing 			return 0;
525acef91a0Sjsing 	}
526acef91a0Sjsing 
527acef91a0Sjsing 	if (!CBB_flush(cbb))
528acef91a0Sjsing 		return 0;
529acef91a0Sjsing 
530acef91a0Sjsing 	tls1_record_sequence_increment(rl->write_seq_num);
531acef91a0Sjsing 
532acef91a0Sjsing 	return 1;
533acef91a0Sjsing }
534