#include "recmethod_local.h"
#include "internal/ktls.h"
+static struct record_functions_st ossl_ktls_funcs;
+
#if defined(__FreeBSD__)
# include "crypto/cryptodev.h"
return 1;
}
-static struct record_functions_st ossl_ktls_funcs = {
- ktls_set_crypto_state,
- ktls_cipher,
- NULL,
- tls_default_set_protocol_version,
- ktls_read_n,
- tls_get_more_records,
- ktls_validate_record_header,
- ktls_post_process_record,
- tls_get_max_records_default,
- tls_write_records_default
-};
-
static int
ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, uint16_t epoch,
return ret;
}
+static int ktls_allocate_write_buffers(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl, size_t *prefix)
+{
+ if (!ossl_assert(numtempl == 1))
+ return 0;
+
+ /*
+ * We just use the end application buffer in the case of KTLS, so nothing
+ * to do. We pretend we set up one buffer.
+ */
+ rl->numwpipes = 1;
+
+ return 1;
+}
+
+static int ktls_initialise_write_packets(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl,
+ OSSL_RECORD_TEMPLATE *prefixtempl,
+ WPACKET *pkt,
+ SSL3_BUFFER *bufs,
+ size_t *wpinited)
+{
+ SSL3_BUFFER *wb;
+
+ /*
+ * We just use the application buffer directly, and don't use any WPACKET
+ * structures
+ */
+ wb = &bufs[0];
+ wb->type = templates[0].type;
+
+ /*
+ * ktls doesn't modify the buffer, but to avoid a warning we need
+ * to discard the const qualifier.
+ * This doesn't leak memory because the buffers have been
+ * released when switching to ktls.
+ */
+ SSL3_BUFFER_set_buf(wb, (unsigned char *)templates[0].buf);
+ SSL3_BUFFER_set_offset(wb, 0);
+ SSL3_BUFFER_set_app_buffer(wb, 1);
+
+ return 1;
+}
+
+static struct record_functions_st ossl_ktls_funcs = {
+ ktls_set_crypto_state,
+ ktls_cipher,
+ NULL,
+ tls_default_set_protocol_version,
+ ktls_read_n,
+ tls_get_more_records,
+ ktls_validate_record_header,
+ ktls_post_process_record,
+ tls_get_max_records_default,
+ tls_write_records_default,
+ ktls_allocate_write_buffers,
+ ktls_initialise_write_packets
+};
+
const OSSL_RECORD_METHOD ossl_ktls_record_method = {
ktls_new_record_layer,
tls_free,
/* Return 1 for success or 0 for error */
int (*write_records)(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
size_t numtempl);
+
+ /* Allocate the rl->wbuf buffers. Return 1 for success or 0 for error */
+ int (*allocate_write_buffers)(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl, size_t *prefix);
+
+ /*
+ * Initialise the packets in the |pkt| array using the buffers in |rl->wbuf|.
+ * Some protocol versions may use the space in |prefixtempl| to add
+ * an artificial template in front of the |templates| array and hence may
+ * initialise 1 more WPACKET than there are templates. |*wpinited|
+ * returns the number of WPACKETs in |pkt| that were successfully
+ * initialised. This must be 0 on entry and will be filled in even on error.
+ */
+ int (*initialise_write_packets)(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl,
+ OSSL_RECORD_TEMPLATE *prefixtempl,
+ WPACKET *pkt,
+ SSL3_BUFFER *bufs,
+ size_t *wpinited);
};
struct ossl_record_layer_st
size_t tls_get_max_records_default(OSSL_RECORD_LAYER *rl, int type, size_t len,
size_t maxfrag, size_t *preffrag);
+int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl, size_t *prefix);
+int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl,
+ OSSL_RECORD_TEMPLATE *prefixtempl,
+ WPACKET *pkt,
+ SSL3_BUFFER *bufs,
+ size_t *wpinited);
+int tls1_allocate_write_buffers(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl, size_t *prefix);
+int tls1_initialise_write_packets(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl,
+ OSSL_RECORD_TEMPLATE *prefixtempl,
+ WPACKET *pkt,
+ SSL3_BUFFER *bufs,
+ size_t *wpinited);
size_t tls_get_max_records_multiblock(OSSL_RECORD_LAYER *rl, int type,
size_t len, size_t maxfrag,
size_t *preffrag);
tls_default_validate_record_header,
tls_default_post_process_record,
tls_get_max_records_default,
- tls_write_records_default
+ tls_write_records_default,
+ /* These 2 functions are defined in tls1_meth.c */
+ tls1_allocate_write_buffers,
+ tls1_initialise_write_packets
};
tls13_validate_record_header,
tls13_post_process_record,
tls_get_max_records_default,
- tls_write_records_default
+ tls_write_records_default,
+ tls_allocate_write_buffers_default,
+ tls_initialise_write_packets_default
};
#include <openssl/evp.h>
#include <openssl/core_names.h>
#include <openssl/rand.h>
+#include <openssl/ssl.h>
#include "../../ssl_local.h"
#include "../record_local.h"
#include "recmethod_local.h"
return ret;
}
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
+# ifndef OPENSSL_NO_COMP
+# define MAX_PREFIX_LEN ((SSL3_ALIGN_PAYLOAD - 1) \
+ + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+ + SSL3_RT_HEADER_LENGTH \
+ + SSL3_RT_MAX_COMPRESSED_OVERHEAD)
+# else
+# define MAX_PREFIX_LEN ((SSL3_ALIGN_PAYLOAD - 1) \
+ + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+ + SSL3_RT_HEADER_LENGTH)
+# endif /* OPENSSL_NO_COMP */
+#else
+# ifndef OPENSSL_NO_COMP
+# define MAX_PREFIX_LEN (SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+ + SSL3_RT_HEADER_LENGTH \
+ + SSL3_RT_MAX_COMPRESSED_OVERHEAD)
+# else
+# define MAX_PREFIX_LEN (SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+ + SSL3_RT_HEADER_LENGTH)
+# endif /* OPENSSL_NO_COMP */
+#endif
+
+/* This function is also used by the SSLv3 implementation */
+int tls1_allocate_write_buffers(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl, size_t *prefix)
+{
+ /* Do we need to add an empty record prefix? */
+ *prefix = rl->need_empty_fragments
+ && templates[0].type == SSL3_RT_APPLICATION_DATA;
+
+ /*
+ * In the prefix case we can allocate a much smaller buffer. Otherwise we
+ * just allocate the default buffer size
+ */
+ if (!tls_setup_write_buffer(rl, numtempl + *prefix,
+ *prefix ? MAX_PREFIX_LEN : 0, 0)) {
+ /* RLAYERfatal() already called */
+ return 0;
+ }
+
+ return 1;
+}
+
+/* This function is also used by the SSLv3 implementation */
+int tls1_initialise_write_packets(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl,
+ OSSL_RECORD_TEMPLATE *prefixtempl,
+ WPACKET *pkt,
+ SSL3_BUFFER *bufs,
+ size_t *wpinited)
+{
+ size_t align = 0;
+ SSL3_BUFFER *wb;
+ size_t prefix;
+
+ /* Do we need to add an empty record prefix? */
+ prefix = rl->need_empty_fragments
+ && templates[0].type == SSL3_RT_APPLICATION_DATA;
+
+ if (prefix) {
+ /*
+ * countermeasure against known-IV weakness in CBC ciphersuites (see
+ * http://www.openssl.org/~bodo/tls-cbc.txt)
+ */
+ prefixtempl->buf = NULL;
+ prefixtempl->version = templates[0].version;
+ prefixtempl->buflen = 0;
+ prefixtempl->type = SSL3_RT_APPLICATION_DATA;
+
+ wb = &bufs[0];
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
+ align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1
+ - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+ SSL3_BUFFER_set_offset(wb, align);
+
+ if (!WPACKET_init_static_len(&pkt[0], SSL3_BUFFER_get_buf(wb),
+ SSL3_BUFFER_get_len(wb), 0)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ *wpinited = 1;
+ if (!WPACKET_allocate_bytes(&pkt[0], align, NULL)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+
+ return tls_initialise_write_packets_default(rl, templates, numtempl,
+ NULL,
+ pkt + prefix, bufs + prefix,
+ wpinited);
+}
+
/* TLSv1.0, TLSv1.1 and TLSv1.2 all use the same funcs */
struct record_functions_st tls_1_funcs = {
tls1_set_crypto_state,
tls_default_validate_record_header,
tls_default_post_process_record,
tls_get_max_records_multiblock,
- tls_write_records_multiblock /* Defined in tls_multib.c */
+ tls_write_records_multiblock, /* Defined in tls_multib.c */
+ tls1_allocate_write_buffers,
+ tls1_initialise_write_packets
};
struct record_functions_st dtls_1_funcs = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
#include <openssl/err.h>
#include <openssl/core_names.h>
#include <openssl/comp.h>
+#include <openssl/ssl.h>
#include "internal/e_os.h"
#include "internal/packet.h"
#include "../../ssl_local.h"
}
}
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
-# ifndef OPENSSL_NO_COMP
-# define MAX_PREFIX_LEN ((SSL3_ALIGN_PAYLOAD - 1) \
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
- + SSL3_RT_HEADER_LENGTH \
- + SSL3_RT_MAX_COMPRESSED_OVERHEAD)
-# else
-# define MAX_PREFIX_LEN ((SSL3_ALIGN_PAYLOAD - 1) \
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
- + SSL3_RT_HEADER_LENGTH)
-# endif /* OPENSSL_NO_COMP */
-#else
-# ifndef OPENSSL_NO_COMP
-# define MAX_PREFIX_LEN (SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
- + SSL3_RT_HEADER_LENGTH \
- + SSL3_RT_MAX_COMPRESSED_OVERHEAD)
-# else
-# define MAX_PREFIX_LEN (SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
- + SSL3_RT_HEADER_LENGTH)
-# endif /* OPENSSL_NO_COMP */
-#endif
-
int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
size_t firstlen, size_t nextlen)
{
* it, then return the preferred number of pipelines.
*/
if (rl->max_pipelines > 0
- && rl->enc_ctx!= NULL
+ && rl->enc_ctx != NULL
&& (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(rl->enc_ctx))
& EVP_CIPH_FLAG_PIPELINE) != 0
&& RLAYER_USE_EXPLICIT_IV(rl)) {
return rl->funcs->get_max_records(rl, type, len, maxfrag, preffrag);
}
+int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl,
+ size_t *prefix)
+{
+ if (!tls_setup_write_buffer(rl, numtempl, 0, 0)) {
+ /* RLAYERfatal() already called */
+ return 0;
+ }
+
+ return 1;
+}
+
+int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl,
+ OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl,
+ OSSL_RECORD_TEMPLATE *prefixtempl,
+ WPACKET *pkt,
+ SSL3_BUFFER *bufs,
+ size_t *wpinited)
+{
+ WPACKET *thispkt;
+ size_t j, align;
+ SSL3_BUFFER *wb;
+
+ for (j = 0; j < numtempl; j++) {
+ thispkt = &pkt[j];
+ wb = &bufs[j];
+
+ wb->type = templates[j].type;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
+ align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1
+ - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+ SSL3_BUFFER_set_offset(wb, align);
+
+ if (!WPACKET_init_static_len(thispkt, SSL3_BUFFER_get_buf(wb),
+ SSL3_BUFFER_get_len(wb), 0)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ (*wpinited)++;
+ if (!WPACKET_allocate_bytes(thispkt, align, NULL)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
int tls_write_records_default(OSSL_RECORD_LAYER *rl,
OSSL_RECORD_TEMPLATE *templates,
size_t numtempl)
SSL3_RECORD *thiswr;
unsigned char *recordstart;
int mac_size = 0, ret = 0;
- size_t align = 0;
- SSL3_BUFFER *wb;
size_t len, wpinited = 0;
size_t j, prefix = 0;
int using_ktls;
OSSL_RECORD_TEMPLATE prefixtempl;
OSSL_RECORD_TEMPLATE *thistempl;
-
if (rl->md_ctx != NULL && EVP_MD_CTX_get0_md(rl->md_ctx) != NULL) {
mac_size = EVP_MD_CTX_get_size(rl->md_ctx);
if (mac_size < 0) {
}
}
- /* Do we need to add an empty record prefix? */
- prefix = rl->need_empty_fragments
- && templates[0].type == SSL3_RT_APPLICATION_DATA;
+ if (!rl->funcs->allocate_write_buffers(rl, templates, numtempl, &prefix)) {
+ /* RLAYERfatal() already called */
+ goto err;
+ }
- /*
- * In the prefix case we can allocate a much smaller buffer. Otherwise we
- * just allocate the default buffer size
- */
- if (!tls_setup_write_buffer(rl, numtempl + prefix,
- prefix ? MAX_PREFIX_LEN : 0, 0)) {
+ if (!rl->funcs->initialise_write_packets(rl, templates, numtempl,
+ &prefixtempl, pkt, rl->wbuf,
+ &wpinited)) {
/* RLAYERfatal() already called */
goto err;
}
goto err;
}
- if (prefix) {
- /*
- * countermeasure against known-IV weakness in CBC ciphersuites (see
- * http://www.openssl.org/~bodo/tls-cbc.txt)
- */
- prefixtempl.buf = NULL;
- prefixtempl.version = templates[0].version;
- prefixtempl.buflen = 0;
- prefixtempl.type = SSL3_RT_APPLICATION_DATA;
- wpinited = 1;
-
- wb = &rl->wbuf[0];
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
- align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
- align = SSL3_ALIGN_PAYLOAD - 1
- - ((align - 1) % SSL3_ALIGN_PAYLOAD);
-#endif
- SSL3_BUFFER_set_offset(wb, align);
- if (!WPACKET_init_static_len(&pkt[0], SSL3_BUFFER_get_buf(wb),
- SSL3_BUFFER_get_len(wb), 0)
- || !WPACKET_allocate_bytes(&pkt[0], align, NULL)) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- wpinited = 1;
- }
- for (j = 0; j < numtempl; j++) {
- thispkt = &pkt[prefix + j];
-
- wb = &rl->wbuf[prefix + j];
- wb->type = templates[j].type;
-
- if (using_ktls) {
- /*
- * ktls doesn't modify the buffer, but to avoid a warning we need
- * to discard the const qualifier.
- * This doesn't leak memory because the buffers have been
- * released when switching to ktls.
- */
- SSL3_BUFFER_set_buf(wb, (unsigned char *)templates[j].buf);
- SSL3_BUFFER_set_offset(wb, 0);
- SSL3_BUFFER_set_app_buffer(wb, 1);
- } else {
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
- align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
- align = SSL3_ALIGN_PAYLOAD - 1
- - ((align - 1) % SSL3_ALIGN_PAYLOAD);
-#endif
- SSL3_BUFFER_set_offset(wb, align);
- if (!WPACKET_init_static_len(thispkt, SSL3_BUFFER_get_buf(wb),
- SSL3_BUFFER_get_len(wb), 0)
- || !WPACKET_allocate_bytes(thispkt, align, NULL)) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- wpinited++;
- }
- }
-
/* Clear our SSL3_RECORD structures */
memset(wr, 0, sizeof(wr));
for (j = 0; j < numtempl + prefix; j++) {
thispkt = &pkt[j];
thiswr = &wr[j];
- thistempl = (j == 0 && prefix == 1) ? &prefixtempl :
- &templates[j - prefix];
+ thistempl = (j < prefix) ? &prefixtempl : &templates[j - prefix];
/*
* In TLSv1.3, once encrypting, we always use application data for the
}
}
- for (j = 0; j < prefix + numtempl; j++) {
+ for (j = 0; j < numtempl + prefix; j++) {
size_t origlen;
thispkt = &pkt[j];
thiswr = &wr[j];
- thistempl = (prefix == 1 && j == 0) ? &prefixtempl
- : &templates[j - prefix];
+ thistempl = (j < prefix) ? &prefixtempl : &templates[j - prefix];
if (using_ktls)
goto mac_done;
tls_validate_record_header,
tls_default_post_process_record,
tls_get_max_records_default,
- tls_write_records_default
+ tls_write_records_default,
+ tls_allocate_write_buffers_default,
+ tls_initialise_write_packets_default
};
static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};