Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2020 20:07:25 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r551541 - in head/security/openssl: . files
Message-ID:  <202010052007.095K7PvU067960@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb (src,doc committer)
Date: Mon Oct  5 20:07:25 2020
New Revision: 551541
URL: https://svnweb.freebsd.org/changeset/ports/551541

Log:
  Expand support for TLS protocols supported by KTLS.
  
  Backport additional patches merged into OpenSSL's master
  branch to support KTLS RX for TLS 1.1 and 1.2 as well as
  support for KTLS TX for TLS 1.3.
  
  Reviewed by:	brnrd (maintainer)
  Sponsored by:	Chelsio Communications, Netflix
  Differential Revision:	https://reviews.freebsd.org/D26261

Modified:
  head/security/openssl/Makefile
  head/security/openssl/files/extra-patch-ktls

Modified: head/security/openssl/Makefile
==============================================================================
--- head/security/openssl/Makefile	Mon Oct  5 19:52:44 2020	(r551540)
+++ head/security/openssl/Makefile	Mon Oct  5 20:07:25 2020	(r551541)
@@ -3,6 +3,7 @@
 
 PORTNAME=	openssl
 PORTVERSION=	1.1.1h
+PORTREVISION=	1
 PORTEPOCH=	1
 CATEGORIES=	security devel
 MASTER_SITES=	https://www.openssl.org/source/ \

Modified: head/security/openssl/files/extra-patch-ktls
==============================================================================
--- head/security/openssl/files/extra-patch-ktls	Mon Oct  5 19:52:44 2020	(r551540)
+++ head/security/openssl/files/extra-patch-ktls	Mon Oct  5 20:07:25 2020	(r551541)
@@ -1,8 +1,8 @@
 diff --git CHANGES CHANGES
-index f4230aaac0..3cc665f654 100644
+index 7ea3d2b823..514cf091a3 100644
 --- CHANGES
 +++ CHANGES
-@@ -306,6 +306,11 @@
+@@ -354,6 +354,11 @@
       necessary to configure just to create a source distribution.
       [Richard Levitte]
  
@@ -15,10 +15,10 @@ index f4230aaac0..3cc665f654 100644
  
    *) Timing vulnerability in DSA signature generation
 diff --git Configure Configure
-index 2e9efaa5f3..524b58cbb9 100755
+index 1d73d06e1b..29e655da96 100755
 --- Configure
 +++ Configure
