[openssl] master update

Matt Caswell matt at openssl.org
Mon Aug 31 08:50:00 UTC 2020


The branch master has been updated
       via  72c1e37421ffe9a4db4bba46f3d736dbc227c255 (commit)
       via  ab114c6ddef52384c3c5d579847b989284f51dfc (commit)
       via  18efb630169a5c2c58a77b0b67fc707a87cb8b93 (commit)
       via  cd03b5dc428568548163890081da99b6e5df11ba (commit)
       via  eb818d23c2f451ed56030d9e9fb94bd60ec48b07 (commit)
       via  c7b46b549d59797c3f1ea6541f8ff6f02009cbc5 (commit)
       via  b22a3ccc07e304df8fdbc79bf4168c1a880d0ac5 (commit)
       via  3c1641e8e86dc86028637251421a57827243f6ca (commit)
       via  0a90a90c4626dab3b6931e6a1e0bba9419720146 (commit)
       via  3e5826061baa7948ab1d2835357403d16470108d (commit)
       via  c34ca13a60f2acb4509be0aec9f506853ffbd1ea (commit)
      from  23e77b0ba328afe3492d990cd24f7b8896b4246f (commit)


- Log -----------------------------------------------------------------
commit 72c1e37421ffe9a4db4bba46f3d736dbc227c255
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Wed Aug 5 16:24:24 2020 -0700

    Use global 'libctx' with RAND_bytes_ex to generate sendfile temp data.
    
    While here, check for failure from RAND_bytes_ex as well.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit ab114c6ddef52384c3c5d579847b989284f51dfc
Author: Vadim Fedorenko <vadimjunk at gmail.com>
Date:   Fri Jul 31 11:21:36 2020 -0700

    Fix two issues with AES-CCM KTLS tests.
    
    - Apply the cipher list to the server context as well as the client
      context.  The tests still worked for AES-GCM cipher suites as those
      are in the default list of ciphers.  AES-CCM cipher suites are not
      in the default list and require the cipher list to be set.
    
    - Use the correct cipher name for AES-CCM.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit 18efb630169a5c2c58a77b0b67fc707a87cb8b93
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Wed Jul 29 15:08:54 2020 -0700

    Skip tests using KTLS RX for TLS 1.3.
    
    KTLS RX is not yet supported for TLS 1.3.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit cd03b5dc428568548163890081da99b6e5df11ba
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Wed Jul 29 15:08:25 2020 -0700

    Skip tests using KTLS RX if KTLS RX is not supported.
    
    This skips tests using KTLS RX when run on systems that only support
    KTLS TX.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit eb818d23c2f451ed56030d9e9fb94bd60ec48b07
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Wed Jul 29 14:56:58 2020 -0700

    Refactor the KTLS tests to minimize code duplication.
    
    Use the low 4 bits of the test number directly as flags for which of
    the connection sides should use KTLS or not for each test instead of
    having 16 nearly identical functions to do the same thing.
    
    This makes it easier to skip tests that aren't supported (e.g. KTLS RX
    on TLS 1.3).
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit c7b46b549d59797c3f1ea6541f8ff6f02009cbc5
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Mon Jul 27 11:35:13 2020 -0700

    Move KTLS inline functions only used by libssl into ssl/ktls.c.
    
    These functions are a bit large to inline and are not usable outside
    of libssl.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit b22a3ccc07e304df8fdbc79bf4168c1a880d0ac5
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Wed Dec 4 16:50:06 2019 -0800

    Support for KTLS TX on FreeBSD for TLS 1.3.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit 3c1641e8e86dc86028637251421a57827243f6ca
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Thu Mar 5 11:26:06 2020 -0800

    Don't check errno if ktls_read_record() returned 0.
    
    errno is only valid if ktls_read_record() fails with a negative return
    value.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit 0a90a90c4626dab3b6931e6a1e0bba9419720146
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Thu Oct 31 16:49:40 2019 -0700

    Add support for KTLS receive for TLS 1.1-1.2 on FreeBSD.
    
    Similar to KTLS receive for Linux, KTLS receive for FreeBSD is enabled
    by passing a session key to the kernel via a new socket option.  Once
    KTLS receive is enabled on a socket, the socket returns records via
    recvmsg().  A control message attached to each record supplies the
    original TLS header, and the decrypted plaintext is returned in the
    data buffer passed to recvmsg().
    
    To support the case that the userland buffer may already contain
    pending encrypted records (which is already handled by Linux's KTLS
    receive), the socket option structure for FreeBSD has been extended to
    include the initial sequence number.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit 3e5826061baa7948ab1d2835357403d16470108d
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Wed Jun 10 13:36:38 2020 -0700

    Add helper functions for FreeBSD KTLS.
    
    These are similar to the helpers added in 95badfeb60.  I've adjusted
    the arguments passed to ktls_check_supported_cipher and
    ktls_configure_crypto so that FreeBSD and Linux can both use the same
    signature to avoid OS-specific #ifdef's in libssl.  This also required
    moving the check on valid TLS versions into
    ktls_check_supported_cipher for Linux.  This has largely removed
    OS-specific code and OS-specific #ifdef's for KTLS outside of
    <internal/ktls.h>.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

