1b2e60773SJohn Baldwin /*- 2b2e60773SJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause 3b2e60773SJohn Baldwin * 4b2e60773SJohn Baldwin * Copyright (c) 2019 Netflix Inc. 5b2e60773SJohn Baldwin * All rights reserved. 6b2e60773SJohn Baldwin * 7b2e60773SJohn Baldwin * Redistribution and use in source and binary forms, with or without 8b2e60773SJohn Baldwin * modification, are permitted provided that the following conditions 9b2e60773SJohn Baldwin * are met: 10b2e60773SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 11b2e60773SJohn Baldwin * notice, this list of conditions and the following disclaimer. 12b2e60773SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 13b2e60773SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 14b2e60773SJohn Baldwin * documentation and/or other materials provided with the distribution. 15b2e60773SJohn Baldwin * 16b2e60773SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17b2e60773SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18b2e60773SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19b2e60773SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20b2e60773SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21b2e60773SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22b2e60773SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23b2e60773SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24b2e60773SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25b2e60773SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26b2e60773SJohn Baldwin * SUCH DAMAGE. 27b2e60773SJohn Baldwin */ 28b2e60773SJohn Baldwin 29b2e60773SJohn Baldwin #include <sys/cdefs.h> 30b2e60773SJohn Baldwin __FBSDID("$FreeBSD$"); 31b2e60773SJohn Baldwin 32b2e60773SJohn Baldwin #include <sys/param.h> 33b2e60773SJohn Baldwin #include <sys/systm.h> 34b2e60773SJohn Baldwin #include <sys/counter.h> 35b2e60773SJohn Baldwin #include <sys/endian.h> 36b2e60773SJohn Baldwin #include <sys/kernel.h> 37b2e60773SJohn Baldwin #include <sys/ktls.h> 38b2e60773SJohn Baldwin #include <sys/lock.h> 39b2e60773SJohn Baldwin #include <sys/malloc.h> 40b2e60773SJohn Baldwin #include <sys/module.h> 41b2e60773SJohn Baldwin #include <sys/mutex.h> 42b2e60773SJohn Baldwin #include <sys/sysctl.h> 43b2e60773SJohn Baldwin #include <sys/uio.h> 44b2e60773SJohn Baldwin #include <opencrypto/cryptodev.h> 45b2e60773SJohn Baldwin 46b2e60773SJohn Baldwin struct ocf_session { 47b2e60773SJohn Baldwin crypto_session_t sid; 48b2e60773SJohn Baldwin int crda_alg; 49b2e60773SJohn Baldwin struct mtx lock; 50b2e60773SJohn Baldwin }; 51b2e60773SJohn Baldwin 52b2e60773SJohn Baldwin struct ocf_operation { 53b2e60773SJohn Baldwin struct ocf_session *os; 54b2e60773SJohn Baldwin bool done; 55b2e60773SJohn Baldwin struct iovec iov[0]; 56b2e60773SJohn Baldwin }; 57b2e60773SJohn Baldwin 58b2e60773SJohn Baldwin static MALLOC_DEFINE(M_KTLS_OCF, "ktls_ocf", "OCF KTLS"); 59b2e60773SJohn Baldwin 60b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls); 61b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls_stats); 62b2e60773SJohn Baldwin 63*7029da5cSPawel Biernacki static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf, 64*7029da5cSPawel Biernacki CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 6555b7a0e1SJohn Baldwin "Kernel TLS offload via OCF stats"); 6655b7a0e1SJohn Baldwin 6755b7a0e1SJohn Baldwin static counter_u64_t ocf_tls12_gcm_crypts; 6855b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_crypts, 6955b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_crypts, 7055b7a0e1SJohn Baldwin "Total number of OCF TLS 1.2 GCM encryption operations"); 7155b7a0e1SJohn Baldwin 7255b7a0e1SJohn Baldwin static counter_u64_t ocf_tls13_gcm_crypts; 7355b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_crypts, 7455b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_crypts, 7555b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 76b2e60773SJohn Baldwin 77b2e60773SJohn Baldwin static counter_u64_t ocf_retries; 7855b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 79b2e60773SJohn Baldwin &ocf_retries, 80b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 81b2e60773SJohn Baldwin 82b2e60773SJohn Baldwin static int 83b2e60773SJohn Baldwin ktls_ocf_callback(struct cryptop *crp) 84b2e60773SJohn Baldwin { 85b2e60773SJohn Baldwin struct ocf_operation *oo; 86b2e60773SJohn Baldwin 87b2e60773SJohn Baldwin oo = crp->crp_opaque; 88b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 89b2e60773SJohn Baldwin oo->done = true; 90b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 91b2e60773SJohn Baldwin wakeup(oo); 92b2e60773SJohn Baldwin return (0); 93b2e60773SJohn Baldwin } 94b2e60773SJohn Baldwin 95b2e60773SJohn Baldwin static int 9655b7a0e1SJohn Baldwin ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls, 9755b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 9855b7a0e1SJohn Baldwin struct iovec *outiov, int iovcnt, uint64_t seqno, 9955b7a0e1SJohn Baldwin uint8_t record_type __unused) 100b2e60773SJohn Baldwin { 101b2e60773SJohn Baldwin struct uio uio; 102b2e60773SJohn Baldwin struct tls_aead_data ad; 103b2e60773SJohn Baldwin struct tls_nonce_data nd; 104b2e60773SJohn Baldwin struct cryptodesc *crde, *crda; 105b2e60773SJohn Baldwin struct cryptop *crp; 106b2e60773SJohn Baldwin struct ocf_session *os; 107b2e60773SJohn Baldwin struct ocf_operation *oo; 108b2e60773SJohn Baldwin struct iovec *iov; 109b2e60773SJohn Baldwin int i, error; 110b2e60773SJohn Baldwin uint16_t tls_comp_len; 111b2e60773SJohn Baldwin 112b2e60773SJohn Baldwin os = tls->cipher; 113b2e60773SJohn Baldwin 114b2e60773SJohn Baldwin oo = malloc(sizeof(*oo) + (iovcnt + 2) * sizeof(*iov), M_KTLS_OCF, 115b2e60773SJohn Baldwin M_WAITOK | M_ZERO); 116b2e60773SJohn Baldwin oo->os = os; 117b2e60773SJohn Baldwin iov = oo->iov; 118b2e60773SJohn Baldwin 119b2e60773SJohn Baldwin crp = crypto_getreq(2); 120b2e60773SJohn Baldwin if (crp == NULL) { 121b2e60773SJohn Baldwin free(oo, M_KTLS_OCF); 122b2e60773SJohn Baldwin return (ENOMEM); 123b2e60773SJohn Baldwin } 124b2e60773SJohn Baldwin 125b2e60773SJohn Baldwin /* Setup the IV. */ 126b2e60773SJohn Baldwin memcpy(nd.fixed, tls->params.iv, TLS_AEAD_GCM_LEN); 127b2e60773SJohn Baldwin memcpy(&nd.seq, hdr + 1, sizeof(nd.seq)); 128b2e60773SJohn Baldwin 129b2e60773SJohn Baldwin /* Setup the AAD. */ 130b2e60773SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 131b2e60773SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(nd.seq)); 132b2e60773SJohn Baldwin ad.seq = htobe64(seqno); 133b2e60773SJohn Baldwin ad.type = hdr->tls_type; 134b2e60773SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 135b2e60773SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 136b2e60773SJohn Baldwin ad.tls_length = htons(tls_comp_len); 137b2e60773SJohn Baldwin iov[0].iov_base = &ad; 138b2e60773SJohn Baldwin iov[0].iov_len = sizeof(ad); 139b2e60773SJohn Baldwin uio.uio_resid = sizeof(ad); 140b2e60773SJohn Baldwin 141b2e60773SJohn Baldwin /* 142b2e60773SJohn Baldwin * OCF always does encryption in place, so copy the data if 143b2e60773SJohn Baldwin * needed. Ugh. 144b2e60773SJohn Baldwin */ 145b2e60773SJohn Baldwin for (i = 0; i < iovcnt; i++) { 146b2e60773SJohn Baldwin iov[i + 1] = outiov[i]; 147b2e60773SJohn Baldwin if (iniov[i].iov_base != outiov[i].iov_base) 148b2e60773SJohn Baldwin memcpy(outiov[i].iov_base, iniov[i].iov_base, 149b2e60773SJohn Baldwin outiov[i].iov_len); 150b2e60773SJohn Baldwin uio.uio_resid += outiov[i].iov_len; 151b2e60773SJohn Baldwin } 152b2e60773SJohn Baldwin 153b2e60773SJohn Baldwin iov[iovcnt + 1].iov_base = trailer; 154b2e60773SJohn Baldwin iov[iovcnt + 1].iov_len = AES_GMAC_HASH_LEN; 155b2e60773SJohn Baldwin uio.uio_resid += AES_GMAC_HASH_LEN; 156b2e60773SJohn Baldwin 157b2e60773SJohn Baldwin uio.uio_iov = iov; 158b2e60773SJohn Baldwin uio.uio_iovcnt = iovcnt + 2; 159b2e60773SJohn Baldwin uio.uio_offset = 0; 160b2e60773SJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 161b2e60773SJohn Baldwin uio.uio_td = curthread; 162b2e60773SJohn Baldwin 163b2e60773SJohn Baldwin crp->crp_session = os->sid; 164b2e60773SJohn Baldwin crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM; 165b2e60773SJohn Baldwin crp->crp_uio = &uio; 166b2e60773SJohn Baldwin crp->crp_ilen = uio.uio_resid; 167b2e60773SJohn Baldwin crp->crp_opaque = oo; 168b2e60773SJohn Baldwin crp->crp_callback = ktls_ocf_callback; 169b2e60773SJohn Baldwin 170b2e60773SJohn Baldwin crde = crp->crp_desc; 171b2e60773SJohn Baldwin crda = crde->crd_next; 172b2e60773SJohn Baldwin 173b2e60773SJohn Baldwin crda->crd_alg = os->crda_alg; 174b2e60773SJohn Baldwin crda->crd_skip = 0; 175b2e60773SJohn Baldwin crda->crd_len = sizeof(ad); 176b2e60773SJohn Baldwin crda->crd_inject = crp->crp_ilen - AES_GMAC_HASH_LEN; 177b2e60773SJohn Baldwin 178b2e60773SJohn Baldwin crde->crd_alg = CRYPTO_AES_NIST_GCM_16; 179b2e60773SJohn Baldwin crde->crd_skip = sizeof(ad); 180b2e60773SJohn Baldwin crde->crd_len = crp->crp_ilen - (sizeof(ad) + AES_GMAC_HASH_LEN); 181b2e60773SJohn Baldwin crde->crd_flags = CRD_F_ENCRYPT | CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 182b2e60773SJohn Baldwin memcpy(crde->crd_iv, &nd, sizeof(nd)); 183b2e60773SJohn Baldwin 18455b7a0e1SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 18555b7a0e1SJohn Baldwin for (;;) { 18655b7a0e1SJohn Baldwin error = crypto_dispatch(crp); 18755b7a0e1SJohn Baldwin if (error) 18855b7a0e1SJohn Baldwin break; 18955b7a0e1SJohn Baldwin 19055b7a0e1SJohn Baldwin mtx_lock(&os->lock); 19155b7a0e1SJohn Baldwin while (!oo->done) 19255b7a0e1SJohn Baldwin mtx_sleep(oo, &os->lock, 0, "ocfktls", 0); 19355b7a0e1SJohn Baldwin mtx_unlock(&os->lock); 19455b7a0e1SJohn Baldwin 19555b7a0e1SJohn Baldwin if (crp->crp_etype != EAGAIN) { 19655b7a0e1SJohn Baldwin error = crp->crp_etype; 19755b7a0e1SJohn Baldwin break; 19855b7a0e1SJohn Baldwin } 19955b7a0e1SJohn Baldwin 20055b7a0e1SJohn Baldwin crp->crp_etype = 0; 20155b7a0e1SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 20255b7a0e1SJohn Baldwin oo->done = false; 20355b7a0e1SJohn Baldwin counter_u64_add(ocf_retries, 1); 20455b7a0e1SJohn Baldwin } 20555b7a0e1SJohn Baldwin 20655b7a0e1SJohn Baldwin crypto_freereq(crp); 20755b7a0e1SJohn Baldwin free(oo, M_KTLS_OCF); 20855b7a0e1SJohn Baldwin return (error); 20955b7a0e1SJohn Baldwin } 21055b7a0e1SJohn Baldwin 21155b7a0e1SJohn Baldwin static int 21255b7a0e1SJohn Baldwin ktls_ocf_tls13_gcm_encrypt(struct ktls_session *tls, 21355b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 21455b7a0e1SJohn Baldwin struct iovec *outiov, int iovcnt, uint64_t seqno, uint8_t record_type) 21555b7a0e1SJohn Baldwin { 21655b7a0e1SJohn Baldwin struct uio uio; 21755b7a0e1SJohn Baldwin struct tls_aead_data_13 ad; 21855b7a0e1SJohn Baldwin char nonce[12]; 21955b7a0e1SJohn Baldwin struct cryptodesc *crde, *crda; 22055b7a0e1SJohn Baldwin struct cryptop *crp; 22155b7a0e1SJohn Baldwin struct ocf_session *os; 22255b7a0e1SJohn Baldwin struct ocf_operation *oo; 22355b7a0e1SJohn Baldwin struct iovec *iov; 22455b7a0e1SJohn Baldwin int i, error; 22555b7a0e1SJohn Baldwin 22655b7a0e1SJohn Baldwin os = tls->cipher; 22755b7a0e1SJohn Baldwin 22855b7a0e1SJohn Baldwin oo = malloc(sizeof(*oo) + (iovcnt + 2) * sizeof(*iov), M_KTLS_OCF, 22955b7a0e1SJohn Baldwin M_WAITOK | M_ZERO); 23055b7a0e1SJohn Baldwin oo->os = os; 23155b7a0e1SJohn Baldwin iov = oo->iov; 23255b7a0e1SJohn Baldwin 23355b7a0e1SJohn Baldwin crp = crypto_getreq(2); 23455b7a0e1SJohn Baldwin if (crp == NULL) { 23555b7a0e1SJohn Baldwin free(oo, M_KTLS_OCF); 23655b7a0e1SJohn Baldwin return (ENOMEM); 23755b7a0e1SJohn Baldwin } 23855b7a0e1SJohn Baldwin 23955b7a0e1SJohn Baldwin /* Setup the nonce. */ 24055b7a0e1SJohn Baldwin memcpy(nonce, tls->params.iv, tls->params.iv_len); 24155b7a0e1SJohn Baldwin *(uint64_t *)(nonce + 4) ^= htobe64(seqno); 24255b7a0e1SJohn Baldwin 24355b7a0e1SJohn Baldwin /* Setup the AAD. */ 24455b7a0e1SJohn Baldwin ad.type = hdr->tls_type; 24555b7a0e1SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 24655b7a0e1SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 24755b7a0e1SJohn Baldwin ad.tls_length = hdr->tls_length; 24855b7a0e1SJohn Baldwin iov[0].iov_base = &ad; 24955b7a0e1SJohn Baldwin iov[0].iov_len = sizeof(ad); 25055b7a0e1SJohn Baldwin uio.uio_resid = sizeof(ad); 25155b7a0e1SJohn Baldwin 25255b7a0e1SJohn Baldwin /* 25355b7a0e1SJohn Baldwin * OCF always does encryption in place, so copy the data if 25455b7a0e1SJohn Baldwin * needed. Ugh. 25555b7a0e1SJohn Baldwin */ 25655b7a0e1SJohn Baldwin for (i = 0; i < iovcnt; i++) { 25755b7a0e1SJohn Baldwin iov[i + 1] = outiov[i]; 25855b7a0e1SJohn Baldwin if (iniov[i].iov_base != outiov[i].iov_base) 25955b7a0e1SJohn Baldwin memcpy(outiov[i].iov_base, iniov[i].iov_base, 26055b7a0e1SJohn Baldwin outiov[i].iov_len); 26155b7a0e1SJohn Baldwin uio.uio_resid += outiov[i].iov_len; 26255b7a0e1SJohn Baldwin } 26355b7a0e1SJohn Baldwin 26455b7a0e1SJohn Baldwin trailer[0] = record_type; 26555b7a0e1SJohn Baldwin iov[iovcnt + 1].iov_base = trailer; 26655b7a0e1SJohn Baldwin iov[iovcnt + 1].iov_len = AES_GMAC_HASH_LEN + 1; 26755b7a0e1SJohn Baldwin uio.uio_resid += AES_GMAC_HASH_LEN + 1; 26855b7a0e1SJohn Baldwin 26955b7a0e1SJohn Baldwin uio.uio_iov = iov; 27055b7a0e1SJohn Baldwin uio.uio_iovcnt = iovcnt + 2; 27155b7a0e1SJohn Baldwin uio.uio_offset = 0; 27255b7a0e1SJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 27355b7a0e1SJohn Baldwin uio.uio_td = curthread; 27455b7a0e1SJohn Baldwin 27555b7a0e1SJohn Baldwin crp->crp_session = os->sid; 27655b7a0e1SJohn Baldwin crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM; 27755b7a0e1SJohn Baldwin crp->crp_uio = &uio; 27855b7a0e1SJohn Baldwin crp->crp_ilen = uio.uio_resid; 27955b7a0e1SJohn Baldwin crp->crp_opaque = oo; 28055b7a0e1SJohn Baldwin crp->crp_callback = ktls_ocf_callback; 28155b7a0e1SJohn Baldwin 28255b7a0e1SJohn Baldwin crde = crp->crp_desc; 28355b7a0e1SJohn Baldwin crda = crde->crd_next; 28455b7a0e1SJohn Baldwin 28555b7a0e1SJohn Baldwin crda->crd_alg = os->crda_alg; 28655b7a0e1SJohn Baldwin crda->crd_skip = 0; 28755b7a0e1SJohn Baldwin crda->crd_len = sizeof(ad); 28855b7a0e1SJohn Baldwin crda->crd_inject = crp->crp_ilen - AES_GMAC_HASH_LEN; 28955b7a0e1SJohn Baldwin 29055b7a0e1SJohn Baldwin crde->crd_alg = CRYPTO_AES_NIST_GCM_16; 29155b7a0e1SJohn Baldwin crde->crd_skip = sizeof(ad); 29255b7a0e1SJohn Baldwin crde->crd_len = crp->crp_ilen - (sizeof(ad) + AES_GMAC_HASH_LEN); 29355b7a0e1SJohn Baldwin crde->crd_flags = CRD_F_ENCRYPT | CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 29455b7a0e1SJohn Baldwin memcpy(crde->crd_iv, nonce, sizeof(nonce)); 29555b7a0e1SJohn Baldwin 29655b7a0e1SJohn Baldwin counter_u64_add(ocf_tls13_gcm_crypts, 1); 297b2e60773SJohn Baldwin for (;;) { 298b2e60773SJohn Baldwin error = crypto_dispatch(crp); 299b2e60773SJohn Baldwin if (error) 300b2e60773SJohn Baldwin break; 301b2e60773SJohn Baldwin 302b2e60773SJohn Baldwin mtx_lock(&os->lock); 303b2e60773SJohn Baldwin while (!oo->done) 304b2e60773SJohn Baldwin mtx_sleep(oo, &os->lock, 0, "ocfktls", 0); 305b2e60773SJohn Baldwin mtx_unlock(&os->lock); 306b2e60773SJohn Baldwin 307b2e60773SJohn Baldwin if (crp->crp_etype != EAGAIN) { 308b2e60773SJohn Baldwin error = crp->crp_etype; 309b2e60773SJohn Baldwin break; 310b2e60773SJohn Baldwin } 311b2e60773SJohn Baldwin 312b2e60773SJohn Baldwin crp->crp_etype = 0; 313b2e60773SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 314b2e60773SJohn Baldwin oo->done = false; 315b2e60773SJohn Baldwin counter_u64_add(ocf_retries, 1); 316b2e60773SJohn Baldwin } 317b2e60773SJohn Baldwin 318b2e60773SJohn Baldwin crypto_freereq(crp); 319b2e60773SJohn Baldwin free(oo, M_KTLS_OCF); 320b2e60773SJohn Baldwin return (error); 321b2e60773SJohn Baldwin } 322b2e60773SJohn Baldwin 323b2e60773SJohn Baldwin static void 324b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 325b2e60773SJohn Baldwin { 326b2e60773SJohn Baldwin struct ocf_session *os; 327b2e60773SJohn Baldwin 328b2e60773SJohn Baldwin os = tls->cipher; 329b2e60773SJohn Baldwin mtx_destroy(&os->lock); 330b2e60773SJohn Baldwin explicit_bzero(os, sizeof(*os)); 331b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 332b2e60773SJohn Baldwin } 333b2e60773SJohn Baldwin 334b2e60773SJohn Baldwin static int 335b2e60773SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls) 336b2e60773SJohn Baldwin { 337b2e60773SJohn Baldwin struct cryptoini cria, crie; 338b2e60773SJohn Baldwin struct ocf_session *os; 339b2e60773SJohn Baldwin int error; 340b2e60773SJohn Baldwin 341b2e60773SJohn Baldwin memset(&cria, 0, sizeof(cria)); 342b2e60773SJohn Baldwin memset(&crie, 0, sizeof(crie)); 343b2e60773SJohn Baldwin 344b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 345b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 346b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 347b2e60773SJohn Baldwin case 128 / 8: 348b2e60773SJohn Baldwin cria.cri_alg = CRYPTO_AES_128_NIST_GMAC; 349b2e60773SJohn Baldwin break; 350b2e60773SJohn Baldwin case 256 / 8: 351b2e60773SJohn Baldwin cria.cri_alg = CRYPTO_AES_256_NIST_GMAC; 352b2e60773SJohn Baldwin break; 353b2e60773SJohn Baldwin default: 354b2e60773SJohn Baldwin return (EINVAL); 355b2e60773SJohn Baldwin } 356b2e60773SJohn Baldwin cria.cri_key = tls->params.cipher_key; 357b2e60773SJohn Baldwin cria.cri_klen = tls->params.cipher_key_len * 8; 358b2e60773SJohn Baldwin break; 359b2e60773SJohn Baldwin default: 360b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 361b2e60773SJohn Baldwin } 362b2e60773SJohn Baldwin 36355b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 364b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 36555b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 36655b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 367b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 368b2e60773SJohn Baldwin 369b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 370b2e60773SJohn Baldwin if (os == NULL) 371b2e60773SJohn Baldwin return (ENOMEM); 372b2e60773SJohn Baldwin 373b2e60773SJohn Baldwin crie.cri_alg = tls->params.cipher_algorithm; 374b2e60773SJohn Baldwin crie.cri_key = tls->params.cipher_key; 375b2e60773SJohn Baldwin crie.cri_klen = tls->params.cipher_key_len * 8; 376b2e60773SJohn Baldwin 377b2e60773SJohn Baldwin crie.cri_next = &cria; 378b2e60773SJohn Baldwin error = crypto_newsession(&os->sid, &crie, 379b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 380b2e60773SJohn Baldwin if (error) { 381b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 382b2e60773SJohn Baldwin return (error); 383b2e60773SJohn Baldwin } 384b2e60773SJohn Baldwin 385b2e60773SJohn Baldwin os->crda_alg = cria.cri_alg; 386b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 387b2e60773SJohn Baldwin tls->cipher = os; 38855b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 38955b7a0e1SJohn Baldwin tls->sw_encrypt = ktls_ocf_tls13_gcm_encrypt; 39055b7a0e1SJohn Baldwin else 39155b7a0e1SJohn Baldwin tls->sw_encrypt = ktls_ocf_tls12_gcm_encrypt; 392b2e60773SJohn Baldwin tls->free = ktls_ocf_free; 393b2e60773SJohn Baldwin return (0); 394b2e60773SJohn Baldwin } 395b2e60773SJohn Baldwin 396b2e60773SJohn Baldwin struct ktls_crypto_backend ocf_backend = { 397b2e60773SJohn Baldwin .name = "OCF", 398b2e60773SJohn Baldwin .prio = 5, 399b2e60773SJohn Baldwin .api_version = KTLS_API_VERSION, 400b2e60773SJohn Baldwin .try = ktls_ocf_try, 401b2e60773SJohn Baldwin }; 402b2e60773SJohn Baldwin 403b2e60773SJohn Baldwin static int 404b2e60773SJohn Baldwin ktls_ocf_modevent(module_t mod, int what, void *arg) 405b2e60773SJohn Baldwin { 406b2e60773SJohn Baldwin int error; 407b2e60773SJohn Baldwin 408b2e60773SJohn Baldwin switch (what) { 409b2e60773SJohn Baldwin case MOD_LOAD: 41055b7a0e1SJohn Baldwin ocf_tls12_gcm_crypts = counter_u64_alloc(M_WAITOK); 41155b7a0e1SJohn Baldwin ocf_tls13_gcm_crypts = counter_u64_alloc(M_WAITOK); 412b2e60773SJohn Baldwin ocf_retries = counter_u64_alloc(M_WAITOK); 413b2e60773SJohn Baldwin return (ktls_crypto_backend_register(&ocf_backend)); 414b2e60773SJohn Baldwin case MOD_UNLOAD: 415b2e60773SJohn Baldwin error = ktls_crypto_backend_deregister(&ocf_backend); 416b2e60773SJohn Baldwin if (error) 417b2e60773SJohn Baldwin return (error); 41855b7a0e1SJohn Baldwin counter_u64_free(ocf_tls12_gcm_crypts); 41955b7a0e1SJohn Baldwin counter_u64_free(ocf_tls13_gcm_crypts); 420b2e60773SJohn Baldwin counter_u64_free(ocf_retries); 421b2e60773SJohn Baldwin return (0); 422b2e60773SJohn Baldwin default: 423b2e60773SJohn Baldwin return (EOPNOTSUPP); 424b2e60773SJohn Baldwin } 425b2e60773SJohn Baldwin } 426b2e60773SJohn Baldwin 427b2e60773SJohn Baldwin static moduledata_t ktls_ocf_moduledata = { 428b2e60773SJohn Baldwin "ktls_ocf", 429b2e60773SJohn Baldwin ktls_ocf_modevent, 430b2e60773SJohn Baldwin NULL 431b2e60773SJohn Baldwin }; 432b2e60773SJohn Baldwin 433b2e60773SJohn Baldwin DECLARE_MODULE(ktls_ocf, ktls_ocf_moduledata, SI_SUB_PROTO_END, SI_ORDER_ANY); 434