git: 5278f6d9bfd0 - main - security/openss32: Add OpenSSL 3.2 ALPHA port

From: Bernard Spil <brnrd_at_FreeBSD.org>
Date: Sun, 10 Sep 2023 15:10:18 UTC
The branch main has been updated by brnrd:

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

commit 5278f6d9bfd0b09e5a17d23a4f7dd86c531bbb88
Author:     Bernard Spil <brnrd@FreeBSD.org>
AuthorDate: 2023-09-10 15:09:43 +0000
Commit:     Bernard Spil <brnrd@FreeBSD.org>
CommitDate: 2023-09-10 15:09:43 +0000

    security/openss32: Add OpenSSL 3.2 ALPHA port
    
     * For early testers
---
 security/Makefile                                  |   1 +
 security/openssl32/Makefile                        | 207 ++++++++
 security/openssl32/distinfo                        |   3 +
 security/openssl32/files/extra-patch-ktls          | 540 +++++++++++++++++++++
 .../openssl32/files/extra-patch-util_find-doc-nits |  20 +
 .../files/patch-Configurations_10-main.conf        |  35 ++
 .../files/patch-crypto_threads__pthread.c          |  13 +
 security/openssl32/pkg-descr                       |  13 +
 security/openssl32/pkg-message                     |  20 +
 security/openssl32/pkg-plist                       | 277 +++++++++++
 security/openssl32/version.mk                      |   1 +
 11 files changed, 1130 insertions(+)

diff --git a/security/Makefile b/security/Makefile
index e6dc8b2191ba..a2717e0372fd 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -423,6 +423,7 @@
     SUBDIR += openssl-unsafe
     SUBDIR += openssl30
     SUBDIR += openssl31
+    SUBDIR += openssl32
     SUBDIR += openvas
     SUBDIR += openvpn
     SUBDIR += openvpn-admin
