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
SSL3_BUFFER_set_data(SSL3_BUFFER * b,const unsigned char * d,size_t n)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 */
SSL3_BUFFER_clear(SSL3_BUFFER * b)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
SSL3_BUFFER_release(SSL3_BUFFER * b)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
ssl3_setup_read_buffer(SSL * s)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
ssl3_setup_write_buffer(SSL * s,size_t numwpipes,size_t len)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
ssl3_setup_buffers(SSL * s)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
ssl3_release_write_buffer(SSL * s)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
ssl3_release_read_buffer(SSL * s)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