commit c34ca13a60f2acb4509be0aec9f506853ffbd1ea
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Fri Jul 24 13:47:35 2020 -0700

    Add a ktls_crypto_info_t typedef.
    
    This type is defined to hold the OS-specific structure passed to
    BIO_set_ktls.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12111)

-----------------------------------------------------------------------

Summary of changes:
 include/internal/ktls.h  | 206 ++++++++++++-------------
 ssl/build.info           |   8 +-
 ssl/ktls.c               | 222 +++++++++++++++++++++++++++
 ssl/record/ssl3_record.c |   2 +-
 ssl/ssl_local.h          |  12 ++
 ssl/t1_enc.c             |  66 +-------
 ssl/tls13_enc.c          |  12 +-
 test/sslapitest.c        | 382 +++++------------------------------------------
 8 files changed, 392 insertions(+), 518 deletions(-)
 create mode 100644 ssl/ktls.c

diff --git a/include/internal/ktls.h b/include/internal/ktls.h
index 535e563479..2af1589f98 100644
--- a/include/internal/ktls.h
+++ b/include/internal/ktls.h
@@ -20,9 +20,9 @@
 # endif
 #endif
 
-#ifndef OPENSSL_NO_KTLS
-# ifndef HEADER_INTERNAL_KTLS
-#  define HEADER_INTERNAL_KTLS
+#ifndef HEADER_INTERNAL_KTLS
+# define HEADER_INTERNAL_KTLS
+# ifndef OPENSSL_NO_KTLS
 
 #  if defined(__FreeBSD__)
 #   include <sys/types.h>
@@ -30,12 +30,22 @@
 #   include <sys/ktls.h>
 #   include <netinet/in.h>
 #   include <netinet/tcp.h>
-#   include <crypto/cryptodev.h>
+#   include "openssl/ssl3.h"
+
+#   ifndef TCP_RXTLS_ENABLE
+#    define OPENSSL_NO_KTLS_RX
+#   endif
+#   define OPENSSL_KTLS_AES_GCM_128
+#   define OPENSSL_KTLS_AES_GCM_256
+#   define OPENSSL_KTLS_TLS13
 
 /*
  * Only used by the tests in sslapitest.c.
  */
 #   define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE             8
+#   define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE             8
+
+typedef struct tls_enable ktls_crypto_info_t;
 
 /*
  * FreeBSD does not require any additional steps to enable KTLS before
@@ -49,8 +59,12 @@ static ossl_inline int ktls_enable(int fd)
 /*
  * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer
  * as using TLS.  If successful, then data sent using this socket will
- * be encrypted and encapsulated in TLS records using the tls_en.
+ * be encrypted and encapsulated in TLS records using the tls_en
  * provided here.
+ *
+ * The TCP_RXTLS_ENABLE socket option marks the incoming socket buffer
+ * as using TLS.  If successful, then data received for this socket will
+ * be authenticated and decrypted using the tls_en provided here.
  */
 static ossl_inline int ktls_start(int fd,
                                   void *tls_en,
@@ -59,8 +73,11 @@ static ossl_inline int ktls_start(int fd,
     if (is_tx)
         return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE,
                           tls_en, len) ? 0 : 1;
-    else
-        return 0;
+#   ifndef OPENSSL_NO_KTLS_RX
+    return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en, len) ? 0 : 1;
+#   else
+    return 0;
+#   endif
 }
 
 /*
@@ -96,11 +113,79 @@ static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type,
     return sendmsg(fd, &msg, 0);
 }
 
+#   ifdef OPENSSL_NO_KTLS_RX
+
 static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
 {
     return -1;
 }
 
+#   else /* !defined(OPENSSL_NO_KTLS_RX) */
+
+/*
+ * Receive a TLS record using the tls_en provided in ktls_start.  The
+ * kernel strips any explicit IV and authentication tag, but provides
+ * the TLS record header via a control message.  If there is an error
+ * with the TLS record such as an invalid header, invalid padding, or
+ * authentication failure recvmsg() will fail with an error.
+ */
+static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
+{
+    struct msghdr msg = { 0 };
+    int cmsg_len = sizeof(struct tls_get_record);
+    struct tls_get_record *tgr;
+    struct cmsghdr *cmsg;
+    char buf[CMSG_SPACE(cmsg_len)];
+    struct iovec msg_iov;   /* Vector of data to send/receive into */
+    int ret;
+    unsigned char *p = data;
+    const size_t prepend_length = SSL3_RT_HEADER_LENGTH;
+
+    if (length <= prepend_length) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    msg.msg_control = buf;
+    msg.msg_controllen = sizeof(buf);
+
+    msg_iov.iov_base = p + prepend_length;
+    msg_iov.iov_len = length - prepend_length;
+    msg.msg_iov = &msg_iov;
+    msg.msg_iovlen = 1;
+
+    ret = recvmsg(fd, &msg, 0);
+    if (ret <= 0)
+        return ret;
+
+    if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) {
+        errno = EMSGSIZE;
+        return -1;
+    }
+
+    if (msg.msg_controllen == 0) {
+        errno = EBADMSG;
+        return -1;
+    }
+
+    cmsg = CMSG_FIRSTHDR(&msg);
+    if (cmsg->cmsg_level != IPPROTO_TCP || cmsg->cmsg_type != TLS_GET_RECORD
+        || cmsg->cmsg_len != CMSG_LEN(cmsg_len)) {
+        errno = EBADMSG;
+        return -1;
+    }
+
+    tgr = (struct tls_get_record *)CMSG_DATA(cmsg);
+    p[0] = tgr->tls_type;
+    p[1] = tgr->tls_vmajor;
+    p[2] = tgr->tls_vminor;
+    *(uint16_t *)(p + 3) = htons(ret);
+
+    return ret + prepend_length;
+}
+
+#   endif /* OPENSSL_NO_KTLS_RX */
+
 /*
  * KTLS enables the sendfile system call to send data from a file over
  * TLS.
@@ -119,6 +204,7 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off,
     }
     return sbytes;
 }
+
 #  endif                         /* __FreeBSD__ */
 
 #  if defined(OPENSSL_SYS_LINUX)
