diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c --- a/sys/kern/uipc_ktls.c +++ b/sys/kern/uipc_ktls.c @@ -199,6 +199,11 @@ 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 @@ &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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 --- a/sys/sys/ktls.h +++ b/sys/sys/ktls.h @@ -44,6 +44,7 @@ #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 */