1 /* Copyright (c) 2015, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/ssl.h>
16
17 #include <assert.h>
18 #include <limits.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <openssl/bio.h>
23 #include <openssl/err.h>
24 #include <openssl/mem.h>
25
26 #include "../crypto/internal.h"
27 #include "internal.h"
28
29
30 BSSL_NAMESPACE_BEGIN
31
32 // BIO uses int instead of size_t. No lengths will exceed uint16_t, so this will
33 // not overflow.
34 static_assert(0xffff <= INT_MAX, "uint16_t does not fit in int");
35
36 static_assert((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0,
37 "SSL3_ALIGN_PAYLOAD must be a power of 2");
38
Clear()39 void SSLBuffer::Clear() {
40 if (buf_allocated_) {
41 free(buf_); // Allocated with malloc().
42 }
43 buf_ = nullptr;
44 buf_allocated_ = false;
45 offset_ = 0;
46 size_ = 0;
47 cap_ = 0;
48 }
49
EnsureCap(size_t header_len,size_t new_cap)50 bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) {
51 if (new_cap > 0xffff) {
52 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
53 return false;
54 }
55
56 if (cap_ >= new_cap) {
57 return true;
58 }
59
60 uint8_t *new_buf;
61 bool new_buf_allocated;
62 size_t new_offset;
63 if (new_cap <= sizeof(inline_buf_)) {
64 // This function is called twice per TLS record, first for the five-byte
65 // header. To avoid allocating twice, use an inline buffer for short inputs.
66 new_buf = inline_buf_;
67 new_buf_allocated = false;
68 new_offset = 0;
69 } else {
70 // Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment.
71 //
72 // Since this buffer gets allocated quite frequently and doesn't contain any
73 // sensitive data, we allocate with malloc rather than |OPENSSL_malloc| and
74 // avoid zeroing on free.
75 new_buf = (uint8_t *)malloc(new_cap + SSL3_ALIGN_PAYLOAD - 1);
76 if (new_buf == NULL) {
77 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
78 return false;
79 }
80 new_buf_allocated = true;
81
82 // Offset the buffer such that the record body is aligned.
83 new_offset =
84 (0 - header_len - (uintptr_t)new_buf) & (SSL3_ALIGN_PAYLOAD - 1);
85 }
86
87 // Note if the both old and new buffer are inline, the source and destination
88 // may alias.
89 OPENSSL_memmove(new_buf + new_offset, buf_ + offset_, size_);
90
91 if (buf_allocated_) {
92 free(buf_); // Allocated with malloc().
93 }
94
95 buf_ = new_buf;
96 buf_allocated_ = new_buf_allocated;
97 offset_ = new_offset;
98 cap_ = new_cap;
99 return true;
100 }
101
DidWrite(size_t new_size)102 void SSLBuffer::DidWrite(size_t new_size) {
103 if (new_size > cap() - size()) {
104 abort();
105 }
106 size_ += new_size;
107 }
108
Consume(size_t len)109 void SSLBuffer::Consume(size_t len) {
110 if (len > size_) {
111 abort();
112 }
113 offset_ += (uint16_t)len;
114 size_ -= (uint16_t)len;
115 cap_ -= (uint16_t)len;
116 }
117
DiscardConsumed()118 void SSLBuffer::DiscardConsumed() {
119 if (size_ == 0) {
120 Clear();
121 }
122 }
123
dtls_read_buffer_next_packet(SSL * ssl)124 static int dtls_read_buffer_next_packet(SSL *ssl) {
125 SSLBuffer *buf = &ssl->s3->read_buffer;
126
127 if (!buf->empty()) {
128 // It is an error to call |dtls_read_buffer_extend| when the read buffer is
129 // not empty.
130 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
131 return -1;
132 }
133
134 // Read a single packet from |ssl->rbio|. |buf->cap()| must fit in an int.
135 int ret =
136 BIO_read(ssl->rbio.get(), buf->data(), static_cast<int>(buf->cap()));
137 if (ret <= 0) {
138 ssl->s3->rwstate = SSL_ERROR_WANT_READ;
139 return ret;
140 }
141 buf->DidWrite(static_cast<size_t>(ret));
142 return 1;
143 }
144
tls_read_buffer_extend_to(SSL * ssl,size_t len)145 static int tls_read_buffer_extend_to(SSL *ssl, size_t len) {
146 SSLBuffer *buf = &ssl->s3->read_buffer;
147
148 if (len > buf->cap()) {
149 OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
150 return -1;
151 }
152
153 // Read until the target length is reached.
154 while (buf->size() < len) {
155 // The amount of data to read is bounded by |buf->cap|, which must fit in an
156 // int.
157 int ret = BIO_read(ssl->rbio.get(), buf->data() + buf->size(),
158 static_cast<int>(len - buf->size()));
159 if (ret <= 0) {
160 ssl->s3->rwstate = SSL_ERROR_WANT_READ;
161 return ret;
162 }
163 buf->DidWrite(static_cast<size_t>(ret));
164 }
165
166 return 1;
167 }
168
ssl_read_buffer_extend_to(SSL * ssl,size_t len)169 int ssl_read_buffer_extend_to(SSL *ssl, size_t len) {
170 // |ssl_read_buffer_extend_to| implicitly discards any consumed data.
171 ssl->s3->read_buffer.DiscardConsumed();
172
173 if (SSL_is_dtls(ssl)) {
174 static_assert(
175 DTLS1_RT_MAX_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= 0xffff,
176 "DTLS read buffer is too large");
177
178 // The |len| parameter is ignored in DTLS.
179 len = DTLS1_RT_MAX_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
180 }
181
182 // The DTLS record header can have a variable length, so the |header_len|
183 // value provided for buffer alignment only works if the header is the maximum
184 // length.
185 if (!ssl->s3->read_buffer.EnsureCap(DTLS1_RT_MAX_HEADER_LENGTH, len)) {
186 return -1;
187 }
188
189 if (ssl->rbio == nullptr) {
190 OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
191 return -1;
192 }
193
194 int ret;
195 if (SSL_is_dtls(ssl)) {
196 // |len| is ignored for a datagram transport.
197 ret = dtls_read_buffer_next_packet(ssl);
198 } else {
199 ret = tls_read_buffer_extend_to(ssl, len);
200 }
201
202 if (ret <= 0) {
203 // If the buffer was empty originally and remained empty after attempting to
204 // extend it, release the buffer until the next attempt.
205 ssl->s3->read_buffer.DiscardConsumed();
206 }
207 return ret;
208 }
209
ssl_handle_open_record(SSL * ssl,bool * out_retry,ssl_open_record_t ret,size_t consumed,uint8_t alert)210 int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret,
211 size_t consumed, uint8_t alert) {
212 *out_retry = false;
213 if (ret != ssl_open_record_partial) {
214 ssl->s3->read_buffer.Consume(consumed);
215 }
216 if (ret != ssl_open_record_success) {
217 // Nothing was returned to the caller, so discard anything marked consumed.
218 ssl->s3->read_buffer.DiscardConsumed();
219 }
220 switch (ret) {
221 case ssl_open_record_success:
222 return 1;
223
224 case ssl_open_record_partial: {
225 int read_ret = ssl_read_buffer_extend_to(ssl, consumed);
226 if (read_ret <= 0) {
227 return read_ret;
228 }
229 *out_retry = true;
230 return 1;
231 }
232
233 case ssl_open_record_discard:
234 *out_retry = true;
235 return 1;
236
237 case ssl_open_record_close_notify:
238 ssl->s3->rwstate = SSL_ERROR_ZERO_RETURN;
239 return 0;
240
241 case ssl_open_record_error:
242 if (alert != 0) {
243 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
244 }
245 return -1;
246 }
247 assert(0);
248 return -1;
249 }
250
251
252 static_assert(SSL3_RT_HEADER_LENGTH * 2 +
253 SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 +
254 SSL3_RT_MAX_PLAIN_LENGTH <=
255 0xffff,
256 "maximum TLS write buffer is too large");
257
258 static_assert(DTLS1_RT_MAX_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
259 SSL3_RT_MAX_PLAIN_LENGTH <=
260 0xffff,
261 "maximum DTLS write buffer is too large");
262
tls_write_buffer_flush(SSL * ssl)263 static int tls_write_buffer_flush(SSL *ssl) {
264 SSLBuffer *buf = &ssl->s3->write_buffer;
265
266 while (!buf->empty()) {
267 int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size());
268 if (ret <= 0) {
269 ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
270 return ret;
271 }
272 buf->Consume(static_cast<size_t>(ret));
273 }
274 buf->Clear();
275 return 1;
276 }
277
dtls_write_buffer_flush(SSL * ssl)278 static int dtls_write_buffer_flush(SSL *ssl) {
279 SSLBuffer *buf = &ssl->s3->write_buffer;
280 if (buf->empty()) {
281 return 1;
282 }
283
284 int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size());
285 if (ret <= 0) {
286 ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
287 // If the write failed, drop the write buffer anyway. Datagram transports
288 // can't write half a packet, so the caller is expected to retry from the
289 // top.
290 buf->Clear();
291 return ret;
292 }
293 buf->Clear();
294 return 1;
295 }
296
ssl_write_buffer_flush(SSL * ssl)297 int ssl_write_buffer_flush(SSL *ssl) {
298 if (ssl->wbio == nullptr) {
299 OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
300 return -1;
301 }
302
303 if (SSL_is_dtls(ssl)) {
304 return dtls_write_buffer_flush(ssl);
305 } else {
306 return tls_write_buffer_flush(ssl);
307 }
308 }
309
310 BSSL_NAMESPACE_END
311