git: d5ec2e12f399 - main - security/openssl: Major version update to 3.0

From: Bernard Spil <brnrd_at_FreeBSD.org>
Date: Sat, 14 Oct 2023 17:30:52 UTC
The branch main has been updated by brnrd:

URL: https://cgit.FreeBSD.org/ports/commit/?id=d5ec2e12f399b7813994564b77a0915821a0ac42

commit d5ec2e12f399b7813994564b77a0915821a0ac42
Author:     Bernard Spil <brnrd@FreeBSD.org>
AuthorDate: 2023-10-14 17:00:42 +0000
Commit:     Bernard Spil <brnrd@FreeBSD.org>
CommitDate: 2023-10-14 17:23:12 +0000

    security/openssl: Major version update to 3.0
    
     * OpenSSL 1.1.1 is EoL, update to new LTS version
     * Aligns with upcoming OpenSSL version in 14.0
---
 UPDATING                                           |   17 +
 security/openssl/Makefile                          |   96 +-
 security/openssl/distinfo                          |    6 +-
 security/openssl/files/extra-patch-ktls            | 3753 +++-----------------
 .../openssl/files/extra-patch-util_find-doc-nits   |   20 +
 .../files/extra-patch-util_process__docs.pl        |   20 -
 .../files/patch-Configurations_10-main.conf        |   35 +
 security/openssl/files/patch-Configure             |   11 +
 security/openssl/files/patch-crypto_ppccap.c       |   34 +
 .../openssl/files/patch-crypto_threads__pthread.c  |   13 +
 .../files/patch-util_perl_OpenSSL_config.pm        |   14 +
 security/openssl/files/pkg-message.in              |    8 -
 security/openssl/pkg-plist                         |  263 +-
 security/openssl/version.mk                        |    2 +-
 14 files changed, 793 insertions(+), 3499 deletions(-)

diff --git a/UPDATING b/UPDATING
index 10a57980b74c..382cf5f5bd48 100644
--- a/UPDATING
+++ b/UPDATING
@@ -5,6 +5,23 @@ they are unavoidable.
 You should get into the habit of checking this file for changes each time
 you update your ports collection, before attempting any port upgrades.
 
+20231014:
+  AFFECTS: users of security/openssl and security/openssl30
+  AUTHOR: brnrd@FreeBSD.org
+
+  The openssl port was renamed to openssl111 and subsequently the
+  openssl30 port was renamed to openssl.
+
+  The shared library version of OpenSSL has been bumped.
+
+  Users of DEFAULT_VERSIONS= ssl=openssl30 must update this to
+  ssl=openssl.
+  Users of DEFAULT_VERSIONS= ssl=openssl should not change this unless
+  they use ports that require the deprecated OpenSSL 1.1.1 version.
+
+  You must rebuild all ports that depend on OpenSSL if you use OpenSSL
+  from ports.
+
 20231011:
   AFFECTS: users of www/caddy
   AUTHOR:  adamw@FreeBSD.org
diff --git a/security/openssl/Makefile b/security/openssl/Makefile
index 77b05e43a321..0d829246a3e9 100644
--- a/security/openssl/Makefile
+++ b/security/openssl/Makefile
@@ -1,5 +1,5 @@
 PORTNAME=	openssl
-PORTVERSION=	1.1.1w
+PORTVERSION=	3.0.11
 PORTEPOCH=	1
 CATEGORIES=	security devel
 MASTER_SITES=	https://www.openssl.org/source/ \
@@ -9,10 +9,16 @@ MAINTAINER=	brnrd@FreeBSD.org
 COMMENT=	TLSv1.3 capable SSL and crypto library
 WWW=		https://www.openssl.org/
 
-LICENSE=	OpenSSL
-LICENSE_FILE=	${WRKSRC}/LICENSE
+LICENSE=	APACHE20
+LICENSE_FILE=	${WRKSRC}/LICENSE.txt
 
-CONFLICTS_INSTALL=	boringssl libressl libressl-devel openssl3[012] openssl-quictls
+#EXPIRES=	2025-03-25
+
+CONFLICTS_INSTALL=	boringssl libressl libressl-devel openssl111 openssl3[12] openssl-quictls
+
+USES=		cpe perl5
+USE_PERL5=	build
+TEST_TARGET=	test
 
 HAS_CONFIGURE=	yes
 CONFIGURE_SCRIPT=	config
@@ -20,32 +26,27 @@ CONFIGURE_ENV=	PERL="${PERL}"
 CONFIGURE_ARGS=	--openssldir=${OPENSSLDIR} \
 		--prefix=${PREFIX}
 
-USES=		cpe perl5
-USE_PERL5=	build
-TEST_TARGET=	test
-
 LDFLAGS_i386=	-Wl,-znotext
 
 MAKE_ARGS+=	WHOLE_ARCHIVE_FLAG=--whole-archive CNF_LDFLAGS="${LDFLAGS}"
 MAKE_ENV+=	LIBRPATH="${PREFIX}/lib" GREP_OPTIONS=
 
-OPTIONS_GROUP=		CIPHERS HASHES OPTIMIZE PROTOCOLS
+OPTIONS_GROUP=		CIPHERS HASHES MODULES OPTIMIZE PROTOCOLS
 OPTIONS_GROUP_CIPHERS=	ARIA DES GOST IDEA SM4 RC2 RC4 RC5 WEAK-SSL-CIPHERS
 OPTIONS_GROUP_HASHES=	MD2 MD4 MDC2 RMD160 SM2 SM3
 OPTIONS_GROUP_OPTIMIZE=	ASM SSE2 THREADS