@@ -173,6 +259,9 @@ struct tls_crypto_info_all {
     };
     size_t tls_crypto_info_len;
 };
+
+typedef struct tls_crypto_info_all ktls_crypto_info_t;
+
 /*
  * When successful, this socket option doesn't change the behaviour of the
  * TCP socket, except changing the TCP setsockopt handler to enable the
@@ -310,106 +399,8 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
 
 #   endif /* OPENSSL_NO_KTLS_RX */
 
-/* Function to check supported ciphers in Linux */
-static ossl_inline int ktls_check_supported_cipher(const EVP_CIPHER *c,
-                                            const EVP_CIPHER_CTX *dd)
-{
-    /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */
-    switch (EVP_CIPHER_nid(c))
-    {
-#  ifdef OPENSSL_KTLS_AES_CCM_128
-    case NID_aes_128_ccm:
-        if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN)
-          return 0;
-#  endif
-#  ifdef OPENSSL_KTLS_AES_GCM_128
-    case NID_aes_128_gcm:
-#  endif
-#  ifdef OPENSSL_KTLS_AES_GCM_256
-    case NID_aes_256_gcm:
-#  endif
-        return 1;
-    default:
-        return 0;
-    }
-}
-
-/* Function to configure kernel TLS structure */
-static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_version,
-                                EVP_CIPHER_CTX *dd, void *rl_sequence,
-                                struct tls_crypto_info_all *crypto_info,
-                                unsigned char **rec_seq, unsigned char *iv,
-                                unsigned char *key)
-{
-    unsigned char geniv[12];
-    unsigned char *iiv = iv;
-
-    if (tls_version == TLS1_2_VERSION &&
-        EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
-        if (!EVP_CIPHER_CTX_get_iv_state(dd, geniv,
-                                         EVP_GCM_TLS_FIXED_IV_LEN
-                                         + EVP_GCM_TLS_EXPLICIT_IV_LEN))
-            return 0;
-        iiv = geniv;
-    }
-
-    memset(crypto_info, 0, sizeof(*crypto_info));
-    switch (EVP_CIPHER_nid(c))
-    {
-#  ifdef OPENSSL_KTLS_AES_GCM_128
-    case NID_aes_128_gcm:
-        crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
-        crypto_info->gcm128.info.version = tls_version;
-        crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
-        memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
-                TLS_CIPHER_AES_GCM_128_IV_SIZE);
-        memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
-        memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c));
-        memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
-                TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-        if (rec_seq != NULL)
-            *rec_seq = crypto_info->gcm128.rec_seq;
-        return 1;
-#  endif
-#  ifdef OPENSSL_KTLS_AES_GCM_256
-    case NID_aes_256_gcm:
-        crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
-        crypto_info->gcm256.info.version = tls_version;
-        crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
-        memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
-                TLS_CIPHER_AES_GCM_256_IV_SIZE);
-        memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
-        memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c));
-        memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
-                TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-        if (rec_seq != NULL)
-            *rec_seq = crypto_info->gcm256.rec_seq;
-        return 1;
-#  endif
-#  ifdef OPENSSL_KTLS_AES_CCM_128
-    case NID_aes_128_ccm:
-        crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
-        crypto_info->ccm128.info.version = tls_version;
-        crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
-        memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN,
-                TLS_CIPHER_AES_CCM_128_IV_SIZE);
-        memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
-        memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c));
-        memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
-                TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-        if (rec_seq != NULL)
-            *rec_seq = crypto_info->ccm128.rec_seq;
-        return 1;
-#  endif
-    default:
-        return 0;
-    }
-
-}
-
 #  endif /* OPENSSL_SYS_LINUX */
