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_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_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
180 }
181
182 if (!ssl->s3->read_buffer.EnsureCap(ssl_record_prefix_len(ssl), len)) {
183 return -1;
184 }
185
186 if (ssl->rbio == nullptr) {
187 OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
188 return -1;
189 }
190
191 int ret;
192 if (SSL_is_dtls(ssl)) {
193 // |len| is ignored for a datagram transport.
194 ret = dtls_read_buffer_next_packet(ssl);
195 } else {
196 ret = tls_read_buffer_extend_to(ssl, len);
197 }
198
199 if (ret <= 0) {
200 // If the buffer was empty originally and remained empty after attempting to
201 // extend it, release the buffer until the next attempt.
202 ssl->s3->read_buffer.DiscardConsumed();
203 }
204 return ret;
205 }
206
ssl_handle_open_record(SSL * ssl,bool * out_retry,ssl_open_record_t ret,size_t consumed,uint8_t alert)207 int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret,
208 size_t consumed, uint8_t alert) {
209 *out_retry = false;
210 if (ret != ssl_open_record_partial) {
211 ssl->s3->read_buffer.Consume(consumed);
212 }
213 if (ret != ssl_open_record_success) {
214 // Nothing was returned to the caller, so discard anything marked consumed.
215 ssl->s3->read_buffer.DiscardConsumed();
216 }
217 switch (ret) {
218 case ssl_open_record_success:
219 return 1;
220
221 case ssl_open_record_partial: {
222 int read_ret = ssl_read_buffer_extend_to(ssl, consumed);
223 if (read_ret <= 0) {
224 return read_ret;
225 }
226 *out_retry = true;
227 return 1;
228 }
229
230 case ssl_open_record_discard:
231 *out_retry = true;
232 return 1;
233
234 case ssl_open_record_close_notify:
235 ssl->s3->rwstate = SSL_ERROR_ZERO_RETURN;
236 return 0;
237
238 case ssl_open_record_error:
239 if (alert != 0) {
240 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
241 }
242 return -1;
243 }
244 assert(0);
245 return -1;
246 }
247
248
249 static_assert(SSL3_RT_HEADER_LENGTH * 2 +
250 SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 +
251 SSL3_RT_MAX_PLAIN_LENGTH <=
252 0xffff,
253 "maximum TLS write buffer is too large");
254
255 static_assert(DTLS1_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
256 SSL3_RT_MAX_PLAIN_LENGTH <=
257 0xffff,
258 "maximum DTLS write buffer is too large");
259
tls_write_buffer_flush(SSL * ssl)260 static int tls_write_buffer_flush(SSL *ssl) {
261 SSLBuffer *buf = &ssl->s3->write_buffer;
262
263 while (!buf->empty()) {
264 int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size());
265 if (ret <= 0) {
266 ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
267 return ret;
268 }
269 buf->Consume(static_cast<size_t>(ret));
270 }
271 buf->Clear();
272 return 1;
273 }
274
dtls_write_buffer_flush(SSL * ssl)275 static int dtls_write_buffer_flush(SSL *ssl) {
276 SSLBuffer *buf = &ssl->s3->write_buffer;
277 if (buf->empty()) {
278 return 1;
279 }
280
281 int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size());
282 if (ret <= 0) {
283 ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
284 // If the write failed, drop the write buffer anyway. Datagram transports
285 // can't write half a packet, so the caller is expected to retry from the
286 // top.
287 buf->Clear();
288 return ret;
289 }
290 buf->Clear();
291 return 1;
292 }
293
ssl_write_buffer_flush(SSL * ssl)294 int ssl_write_buffer_flush(SSL *ssl) {
295 if (ssl->wbio == nullptr) {
296 OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
297 return -1;
298 }
299
300 if (SSL_is_dtls(ssl)) {
301 return dtls_write_buffer_flush(ssl);
302 } else {
303 return tls_write_buffer_flush(ssl);
304 }
305 }
306
307 BSSL_NAMESPACE_END
308