-@@ -331,6 +331,7 @@ my @dtls = qw(dtls1 dtls1_2);
+@@ -341,6 +341,7 @@ my @dtls = qw(dtls1 dtls1_2);
  # For developers: keep it sorted alphabetically
  
  my @disablables = (
@@ -26,7 +26,7 @@ index 2e9efaa5f3..524b58cbb9 100755
      "afalgeng",
      "aria",
      "asan",
-@@ -464,6 +465,7 @@ our %disabled = ( # "what"         => "comment"
+@@ -474,6 +475,7 @@ our %disabled = ( # "what"         => "comment"
                    "weak-ssl-ciphers"    => "default",
                    "zlib"                => "default",
                    "zlib-dynamic"        => "default",
@@ -34,7 +34,7 @@ index 2e9efaa5f3..524b58cbb9 100755
                  );
  
  # Note: => pair form used for aesthetics, not to truly make a hash table
-@@ -1567,6 +1569,33 @@ unless ($disabled{devcryptoeng}) {
+@@ -1580,6 +1582,33 @@ unless ($disabled{devcryptoeng}) {
      }
  }
  
@@ -69,7 +69,7 @@ index 2e9efaa5f3..524b58cbb9 100755
  # do this late because some of them depend on %disabled.
  
 diff --git INSTALL INSTALL
-index 328ad2baf4..46735b8236 100644
+index f5118428b3..be84f2aa8e 100644
 --- INSTALL
 +++ INSTALL
 @@ -262,6 +262,15 @@
@@ -89,10 +89,10 @@ index 328ad2baf4..46735b8236 100644
                     Build with the Address sanitiser. This is a developer option
                     only. It may not work on all platforms and should never be
 diff --git apps/s_client.c apps/s_client.c
-index 26a6789d81..457e539b85 100644
+index 83b3fc9c7f..68bd9ced01 100644
 --- apps/s_client.c
 +++ apps/s_client.c
-@@ -3262,6 +3262,12 @@ static void print_stuff(BIO *bio, SSL *s, int full)
+@@ -3282,6 +3282,12 @@ static void print_stuff(BIO *bio, SSL *s, int full)
      BIO_printf(bio, "Expansion: %s\n",
                 expansion ? SSL_COMP_get_name(expansion) : "NONE");
  #endif
@@ -153,7 +153,7 @@ index 335dfabc61..80ef348d92 100644
      return sock;
  }
 diff --git crypto/bio/bss_conn.c crypto/bio/bss_conn.c
-index dd43a40601..3def4550cb 100644
+index 807a82b23b..f75bf37adb 100644
 --- crypto/bio/bss_conn.c
 +++ crypto/bio/bss_conn.c
 @@ -11,6 +11,7 @@
@@ -174,7 +174,7 @@ index dd43a40601..3def4550cb 100644
  
      BIO_ADDRINFO *addr_first;
      const BIO_ADDRINFO *addr_iter;
-@@ -311,7 +315,12 @@ static int conn_read(BIO *b, char *out, int outl)
+@@ -320,7 +324,12 @@ static int conn_read(BIO *b, char *out, int outl)
  
      if (out != NULL) {
          clear_socket_error();
@@ -188,7 +188,7 @@ index dd43a40601..3def4550cb 100644
          BIO_clear_retry_flags(b);
          if (ret <= 0) {
              if (BIO_sock_should_retry(ret))
-@@ -336,7 +345,16 @@ static int conn_write(BIO *b, const char *in, int inl)
+@@ -345,7 +354,16 @@ static int conn_write(BIO *b, const char *in, int inl)
      }
  
      clear_socket_error();
@@ -206,7 +206,7 @@ index dd43a40601..3def4550cb 100644
      BIO_clear_retry_flags(b);
      if (ret <= 0) {
          if (BIO_sock_should_retry(ret))
-@@ -352,6 +370,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+@@ -361,6 +379,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
      const char **pptr = NULL;
      long ret = 1;
      BIO_CONNECT *data;
@@ -220,7 +220,7 @@ index dd43a40601..3def4550cb 100644
  
      data = (BIO_CONNECT *)b->ptr;
  
-@@ -500,6 +525,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+@@ -520,6 +545,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
      case BIO_CTRL_EOF:
          ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
          break;
@@ -253,7 +253,7 @@ index dd43a40601..3def4550cb 100644
          ret = 0;
          break;
 diff --git crypto/bio/bss_sock.c crypto/bio/bss_sock.c
-index 6251f3d46a..c879533fef 100644
+index 6251f3d46a..7d582b5549 100644
 --- crypto/bio/bss_sock.c
 +++ crypto/bio/bss_sock.c
 @@ -11,6 +11,7 @@
@@ -319,21 +319,22 @@ index 6251f3d46a..c879533fef 100644
      BIO_clear_retry_flags(b);
      if (ret <= 0) {
          if (BIO_sock_should_retry(ret))
-@@ -126,6 +153,13 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+@@ -126,6 +153,14 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
  {
      long ret = 1;
      int *ip;
 +# ifndef OPENSSL_NO_KTLS
++    size_t crypto_info_len;
 +#  ifdef __FreeBSD__
 +    struct tls_enable *crypto_info;
 +#  else
-+    struct tls12_crypto_info_aes_gcm_128 *crypto_info;
++    struct tls_crypto_info_all *crypto_info;
 +#  endif
 +# endif
  
      switch (cmd) {
      case BIO_C_SET_FD:
-@@ -153,6 +187,31 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+@@ -153,6 +188,33 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
      case BIO_CTRL_FLUSH:
          ret = 1;
          break;
@@ -341,10 +342,12 @@ index 6251f3d46a..c879533fef 100644
 +    case BIO_CTRL_SET_KTLS:
 +#  ifdef __FreeBSD__
 +        crypto_info = (struct tls_enable *)ptr;
++        crypto_info_len = sizeof(*crypto_info);
 +#  else
-+        crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
++        crypto_info = (struct tls_crypto_info_all *)ptr;
++        crypto_info_len = crypto_info->tls_crypto_info_len;
 +#  endif
-+        ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
++        ret = ktls_start(b->num, crypto_info, crypto_info_len, num);
 +        if (ret)
 +            BIO_set_ktls_flag(b, num);
 +        break;
@@ -366,10 +369,10 @@ index 6251f3d46a..c879533fef 100644
          ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
          break;
 diff --git crypto/err/openssl.txt crypto/err/openssl.txt
-index 35512f9caf..426297da8b 100644
+index 0b5873ebbc..a4dcacab59 100644
 --- crypto/err/openssl.txt
 +++ crypto/err/openssl.txt
-@@ -1315,6 +1315,7 @@ SSL_F_SSL_RENEGOTIATE:516:SSL_renegotiate
+@@ -1317,6 +1317,7 @@ SSL_F_SSL_RENEGOTIATE:516:SSL_renegotiate
  SSL_F_SSL_RENEGOTIATE_ABBREVIATED:546:SSL_renegotiate_abbreviated
  SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT:320:*
  SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT:321:*
@@ -397,7 +400,7 @@ index 405ddbf9bf..4640c7528a 100644
          /* Special case: -1 length restores whole IV */
          if (arg == -1) {
 diff --git doc/man3/BIO_ctrl.pod doc/man3/BIO_ctrl.pod
-index 60cd10883b..589338dd51 100644
+index 2e438c3ce9..31b18b2879 100644
 --- doc/man3/BIO_ctrl.pod
 +++ doc/man3/BIO_ctrl.pod
 @@ -5,7 +5,8 @@
@@ -455,9 +458,9 @@ index 60cd10883b..589338dd51 100644
 +
  =head1 COPYRIGHT
  
- Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+ Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
 diff --git doc/man3/SSL_CTX_set_mode.pod doc/man3/SSL_CTX_set_mode.pod
-index 387d1ec1ef..373b2aa0f2 100644
+index 85e3353e0e..27eaebad1e 100644
 --- doc/man3/SSL_CTX_set_mode.pod
 +++ doc/man3/SSL_CTX_set_mode.pod
 @@ -114,6 +114,22 @@ enables this behaviour to allow interoperability with such broken
@@ -491,8 +494,50 @@ index 387d1ec1ef..373b2aa0f2 100644
  
  =head1 COPYRIGHT
  
+diff --git doc/man3/SSL_CTX_set_record_padding_callback.pod doc/man3/SSL_CTX_set_record_padding_callback.pod
+index 13e56f0c57..247a39fc03 100644
+--- doc/man3/SSL_CTX_set_record_padding_callback.pod
++++ doc/man3/SSL_CTX_set_record_padding_callback.pod
+@@ -16,7 +16,7 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding
+  #include <openssl/ssl.h>
+ 
+  void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, size_t (*cb)(SSL *s, int type, size_t len, void *arg));
+- void SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg));
++ int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg));
+ 
+  void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg);
+  void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx);
+@@ -32,6 +32,8 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding
+ SSL_CTX_set_record_padding_callback() or SSL_set_record_padding_callback()
+ can be used to assign a callback function I<cb> to specify the padding
+ for TLS 1.3 records. The value set in B<ctx> is copied to a new SSL by SSL_new().
++Kernel TLS is not possible if the record padding callback is set, and the callback
++function cannot be set if Kernel TLS is already configured for the current SSL object.
+ 
+ SSL_CTX_set_record_padding_callback_arg() and SSL_set_record_padding_callback_arg()
+ assign a value B<arg> that is passed to the callback when it is invoked. The value
+@@ -64,6 +66,9 @@ indicates no padding will be added. A return value that causes the record to
+ exceed the maximum record size (SSL3_RT_MAX_PLAIN_LENGTH) will pad out to the
+ maximum record size.
+ 
++The SSL_CTX_get_record_padding_callback_arg() function returns 1 on success or 0 if
++the callback function is not set because Kernel TLS is configured for the SSL object.
++
+ =head1 NOTES
+ 
+ The default behavior is to add no padding to the record.
+@@ -84,6 +89,9 @@ L<ssl(7)>, L<SSL_new(3)>
+ 
+ The record padding API was added for TLS 1.3 support in OpenSSL 1.1.1.
+ 
++The return type of SSL_CTX_set_record_padding_callback() function was
++changed to int in OpenSSL 3.0.
++
+ =head1 COPYRIGHT
+ 
+ Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 diff --git doc/man3/SSL_write.pod doc/man3/SSL_write.pod
-index a76ffbb8fd..d7900fd87b 100644
+index 5e3ce1e7e4..20c7953deb 100644
 --- doc/man3/SSL_write.pod
 +++ doc/man3/SSL_write.pod
 @@ -2,12 +2,13 @@
