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; 4847e2650eSJohn Baldwin crypto_session_t mac_sid; 4947e2650eSJohn Baldwin int mac_len; 50b2e60773SJohn Baldwin struct mtx lock; 5147e2650eSJohn Baldwin bool implicit_iv; 5247e2650eSJohn Baldwin 5347e2650eSJohn Baldwin /* Only used for TLS 1.0 with the implicit IV. */ 5447e2650eSJohn Baldwin #ifdef INVARIANTS 5547e2650eSJohn Baldwin bool in_progress; 5647e2650eSJohn Baldwin uint64_t next_seqno; 5747e2650eSJohn Baldwin #endif 5847e2650eSJohn Baldwin char iv[AES_BLOCK_LEN]; 59b2e60773SJohn Baldwin }; 60b2e60773SJohn Baldwin 61b2e60773SJohn Baldwin struct ocf_operation { 62b2e60773SJohn Baldwin struct ocf_session *os; 63b2e60773SJohn Baldwin bool done; 64b2e60773SJohn Baldwin }; 65b2e60773SJohn Baldwin 66b2e60773SJohn Baldwin static MALLOC_DEFINE(M_KTLS_OCF, "ktls_ocf", "OCF KTLS"); 67b2e60773SJohn Baldwin 68b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls); 69b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls_stats); 70b2e60773SJohn Baldwin 717029da5cSPawel Biernacki static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf, 727029da5cSPawel Biernacki CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 7355b7a0e1SJohn Baldwin "Kernel TLS offload via OCF stats"); 7455b7a0e1SJohn Baldwin 75*1755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls10_cbc_crypts); 7647e2650eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls10_cbc_crypts, 7747e2650eSJohn Baldwin CTLFLAG_RD, &ocf_tls10_cbc_crypts, 7847e2650eSJohn Baldwin "Total number of OCF TLS 1.0 CBC encryption operations"); 7947e2650eSJohn Baldwin 80*1755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_crypts); 8147e2650eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_crypts, 8247e2650eSJohn Baldwin CTLFLAG_RD, &ocf_tls11_cbc_crypts, 8347e2650eSJohn Baldwin "Total number of OCF TLS 1.1/1.2 CBC encryption operations"); 8447e2650eSJohn Baldwin 85*1755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_crypts); 8655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_crypts, 8755b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_crypts, 8855b7a0e1SJohn Baldwin "Total number of OCF TLS 1.2 GCM encryption operations"); 8955b7a0e1SJohn Baldwin 90*1755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_crypts); 9155b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_crypts, 9255b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_crypts, 9355b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 94b2e60773SJohn Baldwin 95*1755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_inplace); 96080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace, 97080933c0SJohn Baldwin CTLFLAG_RD, &ocf_inplace, 98080933c0SJohn Baldwin "Total number of OCF in-place operations"); 99080933c0SJohn Baldwin 100*1755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_separate_output); 101080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output, 102080933c0SJohn Baldwin CTLFLAG_RD, &ocf_separate_output, 103080933c0SJohn Baldwin "Total number of OCF operations with a separate output buffer"); 104080933c0SJohn Baldwin 105*1755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_retries); 10655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 107b2e60773SJohn Baldwin &ocf_retries, 108b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 109b2e60773SJohn Baldwin 110b2e60773SJohn Baldwin static int 111b2e60773SJohn Baldwin ktls_ocf_callback(struct cryptop *crp) 112b2e60773SJohn Baldwin { 113b2e60773SJohn Baldwin struct ocf_operation *oo; 114b2e60773SJohn Baldwin 115b2e60773SJohn Baldwin oo = crp->crp_opaque; 116b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 117b2e60773SJohn Baldwin oo->done = true; 118b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 119b2e60773SJohn Baldwin wakeup(oo); 120b2e60773SJohn Baldwin return (0); 121b2e60773SJohn Baldwin } 122b2e60773SJohn Baldwin 123b2e60773SJohn Baldwin static int 12470d1a435SJohn Baldwin ktls_ocf_dispatch(struct ocf_session *os, struct cryptop *crp) 12570d1a435SJohn Baldwin { 12670d1a435SJohn Baldwin struct ocf_operation oo; 12770d1a435SJohn Baldwin int error; 12870d1a435SJohn Baldwin 12970d1a435SJohn Baldwin oo.os = os; 13070d1a435SJohn Baldwin oo.done = false; 13170d1a435SJohn Baldwin 13270d1a435SJohn Baldwin crp->crp_opaque = &oo; 13370d1a435SJohn Baldwin crp->crp_callback = ktls_ocf_callback; 13470d1a435SJohn Baldwin for (;;) { 13570d1a435SJohn Baldwin error = crypto_dispatch(crp); 13670d1a435SJohn Baldwin if (error) 13770d1a435SJohn Baldwin break; 13870d1a435SJohn Baldwin 13970d1a435SJohn Baldwin mtx_lock(&os->lock); 14070d1a435SJohn Baldwin while (!oo.done) 14170d1a435SJohn Baldwin mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0); 14270d1a435SJohn Baldwin mtx_unlock(&os->lock); 14370d1a435SJohn Baldwin 14470d1a435SJohn Baldwin if (crp->crp_etype != EAGAIN) { 14570d1a435SJohn Baldwin error = crp->crp_etype; 14670d1a435SJohn Baldwin break; 14770d1a435SJohn Baldwin } 14870d1a435SJohn Baldwin 14970d1a435SJohn Baldwin crp->crp_etype = 0; 15070d1a435SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 15170d1a435SJohn Baldwin oo.done = false; 15270d1a435SJohn Baldwin counter_u64_add(ocf_retries, 1); 15370d1a435SJohn Baldwin } 15470d1a435SJohn Baldwin return (error); 15570d1a435SJohn Baldwin } 15670d1a435SJohn Baldwin 15770d1a435SJohn Baldwin static int 15847e2650eSJohn Baldwin ktls_ocf_tls_cbc_encrypt(struct ktls_session *tls, 15947e2650eSJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 16047e2650eSJohn Baldwin struct iovec *outiov, int iovcnt, uint64_t seqno, 16147e2650eSJohn Baldwin uint8_t record_type __unused) 16247e2650eSJohn Baldwin { 16347e2650eSJohn Baldwin struct uio uio, out_uio; 16447e2650eSJohn Baldwin struct tls_mac_data ad; 16547e2650eSJohn Baldwin struct cryptop crp; 16647e2650eSJohn Baldwin struct ocf_session *os; 16747e2650eSJohn Baldwin struct iovec iov[iovcnt + 2]; 16847e2650eSJohn Baldwin struct iovec out_iov[iovcnt + 1]; 16947e2650eSJohn Baldwin int i, error; 17047e2650eSJohn Baldwin uint16_t tls_comp_len; 17147e2650eSJohn Baldwin uint8_t pad; 17247e2650eSJohn Baldwin bool inplace; 17347e2650eSJohn Baldwin 17447e2650eSJohn Baldwin os = tls->cipher; 17547e2650eSJohn Baldwin 17647e2650eSJohn Baldwin #ifdef INVARIANTS 17747e2650eSJohn Baldwin if (os->implicit_iv) { 17847e2650eSJohn Baldwin mtx_lock(&os->lock); 17947e2650eSJohn Baldwin KASSERT(!os->in_progress, 18047e2650eSJohn Baldwin ("concurrent implicit IV encryptions")); 18147e2650eSJohn Baldwin if (os->next_seqno != seqno) { 18247e2650eSJohn Baldwin printf("KTLS CBC: TLS records out of order. " 18347e2650eSJohn Baldwin "Expected %ju, got %ju\n", 18447e2650eSJohn Baldwin (uintmax_t)os->next_seqno, (uintmax_t)seqno); 18547e2650eSJohn Baldwin mtx_unlock(&os->lock); 18647e2650eSJohn Baldwin return (EINVAL); 18747e2650eSJohn Baldwin } 18847e2650eSJohn Baldwin os->in_progress = true; 18947e2650eSJohn Baldwin mtx_unlock(&os->lock); 19047e2650eSJohn Baldwin } 19147e2650eSJohn Baldwin #endif 19247e2650eSJohn Baldwin 19347e2650eSJohn Baldwin /* 19447e2650eSJohn Baldwin * Compute the payload length. 19547e2650eSJohn Baldwin * 19647e2650eSJohn Baldwin * XXX: This could be easily computed O(1) from the mbuf 19747e2650eSJohn Baldwin * fields, but we don't have those accessible here. Can 19847e2650eSJohn Baldwin * at least compute inplace as well while we are here. 19947e2650eSJohn Baldwin */ 20047e2650eSJohn Baldwin tls_comp_len = 0; 20147e2650eSJohn Baldwin inplace = true; 20247e2650eSJohn Baldwin for (i = 0; i < iovcnt; i++) { 20347e2650eSJohn Baldwin tls_comp_len += iniov[i].iov_len; 20447e2650eSJohn Baldwin if (iniov[i].iov_base != outiov[i].iov_base) 20547e2650eSJohn Baldwin inplace = false; 20647e2650eSJohn Baldwin } 20747e2650eSJohn Baldwin 20847e2650eSJohn Baldwin /* Initialize the AAD. */ 20947e2650eSJohn Baldwin ad.seq = htobe64(seqno); 21047e2650eSJohn Baldwin ad.type = hdr->tls_type; 21147e2650eSJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 21247e2650eSJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 21347e2650eSJohn Baldwin ad.tls_length = htons(tls_comp_len); 21447e2650eSJohn Baldwin 21547e2650eSJohn Baldwin /* First, compute the MAC. */ 21647e2650eSJohn Baldwin iov[0].iov_base = &ad; 21747e2650eSJohn Baldwin iov[0].iov_len = sizeof(ad); 21847e2650eSJohn Baldwin memcpy(&iov[1], iniov, sizeof(*iniov) * iovcnt); 21947e2650eSJohn Baldwin iov[iovcnt + 1].iov_base = trailer; 22047e2650eSJohn Baldwin iov[iovcnt + 1].iov_len = os->mac_len; 22147e2650eSJohn Baldwin uio.uio_iov = iov; 22247e2650eSJohn Baldwin uio.uio_iovcnt = iovcnt + 2; 22347e2650eSJohn Baldwin uio.uio_offset = 0; 22447e2650eSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 22547e2650eSJohn Baldwin uio.uio_td = curthread; 22647e2650eSJohn Baldwin uio.uio_resid = sizeof(ad) + tls_comp_len + os->mac_len; 22747e2650eSJohn Baldwin 22847e2650eSJohn Baldwin crypto_initreq(&crp, os->mac_sid); 22947e2650eSJohn Baldwin crp.crp_payload_start = 0; 23047e2650eSJohn Baldwin crp.crp_payload_length = sizeof(ad) + tls_comp_len; 23147e2650eSJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 23247e2650eSJohn Baldwin crp.crp_op = CRYPTO_OP_COMPUTE_DIGEST; 23347e2650eSJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM; 23447e2650eSJohn Baldwin crypto_use_uio(&crp, &uio); 23547e2650eSJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 23647e2650eSJohn Baldwin 23747e2650eSJohn Baldwin crypto_destroyreq(&crp); 23847e2650eSJohn Baldwin if (error) { 23947e2650eSJohn Baldwin #ifdef INVARIANTS 24047e2650eSJohn Baldwin if (os->implicit_iv) { 24147e2650eSJohn Baldwin mtx_lock(&os->lock); 24247e2650eSJohn Baldwin os->in_progress = false; 24347e2650eSJohn Baldwin mtx_unlock(&os->lock); 24447e2650eSJohn Baldwin } 24547e2650eSJohn Baldwin #endif 24647e2650eSJohn Baldwin return (error); 24747e2650eSJohn Baldwin } 24847e2650eSJohn Baldwin 24947e2650eSJohn Baldwin /* Second, add the padding. */ 25047e2650eSJohn Baldwin pad = (unsigned)(AES_BLOCK_LEN - (tls_comp_len + os->mac_len + 1)) % 25147e2650eSJohn Baldwin AES_BLOCK_LEN; 25247e2650eSJohn Baldwin for (i = 0; i < pad + 1; i++) 25347e2650eSJohn Baldwin trailer[os->mac_len + i] = pad; 25447e2650eSJohn Baldwin 25547e2650eSJohn Baldwin /* Finally, encrypt the record. */ 25647e2650eSJohn Baldwin 25747e2650eSJohn Baldwin /* 25847e2650eSJohn Baldwin * Don't recopy the input iovec, instead just adjust the 25947e2650eSJohn Baldwin * trailer length and skip over the AAD vector in the uio. 26047e2650eSJohn Baldwin */ 26147e2650eSJohn Baldwin iov[iovcnt + 1].iov_len += pad + 1; 26247e2650eSJohn Baldwin uio.uio_iov = iov + 1; 26347e2650eSJohn Baldwin uio.uio_iovcnt = iovcnt + 1; 26447e2650eSJohn Baldwin uio.uio_resid = tls_comp_len + iov[iovcnt + 1].iov_len; 26547e2650eSJohn Baldwin KASSERT(uio.uio_resid % AES_BLOCK_LEN == 0, 26647e2650eSJohn Baldwin ("invalid encryption size")); 26747e2650eSJohn Baldwin 26847e2650eSJohn Baldwin crypto_initreq(&crp, os->sid); 26947e2650eSJohn Baldwin crp.crp_payload_start = 0; 27047e2650eSJohn Baldwin crp.crp_payload_length = uio.uio_resid; 27147e2650eSJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT; 27247e2650eSJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 27347e2650eSJohn Baldwin if (os->implicit_iv) 27447e2650eSJohn Baldwin memcpy(crp.crp_iv, os->iv, AES_BLOCK_LEN); 27547e2650eSJohn Baldwin else 27647e2650eSJohn Baldwin memcpy(crp.crp_iv, hdr + 1, AES_BLOCK_LEN); 27747e2650eSJohn Baldwin crypto_use_uio(&crp, &uio); 27847e2650eSJohn Baldwin if (!inplace) { 27947e2650eSJohn Baldwin memcpy(out_iov, outiov, sizeof(*iniov) * iovcnt); 28047e2650eSJohn Baldwin out_iov[iovcnt] = iov[iovcnt + 1]; 28147e2650eSJohn Baldwin out_uio.uio_iov = out_iov; 28247e2650eSJohn Baldwin out_uio.uio_iovcnt = iovcnt + 1; 28347e2650eSJohn Baldwin out_uio.uio_offset = 0; 28447e2650eSJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 28547e2650eSJohn Baldwin out_uio.uio_td = curthread; 28647e2650eSJohn Baldwin out_uio.uio_resid = uio.uio_resid; 28747e2650eSJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 28847e2650eSJohn Baldwin } 28947e2650eSJohn Baldwin 29047e2650eSJohn Baldwin if (os->implicit_iv) 29147e2650eSJohn Baldwin counter_u64_add(ocf_tls10_cbc_crypts, 1); 29247e2650eSJohn Baldwin else 29347e2650eSJohn Baldwin counter_u64_add(ocf_tls11_cbc_crypts, 1); 29447e2650eSJohn Baldwin if (inplace) 29547e2650eSJohn Baldwin counter_u64_add(ocf_inplace, 1); 29647e2650eSJohn Baldwin else 29747e2650eSJohn Baldwin counter_u64_add(ocf_separate_output, 1); 29847e2650eSJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 29947e2650eSJohn Baldwin 30047e2650eSJohn Baldwin crypto_destroyreq(&crp); 30147e2650eSJohn Baldwin 30247e2650eSJohn Baldwin if (os->implicit_iv) { 30347e2650eSJohn Baldwin KASSERT(os->mac_len + pad + 1 >= AES_BLOCK_LEN, 30447e2650eSJohn Baldwin ("trailer too short to read IV")); 30547e2650eSJohn Baldwin memcpy(os->iv, trailer + os->mac_len + pad + 1 - AES_BLOCK_LEN, 30647e2650eSJohn Baldwin AES_BLOCK_LEN); 30747e2650eSJohn Baldwin #ifdef INVARIANTS 30847e2650eSJohn Baldwin mtx_lock(&os->lock); 30947e2650eSJohn Baldwin os->next_seqno = seqno + 1; 31047e2650eSJohn Baldwin os->in_progress = false; 31147e2650eSJohn Baldwin mtx_unlock(&os->lock); 31247e2650eSJohn Baldwin #endif 31347e2650eSJohn Baldwin } 31447e2650eSJohn Baldwin return (error); 31547e2650eSJohn Baldwin } 31647e2650eSJohn Baldwin 31747e2650eSJohn Baldwin static int 31855b7a0e1SJohn Baldwin ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls, 31955b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 32055b7a0e1SJohn Baldwin struct iovec *outiov, int iovcnt, uint64_t seqno, 32155b7a0e1SJohn Baldwin uint8_t record_type __unused) 322b2e60773SJohn Baldwin { 323080933c0SJohn Baldwin struct uio uio, out_uio, *tag_uio; 324b2e60773SJohn Baldwin struct tls_aead_data ad; 32533a1a488SJohn Baldwin struct cryptop crp; 326b2e60773SJohn Baldwin struct ocf_session *os; 32733a1a488SJohn Baldwin struct iovec iov[iovcnt + 1]; 328b2e60773SJohn Baldwin int i, error; 329b2e60773SJohn Baldwin uint16_t tls_comp_len; 330080933c0SJohn Baldwin bool inplace; 331b2e60773SJohn Baldwin 332b2e60773SJohn Baldwin os = tls->cipher; 333b2e60773SJohn Baldwin 3345b750b9aSJohn Baldwin uio.uio_iov = iniov; 3355b750b9aSJohn Baldwin uio.uio_iovcnt = iovcnt; 336080933c0SJohn Baldwin uio.uio_offset = 0; 337080933c0SJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 338080933c0SJohn Baldwin uio.uio_td = curthread; 339080933c0SJohn Baldwin 3405b750b9aSJohn Baldwin out_uio.uio_iov = outiov; 3415b750b9aSJohn Baldwin out_uio.uio_iovcnt = iovcnt; 342080933c0SJohn Baldwin out_uio.uio_offset = 0; 343080933c0SJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 344080933c0SJohn Baldwin out_uio.uio_td = curthread; 345b2e60773SJohn Baldwin 34633a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 347b2e60773SJohn Baldwin 348b2e60773SJohn Baldwin /* Setup the IV. */ 34933a1a488SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 35033a1a488SJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t)); 351b2e60773SJohn Baldwin 352b2e60773SJohn Baldwin /* Setup the AAD. */ 353b2e60773SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 354c0341432SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 355b2e60773SJohn Baldwin ad.seq = htobe64(seqno); 356b2e60773SJohn Baldwin ad.type = hdr->tls_type; 357b2e60773SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 358b2e60773SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 359b2e60773SJohn Baldwin ad.tls_length = htons(tls_comp_len); 36033a1a488SJohn Baldwin crp.crp_aad = &ad; 36133a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 362b2e60773SJohn Baldwin 363080933c0SJohn Baldwin /* Compute payload length and determine if encryption is in place. */ 364080933c0SJohn Baldwin inplace = true; 36533a1a488SJohn Baldwin crp.crp_payload_start = 0; 366b2e60773SJohn Baldwin for (i = 0; i < iovcnt; i++) { 367b2e60773SJohn Baldwin if (iniov[i].iov_base != outiov[i].iov_base) 368080933c0SJohn Baldwin inplace = false; 36933a1a488SJohn Baldwin crp.crp_payload_length += iniov[i].iov_len; 370b2e60773SJohn Baldwin } 37133a1a488SJohn Baldwin uio.uio_resid = crp.crp_payload_length; 37233a1a488SJohn Baldwin out_uio.uio_resid = crp.crp_payload_length; 373b2e60773SJohn Baldwin 374080933c0SJohn Baldwin if (inplace) 375080933c0SJohn Baldwin tag_uio = &uio; 376080933c0SJohn Baldwin else 377080933c0SJohn Baldwin tag_uio = &out_uio; 378b2e60773SJohn Baldwin 3795b750b9aSJohn Baldwin /* Duplicate iovec and append vector for tag. */ 38033a1a488SJohn Baldwin memcpy(iov, tag_uio->uio_iov, iovcnt * sizeof(struct iovec)); 38133a1a488SJohn Baldwin iov[iovcnt].iov_base = trailer; 38233a1a488SJohn Baldwin iov[iovcnt].iov_len = AES_GMAC_HASH_LEN; 38333a1a488SJohn Baldwin tag_uio->uio_iov = iov; 384080933c0SJohn Baldwin tag_uio->uio_iovcnt++; 38533a1a488SJohn Baldwin crp.crp_digest_start = tag_uio->uio_resid; 386080933c0SJohn Baldwin tag_uio->uio_resid += AES_GMAC_HASH_LEN; 387b2e60773SJohn Baldwin 38833a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 38933a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 39033a1a488SJohn Baldwin crypto_use_uio(&crp, &uio); 391080933c0SJohn Baldwin if (!inplace) 39233a1a488SJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 393b2e60773SJohn Baldwin 39455b7a0e1SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 395080933c0SJohn Baldwin if (inplace) 396080933c0SJohn Baldwin counter_u64_add(ocf_inplace, 1); 397080933c0SJohn Baldwin else 398080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 39970d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 40055b7a0e1SJohn Baldwin 40133a1a488SJohn Baldwin crypto_destroyreq(&crp); 40255b7a0e1SJohn Baldwin return (error); 40355b7a0e1SJohn Baldwin } 40455b7a0e1SJohn Baldwin 40555b7a0e1SJohn Baldwin static int 4063c0e5685SJohn Baldwin ktls_ocf_tls12_gcm_decrypt(struct ktls_session *tls, 4073c0e5685SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 4083c0e5685SJohn Baldwin int *trailer_len) 4093c0e5685SJohn Baldwin { 4103c0e5685SJohn Baldwin struct tls_aead_data ad; 4113c0e5685SJohn Baldwin struct cryptop crp; 4123c0e5685SJohn Baldwin struct ocf_session *os; 4133c0e5685SJohn Baldwin struct ocf_operation oo; 4143c0e5685SJohn Baldwin int error; 4153c0e5685SJohn Baldwin uint16_t tls_comp_len; 4163c0e5685SJohn Baldwin 4173c0e5685SJohn Baldwin os = tls->cipher; 4183c0e5685SJohn Baldwin 4193c0e5685SJohn Baldwin oo.os = os; 4203c0e5685SJohn Baldwin oo.done = false; 4213c0e5685SJohn Baldwin 4223c0e5685SJohn Baldwin crypto_initreq(&crp, os->sid); 4233c0e5685SJohn Baldwin 4243c0e5685SJohn Baldwin /* Setup the IV. */ 4253c0e5685SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 4263c0e5685SJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t)); 4273c0e5685SJohn Baldwin 4283c0e5685SJohn Baldwin /* Setup the AAD. */ 4293c0e5685SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 4303c0e5685SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 4313c0e5685SJohn Baldwin ad.seq = htobe64(seqno); 4323c0e5685SJohn Baldwin ad.type = hdr->tls_type; 4333c0e5685SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 4343c0e5685SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 4353c0e5685SJohn Baldwin ad.tls_length = htons(tls_comp_len); 4363c0e5685SJohn Baldwin crp.crp_aad = &ad; 4373c0e5685SJohn Baldwin crp.crp_aad_length = sizeof(ad); 4383c0e5685SJohn Baldwin 4393c0e5685SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 4403c0e5685SJohn Baldwin crp.crp_payload_length = tls_comp_len; 4413c0e5685SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 4423c0e5685SJohn Baldwin 4433c0e5685SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 4443c0e5685SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 4453c0e5685SJohn Baldwin crypto_use_mbuf(&crp, m); 4463c0e5685SJohn Baldwin 4473c0e5685SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 4483c0e5685SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 4493c0e5685SJohn Baldwin 4503c0e5685SJohn Baldwin crypto_destroyreq(&crp); 4513c0e5685SJohn Baldwin *trailer_len = AES_GMAC_HASH_LEN; 4523c0e5685SJohn Baldwin return (error); 4533c0e5685SJohn Baldwin } 4543c0e5685SJohn Baldwin 4553c0e5685SJohn Baldwin static int 45655b7a0e1SJohn Baldwin ktls_ocf_tls13_gcm_encrypt(struct ktls_session *tls, 45755b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 45855b7a0e1SJohn Baldwin struct iovec *outiov, int iovcnt, uint64_t seqno, uint8_t record_type) 45955b7a0e1SJohn Baldwin { 460080933c0SJohn Baldwin struct uio uio, out_uio; 46155b7a0e1SJohn Baldwin struct tls_aead_data_13 ad; 46255b7a0e1SJohn Baldwin char nonce[12]; 46333a1a488SJohn Baldwin struct cryptop crp; 46455b7a0e1SJohn Baldwin struct ocf_session *os; 46533a1a488SJohn Baldwin struct iovec iov[iovcnt + 1], out_iov[iovcnt + 1]; 46655b7a0e1SJohn Baldwin int i, error; 467080933c0SJohn Baldwin bool inplace; 46855b7a0e1SJohn Baldwin 46955b7a0e1SJohn Baldwin os = tls->cipher; 47055b7a0e1SJohn Baldwin 47133a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 47255b7a0e1SJohn Baldwin 47355b7a0e1SJohn Baldwin /* Setup the nonce. */ 47455b7a0e1SJohn Baldwin memcpy(nonce, tls->params.iv, tls->params.iv_len); 47555b7a0e1SJohn Baldwin *(uint64_t *)(nonce + 4) ^= htobe64(seqno); 47655b7a0e1SJohn Baldwin 47755b7a0e1SJohn Baldwin /* Setup the AAD. */ 47855b7a0e1SJohn Baldwin ad.type = hdr->tls_type; 47955b7a0e1SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 48055b7a0e1SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 48155b7a0e1SJohn Baldwin ad.tls_length = hdr->tls_length; 48233a1a488SJohn Baldwin crp.crp_aad = &ad; 48333a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 484080933c0SJohn Baldwin 485080933c0SJohn Baldwin /* Compute payload length and determine if encryption is in place. */ 486080933c0SJohn Baldwin inplace = true; 48733a1a488SJohn Baldwin crp.crp_payload_start = 0; 488080933c0SJohn Baldwin for (i = 0; i < iovcnt; i++) { 489080933c0SJohn Baldwin if (iniov[i].iov_base != outiov[i].iov_base) 490080933c0SJohn Baldwin inplace = false; 49133a1a488SJohn Baldwin crp.crp_payload_length += iniov[i].iov_len; 492080933c0SJohn Baldwin } 49355b7a0e1SJohn Baldwin 4945b750b9aSJohn Baldwin /* Store the record type as the first byte of the trailer. */ 49555b7a0e1SJohn Baldwin trailer[0] = record_type; 49633a1a488SJohn Baldwin crp.crp_payload_length++; 49733a1a488SJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 4985b750b9aSJohn Baldwin 4995b750b9aSJohn Baldwin /* 5005b750b9aSJohn Baldwin * Duplicate the input iov to append the trailer. Always 5015b750b9aSJohn Baldwin * include the full trailer as input to get the record_type 5025b750b9aSJohn Baldwin * even if only the first byte is used. 5035b750b9aSJohn Baldwin */ 5045b750b9aSJohn Baldwin memcpy(iov, iniov, iovcnt * sizeof(*iov)); 5055b750b9aSJohn Baldwin iov[iovcnt].iov_base = trailer; 5065b750b9aSJohn Baldwin iov[iovcnt].iov_len = AES_GMAC_HASH_LEN + 1; 5075b750b9aSJohn Baldwin uio.uio_iov = iov; 5085b750b9aSJohn Baldwin uio.uio_iovcnt = iovcnt + 1; 5095b750b9aSJohn Baldwin uio.uio_offset = 0; 51033a1a488SJohn Baldwin uio.uio_resid = crp.crp_payload_length + AES_GMAC_HASH_LEN; 5115b750b9aSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 5125b750b9aSJohn Baldwin uio.uio_td = curthread; 51333a1a488SJohn Baldwin crypto_use_uio(&crp, &uio); 5145b750b9aSJohn Baldwin 5155b750b9aSJohn Baldwin if (!inplace) { 5165b750b9aSJohn Baldwin /* Duplicate the output iov to append the trailer. */ 5175b750b9aSJohn Baldwin memcpy(out_iov, outiov, iovcnt * sizeof(*out_iov)); 5185b750b9aSJohn Baldwin out_iov[iovcnt] = iov[iovcnt]; 5195b750b9aSJohn Baldwin 5205b750b9aSJohn Baldwin out_uio.uio_iov = out_iov; 5215b750b9aSJohn Baldwin out_uio.uio_iovcnt = iovcnt + 1; 5225b750b9aSJohn Baldwin out_uio.uio_offset = 0; 52333a1a488SJohn Baldwin out_uio.uio_resid = crp.crp_payload_length + 5245b750b9aSJohn Baldwin AES_GMAC_HASH_LEN; 5255b750b9aSJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 5265b750b9aSJohn Baldwin out_uio.uio_td = curthread; 52733a1a488SJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 528080933c0SJohn Baldwin } 52955b7a0e1SJohn Baldwin 53033a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 53133a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 53255b7a0e1SJohn Baldwin 53333a1a488SJohn Baldwin memcpy(crp.crp_iv, nonce, sizeof(nonce)); 53455b7a0e1SJohn Baldwin 53555b7a0e1SJohn Baldwin counter_u64_add(ocf_tls13_gcm_crypts, 1); 536080933c0SJohn Baldwin if (inplace) 537080933c0SJohn Baldwin counter_u64_add(ocf_inplace, 1); 538080933c0SJohn Baldwin else 539080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 54070d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 541b2e60773SJohn Baldwin 54233a1a488SJohn Baldwin crypto_destroyreq(&crp); 543b2e60773SJohn Baldwin return (error); 544b2e60773SJohn Baldwin } 545b2e60773SJohn Baldwin 546b2e60773SJohn Baldwin static void 547b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 548b2e60773SJohn Baldwin { 549b2e60773SJohn Baldwin struct ocf_session *os; 550b2e60773SJohn Baldwin 551b2e60773SJohn Baldwin os = tls->cipher; 552c0341432SJohn Baldwin crypto_freesession(os->sid); 553b2e60773SJohn Baldwin mtx_destroy(&os->lock); 5544a711b8dSJohn Baldwin zfree(os, M_KTLS_OCF); 555b2e60773SJohn Baldwin } 556b2e60773SJohn Baldwin 557b2e60773SJohn Baldwin static int 5583c0e5685SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction) 559b2e60773SJohn Baldwin { 56047e2650eSJohn Baldwin struct crypto_session_params csp, mac_csp; 561b2e60773SJohn Baldwin struct ocf_session *os; 56247e2650eSJohn Baldwin int error, mac_len; 563b2e60773SJohn Baldwin 564c0341432SJohn Baldwin memset(&csp, 0, sizeof(csp)); 56547e2650eSJohn Baldwin memset(&mac_csp, 0, sizeof(mac_csp)); 56647e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_NONE; 56747e2650eSJohn Baldwin mac_len = 0; 568b2e60773SJohn Baldwin 569b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 570b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 571b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 572b2e60773SJohn Baldwin case 128 / 8: 573b2e60773SJohn Baldwin case 256 / 8: 574b2e60773SJohn Baldwin break; 575b2e60773SJohn Baldwin default: 576b2e60773SJohn Baldwin return (EINVAL); 577b2e60773SJohn Baldwin } 578b2e60773SJohn Baldwin 57955b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 580b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 58155b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 58255b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 583b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 584b2e60773SJohn Baldwin 5853c0e5685SJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 5863c0e5685SJohn Baldwin if (direction == KTLS_RX && 5873c0e5685SJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 5883c0e5685SJohn Baldwin return (EPROTONOSUPPORT); 5893c0e5685SJohn Baldwin 59047e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 59147e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 59247e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16; 59347e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 59447e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 59547e2650eSJohn Baldwin csp.csp_ivlen = AES_GCM_IV_LEN; 59647e2650eSJohn Baldwin break; 59747e2650eSJohn Baldwin case CRYPTO_AES_CBC: 59847e2650eSJohn Baldwin switch (tls->params.cipher_key_len) { 59947e2650eSJohn Baldwin case 128 / 8: 60047e2650eSJohn Baldwin case 256 / 8: 60147e2650eSJohn Baldwin break; 60247e2650eSJohn Baldwin default: 60347e2650eSJohn Baldwin return (EINVAL); 60447e2650eSJohn Baldwin } 60547e2650eSJohn Baldwin 60647e2650eSJohn Baldwin switch (tls->params.auth_algorithm) { 60747e2650eSJohn Baldwin case CRYPTO_SHA1_HMAC: 60847e2650eSJohn Baldwin mac_len = SHA1_HASH_LEN; 60947e2650eSJohn Baldwin break; 61047e2650eSJohn Baldwin case CRYPTO_SHA2_256_HMAC: 61147e2650eSJohn Baldwin mac_len = SHA2_256_HASH_LEN; 61247e2650eSJohn Baldwin break; 61347e2650eSJohn Baldwin case CRYPTO_SHA2_384_HMAC: 61447e2650eSJohn Baldwin mac_len = SHA2_384_HASH_LEN; 61547e2650eSJohn Baldwin break; 61647e2650eSJohn Baldwin default: 61747e2650eSJohn Baldwin return (EINVAL); 61847e2650eSJohn Baldwin } 61947e2650eSJohn Baldwin 62047e2650eSJohn Baldwin /* Only TLS 1.0-1.2 are supported. */ 62147e2650eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 62247e2650eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_ZERO || 62347e2650eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_TWO) 62447e2650eSJohn Baldwin return (EPROTONOSUPPORT); 62547e2650eSJohn Baldwin 62647e2650eSJohn Baldwin /* AES-CBC is not supported for receive. */ 62747e2650eSJohn Baldwin if (direction == KTLS_RX) 62847e2650eSJohn Baldwin return (EPROTONOSUPPORT); 62947e2650eSJohn Baldwin 63047e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 63147e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_CIPHER; 63247e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_CBC; 63347e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 63447e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 63547e2650eSJohn Baldwin csp.csp_ivlen = AES_BLOCK_LEN; 63647e2650eSJohn Baldwin 63747e2650eSJohn Baldwin mac_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 63847e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_DIGEST; 63947e2650eSJohn Baldwin mac_csp.csp_auth_alg = tls->params.auth_algorithm; 64047e2650eSJohn Baldwin mac_csp.csp_auth_key = tls->params.auth_key; 64147e2650eSJohn Baldwin mac_csp.csp_auth_klen = tls->params.auth_key_len; 64247e2650eSJohn Baldwin break; 64347e2650eSJohn Baldwin default: 64447e2650eSJohn Baldwin return (EPROTONOSUPPORT); 64547e2650eSJohn Baldwin } 64647e2650eSJohn Baldwin 647b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 648b2e60773SJohn Baldwin if (os == NULL) 649b2e60773SJohn Baldwin return (ENOMEM); 650b2e60773SJohn Baldwin 651c0341432SJohn Baldwin error = crypto_newsession(&os->sid, &csp, 652b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 653b2e60773SJohn Baldwin if (error) { 654b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 655b2e60773SJohn Baldwin return (error); 656b2e60773SJohn Baldwin } 657b2e60773SJohn Baldwin 65847e2650eSJohn Baldwin if (mac_csp.csp_mode != CSP_MODE_NONE) { 65947e2650eSJohn Baldwin error = crypto_newsession(&os->mac_sid, &mac_csp, 66047e2650eSJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 66147e2650eSJohn Baldwin if (error) { 66247e2650eSJohn Baldwin crypto_freesession(os->sid); 66347e2650eSJohn Baldwin free(os, M_KTLS_OCF); 66447e2650eSJohn Baldwin return (error); 66547e2650eSJohn Baldwin } 66647e2650eSJohn Baldwin os->mac_len = mac_len; 66747e2650eSJohn Baldwin } 66847e2650eSJohn Baldwin 669b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 670b2e60773SJohn Baldwin tls->cipher = os; 67147e2650eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 6723c0e5685SJohn Baldwin if (direction == KTLS_TX) { 67355b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 67455b7a0e1SJohn Baldwin tls->sw_encrypt = ktls_ocf_tls13_gcm_encrypt; 67555b7a0e1SJohn Baldwin else 67655b7a0e1SJohn Baldwin tls->sw_encrypt = ktls_ocf_tls12_gcm_encrypt; 6773c0e5685SJohn Baldwin } else { 6783c0e5685SJohn Baldwin tls->sw_decrypt = ktls_ocf_tls12_gcm_decrypt; 6793c0e5685SJohn Baldwin } 68047e2650eSJohn Baldwin } else { 68147e2650eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls_cbc_encrypt; 68247e2650eSJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_ZERO) { 68347e2650eSJohn Baldwin os->implicit_iv = true; 68447e2650eSJohn Baldwin memcpy(os->iv, tls->params.iv, AES_BLOCK_LEN); 68547e2650eSJohn Baldwin } 68647e2650eSJohn Baldwin } 687b2e60773SJohn Baldwin tls->free = ktls_ocf_free; 688b2e60773SJohn Baldwin return (0); 689b2e60773SJohn Baldwin } 690b2e60773SJohn Baldwin 691b2e60773SJohn Baldwin struct ktls_crypto_backend ocf_backend = { 692b2e60773SJohn Baldwin .name = "OCF", 693b2e60773SJohn Baldwin .prio = 5, 694b2e60773SJohn Baldwin .api_version = KTLS_API_VERSION, 695b2e60773SJohn Baldwin .try = ktls_ocf_try, 696b2e60773SJohn Baldwin }; 697b2e60773SJohn Baldwin 698b2e60773SJohn Baldwin static int 699b2e60773SJohn Baldwin ktls_ocf_modevent(module_t mod, int what, void *arg) 700b2e60773SJohn Baldwin { 701b2e60773SJohn Baldwin switch (what) { 702b2e60773SJohn Baldwin case MOD_LOAD: 703b2e60773SJohn Baldwin return (ktls_crypto_backend_register(&ocf_backend)); 704b2e60773SJohn Baldwin case MOD_UNLOAD: 705*1755b2b9SMark Johnston return (ktls_crypto_backend_deregister(&ocf_backend)); 706b2e60773SJohn Baldwin default: 707b2e60773SJohn Baldwin return (EOPNOTSUPP); 708b2e60773SJohn Baldwin } 709b2e60773SJohn Baldwin } 710b2e60773SJohn Baldwin 711b2e60773SJohn Baldwin static moduledata_t ktls_ocf_moduledata = { 712b2e60773SJohn Baldwin "ktls_ocf", 713b2e60773SJohn Baldwin ktls_ocf_modevent, 714b2e60773SJohn Baldwin NULL 715b2e60773SJohn Baldwin }; 716b2e60773SJohn Baldwin 717b2e60773SJohn Baldwin DECLARE_MODULE(ktls_ocf, ktls_ocf_moduledata, SI_SUB_PROTO_END, SI_ORDER_ANY); 718