+OPTIONS_GROUP_MODULES=	FIPS LEGACY
 OPTIONS_DEFINE_i386=	I386
 OPTIONS_GROUP_PROTOCOLS=NEXTPROTONEG SCTP SSL3 TLS1 TLS1_1 TLS1_2
 
 OPTIONS_DEFINE=	ASYNC CRYPTODEV CT KTLS MAN3 RFC3779 SHARED ZLIB
 
-OPTIONS_DEFAULT=ASM ASYNC CT GOST DES EC KTLS MAN3 MD4 NEXTPROTONEG RC2 \
-		RC4 RMD160 SCTP SHARED SSE2 THREADS TLS1 TLS1_1 TLS1_2
+OPTIONS_DEFAULT=ASM ASYNC CT DES EC FIPS GOST KTLS MAN3 MD4 NEXTPROTONEG \
+		RFC3779 RC2 RC4 RMD160 SCTP SHARED SSE2 THREADS TLS1 TLS1_1 TLS1_2
 
 OPTIONS_EXCLUDE=${${OSVERSION} < 1300042:?KTLS:} \
 		${${OSVERSION} > 1300000:?CRYPTODEV:}
 
-OPTIONS_GROUP_OPTIMIZE_amd64=	EC
-
 .if ${MACHINE_ARCH} == "amd64"
 OPTIONS_GROUP_OPTIMIZE+=	EC
 .elif ${MACHINE_ARCH} == "mips64el"
@@ -62,15 +63,18 @@ CRYPTODEV_DESC=	/dev/crypto support
 CT_DESC=	Certificate Transparency Support
 DES_DESC=	(Triple) Data Encryption Standard
 EC_DESC=	Optimize NIST elliptic curves
+FIPS_DESC=	Build FIPS provider
 GOST_DESC=	GOST (Russian standard)
 HASHES_DESC=	Hash Function Support
 I386_DESC=	i386 (instead of i486+)
 IDEA_DESC=	International Data Encryption Algorithm
-KTLS_DESC=	Kernel TLS offload
+KTLS_DESC=	Use in-kernel TLS (FreeBSD >13)
+LEGACY_DESC=	Older algorithms
 MAN3_DESC=	Install API manpages (section 3, 7)
-MD2_DESC=	MD2 (obsolete)
+MD2_DESC=	MD2 (obsolete) (requires LEGACY)
 MD4_DESC=	MD4 (unsafe)
 MDC2_DESC=	MDC-2 (patented, requires DES)
+MODULES_DESC=	Provider modules
 NEXTPROTONEG_DESC=	Next Protocol Negotiation (SPDY)
 OPTIMIZE_DESC=	Optimizations
 PROTOCOLS_DESC=	Protocol Support
@@ -92,30 +96,51 @@ TLS1_2_DESC=	TLSv1.2
 WEAK-SSL-CIPHERS_DESC=	Weak cipher support (unsafe)
 
 # Upstream default disabled options
-.for _option in ktls md2 rc5 sctp ssl3 zlib weak-ssl-ciphers
+.for _option in fips md2 ktls rc5 sctp ssl3 weak-ssl-ciphers zlib
 ${_option:tu}_CONFIGURE_ON=	enable-${_option}
 .endfor
 
 # Upstream default enabled options
-.for _option in aria asm async ct des gost idea md4 mdc2 nextprotoneg rc2 rc4 \
-	rfc3779 rmd160 shared sm2 sm3 sm4 sse2 threads tls1 tls1_1 tls1_2
+.for _option in aria asm async ct des gost idea md4 mdc2 legacy \
+	nextprotoneg rc2 rc4 rfc3779 rmd160 shared sm2 sm3 sm4 sse2 \
+	threads tls1 tls1_1 tls1_2
 ${_option:tu}_CONFIGURE_OFF=	no-${_option}
 .endfor
 
+MD2_IMPLIES=	LEGACY
 MDC2_IMPLIES=	DES
 TLS1_IMPLIES=	TLS1_1
 TLS1_1_IMPLIES=	TLS1_2
 
 EC_CONFIGURE_ON=	enable-ec_nistp_64_gcc_128
+FIPS_VARS=		shlibs+=lib/ossl-modules/fips.so
 I386_CONFIGURE_ON=	386
 KTLS_EXTRA_PATCHES=	${FILESDIR}/extra-patch-ktls
-MAN3_EXTRA_PATCHES_OFF=	${FILESDIR}/extra-patch-util_process__docs.pl
+LEGACY_VARS=		shlibs+=lib/ossl-modules/legacy.so
+MAN3_EXTRA_PATCHES_OFF=	${FILESDIR}/extra-patch-util_find-doc-nits
 SHARED_MAKE_ENV=	SHLIBVER=${OPENSSL_SHLIBVER}
 SHARED_PLIST_SUB=	SHLIBVER=${OPENSSL_SHLIBVER}
 SHARED_USE=		ldconfig=yes
+SHARED_VARS=		shlibs+="lib/libcrypto.so.${OPENSSL_SHLIBVER} \
+				lib/libssl.so.${OPENSSL_SHLIBVER} \
+				lib/engines-${OPENSSL_SHLIBVER}/capi.so \
+				lib/engines-${OPENSSL_SHLIBVER}/devcrypto.so \
+				lib/engines-${OPENSSL_SHLIBVER}/padlock.so"
 SSL3_CONFIGURE_ON+=	enable-ssl3-method
 ZLIB_CONFIGURE_ON=	zlib-dynamic
 