@@ -639,10 +684,10 @@ index c343b27629..521b5fa219 100644
 +#endif
 diff --git include/internal/ktls.h include/internal/ktls.h
 new file mode 100644
-index 0000000000..209dff1689
+index 0000000000..3baa63f781
 --- /dev/null
 +++ include/internal/ktls.h
-@@ -0,0 +1,345 @@
+@@ -0,0 +1,432 @@
 +/*
 + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
 + *
@@ -652,23 +697,46 @@ index 0000000000..209dff1689
 + * https://www.openssl.org/source/license.html
 + */
 +
-+#ifndef OPENSSL_NO_KTLS
-+# ifndef HEADER_INTERNAL_KTLS
-+#  define HEADER_INTERNAL_KTLS
++#if defined(OPENSSL_SYS_LINUX)
++# ifndef OPENSSL_NO_KTLS
++#  include <linux/version.h>
++#  if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
++#   define OPENSSL_NO_KTLS
++#   ifndef PEDANTIC
++#    warning "KTLS requires Kernel Headers >= 4.13.0"
++#    warning "Skipping Compilation of KTLS"
++#   endif
++#  endif
++# endif
++#endif
 +
++#ifndef HEADER_INTERNAL_KTLS
++# define HEADER_INTERNAL_KTLS
++# ifndef OPENSSL_NO_KTLS
++
 +#  if defined(__FreeBSD__)
 +#   include <sys/types.h>
 +#   include <sys/socket.h>
 +#   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
 + * setting keys.
