blob: 5eeff3c566b352dd5e5555164f72f663b4b52b20 [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 Benjaminc11ea9422017-08-29 16:33:21 -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.
David Benjamin4cf369b2015-08-22 01:35:43 -0400128static const uint8_t kMaxEmptyRecords = 32;
129
David Benjaminc11ea9422017-08-29 16:33:21 -0400130// 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.
133// 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 Benjaminc11ea9422017-08-29 16:33:21 -0400137// kMaxWarningAlerts is the number of consecutive warning alerts that will be
138// processed.
David Benjamin728f3542016-06-02 15:42:01 -0400139static const uint8_t kMaxWarningAlerts = 4;
140
David Benjaminc11ea9422017-08-29 16:33:21 -0400141// ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher
142// state needs record-splitting and zero otherwise.
David Benjamind9f06712015-12-06 16:07:47 -0500143static 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() &&
Steven Valdezc7d4d212017-09-11 13:53:08 -0400146 ssl->s3->aead_write_ctx->ProtocolVersion() < 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
David Benjaminc11ea9422017-08-29 16:33:21 -0400198 // Decode the record header.
David Benjaminb8d28cf2015-07-28 21:34:45 -0400199 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
Steven Valdezc7d4d212017-09-11 13:53:08 -0400208 bool version_ok;
David Benjamincfc11c22017-07-18 22:45:18 -0400209 if (ssl->s3->aead_read_ctx->is_null_cipher()) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400210 // Only check the first byte. Enforcing beyond that can prevent decoding
211 // version negotiation failure alerts.
David Benjamine6f22212016-11-08 14:28:24 -0500212 version_ok = (version >> 8) == SSL3_VERSION_MAJOR;
David Benjamine6f22212016-11-08 14:28:24 -0500213 } else {
Steven Valdezc7d4d212017-09-11 13:53:08 -0400214 version_ok = version == ssl->s3->aead_read_ctx->RecordVersion();
David Benjamine6f22212016-11-08 14:28:24 -0500215 }
216
217 if (!version_ok) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400218 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
219 *out_alert = SSL_AD_PROTOCOL_VERSION;
220 return ssl_open_record_error;
221 }
222
David Benjaminc11ea9422017-08-29 16:33:21 -0400223 // Check the ciphertext length.
David Benjamin03f00052015-11-18 20:41:11 -0500224 if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400225 OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
226 *out_alert = SSL_AD_RECORD_OVERFLOW;
227 return ssl_open_record_error;
228 }
229
David Benjaminc11ea9422017-08-29 16:33:21 -0400230 // Extract the body.
David Benjaminb8d28cf2015-07-28 21:34:45 -0400231 CBS body;
232 if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) {
Steven Valdez924a3522017-03-02 16:05:03 -0500233 *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400234 return ssl_open_record_partial;
235 }
236
Steven Valdez924a3522017-03-02 16:05:03 -0500237 ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, in,
238 SSL3_RT_HEADER_LENGTH);
David Benjaminb8d28cf2015-07-28 21:34:45 -0400239
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500240 *out_consumed = in_len - CBS_len(&cbs);
241
David Benjaminc11ea9422017-08-29 16:33:21 -0400242 // Skip early data received when expecting a second ClientHello if we rejected
243 // 0RTT.
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500244 if (ssl->s3->skip_early_data &&
David Benjamincfc11c22017-07-18 22:45:18 -0400245 ssl->s3->aead_read_ctx->is_null_cipher() &&
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500246 type == SSL3_RT_APPLICATION_DATA) {
247 goto skipped_data;
248 }
249
David Benjaminc11ea9422017-08-29 16:33:21 -0400250 // Decrypt the body in-place.
David Benjamincfc11c22017-07-18 22:45:18 -0400251 if (!ssl->s3->aead_read_ctx->Open(out, type, version, ssl->s3->read_sequence,
252 (uint8_t *)CBS_data(&body),
253 CBS_len(&body))) {
254 if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) {
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500255 ERR_clear_error();
256 goto skipped_data;
257 }
258
David Benjaminb8d28cf2015-07-28 21:34:45 -0400259 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
260 *out_alert = SSL_AD_BAD_RECORD_MAC;
261 return ssl_open_record_error;
262 }
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500263
David Benjamin046bc1f2017-08-31 15:06:42 -0400264 ssl->s3->skip_early_data = false;
David Benjamin728f3542016-06-02 15:42:01 -0400265
David Benjamin1db21562015-12-25 15:11:39 -0500266 if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400267 *out_alert = SSL_AD_INTERNAL_ERROR;
268 return ssl_open_record_error;
269 }
270
David Benjaminc11ea9422017-08-29 16:33:21 -0400271 // TLS 1.3 hides the record type inside the encrypted data.
David Benjamincfc11c22017-07-18 22:45:18 -0400272 if (!ssl->s3->aead_read_ctx->is_null_cipher() &&
Steven Valdezc7d4d212017-09-11 13:53:08 -0400273 ssl->s3->aead_read_ctx->ProtocolVersion() >= TLS1_3_VERSION) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400274 // The outer record type is always application_data.
David Benjaminc9ae27c2016-06-24 22:56:37 -0400275 if (type != SSL3_RT_APPLICATION_DATA) {
276 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_RECORD_TYPE);
277 *out_alert = SSL_AD_DECODE_ERROR;
278 return ssl_open_record_error;
279 }
280
David Benjamina7810c12016-06-06 18:54:51 -0400281 do {
282 if (!CBS_get_last_u8(out, &type)) {
283 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
284 *out_alert = SSL_AD_DECRYPT_ERROR;
285 return ssl_open_record_error;
286 }
287 } while (type == 0);
Steven Valdez66af3b02016-06-01 14:07:09 -0400288 }
289
David Benjaminc11ea9422017-08-29 16:33:21 -0400290 // Check the plaintext length.
David Benjamina7810c12016-06-06 18:54:51 -0400291 if (CBS_len(out) > SSL3_RT_MAX_PLAIN_LENGTH) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400292 OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
293 *out_alert = SSL_AD_RECORD_OVERFLOW;
294 return ssl_open_record_error;
295 }
296
David Benjaminc11ea9422017-08-29 16:33:21 -0400297 // Limit the number of consecutive empty records.
David Benjamina7810c12016-06-06 18:54:51 -0400298 if (CBS_len(out) == 0) {
David Benjamin4cf369b2015-08-22 01:35:43 -0400299 ssl->s3->empty_record_count++;
300 if (ssl->s3->empty_record_count > kMaxEmptyRecords) {
301 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
302 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
303 return ssl_open_record_error;
304 }
David Benjaminc11ea9422017-08-29 16:33:21 -0400305 // Apart from the limit, empty records are returned up to the caller. This
306 // allows the caller to reject records of the wrong type.
David Benjamin4cf369b2015-08-22 01:35:43 -0400307 } else {
308 ssl->s3->empty_record_count = 0;
309 }
310
David Benjamin728f3542016-06-02 15:42:01 -0400311 if (type == SSL3_RT_ALERT) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400312 // Return end_of_early_data alerts as-is for the caller to process.
Steven Valdez2d850622017-01-11 11:34:52 -0500313 if (CBS_len(out) == 2 &&
314 CBS_data(out)[0] == SSL3_AL_WARNING &&
315 CBS_data(out)[1] == TLS1_AD_END_OF_EARLY_DATA) {
316 *out_type = type;
317 return ssl_open_record_success;
318 }
319
David Benjamina7810c12016-06-06 18:54:51 -0400320 return ssl_process_alert(ssl, out_alert, CBS_data(out), CBS_len(out));
David Benjamin728f3542016-06-02 15:42:01 -0400321 }
322
323 ssl->s3->warning_alert_count = 0;
324
David Benjaminb8d28cf2015-07-28 21:34:45 -0400325 *out_type = type;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400326 return ssl_open_record_success;
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500327
328skipped_data:
329 ssl->s3->early_data_skipped += *out_consumed;
330 if (ssl->s3->early_data_skipped < *out_consumed) {
331 ssl->s3->early_data_skipped = kMaxEarlyDataSkipped + 1;
332 }
333
334 if (ssl->s3->early_data_skipped > kMaxEarlyDataSkipped) {
335 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA);
336 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
337 return ssl_open_record_error;
338 }
339
340 return ssl_open_record_discard;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400341}
342
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700343static int do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700344 uint8_t *out_suffix, uint8_t type, const uint8_t *in,
345 const size_t in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700346 uint8_t *extra_in = NULL;
347 size_t extra_in_len = 0;
David Benjamincfc11c22017-07-18 22:45:18 -0400348 if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
Steven Valdezc7d4d212017-09-11 13:53:08 -0400349 ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400350 // TLS 1.3 hides the actual record type inside the encrypted data.
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700351 extra_in = &type;
352 extra_in_len = 1;
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700353 }
354
355 size_t suffix_len;
356 if (!ssl->s3->aead_write_ctx->SuffixLen(&suffix_len, in_len, extra_in_len)) {
357 OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
358 return 0;
359 }
360 size_t ciphertext_len =
361 ssl->s3->aead_write_ctx->ExplicitNonceLen() + suffix_len;
362 if (ciphertext_len + in_len < ciphertext_len) {
363 OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
364 return 0;
365 }
366 ciphertext_len += in_len;
367
368 assert(in == out || !buffers_alias(in, in_len, out, in_len));
369 assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl)));
370 assert(!buffers_alias(in, in_len, out_suffix, suffix_len));
371
372 if (extra_in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700373 out_prefix[0] = SSL3_RT_APPLICATION_DATA;
374 } else {
375 out_prefix[0] = type;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400376 }
David Benjamin1a01e1f2016-06-08 18:31:24 -0400377
Steven Valdezc7d4d212017-09-11 13:53:08 -0400378 uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion();
Steven Valdez16821262017-09-08 17:03:42 -0400379
Steven Valdezc7d4d212017-09-11 13:53:08 -0400380 out_prefix[1] = record_version >> 8;
381 out_prefix[2] = record_version & 0xff;
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700382 out_prefix[3] = ciphertext_len >> 8;
383 out_prefix[4] = ciphertext_len & 0xff;
David Benjamin6f600d62016-12-21 16:06:54 -0500384
Steven Valdezc7d4d212017-09-11 13:53:08 -0400385 if (!ssl->s3->aead_write_ctx->SealScatter(
386 out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, type,
387 record_version, ssl->s3->write_sequence, in, in_len, extra_in,
388 extra_in_len) ||
David Benjamin1db21562015-12-25 15:11:39 -0500389 !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400390 return 0;
391 }
392
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700393 ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out_prefix,
Steven Valdez924a3522017-03-02 16:05:03 -0500394 SSL3_RT_HEADER_LENGTH);
David Benjaminb8d28cf2015-07-28 21:34:45 -0400395 return 1;
396}
397
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700398static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type,
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700399 size_t in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700400 size_t ret = SSL3_RT_HEADER_LENGTH;
David Benjamind9f06712015-12-06 16:07:47 -0500401 if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
402 ssl_needs_record_splitting(ssl)) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400403 // In the case of record splitting, the 1-byte record (of the 1/n-1 split)
404 // will be placed in the prefix, as will four of the five bytes of the
405 // record header for the main record. The final byte will replace the first
406 // byte of the plaintext that was used in the small record.
David Benjamincfc11c22017-07-18 22:45:18 -0400407 ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher());
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700408 ret += SSL3_RT_HEADER_LENGTH - 1;
409 } else {
David Benjamincfc11c22017-07-18 22:45:18 -0400410 ret += ssl->s3->aead_write_ctx->ExplicitNonceLen();
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700411 }
412 return ret;
413}
414
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700415static bool tls_seal_scatter_suffix_len(const SSL *ssl, size_t *out_suffix_len,
416 uint8_t type, size_t in_len) {
417 size_t extra_in_len = 0;
418 if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
Steven Valdezc7d4d212017-09-11 13:53:08 -0400419 ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400420 // TLS 1.3 adds an extra byte for encrypted record type.
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700421 extra_in_len = 1;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700422 }
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700423 if (type == SSL3_RT_APPLICATION_DATA && // clang-format off
424 in_len > 1 &&
425 ssl_needs_record_splitting(ssl)) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400426 // With record splitting enabled, the first byte gets sealed into a separate
427 // record which is written into the prefix.
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700428 in_len -= 1;
429 }
430 return ssl->s3->aead_write_ctx->SuffixLen(out_suffix_len, in_len, extra_in_len);
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700431}
432
David Benjaminc11ea9422017-08-29 16:33:21 -0400433// tls_seal_scatter_record seals a new record of type |type| and body |in| and
434// splits it between |out_prefix|, |out|, and |out_suffix|. Exactly
435// |tls_seal_scatter_prefix_len| bytes are written to |out_prefix|, |in_len|
436// bytes to |out|, and |tls_seal_scatter_suffix_len| bytes to |out_suffix|. It
437// returns one on success and zero on error. If enabled,
438// |tls_seal_scatter_record| implements TLS 1.0 CBC 1/n-1 record splitting and
439// may write two records concatenated.
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700440static int tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700441 uint8_t *out_suffix, uint8_t type,
442 const uint8_t *in, size_t in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700443 if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
444 ssl_needs_record_splitting(ssl)) {
David Benjamincfc11c22017-07-18 22:45:18 -0400445 assert(ssl->s3->aead_write_ctx->ExplicitNonceLen() == 0);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700446 const size_t prefix_len = SSL3_RT_HEADER_LENGTH;
447
David Benjaminc11ea9422017-08-29 16:33:21 -0400448 // Write the 1-byte fragment into |out_prefix|.
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700449 uint8_t *split_body = out_prefix + prefix_len;
450 uint8_t *split_suffix = split_body + 1;
451
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700452 if (!do_seal_record(ssl, out_prefix, split_body, split_suffix, type, in,
453 1)) {
David Benjaminb8d28cf2015-07-28 21:34:45 -0400454 return 0;
455 }
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700456
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700457 size_t split_record_suffix_len;
458 if (!ssl->s3->aead_write_ctx->SuffixLen(&split_record_suffix_len, 1, 0)) {
459 assert(false);
460 return 0;
461 }
462 const size_t split_record_len = prefix_len + 1 + split_record_suffix_len;
David Benjamin79978df2015-12-25 15:56:49 -0500463 assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
David Benjamincfc11c22017-07-18 22:45:18 -0400464 ssl->s3->aead_write_ctx->cipher()) ==
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700465 split_record_len);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700466
David Benjaminc11ea9422017-08-29 16:33:21 -0400467 // Write the n-1-byte fragment. The header gets split between |out_prefix|
468 // (header[:-1]) and |out| (header[-1:]).
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700469 uint8_t tmp_prefix[SSL3_RT_HEADER_LENGTH];
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700470 if (!do_seal_record(ssl, tmp_prefix, out + 1, out_suffix, type, in + 1,
471 in_len - 1)) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700472 return 0;
473 }
474 assert(tls_seal_scatter_prefix_len(ssl, type, in_len) ==
475 split_record_len + SSL3_RT_HEADER_LENGTH - 1);
476 OPENSSL_memcpy(out_prefix + split_record_len, tmp_prefix,
477 SSL3_RT_HEADER_LENGTH - 1);
478 OPENSSL_memcpy(out, tmp_prefix + SSL3_RT_HEADER_LENGTH - 1, 1);
479 return 1;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400480 }
481
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700482 return do_seal_record(ssl, out_prefix, out, out_suffix, type, in, in_len);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700483}
484
485int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
486 uint8_t type, const uint8_t *in, size_t in_len) {
487 if (buffers_alias(in, in_len, out, max_out_len)) {
488 OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
David Benjaminb8d28cf2015-07-28 21:34:45 -0400489 return 0;
490 }
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700491
492 const size_t prefix_len = tls_seal_scatter_prefix_len(ssl, type, in_len);
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700493 size_t suffix_len;
494 if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, type, in_len)) {
495 return false;
496 }
497 if (in_len + prefix_len < in_len ||
498 prefix_len + in_len + suffix_len < prefix_len + in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700499 OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
500 return 0;
501 }
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700502 if (max_out_len < in_len + prefix_len + suffix_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700503 OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
504 return 0;
505 }
506
507 uint8_t *prefix = out;
508 uint8_t *body = out + prefix_len;
509 uint8_t *suffix = body + in_len;
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700510 if (!tls_seal_scatter_record(ssl, prefix, body, suffix, type, in, in_len)) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700511 return 0;
512 }
513
514 *out_len = prefix_len + in_len + suffix_len;
David Benjaminb8d28cf2015-07-28 21:34:45 -0400515 return 1;
516}
David Benjamin4119d422015-12-25 15:34:23 -0500517
David Benjamin728f3542016-06-02 15:42:01 -0400518enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,
519 const uint8_t *in, size_t in_len) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400520 // Alerts records may not contain fragmented or multiple alerts.
David Benjamin728f3542016-06-02 15:42:01 -0400521 if (in_len != 2) {
522 *out_alert = SSL_AD_DECODE_ERROR;
523 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
524 return ssl_open_record_error;
525 }
526
David Benjaminc0279992016-09-19 20:15:07 -0400527 ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in, in_len);
David Benjamin728f3542016-06-02 15:42:01 -0400528
529 const uint8_t alert_level = in[0];
530 const uint8_t alert_descr = in[1];
531
532 uint16_t alert = (alert_level << 8) | alert_descr;
533 ssl_do_info_callback(ssl, SSL_CB_READ_ALERT, alert);
534
535 if (alert_level == SSL3_AL_WARNING) {
536 if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
537 ssl->s3->recv_shutdown = ssl_shutdown_close_notify;
538 return ssl_open_record_close_notify;
539 }
540
David Benjaminc11ea9422017-08-29 16:33:21 -0400541 // Warning alerts do not exist in TLS 1.3.
David Benjamine8e84b92016-08-03 15:39:47 -0400542 if (ssl->s3->have_version &&
543 ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
544 *out_alert = SSL_AD_DECODE_ERROR;
545 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
546 return ssl_open_record_error;
547 }
548
David Benjamin728f3542016-06-02 15:42:01 -0400549 ssl->s3->warning_alert_count++;
550 if (ssl->s3->warning_alert_count > kMaxWarningAlerts) {
551 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
552 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS);
553 return ssl_open_record_error;
554 }
555 return ssl_open_record_discard;
556 }
557
558 if (alert_level == SSL3_AL_FATAL) {
559 ssl->s3->recv_shutdown = ssl_shutdown_fatal_alert;
David Benjamin728f3542016-06-02 15:42:01 -0400560
561 char tmp[16];
562 OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
563 BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
564 ERR_add_error_data(2, "SSL alert number ", tmp);
565 return ssl_open_record_fatal_alert;
566 }
567
568 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
569 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE);
570 return ssl_open_record_error;
571}
David Benjamin86e95b82017-07-18 16:34:25 -0400572
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700573OpenRecordResult OpenRecord(SSL *ssl, Span<uint8_t> *out,
574 size_t *out_record_len, uint8_t *out_alert,
575 const Span<uint8_t> in) {
576 // This API is a work in progress and currently only works for TLS 1.2 servers
577 // and below.
578 if (SSL_in_init(ssl) ||
579 SSL_is_dtls(ssl) ||
580 ssl3_protocol_version(ssl) > TLS1_2_VERSION) {
581 assert(false);
582 *out_alert = SSL_AD_INTERNAL_ERROR;
583 return OpenRecordResult::kError;
584 }
585
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700586 CBS plaintext;
587 uint8_t type;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700588 const ssl_open_record_t result = tls_open_record(
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700589 ssl, &type, &plaintext, out_record_len, out_alert, in.data(), in.size());
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700590
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700591 switch (result) {
592 case ssl_open_record_success:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700593 if (type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_ALERT) {
594 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
595 return OpenRecordResult::kError;
596 }
597 *out = MakeSpan(
598 const_cast<uint8_t*>(CBS_data(&plaintext)), CBS_len(&plaintext));
599 return OpenRecordResult::kOK;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700600 case ssl_open_record_discard:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700601 return OpenRecordResult::kDiscard;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700602 case ssl_open_record_partial:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700603 return OpenRecordResult::kIncompleteRecord;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700604 case ssl_open_record_close_notify:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700605 return OpenRecordResult::kAlertCloseNotify;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700606 case ssl_open_record_fatal_alert:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700607 return OpenRecordResult::kAlertFatal;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700608 case ssl_open_record_error:
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700609 return OpenRecordResult::kError;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700610 }
Martin Kreichgauer26ababb2017-08-03 12:02:34 -0700611 assert(false);
612 return OpenRecordResult::kError;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700613}
614
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700615size_t SealRecordPrefixLen(const SSL *ssl, const size_t record_len) {
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700616 return tls_seal_scatter_prefix_len(ssl, SSL3_RT_APPLICATION_DATA, record_len);
617}
618
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700619size_t SealRecordSuffixLen(const SSL *ssl, const size_t plaintext_len) {
620 assert(plaintext_len <= SSL3_RT_MAX_PLAIN_LENGTH);
621 size_t suffix_len;
622 if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, SSL3_RT_APPLICATION_DATA,
623 plaintext_len)) {
624 assert(false);
625 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
626 return 0;
627 }
628 assert(suffix_len <= SSL3_RT_MAX_ENCRYPTED_OVERHEAD);
629 return suffix_len;
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700630}
631
632bool SealRecord(SSL *ssl, const Span<uint8_t> out_prefix,
633 const Span<uint8_t> out, Span<uint8_t> out_suffix,
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700634 const Span<const uint8_t> in) {
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700635 // This API is a work in progress and currently only works for TLS 1.2 servers
636 // and below.
637 if (SSL_in_init(ssl) ||
638 SSL_is_dtls(ssl) ||
639 ssl3_protocol_version(ssl) > TLS1_2_VERSION) {
640 assert(false);
641 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
642 return false;
643 }
644
645 if (out_prefix.size() != SealRecordPrefixLen(ssl, in.size()) ||
646 out.size() != in.size() ||
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700647 out_suffix.size() != SealRecordSuffixLen(ssl, in.size())) {
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700648 OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
649 return false;
650 }
Martin Kreichgauerabbf3652017-07-21 16:27:54 -0700651 return tls_seal_scatter_record(ssl, out_prefix.data(), out.data(),
652 out_suffix.data(), SSL3_RT_APPLICATION_DATA,
653 in.data(), in.size());
Martin Kreichgauer17c30572017-07-18 12:42:18 -0700654}
655
David Benjamin86e95b82017-07-18 16:34:25 -0400656} // namespace bssl
657
658using namespace bssl;
659
660size_t SSL_max_seal_overhead(const SSL *ssl) {
661 if (SSL_is_dtls(ssl)) {
662 return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch);
663 }
664
665 size_t ret = SSL3_RT_HEADER_LENGTH;
David Benjamincfc11c22017-07-18 22:45:18 -0400666 ret += ssl->s3->aead_write_ctx->MaxOverhead();
David Benjaminc11ea9422017-08-29 16:33:21 -0400667 // TLS 1.3 needs an extra byte for the encrypted record type.
David Benjamincfc11c22017-07-18 22:45:18 -0400668 if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
Steven Valdezc7d4d212017-09-11 13:53:08 -0400669 ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) {
David Benjamin86e95b82017-07-18 16:34:25 -0400670 ret += 1;
671 }
672 if (ssl_needs_record_splitting(ssl)) {
673 ret *= 2;
674 }
675 return ret;
676}