+SHLIBS=			lib/engines-${OPENSSL_SHLIBVER}/loader_attic.so
+
+.include <bsd.port.options.mk>
+
+.if ${ARCH} == powerpc64
+CONFIGURE_ARGS+=	BSD-ppc64
+.elif ${ARCH} == powerpc64le
+CONFIGURE_ARGS+=	BSD-ppc64le
+.elif ${ARCH} == riscv64
+CONFIGURE_ARGS+=	BSD-riscv64
+.endif
+
 .include <bsd.port.pre.mk>
 .if ${PREFIX} == /usr
 IGNORE=	the OpenSSL port can not be installed over the base version
@@ -135,35 +160,34 @@ BROKEN_sparc64=	option ASM generates illegal instructions
 .endif
 
 post-patch:
-	${REINPLACE_CMD} \
-		-e 's|^MANDIR=.*$$|MANDIR=$$(INSTALLTOP)/man|' \
-		-e 's| install_html_docs$$||' \
-		-e 's|$$(LIBDIR)/pkgconfig|libdata/pkgconfig|g' \
+	${REINPLACE_CMD} -Ee 's|^MANDIR=.*$$|MANDIR=$$(INSTALLTOP)/man|' \
+		-e 's|^(build\|install)_docs: .*|\1_docs: \1_man_docs|' \
 		${WRKSRC}/Configurations/unix-Makefile.tmpl
-	${REINPLACE_CMD} -e 's|\^GNU ld|GNU|' ${WRKSRC}/Configurations/shared-info.pl
+	${REINPLACE_CMD} 's|SHLIB_VERSION=3|SHLIB_VERSION=${OPENSSL_SHLIBVER}|' \
+		${WRKSRC}/VERSION.dat
 
 post-configure:
+	( cd ${WRKSRC} ; ${PERL} configdata.pm --dump )
+
+post-configure-MAN3-off:
 	${REINPLACE_CMD} \
-		-e 's|SHLIB_VERSION_NUMBER=1.1|SHLIB_VERSION_NUMBER=${OPENSSL_SHLIBVER}|' \
+		-e 's|^build_man_docs:.*|build_man_docs: $$(MANDOCS1) $$(MANDOCS5)|' \
+		-e 's|dummy $$(MANDOCS[37]); do |dummy; do |' \
 		${WRKSRC}/Makefile
-	${REINPLACE_CMD} \
-		-e 's|SHLIB_VERSION_NUMBER "1.1"|SHLIB_VERSION_NUMBER "${OPENSSL_SHLIBVER}"|' \
-		${WRKSRC}/include/openssl/opensslv.h
 
 post-install-SHARED-on:
-.for i in libcrypto libssl
-	${INSTALL_LIB} ${WRKSRC}/$i.so.${OPENSSL_SHLIBVER} ${STAGEDIR}${PREFIX}/lib
-	${LN} -sf $i.so.${OPENSSL_SHLIBVER} ${STAGEDIR}${PREFIX}/lib/$i.so
-.endfor
-.for i in capi padlock
-	${STRIP_CMD} ${STAGEDIR}${PREFIX}/lib/engines-1.1/${i}.so
+.for i in ${SHLIBS}
+	-@${STRIP_CMD} ${STAGEDIR}${PREFIX}/$i
 .endfor
 
+post-install-SHARED-off:
+	${RMDIR} ${STAGEDIR}${PREFIX}/lib/engines-12
+
 post-install:
 	${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/openssl
 
 post-install-MAN3-on:
-	( cd ${STAGEDIR}/${PREFIX} ; ${FIND} man/man3 man/man7 -not -type d ) | \
-		${SED} 's/$$/.gz/' >>${TMPPLIST}
+	( cd ${STAGEDIR}/${PREFIX} ; ${FIND} man/man3 -not -type d ; \
+		${FIND} man/man7 -not -type d ) | ${SED} 's/$$/.gz/' >> ${TMPPLIST}
 
 .include <bsd.port.post.mk>
diff --git a/security/openssl/distinfo b/security/openssl/distinfo
index 11a9beb18815..a62e9e8bb1d6 100644
--- a/security/openssl/distinfo
+++ b/security/openssl/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1694449777
-SHA256 (openssl-1.1.1w.tar.gz) = cf3098950cb4d853ad95c0841f1f9c6d3dc102dccfcacd521d93925208b76ac8
-SIZE (openssl-1.1.1w.tar.gz) = 9893384
+TIMESTAMP = 1695134169
+SHA256 (openssl-3.0.11.tar.gz) = b3425d3bb4a2218d0697eb41f7fc0cdede016ed19ca49d168b78e8d947887f55
+SIZE (openssl-3.0.11.tar.gz) = 15198318
diff --git a/security/openssl/files/extra-patch-ktls b/security/openssl/files/extra-patch-ktls
index d38a70e779e3..8a46c272d95c 100644
--- a/security/openssl/files/extra-patch-ktls
+++ b/security/openssl/files/extra-patch-ktls
@@ -1,2081 +1,318 @@
-diff --git CHANGES CHANGES
-index a5522e5fa5..98961effc0 100644
---- CHANGES
-+++ CHANGES
-@@ -606,6 +606,11 @@
-      necessary to configure just to create a source distribution.
-      [Richard Levitte]
- 
-+  *) Added support for Linux Kernel TLS data-path. The Linux Kernel data-path
-+     improves application performance by removing data copies and providing
-+     applications with zero-copy system calls such as sendfile and splice.
-+     [Boris Pismenny]
-+
-  Changes between 1.1.1 and 1.1.1a [20 Nov 2018]
- 
-   *) Timing vulnerability in DSA signature generation
-diff --git Configure Configure
-index 4bea49d7da..e656814a7f 100755
---- Configure
-+++ Configure
-@@ -341,6 +341,7 @@ my @dtls = qw(dtls1 dtls1_2);
- # For developers: keep it sorted alphabetically
+diff --git include/internal/ktls.h include/internal/ktls.h
+index 95492fd065..3c82cae26b 100644
+--- include/internal/ktls.h
++++ include/internal/ktls.h
+@@ -40,6 +40,11 @@
+ #   define OPENSSL_KTLS_AES_GCM_128
+ #   define OPENSSL_KTLS_AES_GCM_256
+ #   define OPENSSL_KTLS_TLS13
++#   ifdef TLS_CHACHA20_IV_LEN
++#    ifndef OPENSSL_NO_CHACHA
++#     define OPENSSL_KTLS_CHACHA20_POLY1305
++#    endif
++#   endif
  
