Page MenuHomeFreeBSD

D14634.id54990.diff
No OneTemporary

D14634.id54990.diff

Index: security/Makefile
===================================================================
--- security/Makefile
+++ security/Makefile
@@ -466,6 +466,7 @@
SUBDIR += openssh-askpass
SUBDIR += openssh-portable
SUBDIR += openssl
+ SUBDIR += openssl-chelsio
SUBDIR += openssl-unsafe
SUBDIR += openssl111
SUBDIR += openssl_tpm_engine
Index: security/openssl-chelsio/Makefile
===================================================================
--- /dev/null
+++ security/openssl-chelsio/Makefile
@@ -0,0 +1,157 @@
+# Created by: Dirk Froemberg <dirk@FreeBSD.org>
+# $FreeBSD$
+
+PORTNAME= openssl
+DISTVERSION= 1.1.1
+PORTREVISION= 3
+CATEGORIES= security devel
+MASTER_SITES= https://www.openssl.org/source/ \
+ ftp://ftp.cert.dfn.de/pub/tools/net/openssl/source/
+PKGNAMESUFFIX= -chelsio
+
+MAINTAINER= jhb@FreeBSD.org
+COMMENT= TLSv1.3 capable SSL and crypto library supporting Chelsio TLS offload
+
+LICENSE= OpenSSL
+LICENSE_FILE= ${WRKSRC}/LICENSE
+
+HAS_CONFIGURE= yes
+CONFIGURE_SCRIPT= config
+CONFIGURE_ENV= PERL="${PERL}"
+CONFIGURE_ARGS= --openssldir=${OPENSSLDIR}
+CONFIGURE_ARGS+= --prefix=${PREFIX}/openssl-chelsio
+
+USES= cpe perl5
+USE_PERL5= build
+TEST_TARGET= test
+
+LDFLAGS_i386= -Wl,-znotext
+#LDFLAGS= ${LDFLAGS_${ARCH}}
+
+MAKE_ARGS+= WHOLE_ARCHIVE_FLAG=--whole-archive CNF_LDFLAGS="${LDFLAGS}"
+MAKE_ENV+= LIBRPATH="${PREFIX}/openssl-chelsio/lib" GREP_OPTIONS=
+MAKE_ENV+= SHLIBVER=${OPENSSL_SHLIBVER}
+
+OPTIONS_GROUP= CIPHERS HASHES OPTIMIZE PROTOCOLS
+OPTIONS_GROUP_CIPHERS= ARIA DES GOST IDEA SM2 SM3 SM4 RC2 RC4 RC5
+OPTIONS_GROUP_HASHES= MD2 MD4 MDC2 RMD160
+OPTIONS_GROUP_OPTIMIZE= ASM SSE2 THREADS
+OPTIONS_DEFINE_i386= I386
+OPTIONS_GROUP_PROTOCOLS=NEXTPROTONEG SCTP SSL3 TLS1 TLS1_1 TLS1_2
+
+OPTIONS_DEFINE= ASYNC CT RFC3779 ZLIB
+
+OPTIONS_DEFAULT=ASM ASYNC CT GOST DES EC MD4 NEXTPROTONEG RC2 RC4 \
+ RMD160 SCTP SSE2 THREADS TLS1 TLS1_1 TLS1_2
+
+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
+CT_DESC= Certificate Transparency Support
+DES_DESC= (Triple) Data Encryption Standard
+EC_DESC= Optimize NIST elliptic curves
+GOST_DESC= GOST (Russian standard)
+HASHES_DESC= Hash Function Support
+I386_DESC= i386 (instead of i486+)
+IDEA_DESC= International Data Encryption Algorithm
+MD2_DESC= MD2 (obsolete)
+MD4_DESC= MD4 (unsafe)
+MDC2_DESC= MDC-2 (patented, requires DES)
+NEXTPROTONEG_DESC= Next Protocol Negotiation (SPDY)
+OPTIMIZE_DESC= Optimizations
+PROTOCOLS_DESC= Protocol Support
+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)
+SM2_DESC= SM2 (Chinese standard)
+SM3_DESC= SM3 (Chinese standard)
+SM4_DESC= SM4 (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
+ZLIB_DESC= zlib compression support
+
+# Upstream default disabled options
+.for _option in md2 rc5 sctp ssl3 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 \
+ rfc3779 rmd160 shared sm2 sm3 sm4 sse2 threads tls1 tls1_1 tls1_2
+${_option:tu}_CONFIGURE_OFF= no-${_option}
+.endfor
+
+MDC2_IMPLIES= DES
+TLS1_IMPLIES= TLS1_1
+TLS1_1_IMPLIES= TLS1_2
+
+EC_CONFIGURE_ON= enable-ec_nistp_64_gcc_128
+I386_CONFIGURE_ON= 386
+SSL3_CONFIGURE_ON+= enable-ssl3-method
+ZLIB_CONFIGURE_ON= zlib-dynamic
+
+.include <bsd.port.pre.mk>
+.if ${PREFIX} == /usr
+IGNORE= the OpenSSL port can not be installed over the base version
+.endif
+
+OPENSSLDIR= ${PREFIX}/openssl-chelsio
+PLIST_SUB+= OPENSSLDIR=${OPENSSLDIR:S=^${PREFIX}/==}
+PLIST_SUB+= SHLIBVER=${OPENSSL_SHLIBVER}
+CFLAGS+= -DCHELSIO_TLS_OFFLOAD -g
+
+.include "version.mk"
+
+.if ${PORT_OPTIONS:MASM}
+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' \
+ ${WRKSRC}/Configurations/unix-Makefile.tmpl
+ ${REINPLACE_CMD} -e 's|\^GNU ld|GNU|' ${WRKSRC}/Configurations/shared-info.pl
+
+post-configure:
+ ${REINPLACE_CMD} \
+ -e 's|SHLIB_VERSION_NUMBER=1.1|SHLIB_VERSION_NUMBER=${OPENSSL_SHLIBVER}|' \
+ ${WRKSRC}/Makefile
+ ${REINPLACE_CMD} \
+ -e 's|SHLIB_VERSION_NUMBER "1.1"|SHLIB_VERSION_NUMBER "${OPENSSL_SHLIBVER}"|' \
+ ${WRKSRC}/include/openssl/opensslv.h
+
+do-install:
+ ${MKDIR} ${STAGEDIR}${PREFIX}/openssl-chelsio/lib/engines-1.1
+.for i in libcrypto libssl
+ ${INSTALL_DATA} ${WRKSRC}/$i.so.${OPENSSL_SHLIBVER} ${STAGEDIR}${PREFIX}/openssl-chelsio/lib
+# ${STRIP_CMD} ${STAGEDIR}${PREFIX}/openssl-chelsio/lib/$i.so.${OPENSSL_SHLIBVER}
+.endfor
+.for i in capi padlock
+ ${INSTALL_DATA} ${WRKSRC}/engines/${i}.so ${STAGEDIR}${PREFIX}/openssl-chelsio/lib/engines-1.1
+ ${STRIP_CMD} ${STAGEDIR}${PREFIX}/openssl-chelsio/lib/engines-1.1/${i}.so
+.endfor
+ ${MKDIR} ${STAGEDIR}${OPENSSLDIR}/private
+ ${MKDIR} ${STAGEDIR}${OPENSSLDIR}/certs
+ ${INSTALL_DATA} ${WRKSRC}/apps/openssl.cnf ${STAGEDIR}${OPENSSLDIR}/openssl.cnf.dist
+ ${INSTALL_DATA} ${WRKSRC}/apps/ct_log_list.cnf ${STAGEDIR}${OPENSSLDIR}/ct_log_list.cnf.dist
+
+.include <bsd.port.post.mk>
Index: security/openssl-chelsio/distinfo
===================================================================
--- /dev/null
+++ security/openssl-chelsio/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1536741340
+SHA256 (openssl-1.1.1.tar.gz) = 2836875a0f89c03d0fdf483941512613a50cfb421d6fd94b9f41d7279d586a3d
+SIZE (openssl-1.1.1.tar.gz) = 8337920
Index: security/openssl-chelsio/files/patch-CVE-2018-0734
===================================================================
--- /dev/null
+++ security/openssl-chelsio/files/patch-CVE-2018-0734
@@ -0,0 +1,98 @@
+Timing vulnerability in DSA signature generation (CVE-2018-0734).
+
+Avoid a timing attack that leaks information via a side channel that
+triggers when a BN is resized. Increasing the size of the BNs
+prior to doing anything with them suppresses the attack.
+
+Thanks due to Samuel Weiser for finding and locating this.
+
+Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
+(Merged from #7486)
+
+(cherry picked from commit a9cfb8c)
+
+https://github.com/openssl/openssl/commit/8abfe72e8c1de1b95f50aa0d9134803b4d00070f
+--- crypto/dsa/dsa_ossl.c.orig 2018-09-11 12:48:21 UTC
++++ crypto/dsa/dsa_ossl.c
+@@ -9,6 +9,7 @@
+
+ #include <stdio.h>
+ #include "internal/cryptlib.h"
++#include "internal/bn_int.h"
+ #include <openssl/bn.h>
+ #include <openssl/sha.h>
+ #include "dsa_locl.h"
+@@ -178,9 +179,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
+ {
+ BN_CTX *ctx = NULL;
+ BIGNUM *k, *kinv = NULL, *r = *rp;
+- BIGNUM *l, *m;
++ BIGNUM *l;
+ int ret = 0;
+- int q_bits;
++ int q_bits, q_words;
+
+ if (!dsa->p || !dsa->q || !dsa->g) {
+ DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
+@@ -189,8 +190,7 @@ static int dsa_sign_setup(DSA *dsa, BN_C
+
+ k = BN_new();
+ l = BN_new();
+- m = BN_new();
+- if (k == NULL || l == NULL || m == NULL)
++ if (k == NULL || l == NULL)
+ goto err;
+
+ if (ctx_in == NULL) {
+@@ -201,9 +201,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
+
+ /* Preallocate space */
+ q_bits = BN_num_bits(dsa->q);
+- if (!BN_set_bit(k, q_bits)
+- || !BN_set_bit(l, q_bits)
+- || !BN_set_bit(m, q_bits))
++ q_words = bn_get_top(dsa->q);
++ if (!bn_wexpand(k, q_words + 2)
++ || !bn_wexpand(l, q_words + 2))
+ goto err;
+
+ /* Get random k */
+@@ -238,14 +238,17 @@ static int dsa_sign_setup(DSA *dsa, BN_C
+ * small timing information leakage. We then choose the sum that is
+ * one bit longer than the modulus.
+ *
+- * TODO: revisit the BN_copy aiming for a memory access agnostic
+- * conditional copy.
++ * There are some concerns about the efficacy of doing this. More
++ * specificly refer to the discussion starting with:
++ * https://github.com/openssl/openssl/pull/7486#discussion_r228323705
++ * The fix is to rework BN so these gymnastics aren't required.
+ */
+ if (!BN_add(l, k, dsa->q)
+- || !BN_add(m, l, dsa->q)
+- || !BN_copy(k, BN_num_bits(l) > q_bits ? l : m))
++ || !BN_add(k, l, dsa->q))
+ goto err;
+
++ BN_consttime_swap(BN_is_bit_set(l, q_bits), k, l, q_words + 2);
++
+ if ((dsa)->meth->bn_mod_exp != NULL) {
+ if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx,
+ dsa->method_mont_p))
+@@ -258,7 +261,7 @@ static int dsa_sign_setup(DSA *dsa, BN_C
+ if (!BN_mod(r, r, dsa->q, ctx))
+ goto err;
+
+- /* Compute part of 's = inv(k) (m + xr) mod q' */
++ /* Compute part of 's = inv(k) (m + xr) mod q' */
+ if ((kinv = BN_mod_inverse(NULL, k, dsa->q, ctx)) == NULL)
+ goto err;
+
+@@ -273,7 +276,6 @@ static int dsa_sign_setup(DSA *dsa, BN_C
+ BN_CTX_free(ctx);
+ BN_clear_free(k);
+ BN_clear_free(l);
+- BN_clear_free(m);
+ return ret;
+ }
+
Index: security/openssl-chelsio/files/patch-CVE-2018-0735
===================================================================
--- /dev/null
+++ security/openssl-chelsio/files/patch-CVE-2018-0735
@@ -0,0 +1,33 @@
+Timing vulnerability in ECDSA signature generation (CVE-2018-0735)
+
+Preallocate an extra limb for some of the big numbers to avoid a reallocation
+that can potentially provide a side channel.
+
+Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
+(Merged from #7486)
+
+(cherry picked from commit 99540ec)
+
+https://www.openssl.org/news/secadv/20181029.txt
+--- crypto/ec/ec_mult.c.orig 2018-09-11 12:48:21 UTC
++++ crypto/ec/ec_mult.c
+@@ -206,8 +206,8 @@ int ec_scalar_mul_ladder(const EC_GROUP
+ */
+ cardinality_bits = BN_num_bits(cardinality);
+ group_top = bn_get_top(cardinality);
+- if ((bn_wexpand(k, group_top + 1) == NULL)
+- || (bn_wexpand(lambda, group_top + 1) == NULL)) {
++ if ((bn_wexpand(k, group_top + 2) == NULL)
++ || (bn_wexpand(lambda, group_top + 2) == NULL)) {
+ ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ goto err;
+ }
+@@ -244,7 +244,7 @@ int ec_scalar_mul_ladder(const EC_GROUP
+ * k := scalar + 2*cardinality
+ */
+ kbit = BN_is_bit_set(lambda, cardinality_bits);
+- BN_consttime_swap(kbit, k, lambda, group_top + 1);
++ BN_consttime_swap(kbit, k, lambda, group_top + 2);
+
+ group_top = bn_get_top(group->field);
+ if ((bn_wexpand(s->X, group_top) == NULL)
Index: security/openssl-chelsio/files/patch-chelsio-toe
===================================================================
--- /dev/null
+++ security/openssl-chelsio/files/patch-chelsio-toe
@@ -0,0 +1,1051 @@
+diff --git crypto/bio/bss_conn.c crypto/bio/bss_conn.c
+index e9673fe783..20131de7e0 100644
+--- crypto/bio/bss_conn.c
++++ crypto/bio/bss_conn.c
+@@ -11,6 +11,7 @@
+ #include <errno.h>
+
+ #include "bio_lcl.h"
++#include "ssl/ssl_ofld.h"
+
+ #ifndef OPENSSL_NO_SOCK
+
+@@ -179,6 +180,28 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
+ goto exit_loop;
+ } else {
+ c->state = BIO_CONN_S_OK;
++#ifdef CHELSIO_TLS_OFFLOAD
++ int mode, rc;
++#ifdef __linux__
++ rc = ioctl(b->num, IOCTL_TLSOM_GET_TLS_TOM, &mode);
++ if (!rc && mode)
++ BIO_set_chofld_flag(b);
++#else
++ socklen_t optlen;
++ optlen = sizeof(mode);
++ rc = getsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_GET_TLS_TOM,
++ &mode, &optlen);
++ if (rc == 0) {
++ switch (mode) {
++ case TLS_TOM_BOTH:
++ case TLS_TOM_TXONLY:
++ /* For TXONLY, chssl_program_hwkey_context will DTRT. */
++ BIO_set_chofld_flag(b);
++ break;
++ }
++ }
++#endif
++#endif
+ }
+ break;
+
+@@ -343,6 +366,9 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+ const char **pptr = NULL;
+ long ret = 1;
+ BIO_CONNECT *data;
++#ifdef CHELSIO_TLS_OFFLOAD
++ struct tls_key_context *key_context;
++#endif
+
+ data = (BIO_CONNECT *)b->ptr;
+
+@@ -488,6 +514,37 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+ *fptr = data->info_callback;
+ }
+ break;
++ case BIO_CTRL_GET_OFFLOAD_TX:
++ return BIO_should_offload_tx_flag(b);
++ case BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG:
++ BIO_set_offload_tx_ctrl_msg_flag(b);
++ b->ptr = (void *)num;
++ ret = 0;
++ break;
++ case BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG:
++ BIO_clear_offload_tx_ctrl_msg_flag(b);
++ ret = 0;
++ break;
++ case BIO_CTRL_GET_OFFLOAD_RX:
++ return BIO_should_offload_rx_flag(b);
++#ifdef CHELSIO_TLS_OFFLOAD
++ case BIO_CTRL_SET_OFFLOAD_KEY:
++ key_context = (struct tls_key_context *)ptr;
++#ifdef __linux__
++ ret = ioctl(b->num, IOCTL_TLSOM_SET_TLS_CONTEXT, key_context);
++#else
++ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_SET_TLS_CONTEXT,
++ key_context, sizeof(*key_context));
++#endif
++ break;
++ case BIO_CTRL_SET_OFFLOAD_CLEAR_KEY:
++#ifdef __linux__
++ ret = ioctl(b->num, IOCTL_TLSOM_CLR_TLS_TOM);
++#else
++ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_CLR_TLS_TOM, NULL, 0);
++#endif
++ break;
++#endif
+ default:
+ ret = 0;
+ break;
+diff --git crypto/bio/bss_sock.c crypto/bio/bss_sock.c
+index ad38453201..4a0e2a46d4 100644
+--- crypto/bio/bss_sock.c
++++ crypto/bio/bss_sock.c
+@@ -11,6 +11,7 @@
+ #include <errno.h>
+ #include "bio_lcl.h"
+ #include "internal/cryptlib.h"
++#include "ssl/ssl_ofld.h"
+
+ #ifndef OPENSSL_NO_SOCK
+
+@@ -124,6 +125,9 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+ long ret = 1;
+ int *ip;
++#ifdef CHELSIO_TLS_OFFLOAD
++ struct tls_key_context *key_context;
++#endif
+
+ switch (cmd) {
+ case BIO_C_SET_FD:
+@@ -131,6 +135,30 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+ b->num = *((int *)ptr);
+ b->shutdown = (int)num;
+ b->init = 1;
++#ifdef CHELSIO_TLS_OFFLOAD
++ {
++ int mode, rc;
++#ifdef __linux__
++ rc = ioctl(b->num, IOCTL_TLSOM_GET_TLS_TOM, &mode);
++ if (!rc && mode)
++ BIO_set_chofld_flag(b);
++#else
++ socklen_t optlen;
++ optlen = sizeof(mode);
++ rc = getsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_GET_TLS_TOM, &mode,
++ &optlen);
++ if (rc == 0) {
++ switch (mode) {
++ case TLS_TOM_BOTH:
++ case TLS_TOM_TXONLY:
++ /* For TXONLY, chssl_program_hwkey_context will DTRT. */
++ BIO_set_chofld_flag(b);
++ break;
++ }
++ }
++#endif
++ }
++#endif
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+@@ -151,6 +179,37 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
++ case BIO_CTRL_GET_OFFLOAD_TX:
++ return BIO_should_offload_tx_flag(b);
++ case BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG:
++ BIO_set_offload_tx_ctrl_msg_flag(b);
++ b->ptr = (void *)num;
++ ret = 0;
++ break;
++ case BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG:
++ BIO_clear_offload_tx_ctrl_msg_flag(b);
++ ret = 0;
++ break;
++ case BIO_CTRL_GET_OFFLOAD_RX:
++ return BIO_should_offload_rx_flag(b);
++#ifdef CHELSIO_TLS_OFFLOAD
++ case BIO_CTRL_SET_OFFLOAD_KEY:
++ key_context = (struct tls_key_context *)ptr;
++#ifdef __linux__
++ ret = ioctl(b->num, IOCTL_TLSOM_SET_TLS_CONTEXT, key_context);
++#else
++ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_SET_TLS_CONTEXT,
++ key_context, sizeof(*key_context));
++#endif
++ break;
++ case BIO_CTRL_SET_OFFLOAD_CLEAR_KEY:
++#ifdef __linux__
++ ret = ioctl(b->num, IOCTL_TLSOM_CLR_TLS_TOM);
++#else
++ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_CLR_TLS_TOM, NULL, 0);
++#endif
++ break;
++#endif
+ default:
+ ret = 0;
+ break;
+diff --git include/openssl/bio.h include/openssl/bio.h
+index 2888b42da8..38a3cabad1 100644
+--- include/openssl/bio.h
++++ include/openssl/bio.h
+@@ -144,6 +144,14 @@ extern "C" {
+ # endif
+
+ # define BIO_CTRL_DGRAM_SET_PEEK_MODE 71
++# define BIO_CTRL_SET_OFFLOAD_TX 72
++# define BIO_CTRL_GET_OFFLOAD_TX 73
++# define BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG 74
++# define BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG 75
++# define BIO_CTRL_SET_OFFLOAD_RX 76
++# define BIO_CTRL_GET_OFFLOAD_RX 77
++# define BIO_CTRL_SET_OFFLOAD_KEY 78
++# define BIO_CTRL_SET_OFFLOAD_CLEAR_KEY 79
+
+ /* modifiers */
+ # define BIO_FP_READ 0x02
+@@ -174,6 +182,16 @@ extern "C" {
+ # define BIO_FLAGS_MEM_RDONLY 0x200
+ # define BIO_FLAGS_NONCLEAR_RST 0x400
+
++/*
++ * This is used with socket BIOs:
++ * BIO_FLAGS_OFFLOAD_TX means we are using offload with this BIO for TX.
++ * BIO_FLAGS_OFFLOAD_TX_CTRL_MSG means we are about to send a ctrl message next.
++ */
++#define BIO_FLAGS_OFFLOAD_TX 0x2000
++#define BIO_FLAGS_OFFLOAD_TX_CTRL_MSG 0x4000
++#define BIO_FLAGS_OFFLOAD_RX 0x8000
++#define BIO_FLAGS_CHOFLD_INLINE 0x10000
++
+ typedef union bio_addr_st BIO_ADDR;
+ typedef struct bio_addrinfo_st BIO_ADDRINFO;
+
+@@ -189,6 +207,25 @@ void BIO_clear_flags(BIO *b, int flags);
+ BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+ # define BIO_set_retry_write(b) \
+ BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
++/* Offload related controls and flags */
++# define BIO_set_offload_tx_flag(b) \
++ BIO_set_flags(b, BIO_FLAGS_OFFLOAD_TX)
++# define BIO_should_offload_tx_flag(b) \
++ BIO_test_flags(b, BIO_FLAGS_OFFLOAD_TX)
++# define BIO_set_offload_tx_ctrl_msg_flag(b) \
++ BIO_set_flags(b, BIO_FLAGS_OFFLOAD_TX_CTRL_MSG)
++# define BIO_should_offload_tx_ctrl_msg_flag(b) \
++ BIO_test_flags(b, (BIO_FLAGS_OFFLOAD_TX_CTRL_MSG))
++# define BIO_clear_offload_tx_ctrl_msg_flag(b) \
++ BIO_clear_flags(b, (BIO_FLAGS_OFFLOAD_TX_CTRL_MSG))
++# define BIO_set_offload_rx_flag(b) \
++ BIO_set_flags(b, BIO_FLAGS_OFFLOAD_RX)
++# define BIO_should_offload_rx_flag(b) \
++ BIO_test_flags(b, BIO_FLAGS_OFFLOAD_RX)
++# define BIO_set_chofld_flag(b) \
++ BIO_set_flags(b, BIO_FLAGS_CHOFLD_INLINE)
++# define BIO_get_chofld_flag(b) \
++ BIO_test_flags(b, BIO_FLAGS_CHOFLD_INLINE)
+
+ /* These are normally used internally in BIOs */
+ # define BIO_clear_retry_flags(b) \
+@@ -380,6 +417,22 @@ struct bio_dgram_sctp_prinfo {
+ # define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2))
+ # define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL)
+ # define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL)
++# define BIO_set_offload_tx(b, keyblob) \
++ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_TX, 0, keyblob)
++# define BIO_get_offload_tx(b) \
++ BIO_ctrl(b, BIO_CTRL_GET_OFFLOAD_TX, 0, NULL)
++# define BIO_set_offload_tx_ctrl_msg(b, record_type) \
++ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG, record_type, NULL)
++# define BIO_clear_offload_tx_ctrl_msg(b) \
++ BIO_ctrl(b, BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG, 0, NULL)
++# define BIO_set_offload_rx(b, keyblob) \
++ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_RX, 0, keyblob)
++# define BIO_get_offload_rx(b) \
++ BIO_ctrl(b, BIO_CTRL_GET_OFFLOAD_RX, 0, NULL)
++# define BIO_set_offload_key(b, keyblob) \
++ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_KEY, 0, keyblob)
++# define BIO_set_offload_clear_key(b) \
++ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_CLEAR_KEY, 0, NULL)
+
+ /* BIO_s_accept() */
+ # define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \
+diff --git include/openssl/ssl.h include/openssl/ssl.h
+index 0a18a43544..82ac6fd093 100644
+--- include/openssl/ssl.h
++++ include/openssl/ssl.h
+@@ -1069,6 +1069,7 @@ int SSL_is_init_finished(const SSL *s);
+ # define SSL_ST_READ_HEADER 0xF0
+ # define SSL_ST_READ_BODY 0xF1
+ # define SSL_ST_READ_DONE 0xF2
++# define SSL_ST_READ_ERROR 0xF3
+
+ /*-
+ * Obtain latest Finished message
+diff --git ssl/build.info ssl/build.info
+index bb2f1deb53..bbd8c2db7f 100644
+--- ssl/build.info
++++ ssl/build.info
+@@ -11,5 +11,6 @@ SOURCE[../libssl]=\
+ ssl_ciph.c ssl_stat.c ssl_rsa.c \
+ ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \
+ bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \
++ ssl_ofld.c \
+ record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
+ statem/statem.c record/ssl3_record_tls13.c
+diff --git ssl/record/rec_layer_s3.c ssl/record/rec_layer_s3.c
+index 6d495715b2..1ce19d31e4 100644
+--- ssl/record/rec_layer_s3.c
++++ ssl/record/rec_layer_s3.c
+@@ -797,7 +797,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ }
+
+ /* Explicit IV length, block ciphers appropriate version flag */
+- if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)) {
++ if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)
++ && !BIO_get_offload_tx(s->wbio)) {
+ int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+ if (mode == EVP_CIPH_CBC_MODE) {
+ /* TODO(size_t): Convert me */
+@@ -951,7 +952,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ * in the wb->buf
+ */
+
+- if (!SSL_WRITE_ETM(s) && mac_size != 0) {
++ if (!SSL_WRITE_ETM(s) && mac_size != 0
++ && !BIO_get_offload_tx(s->wbio)) {
+ unsigned char *mac;
+
+ if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+@@ -999,7 +1001,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ }
+ goto err;
+ }
+- } else {
++ } else if (!BIO_get_offload_tx(s->wbio)) {
+ if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1) {
+ if (!ossl_statem_in_error(s)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
+@@ -1149,6 +1151,9 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len,
+ (unsigned int)SSL3_BUFFER_get_left(&wb[currbuf]));
+ if (i >= 0)
+ tmpwrit = i;
++
++ if (BIO_get_offload_tx(s->wbio) && type != SSL3_RT_APPLICATION_DATA)
++ (void)BIO_flush(s->wbio);
+ } else {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_WRITE_PENDING,
+ SSL_R_BIO_NOT_SET);
+diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c
+index e59ac5a676..26c8c5f692 100644
+--- ssl/record/ssl3_record.c
++++ ssl/record/ssl3_record.c
+@@ -225,6 +225,11 @@ int ssl3_get_record(SSL *s)
+ ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
++
++ if (BIO_get_offload_rx(s->rbio) && (*p == 0x7F)) {
++ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_ERROR);
++ }
++
+ /*
+ * The first record received by the server may be a V2ClientHello.
+ */
+@@ -393,6 +398,18 @@ int ssl3_get_record(SSL *s)
+ }
+ }
+
++ if (BIO_get_offload_rx(s->rbio) &&
++ RECORD_LAYER_get_rstate(&s->rlayer) == SSL_ST_READ_ERROR) {
++ i = rr[num_recs].length;
++ rret = ssl3_read_n(s, i, i, 1, 0, &n);
++ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
++ if (rret <= 0)
++ return (rret);
++ SSLfatal(s, SSL_AD_BAD_RECORD_MAC, SSL_F_SSL3_GET_RECORD,
++ SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
++ return -1;
++ }
++
+ /*
+ * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
+ * Calculate how much more data we need to read for the rest of the
+@@ -495,7 +512,7 @@ int ssl3_get_record(SSL *s)
+ * If in encrypt-then-mac mode calculate mac from encrypted record. All
+ * the details below are public so no timing details can leak.
+ */
+- if (SSL_READ_ETM(s) && s->read_hash) {
++ if (SSL_READ_ETM(s) && s->read_hash && !BIO_get_offload_rx(s->rbio)) {
+ unsigned char *mac;
+ /* TODO(size_t): convert this to do size_t properly */
+ imac_size = EVP_MD_CTX_size(s->read_hash);
+@@ -526,7 +543,11 @@ int ssl3_get_record(SSL *s)
+
+ first_rec_len = rr[0].length;
+
+- enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0);
++ if (BIO_get_offload_rx(s->rbio)) {
++ enc_err = 1;
++ } else {
++ enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0);
++ }
+
+ /*-
+ * enc_err is:
+@@ -576,6 +597,7 @@ int ssl3_get_record(SSL *s)
+ /* r->length is now the compressed data plus mac */
+ if ((sess != NULL) &&
+ (s->enc_read_ctx != NULL) &&
++ !BIO_get_offload_rx(s->rbio) &&
+ (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)) {
+ /* s->read_hash != NULL => mac_size != -1 */
+ unsigned char *mac = NULL;
+diff --git ssl/s3_msg.c ssl/s3_msg.c
+index 42382547fb..a3d549604b 100644
+--- ssl/s3_msg.c
++++ ssl/s3_msg.c
+@@ -8,6 +8,7 @@
+ */
+
+ #include "ssl_locl.h"
++#include "ssl_ofld.h"
+
+ int ssl3_do_change_cipher_spec(SSL *s)
+ {
+@@ -33,6 +34,18 @@ int ssl3_do_change_cipher_spec(SSL *s)
+ if (!s->method->ssl3_enc->change_cipher_state(s, i))
+ return 0;
+
++#ifdef CHELSIO_TLS_OFFLOAD
++ if (!s->server) {
++ if (s->wbio) {
++ chssl_program_hwkey_context(s, SSL3_CC_READ, SSL_ST_CONNECT);
++ }
++ } else {
++ if (s->wbio) {
++ chssl_program_hwkey_context(s, SSL3_CC_READ, SSL_ST_ACCEPT);
++ }
++ }
++#endif
++
+ return 1;
+ }
+
+diff --git ssl/ssl_ofld.c ssl/ssl_ofld.c
+new file mode 100644
+index 0000000000..ba372e2d99
+--- /dev/null
++++ ssl/ssl_ofld.c
+@@ -0,0 +1,413 @@
++/*
++ * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
++ *
++ * Licensed under the OpenSSL license (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 <stdio.h>
++#include <sys/socket.h>
++#include <sys/ioctl.h>
++#include <openssl/bio.h>
++#include <openssl/ossl_typ.h>
++#include <openssl/comp.h>
++#include <openssl/evp.h>
++#include <openssl/kdf.h>
++#include <openssl/rand.h>
++#include "ssl_locl.h"
++#include "ssl_ofld.h"
++
++#ifdef CHELSIO_TLS_OFFLOAD
++int CHSSL_EVP_Digest(const void *data,
++ void *md, unsigned long algorithm_mac)
++{
++ unsigned char *temp = md;
++ int ret = 1, i;
++
++ if (algorithm_mac == SSL_SHA1){
++ SHA_CTX sha1ctx;
++
++ SHA1_Init(&sha1ctx);
++ SHA1_Update(&sha1ctx, data, SHA_CBLOCK);
++ l2n(sha1ctx.h0, temp);
++ l2n(sha1ctx.h1, temp);
++ l2n(sha1ctx.h2, temp);
++ l2n(sha1ctx.h3, temp);
++ l2n(sha1ctx.h4, temp);
++ } else if (algorithm_mac == SSL_SHA256) {
++ SHA256_CTX sha256ctx;
++ SHA256_Init(&sha256ctx);
++ SHA256_Update(&sha256ctx, data, SHA256_CBLOCK);
++
++ for (i = 0; i < SHA256_DIGEST_LENGTH / 4; i++)
++ l2n(sha256ctx.h[i], temp);
++ } else if (algorithm_mac == SSL_SHA384) {
++ SHA512_CTX sha384ctx;
++
++ SHA384_Init(&sha384ctx);
++ SHA384_Update(&sha384ctx, data, SHA512_BLOCK);
++
++ for (i = 0; i < SHA512_DIGEST_LENGTH / 8; i++)
++ l2n8(sha384ctx.h[i], temp);
++ }
++
++ return ret;
++}
++
++static int tls_ofld_enc_mac(SSL *s)
++{
++ const EVP_CIPHER *p;
++ const SSL_CIPHER *c;
++
++ c = s->s3->tmp.new_cipher;
++ p = s->s3->tmp.new_sym_enc;
++
++ switch(c->algorithm_enc) {
++ case SSL_AES128GCM:
++ case SSL_AES256GCM:
++ return TLS_OFLD_TRUE;
++
++ case SSL_AES128 :
++ case SSL_AES256 :
++ switch(EVP_CIPHER_mode(p)) {
++ case EVP_CIPH_CTR_MODE:
++ case EVP_CIPH_CBC_MODE:
++ break;
++ default:
++ return TLS_OFLD_FALSE;
++ }
++ break;
++
++ case SSL_eNULL:
++ break;
++
++ default:
++ return TLS_OFLD_FALSE;
++ }
++
++ switch(c->algorithm_mac) {
++ case SSL_SHA1:
++ case SSL_SHA256:
++ case SSL_SHA384:
++ break;
++
++ default:
++ /* Revert enc mode to non-offload */
++ return TLS_OFLD_FALSE;
++ }
++ return TLS_OFLD_TRUE;
++}
++
++static unsigned char get_auth_mode(SSL *s)
++{
++ const SSL_CIPHER *c = s->s3->tmp.new_cipher;
++
++ if(c==NULL) return CHSSL_SHA_NOP;
++
++ switch(c->algorithm_mac) {
++ case SSL_SHA1:
++ return CHSSL_SHA1;
++ case SSL_SHA256:
++ return CHSSL_SHA256;
++ case SSL_SHA384:
++ return CHSSL_SHA512_384;
++ case SSL_AEAD:
++ return CHSSL_GHASH;
++ default:
++ return CHSSL_SHA_NOP;
++ }
++}
++
++/*
++ * Cipher Mode expected by HW
++ */
++static unsigned char get_cipher_mode(SSL *s)
++{
++ const EVP_CIPHER *c = s->s3->tmp.new_sym_enc;
++
++ switch(EVP_CIPHER_mode(c)) {
++ case EVP_CIPH_CBC_MODE:
++ return CHSSL_AES_CBC;
++ case EVP_CIPH_GCM_MODE:
++ return CHSSL_AES_GCM;
++ case EVP_CIPH_CTR_MODE:
++ return CHSSL_AES_CTR;
++ case EVP_CIPH_STREAM_CIPHER:
++ return CHSSL_CIPH_NOP;
++ default:
++ return CHSSL_CIPH_NOP;
++ }
++}
++
++/*
++ * H/W requires Partial Hash of opad and ipad. This function create
++ * ipad, opad block using key and generates partial result
++ */
++static void chssl_compute_ipad_opad(unsigned char *key,
++ unsigned char *ipad,
++ unsigned char *opad,
++ int k, unsigned long algorithm_mac)
++{
++ int i, blksize;
++ char iblock[SHA512_BLOCK] = {0};
++ char oblock[SHA512_BLOCK] = {0};
++
++ if (algorithm_mac == SSL_SHA384)
++ blksize = SHA512_CBLOCK;
++ else
++ blksize = SHA256_CBLOCK;
++ memset (iblock + k, 0x36, blksize - k);
++ memset (oblock + k, 0x5c, blksize - k);
++ for(i = 0; i < k; i++) {
++ iblock[i] = key[i] ^ 0x36;
++ oblock[i] = key[i] ^ 0x5c;
++ }
++ CHSSL_EVP_Digest(iblock, ipad, algorithm_mac);
++ CHSSL_EVP_Digest(oblock, opad, algorithm_mac);
++}
++
++static void chssl_compute_cipher_key(unsigned char *key,
++ int key_len,
++ unsigned char *ghash)
++{
++ int len,len1;
++ EVP_CIPHER_CTX *ctx;
++ unsigned char plaintext[GHASH_SIZE] = {0};
++
++ ctx = EVP_CIPHER_CTX_new();
++ EVP_CIPHER_CTX_reset(ctx);
++ if(key_len == 16)
++ EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, NULL);
++ else
++ EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, NULL);
++ EVP_CIPHER_CTX_set_padding(ctx, 0);
++ EVP_EncryptUpdate(ctx, ghash, &len, plaintext, 16);
++ EVP_EncryptFinal_ex(ctx, ghash+len, &len1);
++ EVP_CIPHER_CTX_reset(ctx);
++ EVP_CIPHER_CTX_free(ctx);
++}
++
++/*
++ * Create key Context for receive/transmit and program on HW
++ */
++static int ssl_key_context(SSL *s, struct tls_key_context *kctx, int rw, int state)
++{
++ const EVP_CIPHER *c;
++ unsigned int mac_key_size = 0, cipher_key_size, iv_size;
++ unsigned char *key;
++ unsigned char s_ipad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */
++ unsigned char s_opad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */
++ unsigned char c_ipad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */
++ unsigned char c_opad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */
++
++ unsigned char s_mac_key[MAX_MAC_KSZ] = {0x0};
++ unsigned char c_mac_key[MAX_MAC_KSZ] = {0x0};
++ unsigned char s_key[MAX_CIPHER_KSZ] = {0x0};
++ unsigned char c_key[MAX_CIPHER_KSZ] = {0x0};
++ unsigned char s_iv[MAX_CIPHER_KSZ] = {0x0};
++ unsigned char c_iv[MAX_CIPHER_KSZ] = {0x0};
++ unsigned char ghash[GHASH_SIZE] = {0x0};
++ int pad = 12;
++ int index = 0;
++ int ret = 0;
++
++ if (!tls_ofld_enc_mac(s) || s->version < TLS1_VERSION) {
++ return ret;
++ }
++
++ if (rw == SSL3_CC_READ && SSL_READ_ETM(s))
++ return ret;
++ else if (rw == SSL3_CC_WRITE && SSL_WRITE_ETM(s))
++ return ret;
++
++ c = s->s3->tmp.new_sym_enc;
++ kctx->l_p_key = rw;
++
++ if (s->new_session)
++ kctx->l_p_key |= F_KEY_CLR_LOC;
++ key = s->s3->tmp.key_block;
++
++ mac_key_size = s->s3->tmp.new_mac_secret_size;
++
++ kctx->mac_secret_size = mac_key_size;
++
++ cipher_key_size = EVP_CIPHER_key_length(c);
++ kctx->cipher_secret_size = cipher_key_size;
++
++ iv_size = (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) ?
++ EVP_GCM_TLS_FIXED_IV_LEN:
++ EVP_CIPHER_iv_length(c);
++ kctx->iv_size = iv_size;
++ kctx->iv_ctrl = 1;
++ kctx->iv_algo = 0;
++
++ if ((mac_key_size == SHA256_DIGEST_LENGTH) ||
++ (mac_key_size == SHA384_DIGEST_LENGTH))
++ pad = 0;
++
++ if (mac_key_size) {
++ memcpy(c_mac_key, key, mac_key_size);
++ key += mac_key_size;
++ memcpy(s_mac_key, key, mac_key_size);
++ key += mac_key_size;
++ }
++ memcpy(c_key, key, cipher_key_size);
++ key += cipher_key_size;
++ memcpy(s_key, key, cipher_key_size);
++ key += cipher_key_size;
++
++ memcpy(c_iv, key, iv_size);
++ key += iv_size;
++ memcpy(s_iv, key, iv_size);
++
++ if ((EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE)) {
++ /* IPAD/OPAD for SHA384/512 calculated over 128B block */
++ chssl_compute_ipad_opad(c_mac_key, c_ipad_hash,
++ c_opad_hash, mac_key_size,
++ s->s3->tmp.new_cipher->algorithm_mac);
++ chssl_compute_ipad_opad(s_mac_key, s_ipad_hash,
++ s_opad_hash, mac_key_size,
++ s->s3->tmp.new_cipher->algorithm_mac);
++ }
++
++ if (state == SSL_ST_ACCEPT) {
++ memcpy(kctx->tx.key, s_key, cipher_key_size);
++ memcpy(kctx->rx.key, c_key, cipher_key_size);
++ } else {
++ memcpy(kctx->tx.key, c_key, cipher_key_size);
++ memcpy(kctx->rx.key, s_key, cipher_key_size);
++ }
++
++ if (mac_key_size == SHA384_DIGEST_LENGTH) mac_key_size = MAX_MAC_KSZ;
++ index = cipher_key_size;
++ if (mac_key_size) {
++ if (state == SSL_ST_ACCEPT)
++ memcpy(kctx->tx.key+index, s_ipad_hash, mac_key_size);
++ else
++ memcpy(kctx->tx.key+index, c_ipad_hash, mac_key_size);
++
++ index += (mac_key_size + pad);
++ if (state == SSL_ST_ACCEPT)
++ memcpy(kctx->tx.key+index, s_opad_hash, mac_key_size);
++ else
++ memcpy(kctx->tx.key+index, c_opad_hash, mac_key_size);
++
++ index += (mac_key_size + pad);
++ } else {
++ if (state == SSL_ST_ACCEPT) {
++ chssl_compute_cipher_key(s_key, cipher_key_size, ghash);
++ memcpy(kctx->tx.key+index, ghash, GHASH_SIZE);
++ } else {
++ chssl_compute_cipher_key(c_key, cipher_key_size, ghash);
++ memcpy(kctx->tx.key+index, ghash, GHASH_SIZE);
++ }
++ index += GHASH_SIZE;
++ }
++ kctx->tx_key_info_size = TLS_TX_HDR_SZ + index;
++ index = cipher_key_size;
++ if (mac_key_size) {
++ if (state == SSL_ST_ACCEPT)
++ memcpy(kctx->rx.key+index, c_ipad_hash, mac_key_size);
++ else
++ memcpy(kctx->rx.key+index, s_ipad_hash, mac_key_size);
++
++ index += (mac_key_size + pad);
++ if (state == SSL_ST_ACCEPT)
++ memcpy(kctx->rx.key+index, c_opad_hash, mac_key_size);
++ else
++ memcpy(kctx->rx.key+index, s_opad_hash, mac_key_size);
++
++ index += (mac_key_size + pad);
++ } else {
++ if (state == SSL_ST_ACCEPT) {
++ chssl_compute_cipher_key(c_key, cipher_key_size, ghash);
++ memcpy(kctx->rx.key+index, ghash, GHASH_SIZE);
++ } else {
++ chssl_compute_cipher_key(s_key, cipher_key_size, ghash);
++ memcpy(kctx->rx.key+index, ghash, GHASH_SIZE);
++ }
++ index += GHASH_SIZE;
++ }
++
++ kctx->tx_key_info_size = TLS_RX_HDR_SZ + index;
++
++ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
++ if (state == SSL_ST_ACCEPT) {
++ memcpy(kctx->tx.salt, s_iv, SALT_SIZE);
++ memcpy(kctx->rx.salt, c_iv, SALT_SIZE);
++ } else {
++ memcpy(kctx->tx.salt, c_iv, SALT_SIZE);
++ memcpy(kctx->rx.salt, s_iv, SALT_SIZE);
++ }
++ }
++
++ kctx->proto_ver = s->version;
++ kctx->state.auth_mode = get_auth_mode(s);
++ kctx->state.enc_mode = get_cipher_mode(s);
++
++ if (s->max_send_fragment)
++ kctx->frag_size = s->max_send_fragment;
++ else
++ kctx->frag_size = SSL3_RT_MAX_PLAIN_LENGTH;
++
++ /* handle renegotiation here */
++ if(!BIO_get_offload_tx(s->wbio))
++ kctx->tx_seq_no = 0;
++ else
++ kctx->tx_seq_no = 1;
++
++ if(!BIO_get_offload_rx(s->rbio))
++ kctx->rx_seq_no = 0;
++ else
++ kctx->rx_seq_no = 1;
++
++ if(EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE) {
++ kctx->hmac_ctrl = 1;
++ }
++
++ return 1;
++}
++
++void chssl_program_hwkey_context(SSL *s, int rw, int state)
++{
++ int ret = 0;
++ BIO *wbio;
++ BIO *rbio;
++ struct tls_key_context *key_context;
++
++ wbio = s->wbio;
++ rbio = s->rbio;
++ if (!BIO_get_chofld_flag(rbio))
++ return;
++
++ key_context = (struct tls_key_context *)
++ OPENSSL_malloc(sizeof(struct tls_key_context));
++ if (key_context == NULL)
++ return;
++
++ memset(key_context, 0, sizeof(struct tls_key_context));
++ if((ret = ssl_key_context(s, key_context, rw, state)) <=0) {
++ /* Clear quiesce after CCS receive */
++ if (rw == KEY_WRITE_RX)
++ BIO_set_offload_clear_key(wbio);
++ goto end;
++ }
++
++ /* flush outstanding BIO before key is programmed */
++ statem_flush(s);
++ ret = BIO_set_offload_key(wbio, key_context);
++ if (ret)
++ goto end;
++ if (rw & KEY_WRITE_TX) {
++ /* XXX: wbio? */
++ BIO_set_offload_tx_flag(rbio);
++ } else {
++ BIO_set_offload_rx_flag(rbio);
++ }
++end:
++ free(key_context);
++ return;
++}
++#endif
+diff --git ssl/ssl_ofld.h ssl/ssl_ofld.h
+new file mode 100644
+index 0000000000..6b153bef9b
+--- /dev/null
++++ ssl/ssl_ofld.h
+@@ -0,0 +1,141 @@
++#ifndef _SSL_OFLD_H
++#define _SSL_OFLD_H
++
++#ifdef CHELSIO_TLS_OFFLOAD
++void chssl_program_hwkey_context(SSL *s, int rw, int state);
++
++#define MAX_MAC_KSZ 64 /*512 bits */
++#define SHA512_BLOCK 128 /* Block size for 512 */
++#define MAX_CIPHER_KSZ 32 /* 256 bits */
++#define CIPHER_BLOCK_SZ 16
++#define IV_SIZE (4+8) /*reserved 8 bytes */
++#define SALT_SIZE 4
++#define TLS_TX_HDR_SZ 16
++#define TLS_RX_HDR_SZ 16
++#define GHASH_SIZE 16
++#define MAX_TLS_KSZ (2*MAX_MAC_KSZ + MAX_CIPHER_KSZ)
++
++#ifdef __linux__
++#define IOCTL_TLSOM_SET_TLS_CONTEXT 201 /* Program Key Context on HW */
++#define IOCTL_TLSOM_GET_TLS_TOM 202 /* Query the TLS offload mode */
++#define IOCTL_TLSOM_CLR_TLS_TOM 203 /* Clear the Key */
++#define IOCTL_TLSOM_CLR_QUIES 204 /* Clear the Quiesec */
++#else
++/* Set with 'struct tls_key_context'. */
++#define TCP_TLSOM_SET_TLS_CONTEXT (TCP_VENDOR)
++
++/* Get returns int of enabled (1) / disabled (0). */
++#define TCP_TLSOM_GET_TLS_TOM (TCP_VENDOR + 1)
++
++enum {
++ TLS_TOM_NONE = 0,
++ TLS_TOM_TXONLY,
++ TLS_TOM_BOTH
++};
++
++/* Set with no value. */
++#define TCP_TLSOM_CLR_TLS_TOM (TCP_VENDOR + 2)
++
++/* Set with no value. */
++#define TCP_TLSOM_CLR_QUIES (TCP_VENDOR + 3)
++#endif
++
++enum {
++ TLS_OFLD_FALSE = 0,
++ TLS_OFLD_TRUE,
++};
++
++/* Can accomodate 16, 11-15 are reserved */
++enum {
++ CHSSL_SHA_NOP,
++ CHSSL_SHA1,
++ CHSSL_SHA224,
++ CHSSL_SHA256,
++ CHSSL_GHASH,
++ CHSSL_SHA512_224,
++ CHSSL_SHA512_256,
++ CHSSL_SHA512_384,
++ CHSSL_SHA512_512,
++ CHSSL_CBCMAC,
++ CHSSL_CMAC,
++};
++
++/* Can accomodate 16, 8-15 are reserved */
++enum {
++ CHSSL_CIPH_NOP,
++ CHSSL_AES_CBC,
++ CHSSL_AES_GCM,
++ CHSSL_AES_CTR,
++ CHSSL_AES_GEN,
++ CHSSL_IPSEC_ESP,
++ CHSSL_AES_XTS,
++ CHSSL_AES_CCM,
++};
++
++#define KEY_WRITE_RX 0x1 /* Program Receive Key */
++#define KEY_WRITE_TX 0x2 /* Program Transmit Key */
++#define KEY_DELETE_RX 0x4 /* Delete Receive Key */
++#define KEY_DELETE_TX 0x8 /* Delete Transmit Key */
++
++#define S_KEY_CLR_LOC 4
++#define M_KEY_CLR_LOC 0xf
++#define V_KEY_CLR_LOC(x) ((x) << S_KEY_CLR_LOC)
++#define G_FW_WR_EQUIQ(s) (((x) >> S_KEY_CLR_LOC) & M_KEY_CLR_LOC)
++#define F_KEY_CLR_LOC V_KEY_CLR_LOC(1U)
++
++#define S_KEY_GET_LOC 0
++#define M_KEY_GET_LOC 0xf
++#define V_KEY_GET_LOC(x) ((x) << S_KEY_GET_LOC)
++#define G_KEY_GET_LOC(s) (((x) >> S_KEY_GET_LOC) & M_KEY_GET_LOC)
++
++struct tls_ofld_state {
++ unsigned char enc_mode;
++ unsigned char mac_mode;
++ unsigned char key_loc;
++ unsigned char ofld_mode;
++ unsigned char auth_mode;
++ unsigned char resv[3];
++};
++
++struct tls_tx_ctxt {
++ unsigned char salt[SALT_SIZE];
++ unsigned char key[MAX_CIPHER_KSZ];
++ unsigned char ipad[MAX_MAC_KSZ];
++ unsigned char opad[MAX_MAC_KSZ];
++};
++
++struct tls_rx_ctxt {
++ unsigned char salt[SALT_SIZE];
++ unsigned char key[MAX_CIPHER_KSZ];
++ unsigned char ipad[MAX_MAC_KSZ];
++ unsigned char opad[MAX_MAC_KSZ];
++};
++
++struct tls_key_context {
++ struct tls_tx_ctxt tx;
++ struct tls_rx_ctxt rx;
++
++ unsigned char l_p_key;
++ unsigned char hmac_ctrl;
++ unsigned char mac_first;
++ unsigned char iv_size;
++ unsigned char iv_ctrl;
++ unsigned char iv_algo;
++ unsigned char tx_seq_no;
++ unsigned char rx_seq_no;
++
++ struct tls_ofld_state state;
++
++ unsigned int tx_key_info_size;
++ unsigned int rx_key_info_size;
++ unsigned int frag_size;
++ unsigned int mac_secret_size;
++ unsigned int cipher_secret_size;
++ int proto_ver;
++ unsigned int sock_fd;
++ unsigned short dtls_epoch;
++ unsigned short rsv;
++};
++#endif
++
++#endif /* ssl_ofld.h */
+diff --git ssl/statem/statem_srvr.c ssl/statem/statem_srvr.c
+index 7d0e9d0ba8..4bb38211f9 100644
+--- ssl/statem/statem_srvr.c
++++ ssl/statem/statem_srvr.c
+@@ -650,6 +650,10 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s)
+
+ case TLS_ST_SW_SESSION_TICKET:
+ st->hand_state = TLS_ST_SW_CHANGE;
++#ifdef CHELSIO_TLS_OFFLOAD
++ if (BIO_get_chofld_flag(s->rbio))
++ statem_flush(s);
++#endif
+ return WRITE_TRAN_CONTINUE;
+
+ case TLS_ST_SW_CHANGE:
+diff --git ssl/t1_enc.c ssl/t1_enc.c
+index 2db913fb06..d7c90873af 100644
+--- ssl/t1_enc.c
++++ ssl/t1_enc.c
+@@ -10,6 +10,7 @@
+
+ #include <stdio.h>
+ #include "ssl_locl.h"
++#include "ssl_ofld.h"
+ #include <openssl/comp.h>
+ #include <openssl/evp.h>
+ #include <openssl/kdf.h>
+@@ -98,6 +99,7 @@ int tls1_change_cipher_state(SSL *s, int which)
+ EVP_PKEY *mac_key;
+ size_t n, i, j, k, cl;
+ int reuse_dd = 0;
++ BIO *wbio;
+
+ c = s->s3->tmp.new_sym_enc;
+ m = s->s3->tmp.new_hash;
+@@ -318,6 +320,22 @@ int tls1_change_cipher_state(SSL *s, int which)
+ }
+ s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
+
++#ifdef CHELSIO_TLS_OFFLOAD
++ wbio = s->wbio;
++ if (!wbio)
++ goto skip_offload;
++
++ if (which == SSL3_CHANGE_CIPHER_SERVER_WRITE) {
++ chssl_program_hwkey_context(s, SSL3_CC_WRITE, SSL_ST_ACCEPT);
++ //statem_flush(s);
++ } else if (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) {
++ chssl_program_hwkey_context(s, SSL3_CC_WRITE, SSL_ST_CONNECT);
++ //statem_flush(s);
++ }
++
++skip_offload:
++#endif
++
+ #ifdef SSL_DEBUG
+ printf("which = %04X\nkey=", which);
+ {
Index: security/openssl-chelsio/files/patch-config
===================================================================
--- /dev/null
+++ security/openssl-chelsio/files/patch-config
@@ -0,0 +1,19 @@
+--- config.orig 2018-01-13 13:57:15 UTC
++++ config
+@@ -694,14 +694,8 @@ case "$GUESSOS" in
+ ia64-*-*bsd*) OUT="BSD-ia64" ;;
+ x86_64-*-dragonfly*) OUT="BSD-x86_64" ;;
+ amd64-*-*bsd*) OUT="BSD-x86_64" ;;
+- *86*-*-*bsd*) # mimic ld behaviour when it's looking for libc...
+- if [ -L /usr/lib/libc.so ]; then # [Free|Net]BSD
+- libc=/usr/lib/libc.so
+- else # OpenBSD
+- # ld searches for highest libc.so.* and so do we
+- libc=`(ls /usr/lib/libc.so.* /lib/libc.so.* | tail -1) 2>/dev/null`
+- fi
+- case "`(file -L $libc) 2>/dev/null`" in
++ *86*-*-*bsd*)
++ case "`(file -L /bin/sh) 2>/dev/null`" in
+ *ELF*) OUT="BSD-x86-elf" ;;
+ *) OUT="BSD-x86"; options="$options no-sse2" ;;
+ esac ;;
Index: security/openssl-chelsio/files/pkg-message.in
===================================================================
--- /dev/null
+++ security/openssl-chelsio/files/pkg-message.in
@@ -0,0 +1,4 @@
+
+Copy %%PREFIX%%/openssl-chelsio/openssl.cnf.sample to
+%%PREFIX%%/openssl-chelsio/openssl.cnf and edit it to fit your needs.
+
Index: security/openssl-chelsio/pkg-descr
===================================================================
--- /dev/null
+++ security/openssl-chelsio/pkg-descr
@@ -0,0 +1,19 @@
+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.
+
+This version of OpenSSL includes additional patches to support the
+use of TLS offload for offloaded TCP connections on Chelsio T6
+network adapters.
+
+WWW: https://www.openssl.org/
Index: security/openssl-chelsio/pkg-plist
===================================================================
--- /dev/null
+++ security/openssl-chelsio/pkg-plist
@@ -0,0 +1,8 @@
+openssl-chelsio/lib/engines-1.1/capi.so
+openssl-chelsio/lib/engines-1.1/padlock.so
+openssl-chelsio/lib/libcrypto.so.%%SHLIBVER%%
+openssl-chelsio/lib/libssl.so.%%SHLIBVER%%
+@sample %%OPENSSLDIR%%/openssl.cnf.dist %%OPENSSLDIR%%/openssl.cnf
+@sample %%OPENSSLDIR%%/ct_log_list.cnf.dist %%OPENSSLDIR%%/ct_log_list.cnf
+@dir %%OPENSSLDIR%%/private
+@dir %%OPENSSLDIR%%/certs
Index: security/openssl-chelsio/version.mk
===================================================================
--- /dev/null
+++ security/openssl-chelsio/version.mk
@@ -0,0 +1,2 @@
+# Match FreeBSD 12's base version
+OPENSSL_SHLIBVER?= 111

File Metadata

Mime Type
text/plain
Expires
Sat, Jul 25, 2:23 AM (11 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35459332
Default Alt Text
D14634.id54990.diff (47 KB)

Event Timeline