Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163521663
D14634.id54990.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
47 KB
Referenced Files
None
Subscribers
None
D14634.id54990.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D14634: [new port] security/openssl-chelsio: SSL and crypto library supporting Chelsio TLS offload
Attached
Detach File
Event Timeline
Log In to Comment