summaryrefslogtreecommitdiffstats
path: root/ssl/record/methods
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/record/methods')
-rw-r--r--ssl/record/methods/build.info4
-rw-r--r--ssl/record/methods/ktls_meth.c84
-rw-r--r--ssl/record/methods/recmethod_local.h1
-rw-r--r--ssl/record/methods/tls_common.c201
4 files changed, 239 insertions, 51 deletions
diff --git a/ssl/record/methods/build.info b/ssl/record/methods/build.info
index dfe7d9c808..162739259c 100644
--- a/ssl/record/methods/build.info
+++ b/ssl/record/methods/build.info
@@ -7,4 +7,8 @@ IF[{- !$disabled{'deprecated-3.0'} -}]
SHARED_SOURCE[../../../libssl]=ssl3_cbc.c
ENDIF
+IF[{- !$disabled{'ktls'} -}]
+ SOURCE[../../../libssl]=ktls_meth.c
+ENDIF
+
SOURCE[../../../providers/libdefault.a ../../../providers/libfips.a]=ssl3_cbc.c
diff --git a/ssl/record/methods/ktls_meth.c b/ssl/record/methods/ktls_meth.c
new file mode 100644
index 0000000000..18576cee26
--- /dev/null
+++ b/ssl/record/methods/ktls_meth.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include "../../ssl_local.h"
+#include "../record_local.h"
+#include "recmethod_local.h"
+
+/* TODO(RECLAYER): Handle OPENSSL_NO_COMP */
+static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+ unsigned char *key, size_t keylen,
+ unsigned char *iv, size_t ivlen,
+ unsigned char *mackey, size_t mackeylen,
+ const EVP_CIPHER *ciph,
+ size_t taglen,
+ /* TODO(RECLAYER): This probably should not be an int */
+ int mactype,
+ const EVP_MD *md,
+ const SSL_COMP *comp,
+ /* TODO(RECLAYER): Remove me */
+ SSL_CONNECTION *s)
+{
+ void *rl_sequence;
+ ktls_crypto_info_t crypto_info;
+
+ /* Check if we are suitable for KTLS */
+
+ if (comp != NULL)
+ return 0;
+
+ /* ktls supports only the maximum fragment size */
+ if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
+ return 0;
+
+ /* check that cipher is supported */
+ if (!ktls_check_supported_cipher(s, ciph, taglen))
+ return 0;
+
+ /*
+ * TODO(RECLAYER): For the write side we need to add a check for
+ * use of s->record_padding_cb
+ */
+
+ /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
+ if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) {
+ if (BIO_flush(rl->bio) <= 0)
+ return 0;
+ }
+
+ if (rl->direction == OSSL_RECORD_DIRECTION_WRITE)
+ rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer);
+ else
+ rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer);
+
+ if (!ktls_configure_crypto(s, ciph, rl_sequence, &crypto_info,
+ rl->direction == OSSL_RECORD_DIRECTION_WRITE,
+ iv, ivlen, key, keylen, mackey, mackeylen))
+ return 0;
+
+ if (!BIO_set_ktls(rl->bio, &crypto_info, rl->direction))
+ return 0;
+
+ return 1;
+}
+
+static int ktls_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
+ int sending, SSL_MAC_BUF *mac, size_t macsize,
+ /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
+{
+ return 1;
+}
+
+struct record_functions_st ossl_ktls_funcs = {
+ ktls_set_crypto_state,
+ ktls_cipher,
+ NULL
+};
diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h
index ec4001587d..b5d1bc2305 100644
--- a/ssl/record/methods/recmethod_local.h
+++ b/ssl/record/methods/recmethod_local.h
@@ -113,6 +113,7 @@ struct ossl_record_layer_st
extern struct record_functions_st ssl_3_0_funcs;
extern struct record_functions_st tls_1_funcs;
extern struct record_functions_st tls_1_3_funcs;
+extern struct record_functions_st ossl_ktls_funcs;
extern struct record_functions_st tls_any_funcs;
void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason,
diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c
index b693fcf5db..5106224c6c 100644
--- a/ssl/record/methods/tls_common.c
+++ b/ssl/record/methods/tls_common.c
@@ -185,6 +185,11 @@ static int tls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
return OSSL_RECORD_RETURN_NON_FATAL_ERR;
rb = &rl->rbuf;
+ /*
+ * TODO(RECLAYER): Once this function is only called from inside the rlayer
+ * directly, we can probably remove this since it is initialised in
+ * tls_get_more_records
+ */
if (rb->buf == NULL) {
if (!rlayer_setup_read_buffer(rl)) {
/* RLAYERfatal() already called */
@@ -421,6 +426,12 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
rr = rl->rrec;
rbuf = &rl->rbuf;
+ if (rbuf->buf == NULL) {
+ if (!rlayer_setup_read_buffer(rl)) {
+ /* RLAYERfatal() already called */
+ return OSSL_RECORD_RETURN_FATAL;
+ }
+ }
max_recs = s->max_pipelines;
if (max_recs == 0)
@@ -1091,27 +1102,19 @@ static int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
return OSSL_RECORD_RETURN_SUCCESS;
}
-static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx,
- const char *propq, int vers,
- int role, int direction,
- int level, unsigned char *key,
- size_t keylen,
- unsigned char *iv,
- size_t ivlen,
- unsigned char *mackey,
- size_t mackeylen,
- const EVP_CIPHER *ciph,
- size_t taglen,
- /* TODO(RECLAYER): This probably should not be an int */
- int mactype,
- const EVP_MD *md,
- const SSL_COMP *comp,
- BIO *transport, BIO_ADDR *local,
- BIO_ADDR *peer,
- const OSSL_PARAM *settings,
- const OSSL_PARAM *options,
- /* TODO(RECLAYER): Remove me */
- SSL_CONNECTION *s)
+static OSSL_RECORD_LAYER *
+tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
+ int role, int direction, int level, unsigned char *key,
+ size_t keylen, unsigned char *iv, size_t ivlen,
+ unsigned char *mackey, size_t mackeylen,
+ const EVP_CIPHER *ciph, size_t taglen,
+ /* TODO(RECLAYER): This probably should not be an int */
+ int mactype,
+ const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
+ BIO_ADDR *local, BIO_ADDR *peer,
+ const OSSL_PARAM *settings, const OSSL_PARAM *options,
+ /* TODO(RECLAYER): Remove me */
+ SSL_CONNECTION *s)
{
OSSL_RECORD_LAYER *rl = OPENSSL_zalloc(sizeof(*rl));
const OSSL_PARAM *p;
@@ -1173,6 +1176,37 @@ static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx,
if (!tls_set1_bio(rl, transport))
goto err;
+ return rl;
+ err:
+ OPENSSL_free(rl);
+ return NULL;
+}
+
+static OSSL_RECORD_LAYER *
+tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
+ int role, int direction, int level, unsigned char *key,
+ size_t keylen, unsigned char *iv, size_t ivlen,
+ unsigned char *mackey, size_t mackeylen,
+ const EVP_CIPHER *ciph, size_t taglen,
+ /* TODO(RECLAYER): This probably should not be an int */
+ int mactype,
+ const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
+ BIO_ADDR *local, BIO_ADDR *peer,
+ const OSSL_PARAM *settings, const OSSL_PARAM *options,
+ /* TODO(RECLAYER): Remove me */
+ SSL_CONNECTION *s)
+{
+ OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role,
+ direction, level, key,
+ keylen, iv, ivlen, mackey,
+ mackeylen, ciph, taglen,
+ mactype, md, comp,
+ transport, local, peer,
+ settings, options, s);
+
+ if (rl == NULL)
+ return NULL;
+
switch (vers) {
case TLS_ANY_VERSION:
rl->funcs = &tls_any_funcs;
@@ -1196,45 +1230,37 @@ static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx,
if (!rl->funcs->set_crypto_state(rl, level, key, keylen, iv, ivlen,
mackey, mackeylen, ciph, taglen,
- mactype, md, comp, s)) {
- /* RLAYERfatal already called */
+ mactype, md, comp, s))
goto err;
- }
return rl;
err:
+ /* TODO(RECLAYER): How do we distinguish between fatal and non-fatal errors? */
OPENSSL_free(rl);
return NULL;
}
-static OSSL_RECORD_LAYER *dtls_new_record_layer(OSSL_LIB_CTX *libctx,
- const char *propq, int vers,
- int role, int direction,
- int level, unsigned char *key,
- size_t keylen,
- unsigned char *iv,
- size_t ivlen,
- unsigned char *mackey,
- size_t mackeylen,
- const EVP_CIPHER *ciph,
- size_t taglen,
- /* TODO(RECLAYER): This probably should not be an int */
- int mactype,
- const EVP_MD *md,
- const SSL_COMP *comp,
- BIO *transport, BIO_ADDR *local,
- BIO_ADDR *peer,
- const OSSL_PARAM *settings,
- const OSSL_PARAM *options,
- /* TODO(RECLAYER): Remove me */
- SSL_CONNECTION *s)
+static OSSL_RECORD_LAYER *
+dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
+ int role, int direction, int level, unsigned char *key,
+ size_t keylen, unsigned char *iv, size_t ivlen,
+ unsigned char *mackey, size_t mackeylen,
+ const EVP_CIPHER *ciph, size_t taglen,
+ /* TODO(RECLAYER): This probably should not be an int */
+ int mactype,
+ const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
+ BIO_ADDR *local, BIO_ADDR *peer,
+ const OSSL_PARAM *settings, const OSSL_PARAM *options,
+ /* TODO(RECLAYER): Remove me */
+ SSL_CONNECTION *s)
{
- OSSL_RECORD_LAYER *rl = tls_new_record_layer(libctx, propq, vers, role,
- direction, level, key, keylen,
- iv, ivlen, mackey, mackeylen,
- ciph, taglen, mactype, md,
- comp, transport, local, peer,
- settings, options, s);
+ OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role,
+ direction, level, key,
+ keylen, iv, ivlen, mackey,
+ mackeylen, ciph, taglen,
+ mactype, md, comp,
+ transport, local, peer,
+ settings, options, s);
if (rl == NULL)
return NULL;
@@ -1244,6 +1270,47 @@ static OSSL_RECORD_LAYER *dtls_new_record_layer(OSSL_LIB_CTX *libctx,
return rl;
}
+#ifndef OPENSSL_NO_KTLS
+static OSSL_RECORD_LAYER *
+ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
+ int role, int direction, int level, unsigned char *key,
+ size_t keylen, unsigned char *iv, size_t ivlen,
+ unsigned char *mackey, size_t mackeylen,
+ const EVP_CIPHER *ciph, size_t taglen,
+ /* TODO(RECLAYER): This probably should not be an int */
+ int mactype,
+ const EVP_MD *md, const SSL_COMP *comp, BIO *transport,
+ BIO_ADDR *local, BIO_ADDR *peer,
+ const OSSL_PARAM *settings, const OSSL_PARAM *options,
+ /* TODO(RECLAYER): Remove me */
+ SSL_CONNECTION *s)
+{
+ OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role,
+ direction, level, key,
+ keylen, iv, ivlen, mackey,
+ mackeylen, ciph, taglen,
+ mactype, md, comp,
+ transport, local, peer,
+ settings, options, s);
+
+ if (rl == NULL)
+ return NULL;
+
+ rl->funcs = &ossl_ktls_funcs;
+
+ if (!rl->funcs->set_crypto_state(rl, level, key, keylen, iv, ivlen,
+ mackey, mackeylen, ciph, taglen,
+ mactype, md, comp, s))
+ goto err;
+
+ return rl;
+ err:
+ /* TODO(RECLAYER): How do we distinguish between fatal and non-fatal errors? */
+ OPENSSL_free(rl);
+ return NULL;
+}
+#endif
+
static void tls_free(OSSL_RECORD_LAYER *rl)
{
/* TODO(RECLAYER): Cleanse sensitive fields */
@@ -1368,6 +1435,38 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = {
tls_reset_packet_length
};
+#ifndef OPENSSL_NO_KTLS
+const OSSL_RECORD_METHOD ossl_ktls_record_method = {
+ ktls_new_record_layer,
+ tls_free,
+ tls_reset,
+ tls_unprocessed_read_pending,
+ tls_processed_read_pending,
+ tls_app_data_pending,
+ tls_write_pending,
+ tls_get_max_record_len,
+ tls_get_max_records,
+ tls_write_records,
+ tls_retry_write_records,
+ tls_read_record,
+ tls_release_record,
+ tls_get_alert_code,
+ tls_set1_bio,
+
+ /*
+ * TODO(RECLAYER): Remove these. These function pointers are temporary hacks
+ * during the record layer refactoring. They need to be removed before the
+ * refactor is complete.
+ */
+ tls_read_n,
+ tls_get0_rbuf,
+ tls_get0_packet,
+ tls_set0_packet,
+ tls_get_packet_length,
+ tls_reset_packet_length
+};
+#endif
+
const OSSL_RECORD_METHOD ossl_dtls_record_method = {
dtls_new_record_layer,
tls_free,