- my @disablables = (
-+    "ktls",
-     "afalgeng",
-     "aria",
-     "asan",
-@@ -474,6 +475,7 @@ our %disabled = ( # "what"         => "comment"
-                   "weak-ssl-ciphers"    => "default",
-                   "zlib"                => "default",
-                   "zlib-dynamic"        => "default",
-+		  "ktls"                => "default",
-                 );
+ typedef struct tls_enable ktls_crypto_info_t;
  
- # Note: => pair form used for aesthetics, not to truly make a hash table
-@@ -1583,6 +1585,33 @@ unless ($disabled{devcryptoeng}) {
-     }
- }
+diff --git ssl/ktls.c ssl/ktls.c
+index 79d980959e..e343d382cc 100644
+--- ssl/ktls.c
++++ ssl/ktls.c
+@@ -10,6 +10,67 @@
+ #include "ssl_local.h"
+ #include "internal/ktls.h"
  
-+unless ($disabled{ktls}) {
-+    $config{ktls}="";
-+    if ($target =~ m/^linux/) {
-+        my $usr = "/usr/$config{cross_compile_prefix}";
-+        chop($usr);
-+        if ($config{cross_compile_prefix} eq "") {
-+            $usr = "/usr";
-+        }
-+        my $minver = (4 << 16) + (13 << 8) + 0;
-+        my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`);
++#ifndef OPENSSL_NO_KTLS_RX
++ /*
++  * Count the number of records that were not processed yet from record boundary.
++  *
++  * This function assumes that there are only fully formed records read in the
++  * record layer. If read_ahead is enabled, then this might be false and this
++  * function will fail.
++  */
++static int count_unprocessed_records(SSL *s)
++{
++    SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
++    PACKET pkt, subpkt;
++    int count = 0;
 +
-+        if ($verstr[2] < $minver) {
-+            disable('too-old-kernel', 'ktls');
-+        }
-+    } elsif ($target =~ m/^BSD/) {
-+        my $cc = $config{CROSS_COMPILE}.$config{CC};
-+        system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1");
-+        if ($? != 0) {
-+            disable('too-old-freebsd', 'ktls');
-+        }
-+    } else {
-+        disable('not-linux-or-freebsd', 'ktls');
++    if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left))
++        return -1;
++
++    while (PACKET_remaining(&pkt) > 0) {
++        /* Skip record type and version */
++        if (!PACKET_forward(&pkt, 3))
++            return -1;
++
++        /* Read until next record */
++        if (!PACKET_get_length_prefixed_2(&pkt, &subpkt))
++            return -1;
++
++        count += 1;
 +    }
++
++    return count;
 +}
 +
-+push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
++/*
++ * The kernel cannot offload receive if a partial TLS record has been read.
++ * Check the read buffer for unprocessed records.  If the buffer contains a
++ * partial record, fail and return 0.  Otherwise, update the sequence
++ * number at *rec_seq for the count of unprocessed records and return 1.
++ */
++static int check_rx_read_ahead(SSL *s, unsigned char *rec_seq)
++{
++    int bit, count_unprocessed;
 +
- # Get the extra flags used when building shared libraries and modules.  We
- # do this late because some of them depend on %disabled.
- 
-diff --git INSTALL INSTALL
-index f3ac727183..f6f754fd5e 100644
---- INSTALL
-+++ INSTALL
-@@ -263,6 +263,15 @@
-                    Don't build the AFALG engine. This option will be forced if
-                    on a platform that does not support AFALG.
- 
-+  enable-ktls
-+                   Build with Kernel TLS support. This option will enable the
-+                   use of the Kernel TLS data-path, which can improve
-+                   performance and allow for the use of sendfile and splice
-+                   system calls on TLS sockets. The Kernel may use TLS
-+                   accelerators if any are available on the system.
-+                   This option will be forced off on systems that do not support
-+                   the Kernel TLS data-path.
++    count_unprocessed = count_unprocessed_records(s);
++    if (count_unprocessed < 0)
++        return 0;
 +
-   enable-asan
-                    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 00effc8037..5664e7e04e 100644
---- apps/s_client.c
-+++ apps/s_client.c
-@@ -3295,6 +3295,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
-+#ifndef OPENSSL_NO_KTLS
-+    if (BIO_get_ktls_send(SSL_get_wbio(s)))
-+        BIO_printf(bio_err, "Using Kernel TLS for sending\n");
-+    if (BIO_get_ktls_recv(SSL_get_rbio(s)))
-+        BIO_printf(bio_err, "Using Kernel TLS for receiving\n");
-+#endif
- 
- #ifdef SSL_DEBUG
-     {
-diff --git apps/s_server.c apps/s_server.c
-index 64d53e68d0..9fcb8d7a7b 100644
---- apps/s_server.c
-+++ apps/s_server.c
-@@ -2934,6 +2934,12 @@ static void print_connection_info(SSL *con)
-         }
-         OPENSSL_free(exportedkeymat);
-     }
-+#ifndef OPENSSL_NO_KTLS
-+    if (BIO_get_ktls_send(SSL_get_wbio(con)))
-+        BIO_printf(bio_err, "Using Kernel TLS for sending\n");
-+    if (BIO_get_ktls_recv(SSL_get_rbio(con)))
-+        BIO_printf(bio_err, "Using Kernel TLS for receiving\n");
++    /* increment the crypto_info record sequence */
++    while (count_unprocessed) {
++        for (bit = 7; bit >= 0; bit--) { /* increment */
++            ++rec_seq[bit];
++            if (rec_seq[bit] != 0)
++                break;
++        }
++        count_unprocessed--;
++
++    }
++
++    return 1;
++}
 +#endif
++
+ #if defined(__FreeBSD__)
+ # include "crypto/cryptodev.h"
  
-     (void)BIO_flush(bio_s_out);
- }
-diff --git crypto/bio/b_sock2.c crypto/bio/b_sock2.c
-index 104ff31b0d..771729880e 100644
---- crypto/bio/b_sock2.c
-+++ crypto/bio/b_sock2.c
-@@ -12,6 +12,7 @@
- #include <errno.h>
- 
- #include "bio_local.h"
-+#include "internal/ktls.h"
- 
- #include <openssl/err.h>
- 
-@@ -50,6 +51,17 @@ int BIO_socket(int domain, int socktype, int protocol, int options)
-         BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
-         return INVALID_SOCKET;
-     }
-+# ifndef OPENSSL_NO_KTLS
-+    {
-+        /*
-+         * The new socket is created successfully regardless of ktls_enable.
-+         * ktls_enable doesn't change any functionality of the socket, except
-+         * changing the setsockopt to enable the processing of ktls_start.
-+         * Thus, it is not a problem to call it for non-TLS sockets.
-+         */
-+        ktls_enable(sock);
-+    }
+@@ -37,6 +98,10 @@ int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
+     case SSL_AES128GCM:
+     case SSL_AES256GCM:
+         return 1;
++# ifdef OPENSSL_KTLS_CHACHA20_POLY1305
++    case SSL_CHACHA20POLY1305:
++        return 1;
 +# endif
- 
-     return sock;
+     case SSL_AES128:
+     case SSL_AES256:
+         if (s->ext.use_etm)
+@@ -55,9 +120,9 @@ int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
  }
-diff --git crypto/bio/bss_conn.c crypto/bio/bss_conn.c
-index 807a82b23b..10cf20871c 100644
---- crypto/bio/bss_conn.c
-+++ crypto/bio/bss_conn.c
-@@ -11,6 +11,7 @@
- #include <errno.h>
- 
- #include "bio_local.h"
-+#include "internal/ktls.h"
- 
- #ifndef OPENSSL_NO_SOCK
- 
-@@ -20,6 +21,9 @@ typedef struct bio_connect_st {
-     char *param_hostname;
-     char *param_service;
-     int connect_mode;
-+# ifndef OPENSSL_NO_KTLS
-+    unsigned char record_type;
-+# endif
- 
-     BIO_ADDRINFO *addr_first;
-     const BIO_ADDRINFO *addr_iter;
-@@ -320,7 +324,12 @@ static int conn_read(BIO *b, char *out, int outl)
- 
-     if (out != NULL) {
-         clear_socket_error();
--        ret = readsocket(b->num, out, outl);
-+# ifndef OPENSSL_NO_KTLS
-+        if (BIO_get_ktls_recv(b))
-+            ret = ktls_read_record(b->num, out, outl);
-+        else
-+# endif
-+            ret = readsocket(b->num, out, outl);
-         BIO_clear_retry_flags(b);
-         if (ret <= 0) {
-             if (BIO_sock_should_retry(ret))
-@@ -345,7 +354,16 @@ static int conn_write(BIO *b, const char *in, int inl)
-     }
- 
-     clear_socket_error();
--    ret = writesocket(b->num, in, inl);
-+# ifndef OPENSSL_NO_KTLS
-+    if (BIO_should_ktls_ctrl_msg_flag(b)) {
-+        ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl);
-+        if (ret >= 0) {
-+            ret = inl;
-+            BIO_clear_ktls_ctrl_msg_flag(b);
-+        }
-+    } else
-+# endif
-+        ret = writesocket(b->num, in, inl);
-     BIO_clear_retry_flags(b);
-     if (ret <= 0) {
-         if (BIO_sock_should_retry(ret))
-@@ -361,6 +379,9 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
-     const char **pptr = NULL;
-     long ret = 1;
-     BIO_CONNECT *data;
-+# ifndef OPENSSL_NO_KTLS
-+    ktls_crypto_info_t *crypto_info;
-+# endif
  
-     data = (BIO_CONNECT *)b->ptr;
- 
-@@ -518,8 +539,29 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
-         }
-         break;
-     case BIO_CTRL_EOF:
--        ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
-+        ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
+ /* Function to configure kernel TLS structure */
+-int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
++int ktls_configure_crypto(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,
++                          int is_tx, unsigned char *iv,
+                           unsigned char *key, unsigned char *mac_key,
+                           size_t mac_secret_size)
+ {
+@@ -71,6 +136,12 @@ int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+         else
+             crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
          break;
-+# ifndef OPENSSL_NO_KTLS
-+    case BIO_CTRL_SET_KTLS:
-+        crypto_info = (ktls_crypto_info_t *)ptr;
-+        ret = ktls_start(b->num, crypto_info, num);
-+        if (ret)
-+            BIO_set_ktls_flag(b, num);
-+        break;
-+    case BIO_CTRL_GET_KTLS_SEND:
-+        return BIO_should_ktls_flag(b, 1) != 0;
-+    case BIO_CTRL_GET_KTLS_RECV:
-+        return BIO_should_ktls_flag(b, 0) != 0;
-+    case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
-+        BIO_set_ktls_ctrl_msg_flag(b);
-+        data->record_type = num;
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
-+        BIO_clear_ktls_ctrl_msg_flag(b);
-+        ret = 0;
++# ifdef OPENSSL_KTLS_CHACHA20_POLY1305
++    case SSL_CHACHA20POLY1305:
++        crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
++        crypto_info->iv_len = EVP_CIPHER_CTX_get_iv_length(dd);
 +        break;
 +# endif
-     default:
-         ret = 0;
-         break;
-diff --git crypto/bio/bss_fd.c crypto/bio/bss_fd.c
-index ccbe1626ba..8d03e48ce9 100644
---- crypto/bio/bss_fd.c
-+++ crypto/bio/bss_fd.c
-@@ -189,7 +189,7 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
-         ret = 1;
-         break;
-     case BIO_CTRL_EOF:
--        ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
-+        ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
-         break;
-     default:
-         ret = 0;
-diff --git crypto/bio/bss_sock.c crypto/bio/bss_sock.c
-index 6251f3d46a..8de1f58292 100644
---- crypto/bio/bss_sock.c
-+++ crypto/bio/bss_sock.c
-@@ -11,6 +11,7 @@
- #include <errno.h>
- #include "bio_local.h"
- #include "internal/cryptlib.h"
-+#include "internal/ktls.h"
- 
- #ifndef OPENSSL_NO_SOCK
- 
-@@ -64,6 +65,17 @@ BIO *BIO_new_socket(int fd, int close_flag)
-     if (ret == NULL)
-         return NULL;
-     BIO_set_fd(ret, fd, close_flag);
-+# ifndef OPENSSL_NO_KTLS
-+    {
-+        /*
-+         * The new socket is created successfully regardless of ktls_enable.
-+         * ktls_enable doesn't change any functionality of the socket, except
-+         * changing the setsockopt to enable the processing of ktls_start.
-+         * Thus, it is not a problem to call it for non-TLS sockets.
-+         */
-+        ktls_enable(fd);
-+    }
-+# endif
-     return ret;
+     case SSL_AES128:
+     case SSL_AES256:
+         switch (s->s3.tmp.new_cipher->algorithm_mac) {
+@@ -101,11 +172,11 @@ int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+     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;
++    if (!is_tx && !check_rx_read_ahead(s, crypto_info->rec_seq))
++        return 0;
+ # else
+-    if (rec_seq != NULL)
+-        *rec_seq = NULL;
++    if (!is_tx)
++        return 0;
+ # endif
+     return 1;
+ };
+@@ -154,15 +225,20 @@ int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
  }
  
-@@ -96,7 +108,12 @@ static int sock_read(BIO *b, char *out, int outl)
- 
-     if (out != NULL) {
-         clear_socket_error();
--        ret = readsocket(b->num, out, outl);
-+# ifndef OPENSSL_NO_KTLS
-+        if (BIO_get_ktls_recv(b))
-+            ret = ktls_read_record(b->num, out, outl);
-+        else
-+# endif
-+            ret = readsocket(b->num, out, outl);
-         BIO_clear_retry_flags(b);
-         if (ret <= 0) {
-             if (BIO_sock_should_retry(ret))
-@@ -110,10 +127,20 @@ static int sock_read(BIO *b, char *out, int outl)
- 
- static int sock_write(BIO *b, const char *in, int inl)
- {
--    int ret;
-+    int ret = 0;
- 
-     clear_socket_error();
--    ret = writesocket(b->num, in, inl);
-+# ifndef OPENSSL_NO_KTLS
-+    if (BIO_should_ktls_ctrl_msg_flag(b)) {
-+        unsigned char record_type = (intptr_t)b->ptr;
-+        ret = ktls_send_ctrl_message(b->num, record_type, in, inl);
-+        if (ret >= 0) {
-+            ret = inl;
-+            BIO_clear_ktls_ctrl_msg_flag(b);
-+        }
-+    } else
-+# endif
-+        ret = writesocket(b->num, in, inl);
-     BIO_clear_retry_flags(b);
-     if (ret <= 0) {
-         if (BIO_sock_should_retry(ret))
-@@ -126,6 +153,9 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+ /* Function to configure kernel TLS structure */
+-int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
++int ktls_configure_crypto(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,
++                          int is_tx, unsigned char *iv,
+                           unsigned char *key, unsigned char *mac_key,
+                           size_t mac_secret_size)
  {
-     long ret = 1;
-     int *ip;
-+# ifndef OPENSSL_NO_KTLS
-+    ktls_crypto_info_t *crypto_info;
-+# endif
+     unsigned char geniv[12];
+     unsigned char *iiv = iv;
  
-     switch (cmd) {
-     case BIO_C_SET_FD:
-@@ -153,8 +183,29 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
-     case BIO_CTRL_FLUSH:
-         ret = 1;
-         break;
-+# ifndef OPENSSL_NO_KTLS
-+    case BIO_CTRL_SET_KTLS:
-+        crypto_info = (ktls_crypto_info_t *)ptr;
-+        ret = ktls_start(b->num, crypto_info, num);
-+        if (ret)
-+            BIO_set_ktls_flag(b, num);
-+        break;
-+    case BIO_CTRL_GET_KTLS_SEND:
-+        return BIO_should_ktls_flag(b, 1) != 0;
-+    case BIO_CTRL_GET_KTLS_RECV:
-+        return BIO_should_ktls_flag(b, 0) != 0;
-+    case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
-+        BIO_set_ktls_ctrl_msg_flag(b);
-+        b->ptr = (void *)num;
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
-+        BIO_clear_ktls_ctrl_msg_flag(b);
-+        ret = 0;
-+        break;
++# ifdef OPENSSL_NO_KTLS_RX
++    if (!is_tx)
++        return 0;
 +# endif
-     case BIO_CTRL_EOF:
--        ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
-+        ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
-         break;
-     default:
-         ret = 0;
-diff --git crypto/err/openssl.txt crypto/err/openssl.txt
-index 902e97b843..846c896359 100644
---- crypto/err/openssl.txt
-+++ crypto/err/openssl.txt
-@@ -1319,6 +1319,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:*
-+SSL_F_SSL_SENDFILE:639:SSL_sendfile
- SSL_F_SSL_SESSION_DUP:348:ssl_session_dup
- SSL_F_SSL_SESSION_NEW:189:SSL_SESSION_new
- SSL_F_SSL_SESSION_PRINT_FP:190:SSL_SESSION_print_fp
-diff --git crypto/evp/e_aes.c crypto/evp/e_aes.c
-index a1d3ab90fa..715fac9f88 100644
---- crypto/evp/e_aes.c
-+++ crypto/evp/e_aes.c
-@@ -2889,6 +2889,14 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-         memcpy(ptr, c->buf, arg);
++
+     if (s->version == TLS1_2_VERSION &&
+         EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) {
+         if (!EVP_CIPHER_CTX_get_updated_iv(dd, geniv,
+@@ -186,8 +262,8 @@ int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+         memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_get_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;
++        if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm128.rec_seq))
++            return 0;
          return 1;
- 
-+    case EVP_CTRL_GET_IV:
-+        if (gctx->iv_gen != 1)
+ # endif
+ # ifdef OPENSSL_KTLS_AES_GCM_256
+@@ -201,8 +277,8 @@ int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+         memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_get_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;
++        if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm256.rec_seq))
 +            return 0;
-+        if (gctx->ivlen != arg)
+         return 1;
+ # endif
+ # ifdef OPENSSL_KTLS_AES_CCM_128
+@@ -216,8 +292,8 @@ int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+         memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_get_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;
++        if (!is_tx && !check_rx_read_ahead(s, crypto_info->ccm128.rec_seq))
 +            return 0;
-+        memcpy(ptr, gctx->iv, arg);
-+        return 1;
-+
-     case EVP_CTRL_GCM_SET_IV_FIXED:
-         /* Special case: -1 length restores whole IV */
-         if (arg == -1) {
-diff --git doc/man3/BIO_ctrl.pod doc/man3/BIO_ctrl.pod
-index cf6ba135df..fc51173c8d 100644
---- doc/man3/BIO_ctrl.pod
-+++ doc/man3/BIO_ctrl.pod
-@@ -5,7 +5,8 @@
- BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset,
- BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close,
- BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending,
--BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb
-+BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb, BIO_get_ktls_send,
-+BIO_get_ktls_recv
- - BIO control operations
- 
- =head1 SYNOPSIS
-@@ -34,6 +35,9 @@ BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb
-  int BIO_get_info_callback(BIO *b, BIO_info_cb **cbp);
-  int BIO_set_info_callback(BIO *b, BIO_info_cb *cb);
- 
-+ int BIO_get_ktls_send(BIO *b);
-+ int BIO_get_ktls_recv(BIO *b);
-+
- =head1 DESCRIPTION
- 
- BIO_ctrl(), BIO_callback_ctrl(), BIO_ptr_ctrl() and BIO_int_ctrl()
-@@ -72,6 +76,11 @@ Not all BIOs support these calls. BIO_ctrl_pending() and BIO_ctrl_wpending()
- return a size_t type and are functions, BIO_pending() and BIO_wpending() are
- macros which call BIO_ctrl().
- 
-+BIO_get_ktls_send() returns 1 if the BIO is using the Kernel TLS data-path for
-+sending. Otherwise, it returns zero.
-+BIO_get_ktls_recv() returns 1 if the BIO is using the Kernel TLS data-path for
-+receiving. Otherwise, it returns zero.
-+
- =head1 RETURN VALUES
- 
- BIO_reset() normally returns 1 for success and 0 or -1 for failure. File
-@@ -92,6 +101,11 @@ BIO_get_close() returns the close flag value: BIO_CLOSE or BIO_NOCLOSE.
- BIO_pending(), BIO_ctrl_pending(), BIO_wpending() and BIO_ctrl_wpending()
- return the amount of pending data.
- 
-+BIO_get_ktls_send() returns 1 if the BIO is using the Kernel TLS data-path for
-+sending. Otherwise, it returns zero.
-+BIO_get_ktls_recv() returns 1 if the BIO is using the Kernel TLS data-path for
-+receiving. Otherwise, it returns zero.
-+
- =head1 NOTES
+         return 1;
+ # endif
+ # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
+@@ -231,8 +307,10 @@ int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
+                EVP_CIPHER_get_key_length(c));
+         memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence,
+                TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
+-        if (rec_seq != NULL)
+-            *rec_seq = crypto_info->chacha20poly1305.rec_seq;
++        if (!is_tx
++                && !check_rx_read_ahead(s,
++                                        crypto_info->chacha20poly1305.rec_seq))
++            return 0;
+         return 1;
+ # endif
+     default:
+diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c
+index d8ef018741..63caac080f 100644
+--- ssl/record/ssl3_record.c
++++ ssl/record/ssl3_record.c
+@@ -185,18 +185,23 @@ int ssl3_get_record(SSL *s)
+     int imac_size;
+     size_t num_recs = 0, max_recs, j;
+     PACKET pkt, sslv2pkt;
+-    int is_ktls_left;
++    int using_ktls;
+     SSL_MAC_BUF *macbufs = NULL;
+     int ret = -1;
  
- BIO_flush(), because it can write data may return 0 or -1 indicating
-@@ -124,6 +138,11 @@ particular a return value of 0 can be returned if an operation is not
- supported, if an error occurred, if EOF has not been reached and in
- the case of BIO_seek() on a file BIO for a successful operation.
+     rr = RECORD_LAYER_get_rrec(&s->rlayer);
+     rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+-    is_ktls_left = (SSL3_BUFFER_get_left(rbuf) > 0);
+     max_recs = s->max_pipelines;
+     if (max_recs == 0)
+         max_recs = 1;
+     sess = s->session;
  
-+=head1 HISTORY
-+
-+The BIO_get_ktls_send() and BIO_get_ktls_recv() functions were added in
-+OpenSSL 3.0.0.
++    /*
++     * KTLS reads full records. If there is any data left,
++     * then it is from before enabling ktls.
++     */
++    using_ktls = BIO_get_ktls_recv(s->rbio) && SSL3_BUFFER_get_left(rbuf) == 0;
 +
- =head1 COPYRIGHT
- 
- Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
-diff --git doc/man3/SSL_CONF_cmd.pod doc/man3/SSL_CONF_cmd.pod
-index 7f0e088687..c7cce5486b 100644
---- doc/man3/SSL_CONF_cmd.pod
-+++ doc/man3/SSL_CONF_cmd.pod
-@@ -495,6 +495,10 @@ specification. Some applications may be able to mitigate the replay risks in
- other ways and in such cases the built-in OpenSSL functionality is not required.
- Disabling anti-replay is equivalent to setting B<SSL_OP_NO_ANTI_REPLAY>.
+     do {
+         thisrr = &rr[num_recs];
  
-+B<KTLS>: Enables kernel TLS if support has been compiled in, and it is supported
-+by the negotiated ciphersuites and extensions. Equivalent to
-+B<SSL_OP_ENABLE_KTLS>.
-+
- =item B<VerifyMode>
+@@ -361,7 +366,9 @@ int ssl3_get_record(SSL *s)
+                     }
+                 }
  
- The B<value> argument is a comma separated list of flags to set.
-diff --git doc/man3/SSL_CTX_set_options.pod doc/man3/SSL_CTX_set_options.pod
-index 969e0366c4..231fe92d8e 100644
---- doc/man3/SSL_CTX_set_options.pod
-+++ doc/man3/SSL_CTX_set_options.pod
-@@ -237,6 +237,29 @@ functionality is not required. Those applications can turn this feature off by
- setting this option. This is a server-side opton only. It is ignored by
- clients.
+-                if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL) {
++                if (SSL_IS_TLS13(s)
++                        && s->enc_read_ctx != NULL
++                        && !using_ktls) {
+                     if (thisrr->type != SSL3_RT_APPLICATION_DATA
+                             && (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
+                                 || !SSL_IS_FIRST_HANDSHAKE(s))
+@@ -391,7 +398,13 @@ int ssl3_get_record(SSL *s)
+         }
  
-+=item SSL_OP_ENABLE_KTLS
-+
-+Enable the use of kernel TLS. In order to benefit from kernel TLS OpenSSL must
-+have been compiled with support for it, and it must be supported by the
-+negotiated ciphersuites and extensions. The specific ciphersuites and extensions
-+that are supported may vary by platform and kernel version.
-+
-+The kernel TLS data-path implements the record layer, and the encryption
*** 3708 LINES SKIPPED ***