-# endif /* HEADER_INTERNAL_KTLS */
-#else /* defined(OPENSSL_NO_KTLS) */
+# else /* OPENSSL_NO_KTLS */
 /* Dummy functions here */
 static ossl_inline int ktls_enable(int fd)
 {
@@ -437,4 +428,5 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t s
 {
     return -1;
 }
-#endif
+# endif /* OPENSSL_NO_KTLS */
+#endif /* HEADER_INTERNAL_KTLS */
diff --git a/ssl/build.info b/ssl/build.info
index fd187ac7e5..cfcb2b1737 100644
--- a/ssl/build.info
+++ b/ssl/build.info
@@ -10,6 +10,11 @@ IF[{- !$disabled{asm} -}]
   ENDIF
 ENDIF
 
+$KTLSSRC=
+IF[{- !$disabled{ktls} -}]
+  $KTLSSRC=ktls.c
+ENDIF
+
 #TODO: For now we just include the libcrypto packet.c in libssl as well. We
 #      could either continue to do it like this, or export all the WPACKET
 #      symbols so that libssl can use them like any other. Probably would do
@@ -27,7 +32,8 @@ SOURCE[../libssl]=\
         ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c  ssl_mcnf.c \
         bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \
         record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
-        statem/statem.c record/ssl3_record_tls13.c record/tls_pad.c
+        statem/statem.c record/ssl3_record_tls13.c record/tls_pad.c \
+        $KTLSSRC
 DEFINE[../libssl]=$AESDEF
 
 SOURCE[../providers/libcommon.a]=record/tls_pad.c
diff --git a/ssl/ktls.c b/ssl/ktls.c
new file mode 100644
index 0000000000..e6c0963259
--- /dev/null
+++ b/ssl/ktls.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2018-2020 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 "ssl_local.h"
+#include "internal/ktls.h"
+
+#if defined(__FreeBSD__)
+# include <crypto/cryptodev.h>
+
+/*-
+ * Check if a given cipher is supported by the KTLS interface.
+ * The kernel might still fail the setsockopt() if no suitable
+ * provider is found, but this checks if the socket option
+ * supports the cipher suite used at all.
+ */
+int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
+                                const EVP_CIPHER_CTX *dd)
+{
+
+    switch (s->version) {
+    case TLS1_VERSION:
+    case TLS1_1_VERSION:
+    case TLS1_2_VERSION:
+    case TLS1_3_VERSION:
+        break;
+    default:
+        return 0;
+    }
+
+    switch (s->s3.tmp.new_cipher->algorithm_enc) {
+    case SSL_AES128GCM:
+    case SSL_AES256GCM:
+        return 1;
+    case SSL_AES128:
+    case SSL_AES256:
+        if (s->ext.use_etm)
+            return 0;
+        switch (s->s3.tmp.new_cipher->algorithm_mac) {
+        case SSL_SHA1:
+        case SSL_SHA256:
+        case SSL_SHA384:
+            return 1;
+        default:
+            return 0;
+        }
+    default:
+        return 0;
+    }
+}
+
+/* Function to configure kernel TLS structure */
+int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+                          void *rl_sequence, ktls_crypto_info_t *crypto_info,
+                          unsigned char **rec_seq, unsigned char *iv,
+                          unsigned char *key, unsigned char *mac_key,
+                          size_t mac_secret_size)
+{
+    memset(crypto_info, 0, sizeof(*crypto_info));
+    switch (s->s3.tmp.new_cipher->algorithm_enc) {
+    case SSL_AES128GCM:
+    case SSL_AES256GCM:
+        crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
+        if (s->version == TLS1_3_VERSION)
+            crypto_info->iv_len = EVP_CIPHER_CTX_iv_length(dd);
+        else
+            crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
+        break;
+    case SSL_AES128:
+    case SSL_AES256:
+        switch (s->s3.tmp.new_cipher->algorithm_mac) {
+        case SSL_SHA1:
+            crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC;
+            break;
+        case SSL_SHA256:
+            crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC;
+            break;
+        case SSL_SHA384:
+            crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC;
+            break;
+        default:
+            return 0;
+        }
+        crypto_info->cipher_algorithm = CRYPTO_AES_CBC;
+        crypto_info->iv_len = EVP_CIPHER_iv_length(c);
+        crypto_info->auth_key = mac_key;
+        crypto_info->auth_key_len = mac_secret_size;
+        break;
+    default:
+        return 0;
+    }
+    crypto_info->cipher_key = key;
+    crypto_info->cipher_key_len = EVP_CIPHER_key_length(c);
+    crypto_info->iv = iv;
+    crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff;
+    crypto_info->tls_vminor = (s->version & 0x000000ff);
+# ifdef TCP_RXTLS_ENABLE
+    memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq));
+    if (rec_seq != NULL)
+        *rec_seq = crypto_info->rec_seq;
+# else
+    if (rec_seq != NULL)
+        *rec_seq = NULL;
+# endif
+    return 1;
+};
+
+#endif                         /* __FreeBSD__ */
+
+#if defined(OPENSSL_SYS_LINUX)
+
+/* Function to check supported ciphers in Linux */
+int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
+                                const EVP_CIPHER_CTX *dd)
+{
+    switch (s->version) {
+    case TLS1_2_VERSION:
+    case TLS1_3_VERSION:
+        break;
+    default:
+        return 0;
+    }
+
+    /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */
+    switch (EVP_CIPHER_nid(c))
+    {
+# ifdef OPENSSL_KTLS_AES_CCM_128
+    case NID_aes_128_ccm:
+        if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN)
+          return 0;
+# endif
+# ifdef OPENSSL_KTLS_AES_GCM_128
+    case NID_aes_128_gcm:
+# endif
+# ifdef OPENSSL_KTLS_AES_GCM_256
+    case NID_aes_256_gcm:
+# endif
+        return 1;
+    default:
+        return 0;
+    }
+}
+
+/* Function to configure kernel TLS structure */
+int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+                          void *rl_sequence, ktls_crypto_info_t *crypto_info,
+                          unsigned char **rec_seq, unsigned char *iv,
+                          unsigned char *key, unsigned char *mac_key,
+                          size_t mac_secret_size)
+{
+    unsigned char geniv[12];
+    unsigned char *iiv = iv;
+
+    if (s->version == TLS1_2_VERSION &&
+        EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
+        if (!EVP_CIPHER_CTX_get_iv_state(dd, geniv,
+                                         EVP_GCM_TLS_FIXED_IV_LEN
+                                         + EVP_GCM_TLS_EXPLICIT_IV_LEN))
+            return 0;
+        iiv = geniv;
+    }
+
+    memset(crypto_info, 0, sizeof(*crypto_info));
+    switch (EVP_CIPHER_nid(c))
+    {
+# ifdef OPENSSL_KTLS_AES_GCM_128
+    case NID_aes_128_gcm:
+        crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
+        crypto_info->gcm128.info.version = s->version;
+        crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
+        memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
+                TLS_CIPHER_AES_GCM_128_IV_SIZE);
+        memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
+        memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c));
+        memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
+                TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+        if (rec_seq != NULL)
+            *rec_seq = crypto_info->gcm128.rec_seq;
+        return 1;
+# endif
+# ifdef OPENSSL_KTLS_AES_GCM_256
+    case NID_aes_256_gcm:
+        crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
+        crypto_info->gcm256.info.version = s->version;
+        crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
+        memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
+                TLS_CIPHER_AES_GCM_256_IV_SIZE);
+        memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
+        memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c));
+        memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
+                TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
+        if (rec_seq != NULL)
+            *rec_seq = crypto_info->gcm256.rec_seq;
+        return 1;
+# endif
+# ifdef OPENSSL_KTLS_AES_CCM_128
+    case NID_aes_128_ccm:
+        crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
+        crypto_info->ccm128.info.version = s->version;
+        crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
+        memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN,
+                TLS_CIPHER_AES_CCM_128_IV_SIZE);
+        memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
+        memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c));
+        memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
+                TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
+        if (rec_seq != NULL)
+            *rec_seq = crypto_info->ccm128.rec_seq;
+        return 1;
+# endif
+    default:
+        return 0;
+    }
+
+}
+
+#endif /* OPENSSL_SYS_LINUX */
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index 27167ba92f..634052d342 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -213,7 +213,7 @@ int ssl3_get_record(SSL *s)
                                num_recs == 0 ? 1 : 0, &n);
             if (rret <= 0) {
 #ifndef OPENSSL_NO_KTLS
-                if (!BIO_get_ktls_recv(s->rbio))
+                if (!BIO_get_ktls_recv(s->rbio) || rret == 0)
                     return rret;     /* error or non-blocking */
                 switch (errno) {
                 case EBADMSG:
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 250098600f..f74f833312 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -35,6 +35,7 @@
 # include "internal/refcount.h"
 # include "internal/tsan_assist.h"
 # include "internal/bio.h"
+# include "internal/ktls.h"
 
 # ifdef OPENSSL_BUILD_SHLIBSSL
 #  undef OPENSSL_EXTERN
@@ -2747,6 +2748,17 @@ __owur int ssl_log_secret(SSL *ssl, const char *label,
 #define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET"
 #define EXPORTER_SECRET_LABEL "EXPORTER_SECRET"
 
+#  ifndef OPENSSL_NO_KTLS
+/* ktls.c */
+int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
+                                const EVP_CIPHER_CTX *dd);
+int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+                          void *rl_sequence, ktls_crypto_info_t *crypto_info,
+                          unsigned char **rec_seq, unsigned char *iv,
+                          unsigned char *key, unsigned char *mac_key,
+                          size_t mac_secret_size);
+#  endif
+
 /* s3_cbc.c */
 __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
 __owur int ssl3_cbc_digest_record(SSL *s,
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 2e46187024..52b4ffe132 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -192,16 +192,12 @@ int tls1_change_cipher_state(SSL *s, int which)
     size_t n, i, j, k, cl;
     int reuse_dd = 0;
 #ifndef OPENSSL_NO_KTLS
-# ifdef __FreeBSD__
-    struct tls_enable crypto_info;
-# else
-    struct tls_crypto_info_all crypto_info;
+    ktls_crypto_info_t crypto_info;
     unsigned char *rec_seq;
     void *rl_sequence;
-#  ifndef OPENSSL_NO_KTLS_RX
+# ifndef OPENSSL_NO_KTLS_RX
     int count_unprocessed;
     int bit;
-#  endif
 # endif
     BIO *bio;
 #endif
@@ -465,53 +461,9 @@ int tls1_change_cipher_state(SSL *s, int which)
     if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
         goto skip_ktls;
 
-# ifdef __FreeBSD__
-    memset(&crypto_info, 0, sizeof(crypto_info));
-    switch (s->s3.tmp.new_cipher->algorithm_enc) {
-    case SSL_AES128GCM:
-    case SSL_AES256GCM:
-        crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
-        crypto_info.iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
-        break;
-    case SSL_AES128:
-    case SSL_AES256:
-        if (s->ext.use_etm)
-            goto skip_ktls;
-        switch (s->s3.tmp.new_cipher->algorithm_mac) {
-        case SSL_SHA1:
-            crypto_info.auth_algorithm = CRYPTO_SHA1_HMAC;
-            break;
-        case SSL_SHA256:
-            crypto_info.auth_algorithm = CRYPTO_SHA2_256_HMAC;
-            break;
-        case SSL_SHA384:
-            crypto_info.auth_algorithm = CRYPTO_SHA2_384_HMAC;
-            break;
-        default:
-            goto skip_ktls;
-        }
-        crypto_info.cipher_algorithm = CRYPTO_AES_CBC;
-        crypto_info.iv_len = EVP_CIPHER_iv_length(c);
-        crypto_info.auth_key = ms;
-        crypto_info.auth_key_len = *mac_secret_size;
-        break;
-    default:
-        goto skip_ktls;
-    }
-    crypto_info.cipher_key = key;
-    crypto_info.cipher_key_len = EVP_CIPHER_key_length(c);
-    crypto_info.iv = iv;
-    crypto_info.tls_vmajor = (s->version >> 8) & 0x000000ff;
-    crypto_info.tls_vminor = (s->version & 0x000000ff);
-# else /* !defined(__FreeBSD__) */
     /* check that cipher is supported */
-    if (!ktls_check_supported_cipher(c, dd))
-        goto skip_ktls;
-
-    /* check version */
-    if (s->version != TLS1_2_VERSION)
+    if (!ktls_check_supported_cipher(s, c, dd))
         goto skip_ktls;
-# endif
 
     if (which & SSL3_CC_WRITE)
         bio = s->wbio;
@@ -538,18 +490,17 @@ int tls1_change_cipher_state(SSL *s, int which)
         goto err;
     }
 
-# ifndef __FreeBSD__
     if (which & SSL3_CC_WRITE)
         rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer);
     else
         rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer);
 