@@ -681,18 +749,25 @@ index 0000000000..209dff1689
 +/*
 + * 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,
-+                                  struct tls_enable *tls_en,
++                                  void *tls_en,
 +                                  size_t len, int is_tx)
 +{
 +    if (is_tx)
 +        return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE,
-+                          tls_en, sizeof(*tls_en)) ? 0 : 1;
-+    else
-+        return 0;
++                          tls_en, len) ? 0 : 1;
++#   ifndef OPENSSL_NO_KTLS_RX
++    return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en, len) ? 0 : 1;
++#   else
++    return 0;
++#   endif
 +}
 +
 +/*
@@ -728,12 +803,80 @@ index 0000000000..209dff1689
 +    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.
 + */
@@ -751,97 +894,64 @@ index 0000000000..209dff1689
 +    }
 +    return sbytes;
 +}
++
 +#  endif                         /* __FreeBSD__ */
 +
 +#  if defined(OPENSSL_SYS_LINUX)
-+#   include <linux/version.h>
 +
-+#   define K_MAJ   4
-+#   define K_MIN1  13
-+#   define K_MIN2  0
-+#   if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2)
-+
++#   include <linux/tls.h>
++#   if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
++#    define OPENSSL_NO_KTLS_RX
 +#    ifndef PEDANTIC
