Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109622733
D22802.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D22802.diff
View Options
Index: head/sys/opencrypto/ktls_ocf.c
===================================================================
--- head/sys/opencrypto/ktls_ocf.c
+++ head/sys/opencrypto/ktls_ocf.c
@@ -60,13 +60,21 @@
SYSCTL_DECL(_kern_ipc_tls);
SYSCTL_DECL(_kern_ipc_tls_stats);
-static counter_u64_t ocf_gcm_crypts;
-SYSCTL_COUNTER_U64(_kern_ipc_tls_stats, OID_AUTO, ocf_gcm_crypts, CTLFLAG_RD,
- &ocf_gcm_crypts,
- "Total number of OCF GCM encryption operations");
+static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf, CTLFLAG_RD, 0,
+ "Kernel TLS offload via OCF stats");
+static counter_u64_t ocf_tls12_gcm_crypts;
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_crypts,
+ CTLFLAG_RD, &ocf_tls12_gcm_crypts,
+ "Total number of OCF TLS 1.2 GCM encryption operations");
+
+static counter_u64_t ocf_tls13_gcm_crypts;
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_crypts,
+ CTLFLAG_RD, &ocf_tls13_gcm_crypts,
+ "Total number of OCF TLS 1.3 GCM encryption operations");
+
static counter_u64_t ocf_retries;
-SYSCTL_COUNTER_U64(_kern_ipc_tls_stats, OID_AUTO, ocf_retries, CTLFLAG_RD,
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD,
&ocf_retries,
"Number of OCF encryption operation retries");
@@ -84,9 +92,10 @@
}
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, uint8_t record_type __unused)
+ktls_ocf_tls12_gcm_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,
+ uint8_t record_type __unused)
{
struct uio uio;
struct tls_aead_data ad;
@@ -127,7 +136,7 @@
iov[0].iov_base = &ad;
iov[0].iov_len = sizeof(ad);
uio.uio_resid = sizeof(ad);
-
+
/*
* OCF always does encryption in place, so copy the data if
* needed. Ugh.
@@ -171,7 +180,7 @@
crde->crd_flags = CRD_F_ENCRYPT | CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
memcpy(crde->crd_iv, &nd, sizeof(nd));
- counter_u64_add(ocf_gcm_crypts, 1);
+ counter_u64_add(ocf_tls12_gcm_crypts, 1);
for (;;) {
error = crypto_dispatch(crp);
if (error)
@@ -198,6 +207,118 @@
return (error);
}
+static int
+ktls_ocf_tls13_gcm_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, uint8_t record_type)
+{
+ struct uio uio;
+ struct tls_aead_data_13 ad;
+ char nonce[12];
+ struct cryptodesc *crde, *crda;
+ struct cryptop *crp;
+ struct ocf_session *os;
+ struct ocf_operation *oo;
+ struct iovec *iov;
+ int i, error;
+
+ os = tls->cipher;
+
+ oo = malloc(sizeof(*oo) + (iovcnt + 2) * sizeof(*iov), M_KTLS_OCF,
+ M_WAITOK | M_ZERO);
+ oo->os = os;
+ iov = oo->iov;
+
+ crp = crypto_getreq(2);
+ if (crp == NULL) {
+ free(oo, M_KTLS_OCF);
+ return (ENOMEM);
+ }
+
+ /* Setup the nonce. */
+ memcpy(nonce, tls->params.iv, tls->params.iv_len);
+ *(uint64_t *)(nonce + 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;
+ iov[0].iov_base = &ad;
+ iov[0].iov_len = sizeof(ad);
+ uio.uio_resid = sizeof(ad);
+
+ /*
+ * OCF always does encryption in place, so copy the data if
+ * needed. Ugh.
+ */
+ for (i = 0; i < iovcnt; i++) {
+ iov[i + 1] = outiov[i];
+ if (iniov[i].iov_base != outiov[i].iov_base)
+ memcpy(outiov[i].iov_base, iniov[i].iov_base,
+ outiov[i].iov_len);
+ uio.uio_resid += outiov[i].iov_len;
+ }
+
+ trailer[0] = record_type;
+ iov[iovcnt + 1].iov_base = trailer;
+ iov[iovcnt + 1].iov_len = AES_GMAC_HASH_LEN + 1;
+ uio.uio_resid += AES_GMAC_HASH_LEN + 1;
+
+ uio.uio_iov = iov;
+ uio.uio_iovcnt = iovcnt + 2;
+ uio.uio_offset = 0;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_td = curthread;
+
+ crp->crp_session = os->sid;
+ crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM;
+ crp->crp_uio = &uio;
+ crp->crp_ilen = uio.uio_resid;
+ crp->crp_opaque = oo;
+ crp->crp_callback = ktls_ocf_callback;
+
+ crde = crp->crp_desc;
+ crda = crde->crd_next;
+
+ crda->crd_alg = os->crda_alg;
+ crda->crd_skip = 0;
+ crda->crd_len = sizeof(ad);
+ crda->crd_inject = crp->crp_ilen - AES_GMAC_HASH_LEN;
+
+ crde->crd_alg = CRYPTO_AES_NIST_GCM_16;
+ crde->crd_skip = sizeof(ad);
+ crde->crd_len = crp->crp_ilen - (sizeof(ad) + AES_GMAC_HASH_LEN);
+ crde->crd_flags = CRD_F_ENCRYPT | CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
+ memcpy(crde->crd_iv, nonce, sizeof(nonce));
+
+ counter_u64_add(ocf_tls13_gcm_crypts, 1);
+ for (;;) {
+ error = crypto_dispatch(crp);
+ if (error)
+ break;
+
+ mtx_lock(&os->lock);
+ while (!oo->done)
+ mtx_sleep(oo, &os->lock, 0, "ocfktls", 0);
+ mtx_unlock(&os->lock);
+
+ if (crp->crp_etype != EAGAIN) {
+ error = crp->crp_etype;
+ break;
+ }
+
+ crp->crp_etype = 0;
+ crp->crp_flags &= ~CRYPTO_F_DONE;
+ oo->done = false;
+ counter_u64_add(ocf_retries, 1);
+ }
+
+ crypto_freereq(crp);
+ free(oo, M_KTLS_OCF);
+ return (error);
+}
+
static void
ktls_ocf_free(struct ktls_session *tls)
{
@@ -221,8 +342,6 @@
switch (tls->params.cipher_algorithm) {
case CRYPTO_AES_NIST_GCM_16:
- if (tls->params.iv_len != TLS_AEAD_GCM_LEN)
- return (EINVAL);
switch (tls->params.cipher_key_len) {
case 128 / 8:
cria.cri_alg = CRYPTO_AES_128_NIST_GMAC;
@@ -240,10 +359,10 @@
return (EPROTONOSUPPORT);
}
- /* Only TLS 1.1 and TLS 1.2 are currently supported. */
+ /* Only TLS 1.2 and 1.3 are 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_TWO ||
+ tls->params.tls_vminor > TLS_MINOR_VER_THREE)
return (EPROTONOSUPPORT);
os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO);
@@ -265,7 +384,10 @@
os->crda_alg = cria.cri_alg;
mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF);
tls->cipher = os;
- tls->sw_encrypt = ktls_ocf_encrypt;
+ if (tls->params.tls_vminor == TLS_MINOR_VER_THREE)
+ tls->sw_encrypt = ktls_ocf_tls13_gcm_encrypt;
+ else
+ tls->sw_encrypt = ktls_ocf_tls12_gcm_encrypt;
tls->free = ktls_ocf_free;
return (0);
}
@@ -284,14 +406,16 @@
switch (what) {
case MOD_LOAD:
- ocf_gcm_crypts = counter_u64_alloc(M_WAITOK);
+ ocf_tls12_gcm_crypts = counter_u64_alloc(M_WAITOK);
+ ocf_tls13_gcm_crypts = counter_u64_alloc(M_WAITOK);
ocf_retries = counter_u64_alloc(M_WAITOK);
return (ktls_crypto_backend_register(&ocf_backend));
case MOD_UNLOAD:
error = ktls_crypto_backend_deregister(&ocf_backend);
if (error)
return (error);
- counter_u64_free(ocf_gcm_crypts);
+ counter_u64_free(ocf_tls12_gcm_crypts);
+ counter_u64_free(ocf_tls13_gcm_crypts);
counter_u64_free(ocf_retries);
return (0);
default:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 8, 2:45 PM (20 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16527856
Default Alt Text
D22802.diff (6 KB)
Attached To
Mode
D22802: Add support for TLS 1.3 using AES-GCM to the OCF backend for KTLS.
Attached
Detach File
Event Timeline
Log In to Comment