From nobody Mon Sep 29 15:22:33 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4cb4gZ2w1nz68P7B; Mon, 29 Sep 2025 15:22:34 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cb4gY6WmZz46V1; Mon, 29 Sep 2025 15:22:33 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1759159353; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lRNkBFmQWaPtwQsKIoSZ6Oh9o7ol901hmlNy3aQwnmc=; b=ew6KKoVgJ9Zfo4JGPRwI6wEns47cSzq7ZOwQXiOViWS5IRhAPNEObUUN5DsqJje6FrkOVT +dRaWI78GcluCts0b3bzHwkYrHIPp2JFgokx5a/vWgOGzaweBjwcS9T3gcP8dHI8vfnUcY dD7FzAltxjthFpur1D+TOtoVsnhJPIHyP3oCLyBXN+i2t1ybwuC3pHeD/JnOBb0XSeEHnm ogG4oJ2oUv5yPmehDWmpmHN8tu7TZurZvAJcLw09iO1bBk0pHbpZDYPiC0VJa26c+dXm9C h9OIkxSmO4/xZYY91gKw1S/Cwpq6msluIWti93BbeZqUo2pLEybh/q7rgB1Dyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1759159353; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lRNkBFmQWaPtwQsKIoSZ6Oh9o7ol901hmlNy3aQwnmc=; b=d9t1huxzli4Y/Obv/dbwNgdaAqVrQeunvipRTUBD952HkiF1WdWUoAMiUe3JCVfeH9/wFQ x32iKXbw3shyqgF8iAtxMjodj0dsh3ynLV3SCyFLjP84zWyN+4wT6d9HXb56v2bgwjYYbn x5q10/MbeDhm/xkZkRHKViqloQtqIYEUeg0Y/rOCSWtgPSOFmp90iEPcN3sMPihHNy5Smv 8cTitJRTvt2EIqgROQnPPc4f3QHfSd2RYbQmh47x8r2SjdJWiRec3PphTCfjkI2XJZqMH7 TvDTRDW0EK0bSptCz0P84n5sXU7nVQM6p9FLx9kPvsCeYHNAvuLaEtfXqNVZJw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1759159353; a=rsa-sha256; cv=none; b=vzugF5A3KwI+dTP2WJTHZP5LxBqKYjQnAgVyFLqtiUG7ML6q+z+1IjtpdKdJu/n3E1kk/W 4lZ3gJLoaC7zvevdSMFxMtT8cwyd9QwrVlizfPv5bOyx5dYvxxh097sjJFNJ7ehe5NixCX LjQky9wen36gS5qQ4hDn1WhJqOEABnyKJ1JWyXZyyOkmszYUKwRLXaWaadM7MnLc0SxD42 COMv4CSBsUviOhpFm7x44HLaS3Z+hsulTLkdf3QaS7elLl/VV6G4rCgsjG0hGz2+ND3v8D pulIAqUt4P7MBtap9eVQjRmtebjAJM1RWIzElFRBLImUCRp4egrMQtbZhKolRw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4cb4gY65Tmz19gk; Mon, 29 Sep 2025 15:22:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 58TFMX4b011983; Mon, 29 Sep 2025 15:22:33 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 58TFMX69011980; Mon, 29 Sep 2025 15:22:33 GMT (envelope-from git) Date: Mon, 29 Sep 2025 15:22:33 GMT Message-Id: <202509291522.58TFMX69011980@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Navdeep Parhar Subject: git: 5b9dc22c9106 - main - cxgbe: Extend NIC TLS to support TLS 1.3. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: np X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5b9dc22c91068e206fb6cc18ee0cef27067223df Auto-Submitted: auto-generated The branch main has been updated by np: URL: https://cgit.FreeBSD.org/src/commit/?id=5b9dc22c91068e206fb6cc18ee0cef27067223df commit 5b9dc22c91068e206fb6cc18ee0cef27067223df Author: John Baldwin AuthorDate: 2025-09-29 15:04:44 +0000 Commit: Navdeep Parhar CommitDate: 2025-09-29 15:19:12 +0000 cxgbe: Extend NIC TLS to support TLS 1.3. One unusual quirk is that the crypto engine requires the driver to provide an 8 byte placeholder as input before the AAD that is replaced with the middle 8 bytes of the nonce generated from the sequence number and key context. MFC after: 3 days Sponsored by: Chelsio Communications --- sys/dev/cxgbe/crypto/t7_kern_tls.c | 101 ++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 24 deletions(-) diff --git a/sys/dev/cxgbe/crypto/t7_kern_tls.c b/sys/dev/cxgbe/crypto/t7_kern_tls.c index 402b2cab20ba..5063648b2ba9 100644 --- a/sys/dev/cxgbe/crypto/t7_kern_tls.c +++ b/sys/dev/cxgbe/crypto/t7_kern_tls.c @@ -74,6 +74,7 @@ struct tlspcb { int tx_key_addr; bool inline_key; + bool tls13; unsigned char enc_mode; struct tls_scmd scmd0; @@ -131,14 +132,14 @@ t7_tls_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, struct vi_info *vi; struct inpcb *inp; struct sge_txq *txq; - int error, explicit_iv_size, keyid, mac_first; + int error, iv_size, keyid, mac_first; tls = params->tls.tls; - /* Only TLS 1.1 and TLS 1.2 are currently supported. */ + /* TLS 1.1 through TLS 1.3 are currently supported. */ if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || tls->params.tls_vminor < TLS_MINOR_VER_ONE || - tls->params.tls_vminor > TLS_MINOR_VER_TWO) + tls->params.tls_vminor > TLS_MINOR_VER_THREE) return (EPROTONOSUPPORT); /* Sanity check values in *tls. */ @@ -161,12 +162,10 @@ t7_tls_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, default: return (EPROTONOSUPPORT); } - explicit_iv_size = AES_BLOCK_LEN; + iv_size = AES_BLOCK_LEN; mac_first = 1; break; case CRYPTO_AES_NIST_GCM_16: - if (tls->params.iv_len != SALT_SIZE) - return (EINVAL); switch (tls->params.cipher_key_len) { case 128 / 8: case 192 / 8: @@ -175,7 +174,13 @@ t7_tls_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, default: return (EINVAL); } - explicit_iv_size = 8; + + /* + * The IV size for TLS 1.2 is the explicit IV in the + * record header. For TLS 1.3 it is the size of the + * sequence number. + */ + iv_size = 8; mac_first = 0; break; default: @@ -186,6 +191,7 @@ t7_tls_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, sc = vi->adapter; tlsp = alloc_tlspcb(ifp, vi, M_WAITOK); + tlsp->tls13 = tls->params.tls_vminor == TLS_MINOR_VER_THREE; if (sc->tlst.inline_keys) keyid = -1; @@ -224,14 +230,19 @@ t7_tls_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, tlsp->tx_key_info_size = t4_tls_key_info_size(tls); /* The SCMD fields used when encrypting a full TLS record. */ - tlsp->scmd0.seqno_numivs = htobe32(V_SCMD_SEQ_NO_CTRL(3) | + if (tlsp->tls13) + tlsp->scmd0.seqno_numivs = V_SCMD_SEQ_NO_CTRL(0); + else + tlsp->scmd0.seqno_numivs = V_SCMD_SEQ_NO_CTRL(3); + tlsp->scmd0.seqno_numivs |= V_SCMD_PROTO_VERSION(t4_tls_proto_ver(tls)) | V_SCMD_ENC_DEC_CTRL(SCMD_ENCDECCTRL_ENCRYPT) | V_SCMD_CIPH_AUTH_SEQ_CTRL((mac_first == 0)) | V_SCMD_CIPH_MODE(tlsp->enc_mode) | V_SCMD_AUTH_MODE(t4_tls_auth_mode(tls)) | V_SCMD_HMAC_CTRL(t4_tls_hmac_ctrl(tls)) | - V_SCMD_IV_SIZE(explicit_iv_size / 2) | V_SCMD_NUM_IVS(1)); + V_SCMD_IV_SIZE(iv_size / 2) | V_SCMD_NUM_IVS(1); + tlsp->scmd0.seqno_numivs = htobe32(tlsp->scmd0.seqno_numivs); tlsp->scmd0.ivgen_hdrlen = V_SCMD_IV_GEN_CTRL(0) | V_SCMD_TLS_FRAG_ENABLE(0); @@ -390,20 +401,29 @@ ktls_is_short_record(struct tlspcb *tlsp, struct mbuf *m_tls, u_int *leading_waste, u_int *trailing_waste) { const struct tls_record_layer *hdr; - u_int new_tlen, rlen; + u_int new_tlen, trailer_len, rlen; MPASS(tlen > m_tls->m_epg_hdrlen); hdr = (void *)m_tls->m_epg_hdr; rlen = TLS_HEADER_LENGTH + ntohs(hdr->tls_length); + /* + * For TLS 1.3 treat the inner record type stored as the first + * byte of the trailer as part of the payload rather than part + * of the trailer. + */ + trailer_len = m_tls->m_epg_trllen; + if (tlsp->tls13) + trailer_len--; + /* * Default to sending the full record as input to the crypto * engine and relying on SplitMode to drop any waste. */ *header_len = m_tls->m_epg_hdrlen; *offset = 0; - *plen = rlen - (m_tls->m_epg_hdrlen + m_tls->m_epg_trllen); + *plen = rlen - (m_tls->m_epg_hdrlen + trailer_len); *leading_waste = mtod(m_tls, vm_offset_t); *trailing_waste = rlen - tlen; if (!tlsp->sc->tlst.short_records) @@ -420,7 +440,7 @@ ktls_is_short_record(struct tlspcb *tlsp, struct mbuf *m_tls, */ new_tlen = TLS_HEADER_LENGTH + roundup2(tlen - TLS_HEADER_LENGTH, AES_BLOCK_LEN); - if (rlen - new_tlen < m_tls->m_epg_trllen) + if (rlen - new_tlen < trailer_len) return (false); *trailing_waste = new_tlen - tlen; @@ -431,7 +451,7 @@ ktls_is_short_record(struct tlspcb *tlsp, struct mbuf *m_tls, * the end overlaps with the trailer. Otherwise, we * can use AES-CTR to encrypt a partial PDU. */ - if (rlen - tlen < m_tls->m_epg_trllen) + if (rlen - tlen < trailer_len) return (false); /* @@ -512,11 +532,14 @@ ktls_wr_len(struct tlspcb *tlsp, struct mbuf *m, struct mbuf *m_tls, /* * Headers (including the TLS header) are always sent as * immediate data. Short records include a raw AES IV as - * immediate data. + * immediate data. TLS 1.3 non-short records include a + * placeholder for the sequence number as immediate data. */ imm_len = m->m_len + header_len; if (short_record) imm_len += AES_BLOCK_LEN; + else if (tlsp->tls13) + imm_len += sizeof(uint64_t); wr_len += roundup2(imm_len, 16); /* TLS record payload via DSGL. */ @@ -1044,6 +1067,8 @@ ktls_write_tls_wr(struct tlspcb *tlsp, struct sge_txq *txq, imm_len = m->m_len + header_len; if (short_record) imm_len += AES_BLOCK_LEN; + else if (tlsp->tls13) + imm_len += sizeof(uint64_t); wr_len += roundup2(imm_len, 16); wr_len += ktls_sgl_size(nsegs); @@ -1141,15 +1166,25 @@ ktls_write_tls_wr(struct tlspcb *tlsp, struct sge_txq *txq, txq->kern_tls_short++; } else { /* - * AAD is TLS header. IV is after AAD. The cipher region - * starts after the IV. See comments in ccr_authenc() and - * ccr_gmac() in t4_crypto.c regarding cipher and auth - * start/stop values. + * AAD is TLS header. IV is after AAD for TLS < 1.3. + * For TLS 1.3, a placeholder for the TLS sequence + * number is provided as an IV before the AAD. The + * cipher region starts after the AAD and IV. See + * comments in ccr_authenc() and ccr_gmac() in + * t4_crypto.c regarding cipher and auth start/stop + * values. */ - aad_start = 1; - aad_stop = TLS_HEADER_LENGTH; - iv_offset = TLS_HEADER_LENGTH + 1; - cipher_start = m_tls->m_epg_hdrlen + 1; + if (tlsp->tls13) { + iv_offset = 1; + aad_start = 1 + sizeof(uint64_t); + aad_stop = sizeof(uint64_t) + TLS_HEADER_LENGTH; + cipher_start = aad_stop + 1; + } else { + aad_start = 1; + aad_stop = TLS_HEADER_LENGTH; + iv_offset = TLS_HEADER_LENGTH + 1; + cipher_start = m_tls->m_epg_hdrlen + 1; + } if (tlsp->enc_mode == SCMD_CIPH_MODE_AES_GCM) { cipher_stop = 0; auth_start = cipher_start; @@ -1162,7 +1197,8 @@ ktls_write_tls_wr(struct tlspcb *tlsp, struct sge_txq *txq, auth_insert = 0; } - sec_pdu->pldlen = htobe32(m_tls->m_epg_hdrlen + plen); + sec_pdu->pldlen = htobe32((tlsp->tls13 ? sizeof(uint64_t) : 0) + + m_tls->m_epg_hdrlen + plen); /* These two flits are actually a CPL_TLS_TX_SCMD_FMT. */ sec_pdu->seqno_numivs = tlsp->scmd0.seqno_numivs; @@ -1256,6 +1292,15 @@ ktls_write_tls_wr(struct tlspcb *tlsp, struct sge_txq *txq, newtcp->th_flags = tcp->th_flags & ~(TH_PUSH | TH_FIN); out += m->m_len; + /* + * Insert placeholder for sequence number as IV for TLS 1.3 + * non-short records. + */ + if (tlsp->tls13 && !short_record) { + memset(out, 0, sizeof(uint64_t)); + out += sizeof(uint64_t); + } + /* Populate the TLS header */ memcpy(out, m_tls->m_epg_hdr, header_len); out += header_len; @@ -1265,7 +1310,15 @@ ktls_write_tls_wr(struct tlspcb *tlsp, struct sge_txq *txq, iv = out; if (tlsp->enc_mode == SCMD_CIPH_MODE_AES_GCM) { memcpy(iv, tlsp->keyctx.u.txhdr.txsalt, SALT_SIZE); - memcpy(iv + 4, hdr + 1, 8); + if (tlsp->tls13) { + uint64_t value; + + value = be64dec(tlsp->keyctx.u.txhdr.txsalt + + 4); + value ^= m_tls->m_epg_seqno; + be64enc(iv + 4, value); + } else + memcpy(iv + 4, hdr + 1, 8); be32enc(iv + 12, 2 + offset / AES_BLOCK_LEN); } else memcpy(iv, hdr + 1, AES_BLOCK_LEN);