Date: Thu, 18 Feb 2021 17:54:37 GMT From: John Baldwin <jhb@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 9c64fc40290e - main - Add Chacha20-Poly1305 as a KTLS cipher suite. Message-ID: <202102181754.11IHsb4G033907@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=9c64fc40290e08f6dc6b75aa04084b04e48a61af commit 9c64fc40290e08f6dc6b75aa04084b04e48a61af Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2021-02-18 17:23:59 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2021-02-18 17:26:32 +0000 Add Chacha20-Poly1305 as a KTLS cipher suite. Chacha20-Poly1305 for TLS is an AEAD cipher suite for both TLS 1.2 and TLS 1.3 (RFCs 7905 and 8446). For both versions, Chacha20 uses the server and client IVs as implicit nonces xored with the record sequence number to generate the per-record nonce matching the construction used with AES-GCM for TLS 1.3. Reviewed by: gallatin Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D27839 --- sys/kern/uipc_ktls.c | 76 ++++++++++++++++++++++++++++++++++++++++++---------- sys/sys/ktls.h | 1 + 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c index 26912e410239..f92314d9c607 100644 --- a/sys/kern/uipc_ktls.c +++ b/sys/kern/uipc_ktls.c @@ -199,6 +199,11 @@ static COUNTER_U64_DEFINE_EARLY(ktls_sw_gcm); SYSCTL_COUNTER_U64(_kern_ipc_tls_sw, OID_AUTO, gcm, CTLFLAG_RD, &ktls_sw_gcm, "Active number of software TLS sessions using AES-GCM"); +static COUNTER_U64_DEFINE_EARLY(ktls_sw_chacha20); +SYSCTL_COUNTER_U64(_kern_ipc_tls_sw, OID_AUTO, chacha20, CTLFLAG_RD, + &ktls_sw_chacha20, + "Active number of software TLS sessions using Chacha20-Poly1305"); + static COUNTER_U64_DEFINE_EARLY(ktls_ifnet_cbc); SYSCTL_COUNTER_U64(_kern_ipc_tls_ifnet, OID_AUTO, cbc, CTLFLAG_RD, &ktls_ifnet_cbc, @@ -209,6 +214,11 @@ SYSCTL_COUNTER_U64(_kern_ipc_tls_ifnet, OID_AUTO, gcm, CTLFLAG_RD, &ktls_ifnet_gcm, "Active number of ifnet TLS sessions using AES-GCM"); +static COUNTER_U64_DEFINE_EARLY(ktls_ifnet_chacha20); +SYSCTL_COUNTER_U64(_kern_ipc_tls_ifnet, OID_AUTO, chacha20, CTLFLAG_RD, + &ktls_ifnet_chacha20, + "Active number of ifnet TLS sessions using Chacha20-Poly1305"); + static COUNTER_U64_DEFINE_EARLY(ktls_ifnet_reset); SYSCTL_COUNTER_U64(_kern_ipc_tls_ifnet, OID_AUTO, reset, CTLFLAG_RD, &ktls_ifnet_reset, "TLS sessions updated to a new ifnet send tag"); @@ -238,6 +248,11 @@ static COUNTER_U64_DEFINE_EARLY(ktls_toe_gcm); SYSCTL_COUNTER_U64(_kern_ipc_tls_toe, OID_AUTO, gcm, CTLFLAG_RD, &ktls_toe_gcm, "Active number of TOE TLS sessions using AES-GCM"); + +static counter_u64_t ktls_toe_chacha20; +SYSCTL_COUNTER_U64(_kern_ipc_tls_toe, OID_AUTO, chacha20, CTLFLAG_RD, + &ktls_toe_chacha20, + "Active number of TOE TLS sessions using Chacha20-Poly1305"); #endif static MALLOC_DEFINE(M_KTLS, "ktls", "Kernel TLS"); @@ -507,6 +522,15 @@ ktls_create_session(struct socket *so, struct tls_enable *en, if (en->auth_key_len == 0) return (EINVAL); break; + case CRYPTO_CHACHA20_POLY1305: + if (en->auth_algorithm != 0 || en->auth_key_len != 0) + return (EINVAL); + if (en->tls_vminor != TLS_MINOR_VER_TWO && + en->tls_vminor != TLS_MINOR_VER_THREE) + return (EINVAL); + if (en->iv_len != TLS_CHACHA20_IV_LEN) + return (EINVAL); + break; default: return (EINVAL); } @@ -538,15 +562,6 @@ ktls_create_session(struct socket *so, struct tls_enable *en, 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: @@ -575,10 +590,25 @@ ktls_create_session(struct socket *so, struct tls_enable *en, } tls->params.tls_bs = AES_BLOCK_LEN; break; + case CRYPTO_CHACHA20_POLY1305: + /* + * Chacha20 uses a 12 byte implicit IV. + */ + tls->params.tls_tlen = POLY1305_HASH_LEN; + tls->params.tls_bs = 1; + break; default: panic("invalid cipher"); } + /* + * 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); + KASSERT(tls->params.tls_hlen <= MBUF_PEXT_HDR_LEN, ("TLS header length too long: %d", tls->params.tls_hlen)); KASSERT(tls->params.tls_tlen <= MBUF_PEXT_TRAIL_LEN, @@ -602,9 +632,9 @@ ktls_create_session(struct socket *so, struct tls_enable *en, goto out; /* - * This holds the implicit portion of the nonce for GCM and - * the initial implicit IV for TLS 1.0. The explicit portions - * of the IV are generated in ktls_frame(). + * This holds the implicit portion of the nonce for AEAD + * ciphers and the initial implicit IV for TLS 1.0. The + * explicit portions of the IV are generated in ktls_frame(). */ if (en->iv_len != 0) { tls->params.iv_len = en->iv_len; @@ -613,8 +643,8 @@ ktls_create_session(struct socket *so, struct tls_enable *en, goto out; /* - * For TLS 1.2, generate an 8-byte nonce as a counter - * to generate unique explicit IVs. + * For TLS 1.2 with GCM, generate an 8-byte nonce as a + * counter to generate unique explicit IVs. * * Store this counter in the last 8 bytes of the IV * array so that it is 8-byte aligned. @@ -679,6 +709,9 @@ ktls_cleanup(struct ktls_session *tls) case CRYPTO_AES_NIST_GCM_16: counter_u64_add(ktls_sw_gcm, -1); break; + case CRYPTO_CHACHA20_POLY1305: + counter_u64_add(ktls_sw_chacha20, -1); + break; } tls->free(tls); break; @@ -690,6 +723,9 @@ ktls_cleanup(struct ktls_session *tls) case CRYPTO_AES_NIST_GCM_16: counter_u64_add(ktls_ifnet_gcm, -1); break; + case CRYPTO_CHACHA20_POLY1305: + counter_u64_add(ktls_ifnet_chacha20, -1); + break; } if (tls->snd_tag != NULL) m_snd_tag_rele(tls->snd_tag); @@ -703,6 +739,9 @@ ktls_cleanup(struct ktls_session *tls) case CRYPTO_AES_NIST_GCM_16: counter_u64_add(ktls_toe_gcm, -1); break; + case CRYPTO_CHACHA20_POLY1305: + counter_u64_add(ktls_toe_chacha20, -1); + break; } break; #endif @@ -761,6 +800,9 @@ ktls_try_toe(struct socket *so, struct ktls_session *tls, int direction) case CRYPTO_AES_NIST_GCM_16: counter_u64_add(ktls_toe_gcm, 1); break; + case CRYPTO_CHACHA20_POLY1305: + counter_u64_add(ktls_toe_chacha20, 1); + break; } } return (error); @@ -883,6 +925,9 @@ ktls_try_ifnet(struct socket *so, struct ktls_session *tls, bool force) case CRYPTO_AES_NIST_GCM_16: counter_u64_add(ktls_ifnet_gcm, 1); break; + case CRYPTO_CHACHA20_POLY1305: + counter_u64_add(ktls_ifnet_chacha20, 1); + break; } } return (error); @@ -926,6 +971,9 @@ ktls_try_sw(struct socket *so, struct ktls_session *tls, int direction) case CRYPTO_AES_NIST_GCM_16: counter_u64_add(ktls_sw_gcm, 1); break; + case CRYPTO_CHACHA20_POLY1305: + counter_u64_add(ktls_sw_chacha20, 1); + break; } return (0); } diff --git a/sys/sys/ktls.h b/sys/sys/ktls.h index 8d591888466c..d3da1286403c 100644 --- a/sys/sys/ktls.h +++ b/sys/sys/ktls.h @@ -44,6 +44,7 @@ struct tls_record_layer { #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_CHACHA20_IV_LEN 12 #define TLS_CBC_IMPLICIT_IV_LEN 16 /* Type values for the record layer */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102181754.11IHsb4G033907>