-+#     warning "KTLS requires Kernel Headers >= 4.13.0"
-+#     warning "Skipping Compilation of KTLS"
++#     warning "KTLS requires Kernel Headers >= 4.17.0 for receiving"
++#     warning "Skipping Compilation of KTLS receive data path"
 +#    endif
++#   endif
++#   define OPENSSL_KTLS_AES_GCM_128
++#   if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
++#    define OPENSSL_KTLS_AES_GCM_256
++#    define OPENSSL_KTLS_TLS13
++#    if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
++#     define OPENSSL_KTLS_AES_CCM_128
++#    endif
++#   endif
 +
-+#    define TLS_TX                  1
-+#    define TLS_RX                  2
++#   include <sys/sendfile.h>
++#   include <netinet/tcp.h>
++#   include <linux/socket.h>
++#   include "openssl/ssl3.h"
++#   include "openssl/tls1.h"
++#   include "openssl/evp.h"
 +
-+#    define TLS_CIPHER_AES_GCM_128                          51
-+#    define TLS_CIPHER_AES_GCM_128_IV_SIZE                  8
-+#    define TLS_CIPHER_AES_GCM_128_KEY_SIZE                 16
-+#    define TLS_CIPHER_AES_GCM_128_SALT_SIZE                4
-+#    define TLS_CIPHER_AES_GCM_128_TAG_SIZE                 16
-+#    define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE             8
++#   ifndef SOL_TLS
++#    define SOL_TLS 282
++#   endif
 +
-+#    define TLS_SET_RECORD_TYPE     1
++#   ifndef TCP_ULP
++#    define TCP_ULP 31
++#   endif
 +
-+struct tls_crypto_info {
-+    unsigned short version;
-+    unsigned short cipher_type;
-+};
++#   ifndef TLS_RX
++#    define TLS_RX                  2
++#   endif
 +
-+struct tls12_crypto_info_aes_gcm_128 {
-+    struct tls_crypto_info info;
-+    unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE];
-+    unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE];
-+    unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE];
-+    unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
++struct tls_crypto_info_all {
++    union {
++#   ifdef OPENSSL_KTLS_AES_GCM_128
++        struct tls12_crypto_info_aes_gcm_128 gcm128;
++#   endif
++#   ifdef OPENSSL_KTLS_AES_GCM_256
++        struct tls12_crypto_info_aes_gcm_256 gcm256;
++#   endif
++#   ifdef OPENSSL_KTLS_AES_CCM_128
++        struct tls12_crypto_info_aes_ccm_128 ccm128;
++#   endif
++    };
++    size_t tls_crypto_info_len;
 +};
 +
-+/* Dummy functions here */
-+static ossl_inline int ktls_enable(int fd)
-+{
-+    return 0;
-+}
++typedef struct tls_crypto_info_all ktls_crypto_info_t;
 +
-+static ossl_inline int ktls_start(int fd,
-+                                  struct tls12_crypto_info_aes_gcm_128
-+                                  *crypto_info, size_t len, int is_tx)
-+{
-+    return 0;
-+}
-+
-+static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type,
-+                                              const void *data, size_t length)
-+{
-+    return -1;
-+}
-+
-+static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
-+{
-+    return -1;
-+}
-+
-+static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags)
-+{
-+    return -1;
-+}
-+
-+#   else                        /* KERNEL_VERSION */
-+
-+#    include <sys/sendfile.h>
-+#    include <netinet/tcp.h>
-+#    include <linux/tls.h>
-+#    include <linux/socket.h>
-+#    include "openssl/ssl3.h"
-+#    include "openssl/tls1.h"
-+#    include "openssl/evp.h"
-+
-+#    ifndef SOL_TLS
-+#     define SOL_TLS 282
-+#    endif
-+
-+#    ifndef TCP_ULP
-+#     define TCP_ULP 31
-+#    endif
-+
-+#    ifndef TLS_RX
-+#     define TLS_RX                  2
-+#    endif
-+
 +/*
 + * When successful, this socket option doesn't change the behaviour of the
 + * TCP socket, except changing the TCP setsockopt handler to enable the
@@ -861,12 +971,11 @@ index 0000000000..209dff1689
 + * If successful, then data received using this socket will be decrypted,
 + * authenticated and decapsulated using the crypto_info provided here.
 + */