diff --git a/security/openssl32/Makefile b/security/openssl32/Makefile
new file mode 100644
index 000000000000..8009b84c589d
--- /dev/null
+++ b/security/openssl32/Makefile
@@ -0,0 +1,207 @@
+PORTNAME=	openssl
+DISTVERSION=	3.2.0-alpha1
+CATEGORIES=	security devel
+MASTER_SITES=	https://www.openssl.org/source/ \
+		ftp://ftp.cert.dfn.de/pub/tools/net/openssl/source/
+PKGNAMESUFFIX=	32
+
+MAINTAINER=	brnrd@FreeBSD.org
+COMMENT=	TLSv1.3 capable SSL and crypto library
+WWW=		https://www.openssl.org/
+
+LICENSE=	APACHE20
+LICENSE_FILE=	${WRKSRC}/LICENSE.txt
+
+CONFLICTS_INSTALL=	boringssl libressl libressl-devel openssl openssl3[01] openssl-quictls
+
+HAS_CONFIGURE=	yes
+CONFIGURE_SCRIPT=	config
+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 COMPRESSION HASHES MODULES OPTIMIZE PROTOCOLS
+OPTIONS_GROUP_CIPHERS=	ARIA DES GOST IDEA SM4 RC2 RC4 RC5 WEAK-SSL-CIPHERS
+OPTIONS_GROUP_COMPRESSION=	BROTLI ZLIB ZSTD
+OPTIONS_GROUP_HASHES=	MD2 MD4 MDC2 RMD160 SM2 SM3
+OPTIONS_GROUP_OPTIMIZE=	ASM SSE2 THREADS THREADPOOL
+OPTIONS_GROUP_MODULES=	FIPS LEGACY
+OPTIONS_DEFINE_i386=	I386
+OPTIONS_GROUP_PROTOCOLS=NEXTPROTONEG QUIC SCTP SSL3 TLS1 TLS1_1 TLS1_2
+
+OPTIONS_DEFINE=	ASYNC CRYPTODEV CT KTLS MAN3 RFC3779 SHARED
+
+OPTIONS_DEFAULT=ASM ASYNC CT DES EC FIPS GOST MAN3 MD4 NEXTPROTONEG \
+		QUIC RC2 RC4 RMD160 SCTP SHARED SSE2 THREADPOOL THREADS \
+	       	TLS1 TLS1_1 TLS1_2
+#OPTIONS_DEFAULT+=	KTLS pending updated KTLS patch
+
+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"
+OPTIONS_GROUP_OPTIMIZE+=	EC
+.endif
+
+OPTIONS_SUB=	yes
+
+ARIA_DESC=	ARIA (South Korean standard)
+ASM_DESC=	Assembler code
+ASYNC_DESC=	Asynchronous mode
+CIPHERS_DESC=	Block Cipher Support
+COMPRESSION_DESC=	Compression Support
+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 (Note: NOT yet FIPS validated)
+GOST_DESC=	GOST (Russian standard)
+HASHES_DESC=	Hash Function Support
+I386_DESC=	i386 (instead of i486+)
+IDEA_DESC=	International Data Encryption Algorithm
+KTLS_DESC=	Use in-kernel TLS (FreeBSD >13)
+LEGACY_DESC=	Older algorithms
+MAN3_DESC=	Install API manpages (section 3, 7)
+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
+QUIC_DESC=	HTTP/3
+RC2_DESC=	RC2 (unsafe)
+RC4_DESC=	RC4 (unsafe)
+RC5_DESC=	RC5 (patented)
+RMD160_DESC=	RIPEMD-160
+RFC3779_DESC=	RFC3779 support (BGP)
+SCTP_DESC=	SCTP (Stream Control Transmission)
+SHARED_DESC=	Build shared libraries
+SM2_DESC=	SM2 Elliptic Curve DH (Chinese standard)
+SM3_DESC=	SM3 256bit (Chinese standard)
+SM4_DESC=	SM4 128bit (Chinese standard)
+SSE2_DESC=	Runtime SSE2 detection
+SSL3_DESC=	SSLv3 (unsafe)
+TLS1_DESC=	TLSv1.0 (requires TLS1_1, TLS1_2)
+TLS1_1_DESC=	TLSv1.1 (requires TLS1_2)
+TLS1_2_DESC=	TLSv1.2
+THREADPOOL_DESC=Thread Pooling support
+WEAK-SSL-CIPHERS_DESC=	Weak cipher support (unsafe)
+
+# Upstream default disabled options
+.for _option in brotli fips md2 ktls rc5 sctp ssl3 weak-ssl-ciphers zlib zstd
+${_option:tu}_CONFIGURE_ON=	enable-${_option}
+.endfor
+
+# Upstream default enabled options
+.for _option in aria asm async ct des gost idea md4 mdc2 legacy \
+	nextprotoneg quic 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
+
+BROTLI_CFLAGS=		-I${PREFIX}/include
+BROTLI_CONFIGURE_ON=	enable-brotli-dynamic
+BROTLI_LIB_DEPENDS=	libbrotlicommon.so:archivers/brotli
+EC_CONFIGURE_ON=	enable-ec_nistp_64_gcc_128
+FIPS_VARS=		shlibs+=lib/ossl-modules/fips.so
+I386_CONFIGURE_ON=	386
+KTLS_BROKEN=		Pending updated KTLS patch
+KTLS_EXTRA_PATCHES=	${FILESDIR}/extra-patch-ktls
+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
+THREADPOOL_CONFIGURE_OFF=	no-thread-pool
+ZLIB_CONFIGURE_ON=	zlib-dynamic
+ZSTD_CFLAGS=		-I${PREFIX}/include
+ZSTD_CONFIGURE_ON=	enable-zstd-dynamic
+ZSTD_LIB_DEPENDS=	libzstd.so:archivers/zstd
+
+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
+.endif
+
+.if ${OPSYS} == FreeBSD && ${OSVERSION} < 1300000 && !${PORT_OPTIONS:MCRYPTODEV}
+CONFIGURE_ARGS+=	no-devcryptoeng
+.endif
+
+OPENSSLDIR?=	${PREFIX}/openssl
+PLIST_SUB+=	OPENSSLDIR=${OPENSSLDIR:S=^${PREFIX}/==}
+
+.include "version.mk"
+
+.if ${PORT_OPTIONS:MASM}
+BROKEN_sparc64=	option ASM generates illegal instructions
+.endif
+
+post-patch:
+	${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} '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|^build_man_docs:.*|build_man_docs: $$(MANDOCS1) $$(MANDOCS5)|' \
+		-e 's|dummy $$(MANDOCS[37]); do |dummy; do |' \
+		${WRKSRC}/Makefile
+
+post-install-SHARED-on:
+.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 -not -type d ; \
+		find man/man7 -not -type d ) | sed 's/$$/.gz/' >> ${TMPPLIST}
+
+.include <bsd.port.post.mk>
diff --git a/security/openssl32/distinfo b/security/openssl32/distinfo
new file mode 100644
index 000000000000..fdbc91680cde
--- /dev/null
+++ b/security/openssl32/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1694097653
+SHA256 (openssl-3.2.0-alpha1.tar.gz) = 0cd196f1eb22c3c1401a2ec8e5fe3f3e8373a3db5ec398f957212c0b2e4f8e78
+SIZE (openssl-3.2.0-alpha1.tar.gz) = 17555904
diff --git a/security/openssl32/files/extra-patch-ktls b/security/openssl32/files/extra-patch-ktls
new file mode 100644
index 000000000000..8a46c272d95c
--- /dev/null
+++ b/security/openssl32/files/extra-patch-ktls
@@ -0,0 +1,540 @@
+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
+ 
+ typedef struct tls_enable ktls_crypto_info_t;
+ 
+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"
+ 
++#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 (!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;
++}
++
++/*
++ * 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;
++
++    count_unprocessed = count_unprocessed_records(s);
++    if (count_unprocessed < 0)
++        return 0;
++
++    /* 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"
+ 
+@@ -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
+     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,
+ }
+ 
+ /* 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;
++# 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
+     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,
+ }
+ 
+ /* 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)
+ {
+     unsigned char geniv[12];
+     unsigned char *iiv = iv;
+ 
++# ifdef OPENSSL_NO_KTLS_RX
++    if (!is_tx)
++        return 0;
++# endif
++
+     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;
+ # 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;
+         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;
+         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;
+ 
+     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;
+ 
++    /*
++     * 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;
++
+     do {
+         thisrr = &rr[num_recs];
+ 
+@@ -361,7 +366,9 @@ int ssl3_get_record(SSL *s)
+                     }
+                 }
+ 
+-                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)
+         }
+ 
+         if (SSL_IS_TLS13(s)) {
+-            if (thisrr->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) {
++            size_t len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH;
++
++            /* KTLS strips the inner record type. */
++            if (using_ktls)
++                len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
++
++            if (thisrr->length > len) {
+                 SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
+                          SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+                 return -1;
+@@ -409,7 +422,7 @@ int ssl3_get_record(SSL *s)
+ #endif
+ 
+             /* KTLS may use all of the buffer */
+-            if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left)
++            if (using_ktls)
+                 len = SSL3_BUFFER_get_left(rbuf);
+ 
+             if (thisrr->length > len) {
+@@ -518,11 +531,7 @@ int ssl3_get_record(SSL *s)
+         return 1;
+     }
+ 
+-    /*
+-     * KTLS reads full records. If there is any data left,
+-     * then it is from before enabling ktls
+-     */
+-    if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left)
++    if (using_ktls)
+         goto skip_decryption;
+ 
+     if (s->read_hash != NULL) {
+@@ -677,21 +686,29 @@ int ssl3_get_record(SSL *s)
+         if (SSL_IS_TLS13(s)
+                 && s->enc_read_ctx != NULL
+                 && thisrr->type != SSL3_RT_ALERT) {
+-            size_t end;
++            /*
++             * The following logic are irrelevant in KTLS: the kernel provides
++             * unprotected record and thus record type represent the actual
++             * content type, and padding is already removed and thisrr->type and
++             * thisrr->length should have the correct values.
++             */
++            if (!using_ktls) {
++                size_t end;
+ 
+-            if (thisrr->length == 0
+-                    || thisrr->type != SSL3_RT_APPLICATION_DATA) {
+-                SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
+-                goto end;
++                if (thisrr->length == 0
++                        || thisrr->type != SSL3_RT_APPLICATION_DATA) {
++                    SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
++                    goto end;
++                }
++
++                /* Strip trailing padding */
++                for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0;
++                     end--)
++                    continue;
++
++                thisrr->length = end;
++                thisrr->type = thisrr->data[end];
+             }
+-
+-            /* Strip trailing padding */
+-            for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0;
+-                 end--)
+-                continue;
+-
+-            thisrr->length = end;
+-            thisrr->type = thisrr->data[end];
+             if (thisrr->type != SSL3_RT_APPLICATION_DATA
+                     && thisrr->type != SSL3_RT_ALERT
+                     && thisrr->type != SSL3_RT_HANDSHAKE) {
+@@ -700,7 +717,7 @@ int ssl3_get_record(SSL *s)
+             }
+             if (s->msg_callback)
+                 s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE,
+-                                &thisrr->data[end], 1, s, s->msg_callback_arg);
++                                &thisrr->type, 1, s, s->msg_callback_arg);
+         }
+ 
+         /*
+@@ -723,8 +740,7 @@ int ssl3_get_record(SSL *s)
+          * Therefore we have to rely on KTLS to check the plaintext length
+          * limit in the kernel.
+          */
+-        if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH
+-                && (!BIO_get_ktls_recv(s->rbio) || is_ktls_left)) {
++        if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH && !using_ktls) {
+             SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
+             goto end;
+         }
+diff --git ssl/ssl_local.h ssl/ssl_local.h
+index 5471e900b8..79ced2f468 100644
+--- ssl/ssl_local.h
++++ ssl/ssl_local.h
+@@ -2760,9 +2760,9 @@ __owur int ssl_log_secret(SSL *ssl, const char *label,
+ /* 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,
++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);
+ #  endif
+diff --git ssl/t1_enc.c ssl/t1_enc.c
+index 237a19cd93..900ba14fbd 100644
+--- ssl/t1_enc.c
++++ ssl/t1_enc.c
+@@ -98,42 +98,6 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num)
+     return ret;
+ }
+ 
+-#ifndef OPENSSL_NO_KTLS
+- /*
+-  * 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.
+-  */
+-# ifndef OPENSSL_NO_KTLS_RX
+-static int count_unprocessed_records(SSL *s)
+-{
+-    SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+-    PACKET pkt, subpkt;
+-    int count = 0;
+-
+-    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;
+-}
+-# endif
+-#endif
+-
+-
+ int tls_provider_set_tls_params(SSL *s, EVP_CIPHER_CTX *ctx,
+                                 const EVP_CIPHER *ciph,
+                                 const EVP_MD *md)
+@@ -201,12 +165,7 @@ int tls1_change_cipher_state(SSL *s, int which)
+     int reuse_dd = 0;
+ #ifndef OPENSSL_NO_KTLS
+     ktls_crypto_info_t crypto_info;
+-    unsigned char *rec_seq;
+     void *rl_sequence;
+-# ifndef OPENSSL_NO_KTLS_RX
+-    int count_unprocessed;
+-    int bit;
+-# endif
+     BIO *bio;
+ #endif
+ 
+@@ -473,30 +432,11 @@ int tls1_change_cipher_state(SSL *s, int which)
+     else
+         rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer);
+ 
+-    if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq,
+-                               iv, key, ms, *mac_secret_size))
++    if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info,
++                               which & SSL3_CC_WRITE, iv, key, ms,
++                               *mac_secret_size))
+         goto skip_ktls;
+ 
+-    if (which & SSL3_CC_READ) {
+-# ifndef OPENSSL_NO_KTLS_RX
+-        count_unprocessed = count_unprocessed_records(s);
+-        if (count_unprocessed < 0)
+-            goto skip_ktls;
+-
+-        /* 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--;
+-        }
+-# else
+-        goto skip_ktls;
+-# endif
+-    }
+-
+     /* ktls works with user provided buffers directly */
+     if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) {
+         if (which & SSL3_CC_WRITE)
+diff --git ssl/tls13_enc.c ssl/tls13_enc.c
+index 12388922e3..eaab0e2a74 100644
+--- ssl/tls13_enc.c
++++ ssl/tls13_enc.c
+@@ -434,6 +434,7 @@ int tls13_change_cipher_state(SSL *s, int which)
+     const EVP_CIPHER *cipher = NULL;
+ #if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13)
+     ktls_crypto_info_t crypto_info;
++    void *rl_sequence;
+     BIO *bio;
+ #endif
+ 
+@@ -688,8 +689,7 @@ 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)
+-    if (!(which & SSL3_CC_WRITE)
+-            || !(which & SSL3_CC_APPLICATION)
++    if (!(which & SSL3_CC_APPLICATION)
+             || (s->options & SSL_OP_ENABLE_KTLS) == 0)
+         goto skip_ktls;
+ 
+@@ -705,7 +705,10 @@ int tls13_change_cipher_state(SSL *s, int which)
+     if (!ktls_check_supported_cipher(s, cipher, ciph_ctx))
+         goto skip_ktls;
+ 
+-    bio = s->wbio;
++    if (which & SSL3_CC_WRITE)
++        bio = s->wbio;
++    else
++        bio = s->rbio;
+ 
+     if (!ossl_assert(bio != NULL)) {
+         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+@@ -713,18 +716,26 @@ int tls13_change_cipher_state(SSL *s, int which)
+     }
+ 
+     /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
+-    if (BIO_flush(bio) <= 0)
+-        goto skip_ktls;
++    if (which & SSL3_CC_WRITE) {
++        if (BIO_flush(bio) <= 0)
++            goto skip_ktls;
++    }
+ 
+     /* configure kernel crypto structure */
+-    if (!ktls_configure_crypto(s, cipher, ciph_ctx,
+-                               RECORD_LAYER_get_write_sequence(&s->rlayer),
+-                               &crypto_info, NULL, iv, key, NULL, 0))
++    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(s, cipher, ciph_ctx, rl_sequence, &crypto_info,
++                               which & SSL3_CC_WRITE, 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);
++    if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) {
++        if (which & SSL3_CC_WRITE)
++            ssl3_release_write_buffer(s);
++    }
+ skip_ktls:
+ # endif
+ #endif
+diff --git test/sslapitest.c test/sslapitest.c
+index 2911d6e94b..faf2eec2bc 100644
+--- test/sslapitest.c
++++ test/sslapitest.c
+@@ -1243,7 +1243,7 @@ static int execute_test_ktls(int cis_ktls, int sis_ktls,
+ #if defined(OPENSSL_NO_KTLS_RX)
+     rx_supported = 0;
+ #else
+-    rx_supported = (tls_version != TLS1_3_VERSION);
++    rx_supported = 1;
+ #endif
+     if (!cis_ktls || !rx_supported) {
+         if (!TEST_false(BIO_get_ktls_recv(clientssl->rbio)))
diff --git a/security/openssl32/files/extra-patch-util_find-doc-nits b/security/openssl32/files/extra-patch-util_find-doc-nits
new file mode 100644
index 000000000000..bf70e9fee1ac
--- /dev/null
+++ b/security/openssl32/files/extra-patch-util_find-doc-nits
@@ -0,0 +1,20 @@
+--- util/find-doc-nits.orig	2023-09-07 09:00:22 UTC
++++ util/find-doc-nits
+@@ -80,7 +80,7 @@ my $temp = '/tmp/docnits.txt';
+ my $OUT;
+ my $status = 0;
+ 
+-$opt_m = "man1,man3,man5,man7" unless $opt_m;
++$opt_m = "man1,man5" unless $opt_m;
+ die "Argument of -m option may contain only man1, man3, man5, and/or man7"
+     unless $opt_m =~ /^(man[1357][, ]?)*$/;
+ my @sections = ( split /[, ]/, $opt_m );
+@@ -725,7 +725,7 @@ sub check {
+         next if $target eq '';                  # Skip if links within page, or
+         next if $target =~ /::/;                #   links to a Perl module, or
+         next if $target =~ /^https?:/;          #   is a URL link, or
+-        next if $target =~ /\([1357]\)$/;       #   it has a section
++        next if $target =~ /\([15]\)$/;       #   it has a section
+         err($id, "Missing man section number (likely, $mansect) in L<$target>")
+     }
+     # Check for proper links to commands.
diff --git a/security/openssl32/files/patch-Configurations_10-main.conf b/security/openssl32/files/patch-Configurations_10-main.conf
new file mode 100644
index 000000000000..82503c0ff90c
--- /dev/null
+++ b/security/openssl32/files/patch-Configurations_10-main.conf
@@ -0,0 +1,35 @@
+--- Configurations/10-main.conf.orig	2022-04-12 16:29:42 UTC
++++ Configurations/10-main.conf
+@@ -1069,6 +1069,32 @@ my %targets = (
+         perlasm_scheme   => "linux64",
+     },
+ 
++    "BSD-ppc" => {
++        inherit_from     => [ "BSD-generic32" ],
++        asm_arch         => 'ppc32',
++        perlasm_scheme   => "linux32",
++        lib_cppflags     => add("-DB_ENDIAN"),
++    },
++
++    "BSD-ppc64" => {
++        inherit_from     => [ "BSD-generic64" ],
++        cflags           => add("-m64"),
++        cxxflags         => add("-m64"),
++        lib_cppflags     => add("-DB_ENDIAN"),
++        asm_arch         => 'ppc64',
++        perlasm_scheme   => "linux64",
++    },
++
++    "BSD-ppc64le" => {
++        inherit_from     => [ "BSD-generic64" ],
++        cflags           => add("-m64"),
++        cxxflags         => add("-m64"),
++        lib_cppflags     => add("-DL_ENDIAN"),
++        asm_arch         => 'ppc64',
++        perlasm_scheme   => "linux64le",
++    },
++
++
+     "bsdi-elf-gcc" => {
+         inherit_from     => [ "BASE_unix" ],
+         CC               => "gcc",
diff --git a/security/openssl32/files/patch-crypto_threads__pthread.c b/security/openssl32/files/patch-crypto_threads__pthread.c
new file mode 100644
index 000000000000..3347170e0bd0
--- /dev/null
+++ b/security/openssl32/files/patch-crypto_threads__pthread.c
@@ -0,0 +1,13 @@
+--- crypto/threads_pthread.c.orig	2022-11-01 14:14:36 UTC
++++ crypto/threads_pthread.c
+@@ -29,6 +29,10 @@
+ #define BROKEN_CLANG_ATOMICS
+ #endif
+ 
++#if defined(__FreeBSD__) && defined(__i386__)
++#define BROKEN_CLANG_ATOMICS
++#endif
++
+ #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
+ 
+ # if defined(OPENSSL_SYS_UNIX)
diff --git a/security/openssl32/pkg-descr b/security/openssl32/pkg-descr
new file mode 100644
index 000000000000..c7704288547a
--- /dev/null
+++ b/security/openssl32/pkg-descr
@@ -0,0 +1,13 @@
+The OpenSSL Project is a collaborative effort to develop a robust,
+commercial-grade, full-featured, and Open Source toolkit implementing
+the Secure Sockets Layer (SSL v3) and Transport Layer Security (TLS v1,
+v1.1, v1.2, v1.3) protocols with full-strength cryptography world-wide.
+The project is managed by a worldwide community of volunteers that use
+the Internet to communicate, plan, and develop the OpenSSL tookit
+and its related documentation.
+
+OpenSSL is based on the excellent SSLeay library developed by Eric
+A. Young and Tim J. Hudson. The OpenSSL toolkit is licensed under
+an Apache-style licence, which basically means that you are free
+to get and use it for commercial and non-commercial purposes subject
+to some simple license conditions.
diff --git a/security/openssl32/pkg-message b/security/openssl32/pkg-message
new file mode 100644
index 000000000000..5bd0a73eafea
--- /dev/null
+++ b/security/openssl32/pkg-message
@@ -0,0 +1,20 @@
+[
+{ type: install
+  message: <<EOM
+
+This OpenSSL version is in an ALPHA stage
+
+Do NOT use for production!
+
+EOM
+}
+{ type: upgrade
+  message: <<EOM
+
+This OpenSSL version is in an ALPHA stage
+
+Do NOT use for production!
+
+EOM
+}
+]
diff --git a/security/openssl32/pkg-plist b/security/openssl32/pkg-plist
new file mode 100644
index 000000000000..bbb45b11ce26
--- /dev/null
+++ b/security/openssl32/pkg-plist
@@ -0,0 +1,277 @@
+bin/c_rehash
+bin/openssl
+include/openssl/aes.h
+include/openssl/asn1.h
+include/openssl/asn1_mac.h
+include/openssl/asn1err.h
+include/openssl/asn1t.h
+include/openssl/async.h
+include/openssl/asyncerr.h
+include/openssl/bio.h
+include/openssl/bioerr.h
+include/openssl/blowfish.h
+include/openssl/bn.h
+include/openssl/bnerr.h
+include/openssl/buffer.h
+include/openssl/buffererr.h
+include/openssl/camellia.h
+include/openssl/cast.h
+include/openssl/cmac.h
+include/openssl/cmp.h
+include/openssl/cmp_util.h
+include/openssl/cmperr.h
+include/openssl/cms.h
+include/openssl/cmserr.h
+include/openssl/comp.h
+include/openssl/comperr.h
+include/openssl/conf.h
+include/openssl/conf_api.h
+include/openssl/conferr.h
+include/openssl/configuration.h
+include/openssl/conftypes.h
+include/openssl/core.h
+include/openssl/core_dispatch.h
+include/openssl/core_names.h
+include/openssl/core_object.h
+include/openssl/crmf.h
+include/openssl/crmferr.h
+include/openssl/crypto.h
+include/openssl/cryptoerr.h
+include/openssl/cryptoerr_legacy.h
+include/openssl/ct.h
+include/openssl/cterr.h
*** 242 LINES SKIPPED ***