From owner-svn-src-all@freebsd.org Fri Sep 27 19:17:42 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2013512A9B2; Fri, 27 Sep 2019 19:17:42 +0000 (UTC) (envelope-from gallatin@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46g1lV03Wyz4CSN; Fri, 27 Sep 2019 19:17:42 +0000 (UTC) (envelope-from gallatin@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D98481D875; Fri, 27 Sep 2019 19:17:41 +0000 (UTC) (envelope-from gallatin@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x8RJHf7r047194; Fri, 27 Sep 2019 19:17:41 GMT (envelope-from gallatin@FreeBSD.org) Received: (from gallatin@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x8RJHec7047188; Fri, 27 Sep 2019 19:17:40 GMT (envelope-from gallatin@FreeBSD.org) Message-Id: <201909271917.x8RJHec7047188@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: gallatin set sender to gallatin@FreeBSD.org using -f From: Andrew Gallatin Date: Fri, 27 Sep 2019 19:17:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r352814 - in head/sys: kern net opencrypto sys X-SVN-Group: head X-SVN-Commit-Author: gallatin X-SVN-Commit-Paths: in head/sys: kern net opencrypto sys X-SVN-Commit-Revision: 352814 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Sep 2019 19:17:42 -0000 Author: gallatin Date: Fri Sep 27 19:17:40 2019 New Revision: 352814 URL: https://svnweb.freebsd.org/changeset/base/352814 Log: kTLS support for TLS 1.3 TLS 1.3 requires a few changes because 1.3 pretends to be 1.2 with a record type of application data. The "real" record type is then included at the end of the user-supplied plaintext data. This required adding a field to the mbuf_ext_pgs struct to save the record type, and passing the real record type to the sw_encrypt() ktls backend functions. Reviewed by: jhb, hselasky Sponsored by: Netflix Differential Revision: D21801 Modified: head/sys/kern/uipc_ktls.c head/sys/net/iflib.c head/sys/opencrypto/ktls_ocf.c head/sys/sys/ktls.h head/sys/sys/mbuf.h Modified: head/sys/kern/uipc_ktls.c ============================================================================== --- head/sys/kern/uipc_ktls.c Fri Sep 27 19:14:03 2019 (r352813) +++ head/sys/kern/uipc_ktls.c Fri Sep 27 19:17:40 2019 (r352814) @@ -389,14 +389,14 @@ ktls_create_session(struct socket *so, struct tls_enab if (en->tls_vmajor != TLS_MAJOR_VER_ONE) return (EINVAL); if (en->tls_vminor < TLS_MINOR_VER_ZERO || - en->tls_vminor > TLS_MINOR_VER_TWO) + en->tls_vminor > TLS_MINOR_VER_THREE) return (EINVAL); if (en->auth_key_len < 0 || en->auth_key_len > TLS_MAX_PARAM_SIZE) return (EINVAL); if (en->cipher_key_len < 0 || en->cipher_key_len > TLS_MAX_PARAM_SIZE) return (EINVAL); - if (en->iv_len < 0 || en->iv_len > TLS_MAX_PARAM_SIZE) + if (en->iv_len < 0 || en->iv_len > sizeof(tls->params.iv)) return (EINVAL); /* All supported algorithms require a cipher key. */ @@ -425,7 +425,10 @@ ktls_create_session(struct socket *so, struct tls_enab } if (en->auth_key_len != 0) return (EINVAL); - if (en->iv_len != TLS_AEAD_GCM_LEN) + if ((en->tls_vminor == TLS_MINOR_VER_TWO && + en->iv_len != TLS_AEAD_GCM_LEN) || + (en->tls_vminor == TLS_MINOR_VER_THREE && + en->iv_len != TLS_1_3_GCM_IV_LEN)) return (EINVAL); break; case CRYPTO_AES_CBC: @@ -477,8 +480,22 @@ ktls_create_session(struct socket *so, struct tls_enab tls->params.tls_hlen = sizeof(struct tls_record_layer); switch (en->cipher_algorithm) { case CRYPTO_AES_NIST_GCM_16: - tls->params.tls_hlen += 8; + /* + * TLS 1.2 uses a 4 byte implicit IV with an explicit 8 byte + * nonce. TLS 1.3 uses a 12 byte implicit IV. + */ + if (en->tls_vminor < TLS_MINOR_VER_THREE) + tls->params.tls_hlen += sizeof(uint64_t); tls->params.tls_tlen = AES_GMAC_HASH_LEN; + + /* + * TLS 1.3 includes optional padding which we + * do not support, and also puts the "real" record + * type at the end of the encrypted data. + */ + if (en->tls_vminor == TLS_MINOR_VER_THREE) + tls->params.tls_tlen += sizeof(uint8_t); + tls->params.tls_bs = 1; break; case CRYPTO_AES_CBC: @@ -539,7 +556,6 @@ ktls_create_session(struct socket *so, struct tls_enab * of the IV are generated in ktls_frame() and ktls_seq(). */ if (en->iv_len != 0) { - MPASS(en->iv_len <= sizeof(tls->params.iv)); tls->params.iv_len = en->iv_len; error = copyin(en->iv, tls->params.iv, en->iv_len); if (error) @@ -1188,8 +1204,21 @@ ktls_frame(struct mbuf *top, struct ktls_session *tls, /* Populate the TLS header. */ tlshdr = (void *)pgs->hdr; tlshdr->tls_vmajor = tls->params.tls_vmajor; - tlshdr->tls_vminor = tls->params.tls_vminor; - tlshdr->tls_type = record_type; + + /* + * TLS 1.3 masquarades as TLS 1.2 with a record type + * of TLS_RLTYPE_APP. + */ + if (tls->params.tls_vminor == TLS_MINOR_VER_THREE && + tls->params.tls_vmajor == TLS_MAJOR_VER_ONE) { + tlshdr->tls_vminor = TLS_MINOR_VER_TWO; + tlshdr->tls_type = TLS_RLTYPE_APP; + /* save the real record type for later */ + pgs->record_type = record_type; + } else { + tlshdr->tls_vminor = tls->params.tls_vminor; + tlshdr->tls_type = record_type; + } tlshdr->tls_length = htons(m->m_len - sizeof(*tlshdr)); /* @@ -1365,7 +1394,8 @@ retry_page: error = (*tls->sw_encrypt)(tls, (const struct tls_record_layer *)pgs->hdr, - pgs->trail, src_iov, dst_iov, i, pgs->seqno); + pgs->trail, src_iov, dst_iov, i, pgs->seqno, + pgs->record_type); if (error) { counter_u64_add(ktls_offload_failed_crypto, 1); break; Modified: head/sys/net/iflib.c ============================================================================== --- head/sys/net/iflib.c Fri Sep 27 19:14:03 2019 (r352813) +++ head/sys/net/iflib.c Fri Sep 27 19:17:40 2019 (r352814) @@ -4076,7 +4076,7 @@ iflib_if_qflush(if_t ifp) #define IFCAP_FLAGS (IFCAP_HWCSUM_IPV6 | IFCAP_HWCSUM | IFCAP_LRO | \ IFCAP_TSO | IFCAP_VLAN_HWTAGGING | IFCAP_HWSTATS | \ IFCAP_VLAN_MTU | IFCAP_VLAN_HWFILTER | \ - IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM) + IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM | IFCAP_NOMAP) static int iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) @@ -4201,7 +4201,7 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) oldmask = if_getcapenable(ifp); mask = ifr->ifr_reqcap ^ oldmask; - mask &= ctx->ifc_softc_ctx.isc_capabilities; + mask &= ctx->ifc_softc_ctx.isc_capabilities | IFCAP_NOMAP; setmask = 0; #ifdef TCP_OFFLOAD setmask |= mask & (IFCAP_TOE4|IFCAP_TOE6); @@ -4596,8 +4596,10 @@ iflib_device_register(device_t dev, void *sc, if_share MPASS(scctx->isc_tx_csum_flags); #endif - if_setcapabilities(ifp, scctx->isc_capabilities | IFCAP_HWSTATS); - if_setcapenable(ifp, scctx->isc_capenable | IFCAP_HWSTATS); + if_setcapabilities(ifp, + scctx->isc_capabilities | IFCAP_HWSTATS | IFCAP_NOMAP); + if_setcapenable(ifp, + scctx->isc_capenable | IFCAP_HWSTATS | IFCAP_NOMAP); if (scctx->isc_ntxqsets == 0 || (scctx->isc_ntxqsets_max && scctx->isc_ntxqsets_max < scctx->isc_ntxqsets)) scctx->isc_ntxqsets = scctx->isc_ntxqsets_max; Modified: head/sys/opencrypto/ktls_ocf.c ============================================================================== --- head/sys/opencrypto/ktls_ocf.c Fri Sep 27 19:14:03 2019 (r352813) +++ head/sys/opencrypto/ktls_ocf.c Fri Sep 27 19:17:40 2019 (r352814) @@ -86,7 +86,7 @@ ktls_ocf_callback(struct cryptop *crp) static int ktls_ocf_encrypt(struct ktls_session *tls, const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, struct iovec *outiov, int iovcnt, - uint64_t seqno) + uint64_t seqno, uint8_t record_type __unused) { struct uio uio; struct tls_aead_data ad; Modified: head/sys/sys/ktls.h ============================================================================== --- head/sys/sys/ktls.h Fri Sep 27 19:14:03 2019 (r352813) +++ head/sys/sys/ktls.h Fri Sep 27 19:17:40 2019 (r352814) @@ -43,6 +43,7 @@ struct tls_record_layer { #define TLS_MAX_MSG_SIZE_V10_2 16384 #define TLS_MAX_PARAM_SIZE 1024 /* Max key/mac/iv in sockopt */ #define TLS_AEAD_GCM_LEN 4 +#define TLS_1_3_GCM_IV_LEN 12 #define TLS_CBC_IMPLICIT_IV_LEN 16 /* Type values for the record layer */ @@ -85,6 +86,7 @@ struct tls_mac_data { #define TLS_MINOR_VER_ZERO 1 /* 3, 1 */ #define TLS_MINOR_VER_ONE 2 /* 3, 2 */ #define TLS_MINOR_VER_TWO 3 /* 3, 3 */ +#define TLS_MINOR_VER_THREE 4 /* 3, 4 */ /* For TCP_TXTLS_ENABLE */ struct tls_enable { @@ -121,7 +123,7 @@ struct tls_session_params { #ifdef _KERNEL -#define KTLS_API_VERSION 5 +#define KTLS_API_VERSION 6 struct iovec; struct ktls_session; @@ -144,7 +146,7 @@ struct ktls_session { int (*sw_encrypt)(struct ktls_session *tls, const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *src, struct iovec *dst, int iovcnt, - uint64_t seqno); + uint64_t seqno, uint8_t record_type); union { void *cipher; struct m_snd_tag *snd_tag; Modified: head/sys/sys/mbuf.h ============================================================================== --- head/sys/sys/mbuf.h Fri Sep 27 19:14:03 2019 (r352813) +++ head/sys/sys/mbuf.h Fri Sep 27 19:17:40 2019 (r352814) @@ -359,6 +359,7 @@ struct mbuf_ext_pgs { union { char trail[MBUF_PEXT_TRAIL_LEN]; /* TLS trailer */ struct { + uint8_t record_type; /* Must be first */ struct socket *so; struct mbuf *mbuf; uint64_t seqno;