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 struct mtx lock; 49b2e60773SJohn Baldwin }; 50b2e60773SJohn Baldwin 51b2e60773SJohn Baldwin struct ocf_operation { 52b2e60773SJohn Baldwin struct ocf_session *os; 53b2e60773SJohn Baldwin bool done; 54b2e60773SJohn Baldwin }; 55b2e60773SJohn Baldwin 56b2e60773SJohn Baldwin static MALLOC_DEFINE(M_KTLS_OCF, "ktls_ocf", "OCF KTLS"); 57b2e60773SJohn Baldwin 58b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls); 59b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls_stats); 60b2e60773SJohn Baldwin 617029da5cSPawel Biernacki static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf, 627029da5cSPawel Biernacki CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 6355b7a0e1SJohn Baldwin "Kernel TLS offload via OCF stats"); 6455b7a0e1SJohn Baldwin 6555b7a0e1SJohn Baldwin static counter_u64_t ocf_tls12_gcm_crypts; 6655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_crypts, 6755b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_crypts, 6855b7a0e1SJohn Baldwin "Total number of OCF TLS 1.2 GCM encryption operations"); 6955b7a0e1SJohn Baldwin 7055b7a0e1SJohn Baldwin static counter_u64_t ocf_tls13_gcm_crypts; 7155b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_crypts, 7255b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_crypts, 7355b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 74b2e60773SJohn Baldwin 75080933c0SJohn Baldwin static counter_u64_t ocf_inplace; 76080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace, 77080933c0SJohn Baldwin CTLFLAG_RD, &ocf_inplace, 78080933c0SJohn Baldwin "Total number of OCF in-place operations"); 79080933c0SJohn Baldwin 80080933c0SJohn Baldwin static counter_u64_t ocf_separate_output; 81080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output, 82080933c0SJohn Baldwin CTLFLAG_RD, &ocf_separate_output, 83080933c0SJohn Baldwin "Total number of OCF operations with a separate output buffer"); 84080933c0SJohn Baldwin 85b2e60773SJohn Baldwin static counter_u64_t ocf_retries; 8655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 87b2e60773SJohn Baldwin &ocf_retries, 88b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 89b2e60773SJohn Baldwin 90b2e60773SJohn Baldwin static int 91b2e60773SJohn Baldwin ktls_ocf_callback(struct cryptop *crp) 92b2e60773SJohn Baldwin { 93b2e60773SJohn Baldwin struct ocf_operation *oo; 94b2e60773SJohn Baldwin 95b2e60773SJohn Baldwin oo = crp->crp_opaque; 96b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 97b2e60773SJohn Baldwin oo->done = true; 98b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 99b2e60773SJohn Baldwin wakeup(oo); 100b2e60773SJohn Baldwin return (0); 101b2e60773SJohn Baldwin } 102b2e60773SJohn Baldwin 103b2e60773SJohn Baldwin static int 10470d1a435SJohn Baldwin ktls_ocf_dispatch(struct ocf_session *os, struct cryptop *crp) 10570d1a435SJohn Baldwin { 10670d1a435SJohn Baldwin struct ocf_operation oo; 10770d1a435SJohn Baldwin int error; 10870d1a435SJohn Baldwin 10970d1a435SJohn Baldwin oo.os = os; 11070d1a435SJohn Baldwin oo.done = false; 11170d1a435SJohn Baldwin 11270d1a435SJohn Baldwin crp->crp_opaque = &oo; 11370d1a435SJohn Baldwin crp->crp_callback = ktls_ocf_callback; 11470d1a435SJohn Baldwin for (;;) { 11570d1a435SJohn Baldwin error = crypto_dispatch(crp); 11670d1a435SJohn Baldwin if (error) 11770d1a435SJohn Baldwin break; 11870d1a435SJohn Baldwin 11970d1a435SJohn Baldwin mtx_lock(&os->lock); 12070d1a435SJohn Baldwin while (!oo.done) 12170d1a435SJohn Baldwin mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0); 12270d1a435SJohn Baldwin mtx_unlock(&os->lock); 12370d1a435SJohn Baldwin 12470d1a435SJohn Baldwin if (crp->crp_etype != EAGAIN) { 12570d1a435SJohn Baldwin error = crp->crp_etype; 12670d1a435SJohn Baldwin break; 12770d1a435SJohn Baldwin } 12870d1a435SJohn Baldwin 12970d1a435SJohn Baldwin crp->crp_etype = 0; 13070d1a435SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 13170d1a435SJohn Baldwin oo.done = false; 13270d1a435SJohn Baldwin counter_u64_add(ocf_retries, 1); 13370d1a435SJohn Baldwin } 13470d1a435SJohn Baldwin return (error); 13570d1a435SJohn Baldwin } 13670d1a435SJohn Baldwin 13770d1a435SJohn Baldwin static int 13855b7a0e1SJohn Baldwin ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls, 13955b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 14055b7a0e1SJohn Baldwin struct iovec *outiov, int iovcnt, uint64_t seqno, 14155b7a0e1SJohn Baldwin uint8_t record_type __unused) 142b2e60773SJohn Baldwin { 143080933c0SJohn Baldwin struct uio uio, out_uio, *tag_uio; 144b2e60773SJohn Baldwin struct tls_aead_data ad; 14533a1a488SJohn Baldwin struct cryptop crp; 146b2e60773SJohn Baldwin struct ocf_session *os; 14733a1a488SJohn Baldwin struct iovec iov[iovcnt + 1]; 148b2e60773SJohn Baldwin int i, error; 149b2e60773SJohn Baldwin uint16_t tls_comp_len; 150080933c0SJohn Baldwin bool inplace; 151b2e60773SJohn Baldwin 152b2e60773SJohn Baldwin os = tls->cipher; 153b2e60773SJohn Baldwin 1545b750b9aSJohn Baldwin uio.uio_iov = iniov; 1555b750b9aSJohn Baldwin uio.uio_iovcnt = iovcnt; 156080933c0SJohn Baldwin uio.uio_offset = 0; 157080933c0SJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 158080933c0SJohn Baldwin uio.uio_td = curthread; 159080933c0SJohn Baldwin 1605b750b9aSJohn Baldwin out_uio.uio_iov = outiov; 1615b750b9aSJohn Baldwin out_uio.uio_iovcnt = iovcnt; 162080933c0SJohn Baldwin out_uio.uio_offset = 0; 163080933c0SJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 164080933c0SJohn Baldwin out_uio.uio_td = curthread; 165b2e60773SJohn Baldwin 16633a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 167b2e60773SJohn Baldwin 168b2e60773SJohn Baldwin /* Setup the IV. */ 16933a1a488SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 17033a1a488SJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t)); 171b2e60773SJohn Baldwin 172b2e60773SJohn Baldwin /* Setup the AAD. */ 173b2e60773SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 174c0341432SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 175b2e60773SJohn Baldwin ad.seq = htobe64(seqno); 176b2e60773SJohn Baldwin ad.type = hdr->tls_type; 177b2e60773SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 178b2e60773SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 179b2e60773SJohn Baldwin ad.tls_length = htons(tls_comp_len); 18033a1a488SJohn Baldwin crp.crp_aad = &ad; 18133a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 182b2e60773SJohn Baldwin 183080933c0SJohn Baldwin /* Compute payload length and determine if encryption is in place. */ 184080933c0SJohn Baldwin inplace = true; 18533a1a488SJohn Baldwin crp.crp_payload_start = 0; 186b2e60773SJohn Baldwin for (i = 0; i < iovcnt; i++) { 187b2e60773SJohn Baldwin if (iniov[i].iov_base != outiov[i].iov_base) 188080933c0SJohn Baldwin inplace = false; 18933a1a488SJohn Baldwin crp.crp_payload_length += iniov[i].iov_len; 190b2e60773SJohn Baldwin } 19133a1a488SJohn Baldwin uio.uio_resid = crp.crp_payload_length; 19233a1a488SJohn Baldwin out_uio.uio_resid = crp.crp_payload_length; 193b2e60773SJohn Baldwin 194080933c0SJohn Baldwin if (inplace) 195080933c0SJohn Baldwin tag_uio = &uio; 196080933c0SJohn Baldwin else 197080933c0SJohn Baldwin tag_uio = &out_uio; 198b2e60773SJohn Baldwin 1995b750b9aSJohn Baldwin /* Duplicate iovec and append vector for tag. */ 20033a1a488SJohn Baldwin memcpy(iov, tag_uio->uio_iov, iovcnt * sizeof(struct iovec)); 20133a1a488SJohn Baldwin iov[iovcnt].iov_base = trailer; 20233a1a488SJohn Baldwin iov[iovcnt].iov_len = AES_GMAC_HASH_LEN; 20333a1a488SJohn Baldwin tag_uio->uio_iov = iov; 204080933c0SJohn Baldwin tag_uio->uio_iovcnt++; 20533a1a488SJohn Baldwin crp.crp_digest_start = tag_uio->uio_resid; 206080933c0SJohn Baldwin tag_uio->uio_resid += AES_GMAC_HASH_LEN; 207b2e60773SJohn Baldwin 20833a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 20933a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 21033a1a488SJohn Baldwin crypto_use_uio(&crp, &uio); 211080933c0SJohn Baldwin if (!inplace) 21233a1a488SJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 213b2e60773SJohn Baldwin 21455b7a0e1SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 215080933c0SJohn Baldwin if (inplace) 216080933c0SJohn Baldwin counter_u64_add(ocf_inplace, 1); 217080933c0SJohn Baldwin else 218080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 21970d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 22055b7a0e1SJohn Baldwin 22133a1a488SJohn Baldwin crypto_destroyreq(&crp); 22255b7a0e1SJohn Baldwin return (error); 22355b7a0e1SJohn Baldwin } 22455b7a0e1SJohn Baldwin 22555b7a0e1SJohn Baldwin static int 226*3c0e5685SJohn Baldwin ktls_ocf_tls12_gcm_decrypt(struct ktls_session *tls, 227*3c0e5685SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 228*3c0e5685SJohn Baldwin int *trailer_len) 229*3c0e5685SJohn Baldwin { 230*3c0e5685SJohn Baldwin struct tls_aead_data ad; 231*3c0e5685SJohn Baldwin struct cryptop crp; 232*3c0e5685SJohn Baldwin struct ocf_session *os; 233*3c0e5685SJohn Baldwin struct ocf_operation oo; 234*3c0e5685SJohn Baldwin int error; 235*3c0e5685SJohn Baldwin uint16_t tls_comp_len; 236*3c0e5685SJohn Baldwin 237*3c0e5685SJohn Baldwin os = tls->cipher; 238*3c0e5685SJohn Baldwin 239*3c0e5685SJohn Baldwin oo.os = os; 240*3c0e5685SJohn Baldwin oo.done = false; 241*3c0e5685SJohn Baldwin 242*3c0e5685SJohn Baldwin crypto_initreq(&crp, os->sid); 243*3c0e5685SJohn Baldwin 244*3c0e5685SJohn Baldwin /* Setup the IV. */ 245*3c0e5685SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 246*3c0e5685SJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t)); 247*3c0e5685SJohn Baldwin 248*3c0e5685SJohn Baldwin /* Setup the AAD. */ 249*3c0e5685SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 250*3c0e5685SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 251*3c0e5685SJohn Baldwin ad.seq = htobe64(seqno); 252*3c0e5685SJohn Baldwin ad.type = hdr->tls_type; 253*3c0e5685SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 254*3c0e5685SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 255*3c0e5685SJohn Baldwin ad.tls_length = htons(tls_comp_len); 256*3c0e5685SJohn Baldwin crp.crp_aad = &ad; 257*3c0e5685SJohn Baldwin crp.crp_aad_length = sizeof(ad); 258*3c0e5685SJohn Baldwin 259*3c0e5685SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 260*3c0e5685SJohn Baldwin crp.crp_payload_length = tls_comp_len; 261*3c0e5685SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 262*3c0e5685SJohn Baldwin 263*3c0e5685SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 264*3c0e5685SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 265*3c0e5685SJohn Baldwin crypto_use_mbuf(&crp, m); 266*3c0e5685SJohn Baldwin 267*3c0e5685SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 268*3c0e5685SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 269*3c0e5685SJohn Baldwin 270*3c0e5685SJohn Baldwin crypto_destroyreq(&crp); 271*3c0e5685SJohn Baldwin *trailer_len = AES_GMAC_HASH_LEN; 272*3c0e5685SJohn Baldwin return (error); 273*3c0e5685SJohn Baldwin } 274*3c0e5685SJohn Baldwin 275*3c0e5685SJohn Baldwin static int 27655b7a0e1SJohn Baldwin ktls_ocf_tls13_gcm_encrypt(struct ktls_session *tls, 27755b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 27855b7a0e1SJohn Baldwin struct iovec *outiov, int iovcnt, uint64_t seqno, uint8_t record_type) 27955b7a0e1SJohn Baldwin { 280080933c0SJohn Baldwin struct uio uio, out_uio; 28155b7a0e1SJohn Baldwin struct tls_aead_data_13 ad; 28255b7a0e1SJohn Baldwin char nonce[12]; 28333a1a488SJohn Baldwin struct cryptop crp; 28455b7a0e1SJohn Baldwin struct ocf_session *os; 28533a1a488SJohn Baldwin struct iovec iov[iovcnt + 1], out_iov[iovcnt + 1]; 28655b7a0e1SJohn Baldwin int i, error; 287080933c0SJohn Baldwin bool inplace; 28855b7a0e1SJohn Baldwin 28955b7a0e1SJohn Baldwin os = tls->cipher; 29055b7a0e1SJohn Baldwin 29133a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 29255b7a0e1SJohn Baldwin 29355b7a0e1SJohn Baldwin /* Setup the nonce. */ 29455b7a0e1SJohn Baldwin memcpy(nonce, tls->params.iv, tls->params.iv_len); 29555b7a0e1SJohn Baldwin *(uint64_t *)(nonce + 4) ^= htobe64(seqno); 29655b7a0e1SJohn Baldwin 29755b7a0e1SJohn Baldwin /* Setup the AAD. */ 29855b7a0e1SJohn Baldwin ad.type = hdr->tls_type; 29955b7a0e1SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 30055b7a0e1SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 30155b7a0e1SJohn Baldwin ad.tls_length = hdr->tls_length; 30233a1a488SJohn Baldwin crp.crp_aad = &ad; 30333a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 304080933c0SJohn Baldwin 305080933c0SJohn Baldwin /* Compute payload length and determine if encryption is in place. */ 306080933c0SJohn Baldwin inplace = true; 30733a1a488SJohn Baldwin crp.crp_payload_start = 0; 308080933c0SJohn Baldwin for (i = 0; i < iovcnt; i++) { 309080933c0SJohn Baldwin if (iniov[i].iov_base != outiov[i].iov_base) 310080933c0SJohn Baldwin inplace = false; 31133a1a488SJohn Baldwin crp.crp_payload_length += iniov[i].iov_len; 312080933c0SJohn Baldwin } 31355b7a0e1SJohn Baldwin 3145b750b9aSJohn Baldwin /* Store the record type as the first byte of the trailer. */ 31555b7a0e1SJohn Baldwin trailer[0] = record_type; 31633a1a488SJohn Baldwin crp.crp_payload_length++; 31733a1a488SJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 3185b750b9aSJohn Baldwin 3195b750b9aSJohn Baldwin /* 3205b750b9aSJohn Baldwin * Duplicate the input iov to append the trailer. Always 3215b750b9aSJohn Baldwin * include the full trailer as input to get the record_type 3225b750b9aSJohn Baldwin * even if only the first byte is used. 3235b750b9aSJohn Baldwin */ 3245b750b9aSJohn Baldwin memcpy(iov, iniov, iovcnt * sizeof(*iov)); 3255b750b9aSJohn Baldwin iov[iovcnt].iov_base = trailer; 3265b750b9aSJohn Baldwin iov[iovcnt].iov_len = AES_GMAC_HASH_LEN + 1; 3275b750b9aSJohn Baldwin uio.uio_iov = iov; 3285b750b9aSJohn Baldwin uio.uio_iovcnt = iovcnt + 1; 3295b750b9aSJohn Baldwin uio.uio_offset = 0; 33033a1a488SJohn Baldwin uio.uio_resid = crp.crp_payload_length + AES_GMAC_HASH_LEN; 3315b750b9aSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 3325b750b9aSJohn Baldwin uio.uio_td = curthread; 33333a1a488SJohn Baldwin crypto_use_uio(&crp, &uio); 3345b750b9aSJohn Baldwin 3355b750b9aSJohn Baldwin if (!inplace) { 3365b750b9aSJohn Baldwin /* Duplicate the output iov to append the trailer. */ 3375b750b9aSJohn Baldwin memcpy(out_iov, outiov, iovcnt * sizeof(*out_iov)); 3385b750b9aSJohn Baldwin out_iov[iovcnt] = iov[iovcnt]; 3395b750b9aSJohn Baldwin 3405b750b9aSJohn Baldwin out_uio.uio_iov = out_iov; 3415b750b9aSJohn Baldwin out_uio.uio_iovcnt = iovcnt + 1; 3425b750b9aSJohn Baldwin out_uio.uio_offset = 0; 34333a1a488SJohn Baldwin out_uio.uio_resid = crp.crp_payload_length + 3445b750b9aSJohn Baldwin AES_GMAC_HASH_LEN; 3455b750b9aSJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 3465b750b9aSJohn Baldwin out_uio.uio_td = curthread; 34733a1a488SJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 348080933c0SJohn Baldwin } 34955b7a0e1SJohn Baldwin 35033a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 35133a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 35255b7a0e1SJohn Baldwin 35333a1a488SJohn Baldwin memcpy(crp.crp_iv, nonce, sizeof(nonce)); 35455b7a0e1SJohn Baldwin 35555b7a0e1SJohn Baldwin counter_u64_add(ocf_tls13_gcm_crypts, 1); 356080933c0SJohn Baldwin if (inplace) 357080933c0SJohn Baldwin counter_u64_add(ocf_inplace, 1); 358080933c0SJohn Baldwin else 359080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 36070d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 361b2e60773SJohn Baldwin 36233a1a488SJohn Baldwin crypto_destroyreq(&crp); 363b2e60773SJohn Baldwin return (error); 364b2e60773SJohn Baldwin } 365b2e60773SJohn Baldwin 366b2e60773SJohn Baldwin static void 367b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 368b2e60773SJohn Baldwin { 369b2e60773SJohn Baldwin struct ocf_session *os; 370b2e60773SJohn Baldwin 371b2e60773SJohn Baldwin os = tls->cipher; 372c0341432SJohn Baldwin crypto_freesession(os->sid); 373b2e60773SJohn Baldwin mtx_destroy(&os->lock); 3744a711b8dSJohn Baldwin zfree(os, M_KTLS_OCF); 375b2e60773SJohn Baldwin } 376b2e60773SJohn Baldwin 377b2e60773SJohn Baldwin static int 378*3c0e5685SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction) 379b2e60773SJohn Baldwin { 380c0341432SJohn Baldwin struct crypto_session_params csp; 381b2e60773SJohn Baldwin struct ocf_session *os; 382b2e60773SJohn Baldwin int error; 383b2e60773SJohn Baldwin 384c0341432SJohn Baldwin memset(&csp, 0, sizeof(csp)); 3855b750b9aSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 386b2e60773SJohn Baldwin 387b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 388b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 389b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 390b2e60773SJohn Baldwin case 128 / 8: 391b2e60773SJohn Baldwin case 256 / 8: 392b2e60773SJohn Baldwin break; 393b2e60773SJohn Baldwin default: 394b2e60773SJohn Baldwin return (EINVAL); 395b2e60773SJohn Baldwin } 396c0341432SJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 397c0341432SJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16; 398c0341432SJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 399c0341432SJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 400c0341432SJohn Baldwin csp.csp_ivlen = AES_GCM_IV_LEN; 401b2e60773SJohn Baldwin break; 402b2e60773SJohn Baldwin default: 403b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 404b2e60773SJohn Baldwin } 405b2e60773SJohn Baldwin 40655b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 407b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 40855b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 40955b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 410b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 411b2e60773SJohn Baldwin 412*3c0e5685SJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 413*3c0e5685SJohn Baldwin if (direction == KTLS_RX && 414*3c0e5685SJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 415*3c0e5685SJohn Baldwin return (EPROTONOSUPPORT); 416*3c0e5685SJohn Baldwin 417b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 418b2e60773SJohn Baldwin if (os == NULL) 419b2e60773SJohn Baldwin return (ENOMEM); 420b2e60773SJohn Baldwin 421c0341432SJohn Baldwin error = crypto_newsession(&os->sid, &csp, 422b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 423b2e60773SJohn Baldwin if (error) { 424b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 425b2e60773SJohn Baldwin return (error); 426b2e60773SJohn Baldwin } 427b2e60773SJohn Baldwin 428b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 429b2e60773SJohn Baldwin tls->cipher = os; 430*3c0e5685SJohn Baldwin if (direction == KTLS_TX) { 43155b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 43255b7a0e1SJohn Baldwin tls->sw_encrypt = ktls_ocf_tls13_gcm_encrypt; 43355b7a0e1SJohn Baldwin else 43455b7a0e1SJohn Baldwin tls->sw_encrypt = ktls_ocf_tls12_gcm_encrypt; 435*3c0e5685SJohn Baldwin } else { 436*3c0e5685SJohn Baldwin tls->sw_decrypt = ktls_ocf_tls12_gcm_decrypt; 437*3c0e5685SJohn Baldwin } 438b2e60773SJohn Baldwin tls->free = ktls_ocf_free; 439b2e60773SJohn Baldwin return (0); 440b2e60773SJohn Baldwin } 441b2e60773SJohn Baldwin 442b2e60773SJohn Baldwin struct ktls_crypto_backend ocf_backend = { 443b2e60773SJohn Baldwin .name = "OCF", 444b2e60773SJohn Baldwin .prio = 5, 445b2e60773SJohn Baldwin .api_version = KTLS_API_VERSION, 446b2e60773SJohn Baldwin .try = ktls_ocf_try, 447b2e60773SJohn Baldwin }; 448b2e60773SJohn Baldwin 449b2e60773SJohn Baldwin static int 450b2e60773SJohn Baldwin ktls_ocf_modevent(module_t mod, int what, void *arg) 451b2e60773SJohn Baldwin { 452b2e60773SJohn Baldwin int error; 453b2e60773SJohn Baldwin 454b2e60773SJohn Baldwin switch (what) { 455b2e60773SJohn Baldwin case MOD_LOAD: 45655b7a0e1SJohn Baldwin ocf_tls12_gcm_crypts = counter_u64_alloc(M_WAITOK); 45755b7a0e1SJohn Baldwin ocf_tls13_gcm_crypts = counter_u64_alloc(M_WAITOK); 458080933c0SJohn Baldwin ocf_inplace = counter_u64_alloc(M_WAITOK); 459080933c0SJohn Baldwin ocf_separate_output = counter_u64_alloc(M_WAITOK); 460b2e60773SJohn Baldwin ocf_retries = counter_u64_alloc(M_WAITOK); 461b2e60773SJohn Baldwin return (ktls_crypto_backend_register(&ocf_backend)); 462b2e60773SJohn Baldwin case MOD_UNLOAD: 463b2e60773SJohn Baldwin error = ktls_crypto_backend_deregister(&ocf_backend); 464b2e60773SJohn Baldwin if (error) 465b2e60773SJohn Baldwin return (error); 46655b7a0e1SJohn Baldwin counter_u64_free(ocf_tls12_gcm_crypts); 46755b7a0e1SJohn Baldwin counter_u64_free(ocf_tls13_gcm_crypts); 468080933c0SJohn Baldwin counter_u64_free(ocf_inplace); 469080933c0SJohn Baldwin counter_u64_free(ocf_separate_output); 470b2e60773SJohn Baldwin counter_u64_free(ocf_retries); 471b2e60773SJohn Baldwin return (0); 472b2e60773SJohn Baldwin default: 473b2e60773SJohn Baldwin return (EOPNOTSUPP); 474b2e60773SJohn Baldwin } 475b2e60773SJohn Baldwin } 476b2e60773SJohn Baldwin 477b2e60773SJohn Baldwin static moduledata_t ktls_ocf_moduledata = { 478b2e60773SJohn Baldwin "ktls_ocf", 479b2e60773SJohn Baldwin ktls_ocf_modevent, 480b2e60773SJohn Baldwin NULL 481b2e60773SJohn Baldwin }; 482b2e60773SJohn Baldwin 483b2e60773SJohn Baldwin DECLARE_MODULE(ktls_ocf, ktls_ocf_moduledata, SI_SUB_PROTO_END, SI_ORDER_ANY); 484