-+static ossl_inline int ktls_start(int fd,
-+                                  struct tls12_crypto_info_aes_gcm_128
-+                                  *crypto_info, size_t len, int is_tx)
++static ossl_inline int ktls_start(int fd, void *crypto_info,
++                                  size_t len, int is_tx)
 +{
 +    return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX,
-+                      crypto_info, sizeof(*crypto_info)) ? 0 : 1;
++                      crypto_info, len) ? 0 : 1;
 +}
 +
 +/*
@@ -915,20 +1024,15 @@ index 0000000000..209dff1689
 +    return sendfile(s, fd, &off, size);
 +}
 +
-+#    define K_MIN1_RX  17
-+#    if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1_RX, K_MIN2)
++#   ifdef OPENSSL_NO_KTLS_RX
 +
-+#     ifndef PEDANTIC
-+#      warning "KTLS requires Kernel Headers >= 4.17.0 for receiving"
-+#      warning "Skipping Compilation of KTLS receive data path"
-+#     endif
 +
 +static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
 +{
 +    return -1;
 +}
 +
-+#    else
++#   else /* !defined(OPENSSL_NO_KTLS_RX) */
 +
 +/*
 + * Receive a TLS record using the crypto_info provided in ktls_start.
@@ -983,11 +1087,39 @@ index 0000000000..209dff1689
 +    return ret;
 +}
 +
-+#    endif
-+#   endif
-+#  endif
-+# endif
-+#endif
++#   endif /* OPENSSL_NO_KTLS_RX */
++
++#  endif /* OPENSSL_SYS_LINUX */
++# else /* OPENSSL_NO_KTLS */
++/* Dummy functions here */
++static ossl_inline int ktls_enable(int fd)
++{
++    return 0;
++}
++
++static ossl_inline int ktls_start(int fd, void *crypto_info,
++                                  size_t len, int is_tx)
++{
++    return 0;
++}
++
++static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type,
++                                              const void *data, size_t length)
++{
++    return -1;
++}
++
++static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
++{
++    return -1;
++}
++
++static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags)
++{
++    return -1;
++}
++# endif /* OPENSSL_NO_KTLS */
++#endif /* HEADER_INTERNAL_KTLS */
 diff --git include/openssl/bio.h include/openssl/bio.h
 index ae559a5105..fa50337aab 100644
 --- include/openssl/bio.h
@@ -1045,7 +1177,7 @@ index a411f3f2f9..60103707d2 100644
  /* Padding modes */
  #define EVP_PADDING_PKCS7       1
 diff --git include/openssl/ssl.h include/openssl/ssl.h
-index 6724ccf2d2..48710cde1f 100644
+index fd0c5a9996..09620489bc 100644
 --- include/openssl/ssl.h
 +++ include/openssl/ssl.h
 @@ -493,6 +493,10 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
@@ -1079,6 +1211,15 @@ index 6724ccf2d2..48710cde1f 100644
  __owur int SSL_write(SSL *ssl, const void *buf, int num);
  __owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written);
  __owur int SSL_write_early_data(SSL *s, const void *buf, size_t num,
+@@ -2123,7 +2133,7 @@ void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg);
+ void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx);
+ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size);
+ 
+-void SSL_set_record_padding_callback(SSL *ssl,
++int SSL_set_record_padding_callback(SSL *ssl,
+                                     size_t (*cb) (SSL *ssl, int type,
+                                                   size_t len, void *arg));
+ void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg);
 diff --git include/openssl/sslerr.h include/openssl/sslerr.h
 index 82983d3c1e..0bdc8f3b2c 100644
 --- include/openssl/sslerr.h