-    if (!ktls_configure_crypto(c, s->version, dd, rl_sequence, &crypto_info,
-                               &rec_seq, iv, key))
+    if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq,
+                               iv, key, ms, *mac_secret_size))
         goto skip_ktls;
 
     if (which & SSL3_CC_READ) {
-#  ifndef OPENSSL_NO_KTLS_RX
+# ifndef OPENSSL_NO_KTLS_RX
         count_unprocessed = count_unprocessed_records(s);
         if (count_unprocessed < 0)
             goto skip_ktls;
@@ -563,11 +514,10 @@ int tls1_change_cipher_state(SSL *s, int which)
             }
             count_unprocessed--;
         }
-#  else
+# else
         goto skip_ktls;
-#  endif
+# endif
     }
-# endif /* !__FreeBSD__ */
 
     /* ktls works with user provided buffers directly */
     if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) {
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index ba385f6ea2..829a6e9be1 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -516,10 +516,8 @@ int tls13_change_cipher_state(SSL *s, int which)
     const EVP_MD *md = NULL;
     const EVP_CIPHER *cipher = NULL;
 #if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13)
-# ifndef __FreeBSD__
-    struct tls_crypto_info_all crypto_info;
+    ktls_crypto_info_t crypto_info;
     BIO *bio;
-# endif
 #endif
 
     if (which & SSL3_CC_READ) {
@@ -784,7 +782,6 @@ int tls13_change_cipher_state(SSL *s, int which)
         s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
 #ifndef OPENSSL_NO_KTLS
 # if defined(OPENSSL_KTLS_TLS13)
-#  ifndef __FreeBSD__
     if (!(which & SSL3_CC_WRITE) || !(which & SSL3_CC_APPLICATION)
         || ((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX)))
         goto skip_ktls;
@@ -798,7 +795,7 @@ int tls13_change_cipher_state(SSL *s, int which)
         goto skip_ktls;
 
     /* check that cipher is supported */
-    if (!ktls_check_supported_cipher(cipher, ciph_ctx))
+    if (!ktls_check_supported_cipher(s, cipher, ciph_ctx))
         goto skip_ktls;
 
     bio = s->wbio;
@@ -814,15 +811,14 @@ int tls13_change_cipher_state(SSL *s, int which)
         goto skip_ktls;
 
     /* configure kernel crypto structure */
-    if (!ktls_configure_crypto(cipher, s->version, ciph_ctx, 
+    if (!ktls_configure_crypto(s, cipher, ciph_ctx,
                                RECORD_LAYER_get_write_sequence(&s->rlayer),
-                               &crypto_info, NULL, iv, key))
+                               &crypto_info, NULL, iv, key, NULL, 0))
         goto skip_ktls;
 
     /* ktls works with user provided buffers directly */
     if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE))
         ssl3_release_write_buffer(s);
