blob: f8bb521d3109ea9366b9190048dc2daf4fd75f5c [file] [log] [blame]
David Benjaminb8d28cf2015-07-28 21:34:45 -04001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com). */
108
109#include <openssl/ssl.h>
110
111#include <assert.h>
David Benjamin4119d422015-12-25 15:34:23 -0500112#include <string.h>
David Benjaminb8d28cf2015-07-28 21:34:45 -0400113
114#include <openssl/bytestring.h>
115#include <openssl/err.h>
David Benjamin728f3542016-06-02 15:42:01 -0400116#include <openssl/mem.h>
David Benjaminb8d28cf2015-07-28 21:34:45 -0400117
118#include "internal.h"
David Benjamin1a01e1f2016-06-08 18:31:24 -0400119#include "../crypto/internal.h"
David Benjaminb8d28cf2015-07-28 21:34:45 -0400120
121
David Benjamin86e95b82017-07-18 16:34:25 -0400122namespace bssl {
123
David Benjamin4cf369b2015-08-22 01:35:43 -0400124/* kMaxEmptyRecords is the number of consecutive, empty records that will be
125 * processed. Without this limit an attacker could send empty records at a
126 * faster rate than we can process and cause record processing to loop
127 * forever. */
128static const uint8_t kMaxEmptyRecords = 32;
129
Steven Valdez08b65f42016-12-07 15:29:45 -0500130/* kMaxEarlyDataSkipped is the maximum number of rejected early data bytes that
131 * will be skipped. Without this limit an attacker could send records at a
132 * faster rate than we can process and cause trial decryption to loop forever.
Alessandro Ghedinide254b42017-04-17 19:12:33 +0100133 * This value should be slightly above kMaxEarlyDataAccepted, which is measured
134 * in plaintext. */
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500135static const size_t kMaxEarlyDataSkipped = 16384;
136
David Benjamin728f3542016-06-02 15:42:01 -0400137/* kMaxWarningAlerts is the number of consecutive warning alerts that will be
138 * processed. */
139static const uint8_t kMaxWarningAlerts = 4;
140
David Benjamind9f06712015-12-06 16:07:47 -0500141/* ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher
142 * state needs record-splitting and zero otherwise. */
143static int ssl_needs_record_splitting(const SSL *ssl) {
Adam Langley14308732017-07-14 16:51:39 -0700144#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
David Benjamincfc11c22017-07-18 22:45:18 -0400145 return !ssl->s3->aead_write_ctx->is_null_cipher() &&
146 ssl->s3->aead_write_ctx->version() < TLS1_1_VERSION &&
David Benjamind9f06712015-12-06 16:07:47 -0500147 (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
David Benjamincfc11c22017-07-18 22:45:18 -0400148 SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher());
Adam Langley14308732017-07-14 16:51:39 -0700149#else
150 return 0;
151#endif
David Benjamind9f06712015-12-06 16:07:47 -0500152}
153
David Benjamin1db21562015-12-25 15:11:39 -0500154int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) {
David Benjamin54091232016-09-05 12:47:25 -0400155 for (size_t i = seq_len - 1; i < seq_len; i--) {
David Benjamin1db21562015-12-25 15:11:39 -0500156 ++seq[i];
157 if (seq[i] != 0) {
158 return 1;
159 }
160 }
161 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
162 return 0;
163}
164
David Benjaminb8d28cf2015-07-28 21:34:45 -0400165size_t ssl_record_prefix_len(const SSL *ssl) {
David Benjamin6f600d62016-12-21 16:06:54 -0500166 size_t header_len;
David Benjamince079fd2016-08-02 16:22:34 -0400167 if (SSL_is_dtls(ssl)) {
David Benjamin6f600d62016-12-21 16:06:54 -0500168 header_len = DTLS1_RT_HEADER_LENGTH;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400169 } else {
David Benjamin6f600d62016-12-21 16:06:54 -0500170 header_len = SSL3_RT_HEADER_LENGTH;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400171 }
David Benjamin6f600d62016-12-21 16:06:54 -0500172
David Benjamincfc11c22017-07-18 22:45:18 -0400173 return header_len + ssl->s3->aead_read_ctx->ExplicitNonceLen();
David Benjaminb8d28cf2015-07-28 21:34:45 -0400174}
175
David Benjamin1a01e1f2016-06-08 18:31:24 -0400176size_t ssl_seal_align_prefix_len(const SSL *ssl) {
David Benjamince079fd2016-08-02 16:22:34 -0400177 if (SSL_is_dtls(ssl)) {
David Benjamincfc11c22017-07-18 22:45:18 -0400178 return DTLS1_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen();
David Benjaminb8d28cf2015-07-28 21:34:45 -0400179 }
David Benjamin6f600d62016-12-21 16:06:54 -0500180
David Benjamincfc11c22017-07-18 22:45:18 -0400181 size_t ret =
182 SSL3_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen();
David Benjamin6f600d62016-12-21 16:06:54 -0500183 if (ssl_needs_record_splitting(ssl)) {
Steven Valdez924a3522017-03-02 16:05:03 -0500184 ret += SSL3_RT_HEADER_LENGTH;
David Benjamincfc11c22017-07-18 22:45:18 -0400185 ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher());
David Benjamin6f600d62016-12-21 16:06:54 -0500186 }
187 return ret;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400188}
189
David Benjamina7810c12016-06-06 18:54:51 -0400190enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, CBS *out,
191 size_t *out_consumed, uint8_t *out_alert,
192 uint8_t *in, size_t in_len) {
David Benjamin728f3542016-06-02 15:42:01 -0400193 *out_consumed = 0;
194
David Benjaminb8d28cf2015-07-28 21:34:45 -0400195 CBS cbs;
196 CBS_init(&cbs, in, in_len);
197
198 /* Decode the record header. */
199 uint8_t type;
200 uint16_t version, ciphertext_len;
Steven Valdez924a3522017-03-02 16:05:03 -0500201 if (!CBS_get_u8(&cbs, &type) ||
202 !CBS_get_u16(&cbs, &version) ||
203 !CBS_get_u16(&cbs, &ciphertext_len)) {
204 *out_consumed = SSL3_RT_HEADER_LENGTH;
205 return ssl_open_record_partial;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400206 }
207
David Benjamine6f22212016-11-08 14:28:24 -0500208 int version_ok;
David Benjamincfc11c22017-07-18 22:45:18 -0400209 if (ssl->s3->aead_read_ctx->is_null_cipher()) {
David Benjamine6f22212016-11-08 14:28:24 -0500210 /* Only check the first byte. Enforcing beyond that can prevent decoding
211 * version negotiation failure alerts. */
212 version_ok = (version >> 8) == SSL3_VERSION_MAJOR;
213 } else if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
214 /* Earlier versions of TLS switch the record version. */
215 version_ok = version == ssl->version;
216 } else {
217 /* Starting TLS 1.3, the version field is frozen at {3, 1}. */
218 version_ok = version == TLS1_VERSION;
219 }
220
221 if (!version_ok) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400222 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
223 *out_alert = SSL_AD_PROTOCOL_VERSION;
224 return ssl_open_record_error;
225 }
226
227 /* Check the ciphertext length. */
David Benjamin03f00052015-11-18 20:41:11 -0500228 if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400229 OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
230 *out_alert = SSL_AD_RECORD_OVERFLOW;
231 return ssl_open_record_error;
232 }
233
234 /* Extract the body. */
235 CBS body;
236 if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) {
Steven Valdez924a3522017-03-02 16:05:03 -0500237 *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400238 return ssl_open_record_partial;
239 }
240
Steven Valdez924a3522017-03-02 16:05:03 -0500241 ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, in,
242 SSL3_RT_HEADER_LENGTH);
David Benjaminb8d28cf2015-07-28 21:34:45 -0400243
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500244 *out_consumed = in_len - CBS_len(&cbs);
245
246 /* Skip early data received when expecting a second ClientHello if we rejected
247 * 0RTT. */
248 if (ssl->s3->skip_early_data &&
David Benjamincfc11c22017-07-18 22:45:18 -0400249 ssl->s3->aead_read_ctx->is_null_cipher() &&
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500250 type == SSL3_RT_APPLICATION_DATA) {
251 goto skipped_data;
252 }
253
David Benjamina7810c12016-06-06 18:54:51 -0400254 /* Decrypt the body in-place. */
David Benjamincfc11c22017-07-18 22:45:18 -0400255 if (!ssl->s3->aead_read_ctx->Open(out, type, version, ssl->s3->read_sequence,
256 (uint8_t *)CBS_data(&body),
257 CBS_len(&body))) {
258 if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) {
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500259 ERR_clear_error();
260 goto skipped_data;
261 }
262
David Benjaminb8d28cf2015-07-28 21:34:45 -0400263 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
264 *out_alert = SSL_AD_BAD_RECORD_MAC;
265 return ssl_open_record_error;
266 }
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500267
268 ssl->s3->skip_early_data = 0;
David Benjamin728f3542016-06-02 15:42:01 -0400269
David Benjamin1db21562015-12-25 15:11:39 -0500270 if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400271 *out_alert = SSL_AD_INTERNAL_ERROR;
272 return ssl_open_record_error;
273 }
274
Steven Valdez66af3b02016-06-01 14:07:09 -0400275 /* TLS 1.3 hides the record type inside the encrypted data. */
David Benjamincfc11c22017-07-18 22:45:18 -0400276 if (!ssl->s3->aead_read_ctx->is_null_cipher() &&
277 ssl->s3->aead_read_ctx->version() >= TLS1_3_VERSION) {
David Benjaminc9ae27c2016-06-24 22:56:37 -0400278 /* The outer record type is always application_data. */
279 if (type != SSL3_RT_APPLICATION_DATA) {
280 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_RECORD_TYPE);
281 *out_alert = SSL_AD_DECODE_ERROR;
282 return ssl_open_record_error;
283 }
284
David Benjamina7810c12016-06-06 18:54:51 -0400285 do {
286 if (!CBS_get_last_u8(out, &type)) {
287 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
288 *out_alert = SSL_AD_DECRYPT_ERROR;
289 return ssl_open_record_error;
290 }
291 } while (type == 0);
Steven Valdez66af3b02016-06-01 14:07:09 -0400292 }
293
David Benjaminb8d28cf2015-07-28 21:34:45 -0400294 /* Check the plaintext length. */
David Benjamina7810c12016-06-06 18:54:51 -0400295 if (CBS_len(out) > SSL3_RT_MAX_PLAIN_LENGTH) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400296 OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
297 *out_alert = SSL_AD_RECORD_OVERFLOW;
298 return ssl_open_record_error;
299 }
300
David Benjamin4cf369b2015-08-22 01:35:43 -0400301 /* Limit the number of consecutive empty records. */
David Benjamina7810c12016-06-06 18:54:51 -0400302 if (CBS_len(out) == 0) {
David Benjamin4cf369b2015-08-22 01:35:43 -0400303 ssl->s3->empty_record_count++;
304 if (ssl->s3->empty_record_count > kMaxEmptyRecords) {
305 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
306 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
307 return ssl_open_record_error;
308 }
309 /* Apart from the limit, empty records are returned up to the caller. This
310 * allows the caller to reject records of the wrong type. */
311 } else {
312 ssl->s3->empty_record_count = 0;
313 }
314
David Benjamin728f3542016-06-02 15:42:01 -0400315 if (type == SSL3_RT_ALERT) {
Steven Valdez2d850622017-01-11 11:34:52 -0500316 /* Return end_of_early_data alerts as-is for the caller to process. */
317 if (CBS_len(out) == 2 &&
318 CBS_data(out)[0] == SSL3_AL_WARNING &&
319 CBS_data(out)[1] == TLS1_AD_END_OF_EARLY_DATA) {
320 *out_type = type;
321 return ssl_open_record_success;
322 }
323
David Benjamina7810c12016-06-06 18:54:51 -0400324 return ssl_process_alert(ssl, out_alert, CBS_data(out), CBS_len(out));
David Benjamin728f3542016-06-02 15:42:01 -0400325 }
326
327 ssl->s3->warning_alert_count = 0;
328
David Benjaminb8d28cf2015-07-28 21:34:45 -0400329 *out_type = type;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400330 return ssl_open_record_success;
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500331
332skipped_data:
333 ssl->s3->early_data_skipped += *out_consumed;
334 if (ssl->s3->early_data_skipped < *out_consumed) {
335 ssl->s3->early_data_skipped = kMaxEarlyDataSkipped + 1;
336 }
337
338 if (ssl->s3->early_data_skipped > kMaxEarlyDataSkipped) {
339 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA);
340 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
341 return ssl_open_record_error;
342 }
343
344 return ssl_open_record_discard;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400345}
346
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700347static int do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700348 uint8_t *out_suffix, uint8_t type, const uint8_t *in,
349 const size_t in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700350 uint8_t *extra_in = NULL;
351 size_t extra_in_len = 0;
David Benjamincfc11c22017-07-18 22:45:18 -0400352 if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
353 ssl->s3->aead_write_ctx->version() >= TLS1_3_VERSION) {
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700354 /* TLS 1.3 hides the actual record type inside the encrypted data. */
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700355 extra_in = &type;
356 extra_in_len = 1;
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700357 }
358
359 size_t suffix_len;
360 if (!ssl->s3->aead_write_ctx->SuffixLen(&suffix_len, in_len, extra_in_len)) {
361 OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
362 return 0;
363 }
364 size_t ciphertext_len =
365 ssl->s3->aead_write_ctx->ExplicitNonceLen() + suffix_len;
366 if (ciphertext_len + in_len < ciphertext_len) {
367 OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
368 return 0;
369 }
370 ciphertext_len += in_len;
371
372 assert(in == out || !buffers_alias(in, in_len, out, in_len));
373 assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl)));
374 assert(!buffers_alias(in, in_len, out_suffix, suffix_len));
375
376 if (extra_in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700377 out_prefix[0] = SSL3_RT_APPLICATION_DATA;
378 } else {
379 out_prefix[0] = type;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400380 }
David Benjamin1a01e1f2016-06-08 18:31:24 -0400381
Steven Valdez66af3b02016-06-01 14:07:09 -0400382 /* The TLS record-layer version number is meaningless and, starting in
383 * TLS 1.3, is frozen at TLS 1.0. But for historical reasons, SSL 3.0
384 * ClientHellos should use SSL 3.0 and pre-TLS-1.3 expects the version
385 * to change after version negotiation. */
386 uint16_t wire_version = TLS1_VERSION;
Steven Valdez8f36c512017-06-20 10:55:02 -0400387 if (ssl->s3->hs != NULL && ssl->s3->hs->max_version == SSL3_VERSION) {
388 wire_version = SSL3_VERSION;
389 }
390 if (ssl->s3->have_version && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
Steven Valdez66af3b02016-06-01 14:07:09 -0400391 wire_version = ssl->version;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400392 }
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700393 out_prefix[1] = wire_version >> 8;
394 out_prefix[2] = wire_version & 0xff;
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700395 out_prefix[3] = ciphertext_len >> 8;
396 out_prefix[4] = ciphertext_len & 0xff;
David Benjamin6f600d62016-12-21 16:06:54 -0500397
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700398 if (!ssl->s3->aead_write_ctx->SealScatter(out_prefix + SSL3_RT_HEADER_LENGTH,
399 out, out_suffix, type, wire_version,
400 ssl->s3->write_sequence, in, in_len,
401 extra_in, extra_in_len) ||
David Benjamin1db21562015-12-25 15:11:39 -0500402 !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400403 return 0;
404 }
405
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700406 ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out_prefix,
Steven Valdez924a3522017-03-02 16:05:03 -0500407 SSL3_RT_HEADER_LENGTH);
David Benjaminb8d28cf2015-07-28 21:34:45 -0400408 return 1;
409}
410
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700411static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type,
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700412 size_t in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700413 size_t ret = SSL3_RT_HEADER_LENGTH;
David Benjamind9f06712015-12-06 16:07:47 -0500414 if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
415 ssl_needs_record_splitting(ssl)) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700416 /* In the case of record splitting, the 1-byte record (of the 1/n-1 split)
417 * will be placed in the prefix, as will four of the five bytes of the
418 * record header for the main record. The final byte will replace the first
419 * byte of the plaintext that was used in the small record. */
David Benjamincfc11c22017-07-18 22:45:18 -0400420 ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher());
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700421 ret += SSL3_RT_HEADER_LENGTH - 1;
422 } else {
David Benjamincfc11c22017-07-18 22:45:18 -0400423 ret += ssl->s3->aead_write_ctx->ExplicitNonceLen();
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700424 }
425 return ret;
426}
427
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700428static bool tls_seal_scatter_suffix_len(const SSL *ssl, size_t *out_suffix_len,
429 uint8_t type, size_t in_len) {
430 size_t extra_in_len = 0;
431 if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700432 ssl->s3->aead_write_ctx->version() >= TLS1_3_VERSION) {
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700433 /* TLS 1.3 adds an extra byte for encrypted record type. */
434 extra_in_len = 1;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700435 }
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700436 if (type == SSL3_RT_APPLICATION_DATA && // clang-format off
437 in_len > 1 &&
438 ssl_needs_record_splitting(ssl)) {
439 /* With record splitting enabled, the first byte gets sealed into a separate
440 * record which is written into the prefix. */
441 in_len -= 1;
442 }
443 return ssl->s3->aead_write_ctx->SuffixLen(out_suffix_len, in_len, extra_in_len);
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700444}
445
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700446/* tls_seal_scatter_record seals a new record of type |type| and body |in| and
447 * splits it between |out_prefix|, |out|, and |out_suffix|. Exactly
448 * |tls_seal_scatter_prefix_len| bytes are written to |out_prefix|, |in_len|
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700449 * bytes to |out|, and |tls_seal_scatter_suffix_len| bytes to |out_suffix|. It
450 * returns one on success and zero on error. If enabled,
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700451 * |tls_seal_scatter_record| implements TLS 1.0 CBC 1/n-1 record splitting and
452 * may write two records concatenated. */
453static int tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700454 uint8_t *out_suffix, uint8_t type,
455 const uint8_t *in, size_t in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700456 if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
457 ssl_needs_record_splitting(ssl)) {
David Benjamincfc11c22017-07-18 22:45:18 -0400458 assert(ssl->s3->aead_write_ctx->ExplicitNonceLen() == 0);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700459 const size_t prefix_len = SSL3_RT_HEADER_LENGTH;
460
461 /* Write the 1-byte fragment into |out_prefix|. */
462 uint8_t *split_body = out_prefix + prefix_len;
463 uint8_t *split_suffix = split_body + 1;
464
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700465 if (!do_seal_record(ssl, out_prefix, split_body, split_suffix, type, in,
466 1)) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400467 return 0;
468 }
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700469
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700470 size_t split_record_suffix_len;
471 if (!ssl->s3->aead_write_ctx->SuffixLen(&split_record_suffix_len, 1, 0)) {
472 assert(false);
473 return 0;
474 }
475 const size_t split_record_len = prefix_len + 1 + split_record_suffix_len;
David Benjamin79978df2015-12-25 15:56:49 -0500476 assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
David Benjamincfc11c22017-07-18 22:45:18 -0400477 ssl->s3->aead_write_ctx->cipher()) ==
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700478 split_record_len);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700479
480 /* Write the n-1-byte fragment. The header gets split between |out_prefix|
481 * (header[:-1]) and |out| (header[-1:]). */
482 uint8_t tmp_prefix[SSL3_RT_HEADER_LENGTH];
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700483 if (!do_seal_record(ssl, tmp_prefix, out + 1, out_suffix, type, in + 1,
484 in_len - 1)) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700485 return 0;
486 }
487 assert(tls_seal_scatter_prefix_len(ssl, type, in_len) ==
488 split_record_len + SSL3_RT_HEADER_LENGTH - 1);
489 OPENSSL_memcpy(out_prefix + split_record_len, tmp_prefix,
490 SSL3_RT_HEADER_LENGTH - 1);
491 OPENSSL_memcpy(out, tmp_prefix + SSL3_RT_HEADER_LENGTH - 1, 1);
492 return 1;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400493 }
494
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700495 return do_seal_record(ssl, out_prefix, out, out_suffix, type, in, in_len);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700496}
497
498int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
499 uint8_t type, const uint8_t *in, size_t in_len) {
500 if (buffers_alias(in, in_len, out, max_out_len)) {
501 OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
David Benjaminb8d28cf2015-07-28 21:34:45 -0400502 return 0;
503 }
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700504
505 const size_t prefix_len = tls_seal_scatter_prefix_len(ssl, type, in_len);
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700506 size_t suffix_len;
507 if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, type, in_len)) {
508 return false;
509 }
510 if (in_len + prefix_len < in_len ||
511 prefix_len + in_len + suffix_len < prefix_len + in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700512 OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
513 return 0;
514 }
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700515 if (max_out_len < in_len + prefix_len + suffix_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700516 OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
517 return 0;
518 }
519
520 uint8_t *prefix = out;
521 uint8_t *body = out + prefix_len;
522 uint8_t *suffix = body + in_len;
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700523 if (!tls_seal_scatter_record(ssl, prefix, body, suffix, type, in, in_len)) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700524 return 0;
525 }
526
527 *out_len = prefix_len + in_len + suffix_len;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400528 return 1;
529}
David Benjamin4119d422015-12-25 15:34:23 -0500530
David Benjamin728f3542016-06-02 15:42:01 -0400531enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,
532 const uint8_t *in, size_t in_len) {
533 /* Alerts records may not contain fragmented or multiple alerts. */
534 if (in_len != 2) {
535 *out_alert = SSL_AD_DECODE_ERROR;
536 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
537 return ssl_open_record_error;
538 }
539
David Benjaminc0279992016-09-19 20:15:07 -0400540 ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in, in_len);
David Benjamin728f3542016-06-02 15:42:01 -0400541
542 const uint8_t alert_level = in[0];
543 const uint8_t alert_descr = in[1];
544
545 uint16_t alert = (alert_level << 8) | alert_descr;
546 ssl_do_info_callback(ssl, SSL_CB_READ_ALERT, alert);
547
548 if (alert_level == SSL3_AL_WARNING) {
549 if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
550 ssl->s3->recv_shutdown = ssl_shutdown_close_notify;
551 return ssl_open_record_close_notify;
552 }
553
David Benjamine8e84b92016-08-03 15:39:47 -0400554 /* Warning alerts do not exist in TLS 1.3. */
555 if (ssl->s3->have_version &&
556 ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
557 *out_alert = SSL_AD_DECODE_ERROR;
558 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
559 return ssl_open_record_error;
560 }
561
David Benjamin728f3542016-06-02 15:42:01 -0400562 ssl->s3->warning_alert_count++;
563 if (ssl->s3->warning_alert_count > kMaxWarningAlerts) {
564 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
565 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS);
566 return ssl_open_record_error;
567 }
568 return ssl_open_record_discard;
569 }
570
571 if (alert_level == SSL3_AL_FATAL) {
572 ssl->s3->recv_shutdown = ssl_shutdown_fatal_alert;
David Benjamin728f3542016-06-02 15:42:01 -0400573
574 char tmp[16];
575 OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
576 BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
577 ERR_add_error_data(2, "SSL alert number ", tmp);
578 return ssl_open_record_fatal_alert;
579 }
580
581 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
582 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE);
583 return ssl_open_record_error;
584}
David Benjamin86e95b82017-07-18 16:34:25 -0400585
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700586OpenRecordResult OpenRecord(SSL *ssl, Span<uint8_t> *out,
587 size_t *out_record_len, uint8_t *out_alert,
588 const Span<uint8_t> in) {
589 // This API is a work in progress and currently only works for TLS 1.2 servers
590 // and below.
591 if (SSL_in_init(ssl) ||
592 SSL_is_dtls(ssl) ||
593 ssl3_protocol_version(ssl) > TLS1_2_VERSION) {
594 assert(false);
595 *out_alert = SSL_AD_INTERNAL_ERROR;
596 return OpenRecordResult::kError;
597 }
598
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700599 CBS plaintext;
600 uint8_t type;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700601 const ssl_open_record_t result = tls_open_record(
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700602 ssl, &type, &plaintext, out_record_len, out_alert, in.data(), in.size());
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700603
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700604 switch (result) {
605 case ssl_open_record_success:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700606 if (type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_ALERT) {
607 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
608 return OpenRecordResult::kError;
609 }
610 *out = MakeSpan(
611 const_cast<uint8_t*>(CBS_data(&plaintext)), CBS_len(&plaintext));
612 return OpenRecordResult::kOK;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700613 case ssl_open_record_discard:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700614 return OpenRecordResult::kDiscard;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700615 case ssl_open_record_partial:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700616 return OpenRecordResult::kIncompleteRecord;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700617 case ssl_open_record_close_notify:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700618 return OpenRecordResult::kAlertCloseNotify;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700619 case ssl_open_record_fatal_alert:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700620 return OpenRecordResult::kAlertFatal;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700621 case ssl_open_record_error:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700622 return OpenRecordResult::kError;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700623 }
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700624 assert(false);
625 return OpenRecordResult::kError;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700626}
627
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700628size_t SealRecordPrefixLen(const SSL *ssl, const size_t record_len) {
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700629 return tls_seal_scatter_prefix_len(ssl, SSL3_RT_APPLICATION_DATA, record_len);
630}
631
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700632size_t SealRecordSuffixLen(const SSL *ssl, const size_t plaintext_len) {
633 assert(plaintext_len <= SSL3_RT_MAX_PLAIN_LENGTH);
634 size_t suffix_len;
635 if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, SSL3_RT_APPLICATION_DATA,
636 plaintext_len)) {
637 assert(false);
638 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
639 return 0;
640 }
641 assert(suffix_len <= SSL3_RT_MAX_ENCRYPTED_OVERHEAD);
642 return suffix_len;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700643}
644
645bool SealRecord(SSL *ssl, const Span<uint8_t> out_prefix,
646 const Span<uint8_t> out, Span<uint8_t> out_suffix,
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700647 const Span<const uint8_t> in) {
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700648 // This API is a work in progress and currently only works for TLS 1.2 servers
649 // and below.
650 if (SSL_in_init(ssl) ||
651 SSL_is_dtls(ssl) ||
652 ssl3_protocol_version(ssl) > TLS1_2_VERSION) {
653 assert(false);
654 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
655 return false;
656 }
657
658 if (out_prefix.size() != SealRecordPrefixLen(ssl, in.size()) ||
659 out.size() != in.size() ||
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700660 out_suffix.size() != SealRecordSuffixLen(ssl, in.size())) {
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700661 OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
662 return false;
663 }
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700664 return tls_seal_scatter_record(ssl, out_prefix.data(), out.data(),
665 out_suffix.data(), SSL3_RT_APPLICATION_DATA,
666 in.data(), in.size());
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700667}
668
David Benjamin86e95b82017-07-18 16:34:25 -0400669} // namespace bssl
670
671using namespace bssl;
672
673size_t SSL_max_seal_overhead(const SSL *ssl) {
674 if (SSL_is_dtls(ssl)) {
675 return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch);
676 }
677
678 size_t ret = SSL3_RT_HEADER_LENGTH;
David Benjamincfc11c22017-07-18 22:45:18 -0400679 ret += ssl->s3->aead_write_ctx->MaxOverhead();
David Benjamin86e95b82017-07-18 16:34:25 -0400680 /* TLS 1.3 needs an extra byte for the encrypted record type. */
David Benjamincfc11c22017-07-18 22:45:18 -0400681 if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
682 ssl->s3->aead_write_ctx->version() >= TLS1_3_VERSION) {
David Benjamin86e95b82017-07-18 16:34:25 -0400683 ret += 1;
684 }
685 if (ssl_needs_record_splitting(ssl)) {
686 ret *= 2;
687 }
688 return ret;
689}