@@ -1091,8 +1232,253 @@ index 82983d3c1e..0bdc8f3b2c 100644
  # define SSL_F_SSL_SESSION_DUP                            348
  # define SSL_F_SSL_SESSION_NEW                            189
  # define SSL_F_SSL_SESSION_PRINT_FP                       190
+diff --git ssl/build.info ssl/build.info
+index bb2f1deb53..1c49ac9aee 100644
+--- ssl/build.info
++++ ssl/build.info
+@@ -1,4 +1,5 @@
+ LIBS=../libssl
++
+ SOURCE[../libssl]=\
+         pqueue.c packet.c \
+         statem/statem_srvr.c statem/statem_clnt.c  s3_lib.c  s3_enc.c record/rec_layer_s3.c \
+@@ -13,3 +14,7 @@ SOURCE[../libssl]=\
+         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
++
++IF[{- !$disabled{ktls} -}]
++  SOURCE[../libssl]=ktls.c
++ENDIF
+diff --git ssl/ktls.c ssl/ktls.c
+new file mode 100644
+index 0000000000..7123ecac00
+--- /dev/null
++++ ssl/ktls.c
+@@ -0,0 +1,221 @@
++/*
++ * 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) {
++        EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV,
++                            EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN,
++                            geniv);
++        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 ssl/record/rec_layer_s3.c ssl/record/rec_layer_s3.c
-index b2a7a47eb0..36f37c4ae2 100644
+index b2a7a47eb0..0c4af1981b 100644
 --- ssl/record/rec_layer_s3.c
 +++ ssl/record/rec_layer_s3.c
 @@ -268,11 +268,15 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold,
@@ -1174,7 +1560,7 @@ index b2a7a47eb0..36f37c4ae2 100644
              SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
                       ERR_R_INTERNAL_ERROR);
              goto err;
-@@ -895,12 +919,16 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+@@ -895,15 +919,20 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
                  goto err;
              }
          } else {
@@ -1196,7 +1582,11 @@ index b2a7a47eb0..36f37c4ae2 100644
          }
  
          if (SSL_TREAT_AS_TLS13(s)
-@@ -959,7 +987,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
++                && !BIO_get_ktls_send(s->wbio)
+                 && s->enc_write_ctx != NULL
+                 && (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS
+                     || type != SSL3_RT_ALERT)) {
+@@ -959,7 +988,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
           * in the wb->buf
           */
  
@@ -1205,7 +1595,7 @@ index b2a7a47eb0..36f37c4ae2 100644
              unsigned char *mac;
  
              if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
-@@ -975,24 +1003,26 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+@@ -975,24 +1004,26 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
           * This will be at most one cipher block or the tag length if using
           * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
           */
@@ -1245,7 +1635,7 @@ index b2a7a47eb0..36f37c4ae2 100644
      }
  
      if (s->statem.enc_write_state == ENC_WRITE_STATE_WRITE_PLAIN_ALERTS) {
-@@ -1008,12 +1038,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+@@ -1008,12 +1039,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
              goto err;
          }
      } else {
@@ -1265,7 +1655,7 @@ index b2a7a47eb0..36f37c4ae2 100644
          }
      }
  
-@@ -1023,13 +1055,17 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+@@ -1023,13 +1056,17 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
          thispkt = &pkt[j];
          thiswr = &wr[j];
  
@@ -1284,7 +1674,7 @@ index b2a7a47eb0..36f37c4ae2 100644
              SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
                       ERR_R_INTERNAL_ERROR);
              goto err;
-@@ -1074,13 +1110,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+@@ -1074,13 +1111,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
              goto err;
          }
  
@@ -1300,7 +1690,7 @@ index b2a7a47eb0..36f37c4ae2 100644
  
          if (create_empty_fragment) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202010052007.095K7PvU067960>