-#  endif
 skip_ktls:
 # endif
 #endif
diff --git a/test/sslapitest.c b/test/sslapitest.c
index cf9947ea0b..240cadde90 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -993,6 +993,7 @@ static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx,
                                        tls_version, tls_version,
                                        &sctx, &cctx, cert, privkey))
             || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher))
+            || !TEST_true(SSL_CTX_set_cipher_list(sctx, cipher))
             || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl,
                                           &clientssl, sfd, cfd)))
         goto end;
@@ -1107,6 +1108,7 @@ static int test_ktls_sendfile(int tls_version, const char *cipher)
                                        tls_version, tls_version,
                                        &sctx, &cctx, cert, privkey))
         || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher))
+        || !TEST_true(SSL_CTX_set_cipher_list(sctx, cipher))
         || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl,
                                           &clientssl, sfd, cfd)))
         goto end;
@@ -1116,7 +1118,9 @@ static int test_ktls_sendfile(int tls_version, const char *cipher)
         || !TEST_true(BIO_get_ktls_send(serverssl->wbio)))
         goto end;
 
-    RAND_bytes(buf, SENDFILE_SZ);
+    if (!TEST_true(RAND_bytes_ex(libctx, buf, SENDFILE_SZ)))
+        goto end;
+
     out = BIO_new_file(tmpfilename, "wb");
     if (!TEST_ptr(out))
         goto end;
