xref: /freebsd/crypto/openssl/ssl/record/ssl3_buffer.c (revision 44096ebd22ddd0081a357011714eff8963614b65)
1e71b7053SJung-uk Kim /*
2*44096ebdSEnji Cooper  * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  *
4b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim  */
9e71b7053SJung-uk Kim 
1017f01e99SJung-uk Kim #include "../ssl_local.h"
1117f01e99SJung-uk Kim #include "record_local.h"
12e71b7053SJung-uk Kim 
13e71b7053SJung-uk Kim void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, size_t n)
14e71b7053SJung-uk Kim {
15e71b7053SJung-uk Kim     if (d != NULL)
16e71b7053SJung-uk Kim         memcpy(b->buf, d, n);
17e71b7053SJung-uk Kim     b->left = n;
18e71b7053SJung-uk Kim     b->offset = 0;
19e71b7053SJung-uk Kim }
20e71b7053SJung-uk Kim 
21e71b7053SJung-uk Kim /*
22e71b7053SJung-uk Kim  * Clear the contents of an SSL3_BUFFER but retain any memory allocated. Also
23e71b7053SJung-uk Kim  * retains the default_len setting
24e71b7053SJung-uk Kim  */
25e71b7053SJung-uk Kim void SSL3_BUFFER_clear(SSL3_BUFFER *b)
26e71b7053SJung-uk Kim {
27e71b7053SJung-uk Kim     b->offset = 0;
28e71b7053SJung-uk Kim     b->left = 0;
29e71b7053SJung-uk Kim }
30e71b7053SJung-uk Kim 
31e71b7053SJung-uk Kim void SSL3_BUFFER_release(SSL3_BUFFER *b)
32e71b7053SJung-uk Kim {
33e71b7053SJung-uk Kim     OPENSSL_free(b->buf);
34e71b7053SJung-uk Kim     b->buf = NULL;
35e71b7053SJung-uk Kim }
36e71b7053SJung-uk Kim 
37e71b7053SJung-uk Kim int ssl3_setup_read_buffer(SSL *s)
38e71b7053SJung-uk Kim {
39e71b7053SJung-uk Kim     unsigned char *p;
40e71b7053SJung-uk Kim     size_t len, align = 0, headerlen;
41e71b7053SJung-uk Kim     SSL3_BUFFER *b;
42e71b7053SJung-uk Kim 
43e71b7053SJung-uk Kim     b = RECORD_LAYER_get_rbuf(&s->rlayer);
44e71b7053SJung-uk Kim 
45e71b7053SJung-uk Kim     if (SSL_IS_DTLS(s))
46e71b7053SJung-uk Kim         headerlen = DTLS1_RT_HEADER_LENGTH;
47e71b7053SJung-uk Kim     else
48e71b7053SJung-uk Kim         headerlen = SSL3_RT_HEADER_LENGTH;
49e71b7053SJung-uk Kim 
50e71b7053SJung-uk Kim #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
51e71b7053SJung-uk Kim     align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
52e71b7053SJung-uk Kim #endif
53e71b7053SJung-uk Kim 
54e71b7053SJung-uk Kim     if (b->buf == NULL) {
55e71b7053SJung-uk Kim         len = SSL3_RT_MAX_PLAIN_LENGTH
56e71b7053SJung-uk Kim             + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
57e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
58e71b7053SJung-uk Kim         if (ssl_allow_compression(s))
59e71b7053SJung-uk Kim             len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
60e71b7053SJung-uk Kim #endif
61b077aed3SPierre Pronchery 
62b077aed3SPierre Pronchery         /* Ensure our buffer is large enough to support all our pipelines */
63b077aed3SPierre Pronchery         if (s->max_pipelines > 1)
64b077aed3SPierre Pronchery             len *= s->max_pipelines;
65b077aed3SPierre Pronchery 
66e71b7053SJung-uk Kim         if (b->default_len > len)
67e71b7053SJung-uk Kim             len = b->default_len;
68e71b7053SJung-uk Kim         if ((p = OPENSSL_malloc(len)) == NULL) {
69e71b7053SJung-uk Kim             /*
70e71b7053SJung-uk Kim              * We've got a malloc failure, and we're still initialising buffers.
71e71b7053SJung-uk Kim              * We assume we're so doomed that we won't even be able to send an
72e71b7053SJung-uk Kim              * alert.
73e71b7053SJung-uk Kim              */
74b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE);
75e71b7053SJung-uk Kim             return 0;
76e71b7053SJung-uk Kim         }
77e71b7053SJung-uk Kim         b->buf = p;
78e71b7053SJung-uk Kim         b->len = len;
79e71b7053SJung-uk Kim     }
80e71b7053SJung-uk Kim 
81e71b7053SJung-uk Kim     return 1;
82e71b7053SJung-uk Kim }
83e71b7053SJung-uk Kim 
84e71b7053SJung-uk Kim int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len)
85e71b7053SJung-uk Kim {
86e71b7053SJung-uk Kim     unsigned char *p;
87e71b7053SJung-uk Kim     size_t align = 0, headerlen;
88e71b7053SJung-uk Kim     SSL3_BUFFER *wb;
89e71b7053SJung-uk Kim     size_t currpipe;
90e71b7053SJung-uk Kim 
91e71b7053SJung-uk Kim     s->rlayer.numwpipes = numwpipes;
92e71b7053SJung-uk Kim 
93e71b7053SJung-uk Kim     if (len == 0) {
94e71b7053SJung-uk Kim         if (SSL_IS_DTLS(s))
95e71b7053SJung-uk Kim             headerlen = DTLS1_RT_HEADER_LENGTH + 1;
96e71b7053SJung-uk Kim         else
97e71b7053SJung-uk Kim             headerlen = SSL3_RT_HEADER_LENGTH;
98e71b7053SJung-uk Kim 
99e71b7053SJung-uk Kim #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
10058f35182SJung-uk Kim         align = SSL3_ALIGN_PAYLOAD - 1;
101e71b7053SJung-uk Kim #endif
102e71b7053SJung-uk Kim 
103e71b7053SJung-uk Kim         len = ssl_get_max_send_fragment(s)
104640242a5SJung-uk Kim             + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align
105640242a5SJung-uk Kim             + SSL_RT_MAX_CIPHER_BLOCK_SIZE /* Explicit IV allowance */;
106e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
107e71b7053SJung-uk Kim         if (ssl_allow_compression(s))
108e71b7053SJung-uk Kim             len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
109e71b7053SJung-uk Kim #endif
110640242a5SJung-uk Kim         /*
111640242a5SJung-uk Kim          * We don't need to add an allowance for eivlen here since empty
112640242a5SJung-uk Kim          * fragments only occur when we don't have an explicit IV
113640242a5SJung-uk Kim          */
114e71b7053SJung-uk Kim         if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
115e71b7053SJung-uk Kim             len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
116e71b7053SJung-uk Kim     }
117e71b7053SJung-uk Kim 
118e71b7053SJung-uk Kim     wb = RECORD_LAYER_get_wbuf(&s->rlayer);
119e71b7053SJung-uk Kim     for (currpipe = 0; currpipe < numwpipes; currpipe++) {
120e71b7053SJung-uk Kim         SSL3_BUFFER *thiswb = &wb[currpipe];
121e71b7053SJung-uk Kim 
122aa906e2aSJohn Baldwin         if (thiswb->len != len) {
123e71b7053SJung-uk Kim             OPENSSL_free(thiswb->buf);
124e71b7053SJung-uk Kim             thiswb->buf = NULL;         /* force reallocation */
125e71b7053SJung-uk Kim         }
126e71b7053SJung-uk Kim 
127e71b7053SJung-uk Kim         if (thiswb->buf == NULL) {
128aa906e2aSJohn Baldwin             if (s->wbio == NULL || !BIO_get_ktls_send(s->wbio)) {
129e71b7053SJung-uk Kim                 p = OPENSSL_malloc(len);
130e71b7053SJung-uk Kim                 if (p == NULL) {
131e71b7053SJung-uk Kim                     s->rlayer.numwpipes = currpipe;
132e71b7053SJung-uk Kim                     /*
133e71b7053SJung-uk Kim                      * We've got a malloc failure, and we're still initialising
134e71b7053SJung-uk Kim                      * buffers. We assume we're so doomed that we won't even be able
135e71b7053SJung-uk Kim                      * to send an alert.
136e71b7053SJung-uk Kim                      */
137b077aed3SPierre Pronchery                     SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE);
138e71b7053SJung-uk Kim                     return 0;
139e71b7053SJung-uk Kim                 }
140aa906e2aSJohn Baldwin             } else {
141aa906e2aSJohn Baldwin                 p = NULL;
142aa906e2aSJohn Baldwin             }
143e71b7053SJung-uk Kim             memset(thiswb, 0, sizeof(SSL3_BUFFER));
144e71b7053SJung-uk Kim             thiswb->buf = p;
145e71b7053SJung-uk Kim             thiswb->len = len;
146e71b7053SJung-uk Kim         }
147e71b7053SJung-uk Kim     }
148e71b7053SJung-uk Kim 
149e71b7053SJung-uk Kim     return 1;
150e71b7053SJung-uk Kim }
151e71b7053SJung-uk Kim 
152e71b7053SJung-uk Kim int ssl3_setup_buffers(SSL *s)
153e71b7053SJung-uk Kim {
154e71b7053SJung-uk Kim     if (!ssl3_setup_read_buffer(s)) {
155e71b7053SJung-uk Kim         /* SSLfatal() already called */
156e71b7053SJung-uk Kim         return 0;
157e71b7053SJung-uk Kim     }
158e71b7053SJung-uk Kim     if (!ssl3_setup_write_buffer(s, 1, 0)) {
159e71b7053SJung-uk Kim         /* SSLfatal() already called */
160e71b7053SJung-uk Kim         return 0;
161e71b7053SJung-uk Kim     }
162e71b7053SJung-uk Kim     return 1;
163e71b7053SJung-uk Kim }
164e71b7053SJung-uk Kim 
165e71b7053SJung-uk Kim int ssl3_release_write_buffer(SSL *s)
166e71b7053SJung-uk Kim {
167e71b7053SJung-uk Kim     SSL3_BUFFER *wb;
168e71b7053SJung-uk Kim     size_t pipes;
169e71b7053SJung-uk Kim 
170e71b7053SJung-uk Kim     pipes = s->rlayer.numwpipes;
171e71b7053SJung-uk Kim     while (pipes > 0) {
172e71b7053SJung-uk Kim         wb = &RECORD_LAYER_get_wbuf(&s->rlayer)[pipes - 1];
173e71b7053SJung-uk Kim 
174aa906e2aSJohn Baldwin         if (SSL3_BUFFER_is_app_buffer(wb))
175aa906e2aSJohn Baldwin             SSL3_BUFFER_set_app_buffer(wb, 0);
176aa906e2aSJohn Baldwin         else
177e71b7053SJung-uk Kim             OPENSSL_free(wb->buf);
178e71b7053SJung-uk Kim         wb->buf = NULL;
179e71b7053SJung-uk Kim         pipes--;
180e71b7053SJung-uk Kim     }
181e71b7053SJung-uk Kim     s->rlayer.numwpipes = 0;
182e71b7053SJung-uk Kim     return 1;
183e71b7053SJung-uk Kim }
184e71b7053SJung-uk Kim 
185e71b7053SJung-uk Kim int ssl3_release_read_buffer(SSL *s)
186e71b7053SJung-uk Kim {
187e71b7053SJung-uk Kim     SSL3_BUFFER *b;
188e71b7053SJung-uk Kim 
189e71b7053SJung-uk Kim     b = RECORD_LAYER_get_rbuf(&s->rlayer);
190b077aed3SPierre Pronchery     if (s->options & SSL_OP_CLEANSE_PLAINTEXT)
191b077aed3SPierre Pronchery         OPENSSL_cleanse(b->buf, b->len);
192e71b7053SJung-uk Kim     OPENSSL_free(b->buf);
193e71b7053SJung-uk Kim     b->buf = NULL;
194*44096ebdSEnji Cooper     s->rlayer.packet = NULL;
195*44096ebdSEnji Cooper     s->rlayer.packet_length = 0;
196e71b7053SJung-uk Kim     return 1;
197e71b7053SJung-uk Kim }
198