aboutsummaryrefslogtreecommitdiff
path: root/sys/opencrypto/ktls_ocf.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2021-12-14 19:01:05 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2021-12-14 19:01:05 +0000
commit05a1d0f5d7ac8400975d1eaa30a718a1ff48b139 (patch)
tree93c921be9355436326c5223bb5496557e10535ff /sys/opencrypto/ktls_ocf.c
parent483e464ed4325a0710485925ecfbe0e1c8d6bb02 (diff)
downloadsrc-05a1d0f5d7ac8400975d1eaa30a718a1ff48b139.tar.gz
src-05a1d0f5d7ac8400975d1eaa30a718a1ff48b139.zip
ktls: Support for TLS 1.3 receive offload.
Note that support for TLS 1.3 receive offload in OpenSSL is still an open pull request in active development. However, potential changes to that pull request should not affect the kernel interface. Reviewed by: hselasky Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D33007
Diffstat (limited to 'sys/opencrypto/ktls_ocf.c')
-rw-r--r--sys/opencrypto/ktls_ocf.c77
1 files changed, 66 insertions, 11 deletions
diff --git a/sys/opencrypto/ktls_ocf.c b/sys/opencrypto/ktls_ocf.c
index dc8b6f76257b..a2bb94dc717a 100644
--- a/sys/opencrypto/ktls_ocf.c
+++ b/sys/opencrypto/ktls_ocf.c
@@ -106,11 +106,21 @@ SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_encrypts,
CTLFLAG_RD, &ocf_tls12_chacha20_encrypts,
"Total number of OCF TLS 1.2 Chacha20-Poly1305 encryption operations");
+static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_decrypts);
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_decrypts,
+ CTLFLAG_RD, &ocf_tls13_gcm_decrypts,
+ "Total number of OCF TLS 1.3 GCM decryption operations");
+
static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_encrypts);
SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_encrypts,
CTLFLAG_RD, &ocf_tls13_gcm_encrypts,
"Total number of OCF TLS 1.3 GCM encryption operations");
+static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_decrypts);
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_decrypts,
+ CTLFLAG_RD, &ocf_tls13_chacha20_decrypts,
+ "Total number of OCF TLS 1.3 Chacha20-Poly1305 decryption operations");
+
static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_encrypts);
SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_encrypts,
CTLFLAG_RD, &ocf_tls13_chacha20_encrypts,
@@ -600,6 +610,58 @@ ktls_ocf_tls13_aead_encrypt(struct ktls_ocf_encrypt_state *state,
return (error);
}
+static int
+ktls_ocf_tls13_aead_decrypt(struct ktls_session *tls,
+ const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno,
+ int *trailer_len)
+{
+ struct tls_aead_data_13 ad;
+ struct cryptop crp;
+ struct ktls_ocf_session *os;
+ int error;
+ u_int tag_len;
+
+ os = tls->ocf_session;
+
+ tag_len = tls->params.tls_tlen - 1;
+
+ /* Payload must contain at least one byte for the record type. */
+ if (ntohs(hdr->tls_length) < tag_len + 1)
+ return (EBADMSG);
+
+ crypto_initreq(&crp, os->sid);
+
+ /* Setup the nonce. */
+ memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len);
+ *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno);
+
+ /* Setup the AAD. */
+ ad.type = hdr->tls_type;
+ ad.tls_vmajor = hdr->tls_vmajor;
+ ad.tls_vminor = hdr->tls_vminor;
+ ad.tls_length = hdr->tls_length;
+ crp.crp_aad = &ad;
+ crp.crp_aad_length = sizeof(ad);
+
+ crp.crp_payload_start = tls->params.tls_hlen;
+ crp.crp_payload_length = ntohs(hdr->tls_length) - tag_len;
+ crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length;
+
+ crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST;
+ crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
+ crypto_use_mbuf(&crp, m);
+
+ if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16)
+ counter_u64_add(ocf_tls13_gcm_decrypts, 1);
+ else
+ counter_u64_add(ocf_tls13_chacha20_decrypts, 1);
+ error = ktls_ocf_dispatch(os, &crp);
+
+ crypto_destroyreq(&crp);
+ *trailer_len = tag_len;
+ return (error);
+}
+
void
ktls_ocf_free(struct ktls_session *tls)
{
@@ -639,11 +701,6 @@ ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction)
tls->params.tls_vminor > TLS_MINOR_VER_THREE)
return (EPROTONOSUPPORT);
- /* TLS 1.3 is not yet supported for receive. */
- if (direction == KTLS_RX &&
- tls->params.tls_vminor == TLS_MINOR_VER_THREE)
- return (EPROTONOSUPPORT);
-
csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD;
csp.csp_mode = CSP_MODE_AEAD;
csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16;
@@ -711,11 +768,6 @@ ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction)
tls->params.tls_vminor > TLS_MINOR_VER_THREE)
return (EPROTONOSUPPORT);
- /* TLS 1.3 is not yet supported for receive. */
- if (direction == KTLS_RX &&
- tls->params.tls_vminor == TLS_MINOR_VER_THREE)
- return (EPROTONOSUPPORT);
-
csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD;
csp.csp_mode = CSP_MODE_AEAD;
csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305;
@@ -759,7 +811,10 @@ ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction)
else
tls->sw_encrypt = ktls_ocf_tls12_aead_encrypt;
} else {
- tls->sw_decrypt = ktls_ocf_tls12_aead_decrypt;
+ if (tls->params.tls_vminor == TLS_MINOR_VER_THREE)
+ tls->sw_decrypt = ktls_ocf_tls13_aead_decrypt;
+ else
+ tls->sw_decrypt = ktls_ocf_tls12_aead_decrypt;
}
} else {
tls->sw_encrypt = ktls_ocf_tls_cbc_encrypt;