@@ -1177,314 +1181,11 @@ end:
     return testresult;
 }
 
-static int test_ktls_no_txrx_client_no_txrx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 0, 0, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 0, 0, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 0, 0, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_rx_client_no_txrx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 0, 0, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 0, 0, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 0, 0, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_tx_client_no_txrx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 1, 0, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 1, 0, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 1, 0, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_client_no_txrx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 1, 0, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 1, 0, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 1, 0, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_txrx_client_no_rx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 0, 1, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 0, 1, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 0, 1, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_rx_client_no_rx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 0, 1, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 0, 1, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 0, 1, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_tx_client_no_rx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 1, 1, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 1, 1, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 1, 1, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_client_no_rx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 1, 1, 0, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 1, 1, 0, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 1, 1, 0, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_txrx_client_no_tx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 0, 0, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 0, 0, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 0, 0, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_rx_client_no_tx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 0, 0, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 0, 0, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 0, 0, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_tx_client_no_tx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 1, 0, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 1, 0, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 1, 0, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_client_no_tx_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 1, 0, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 1, 0, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 1, 0, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_txrx_client_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 0, 1, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 0, 1, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 0, 1, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_rx_client_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 0, 1, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 0, 1, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 0, 1, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_no_tx_client_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(0, 1, 1, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(0, 1, 1, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(0, 1, 1, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
-static int test_ktls_client_server(int tlsver)
-{
-    int testresult = 1;
-
-#ifdef OPENSSL_KTLS_AES_GCM_128
-    testresult &= execute_test_ktls(1, 1, 1, 1, tlsver,
-         "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_CCM_128
-    testresult &= execute_test_ktls(1, 1, 1, 1, tlsver,
-         "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-#endif
-#ifdef OPENSSL_KTLS_AES_GCM_256
-    testresult &= execute_test_ktls(1, 1, 1, 1, tlsver,
-         "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-#endif
-    return testresult;
-}
-
 #if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3)
 static int test_ktls(int test)
 {
-    int tlsver;
+    int cis_ktls_tx, cis_ktls_rx, sis_ktls_tx, sis_ktls_rx;
+    int tlsver, testresult;
 
     if (test > 15) {
 #if defined(OPENSSL_NO_TLS1_3)
@@ -1501,47 +1202,42 @@ static int test_ktls(int test)
 #endif
     }
 
-    switch(test) {
-    case 0:
-       return test_ktls_no_txrx_client_no_txrx_server(tlsver);
-    case 1:
-       return test_ktls_no_rx_client_no_txrx_server(tlsver);
-    case 2:
-       return test_ktls_no_tx_client_no_txrx_server(tlsver);
-    case 3:
-       return test_ktls_client_no_txrx_server(tlsver);
-    case 4:
-       return test_ktls_no_txrx_client_no_rx_server(tlsver);
-    case 5:
-       return test_ktls_no_rx_client_no_rx_server(tlsver);
-    case 6:
-       return test_ktls_no_tx_client_no_rx_server(tlsver);
-    case 7:
-       return test_ktls_client_no_rx_server(tlsver);
-    case 8:
-       return test_ktls_no_txrx_client_no_tx_server(tlsver);
-    case 9:
-       return test_ktls_no_rx_client_no_tx_server(tlsver);
-    case 10:
-       return test_ktls_no_tx_client_no_tx_server(tlsver);
-    case 11:
-       return test_ktls_client_no_tx_server(tlsver);
-    case 12:
-       return test_ktls_no_txrx_client_server(tlsver);
-    case 13:
-       return test_ktls_no_rx_client_server(tlsver);
-    case 14:
-       return test_ktls_no_tx_client_server(tlsver);
-    case 15:
-       return test_ktls_client_server(tlsver);
-    default:
-       return 0;
-    }
+    cis_ktls_tx = (test & 1) != 0;
+    cis_ktls_rx = (test & 2) != 0;
+    sis_ktls_tx = (test & 4) != 0;
+    sis_ktls_rx = (test & 8) != 0;
+
+#if defined(OPENSSL_NO_KTLS_RX)
+    if (cis_ktls_rx || sis_ktls_rx)
+        return 1;
+#endif
+#if !defined(OPENSSL_NO_TLS1_3)
+    if (tlsver == TLS1_3_VERSION && (cis_ktls_rx || sis_ktls_rx))
+        return 1;
+#endif
+
+    testresult = 1;
+#ifdef OPENSSL_KTLS_AES_GCM_128
+    testresult &= execute_test_ktls(cis_ktls_tx, cis_ktls_rx, sis_ktls_tx,
+                                    sis_ktls_rx, tlsver, "AES128-GCM-SHA256",
+                                    TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+#endif
+#ifdef OPENSSL_KTLS_AES_CCM_128
+    testresult &= execute_test_ktls(cis_ktls_tx, cis_ktls_rx, sis_ktls_tx,
+                                    sis_ktls_rx, tlsver, "AES128-CCM",
+                                    TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
+#endif
+#ifdef OPENSSL_KTLS_AES_GCM_256
+    testresult &= execute_test_ktls(cis_ktls_tx, cis_ktls_rx, sis_ktls_tx,
+                                    sis_ktls_rx, tlsver, "AES256-GCM-SHA384",
+                                    TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
+#endif
+    return testresult;
 }
 
 static int test_ktls_sendfile_anytls(int tst)
 {
-    char *cipher[] = {"AES128-GCM-SHA256","AES128-CCM-SHA256","AES256-GCM-SHA384"};
+    char *cipher[] = {"AES128-GCM-SHA256","AES128-CCM","AES256-GCM-SHA384"};
     int tlsver;
 
     if (tst > 2) {


More information about the openssl-commits mailing list