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 751755b2b9SMark 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 801755b2b9SMark 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 851755b2b9SMark 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 904dd6800eSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_crypts); 914dd6800eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_crypts, 924dd6800eSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_crypts, 934dd6800eSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 encryption operations"); 944dd6800eSJohn Baldwin 951755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_crypts); 9655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_crypts, 9755b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_crypts, 9855b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 99b2e60773SJohn Baldwin 1004dd6800eSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_crypts); 1014dd6800eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_crypts, 1024dd6800eSJohn Baldwin CTLFLAG_RD, &ocf_tls13_chacha20_crypts, 1034dd6800eSJohn Baldwin "Total number of OCF TLS 1.3 Chacha20-Poly1305 encryption operations"); 1044dd6800eSJohn Baldwin 1051755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_inplace); 106080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace, 107080933c0SJohn Baldwin CTLFLAG_RD, &ocf_inplace, 108080933c0SJohn Baldwin "Total number of OCF in-place operations"); 109080933c0SJohn Baldwin 1101755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_separate_output); 111080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output, 112080933c0SJohn Baldwin CTLFLAG_RD, &ocf_separate_output, 113080933c0SJohn Baldwin "Total number of OCF operations with a separate output buffer"); 114080933c0SJohn Baldwin 1151755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_retries); 11655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 117b2e60773SJohn Baldwin &ocf_retries, 118b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 119b2e60773SJohn Baldwin 120b2e60773SJohn Baldwin static int 121db6b5644SMark Johnston ktls_ocf_callback_sync(struct cryptop *crp __unused) 122db6b5644SMark Johnston { 123db6b5644SMark Johnston return (0); 124db6b5644SMark Johnston } 125db6b5644SMark Johnston 126db6b5644SMark Johnston static int 127db6b5644SMark Johnston ktls_ocf_callback_async(struct cryptop *crp) 128b2e60773SJohn Baldwin { 129b2e60773SJohn Baldwin struct ocf_operation *oo; 130b2e60773SJohn Baldwin 131b2e60773SJohn Baldwin oo = crp->crp_opaque; 132b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 133b2e60773SJohn Baldwin oo->done = true; 134b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 135b2e60773SJohn Baldwin wakeup(oo); 136b2e60773SJohn Baldwin return (0); 137b2e60773SJohn Baldwin } 138b2e60773SJohn Baldwin 139b2e60773SJohn Baldwin static int 14070d1a435SJohn Baldwin ktls_ocf_dispatch(struct ocf_session *os, struct cryptop *crp) 14170d1a435SJohn Baldwin { 14270d1a435SJohn Baldwin struct ocf_operation oo; 14370d1a435SJohn Baldwin int error; 144db6b5644SMark Johnston bool async; 14570d1a435SJohn Baldwin 14670d1a435SJohn Baldwin oo.os = os; 14770d1a435SJohn Baldwin oo.done = false; 14870d1a435SJohn Baldwin 14970d1a435SJohn Baldwin crp->crp_opaque = &oo; 15070d1a435SJohn Baldwin for (;;) { 151db6b5644SMark Johnston async = !CRYPTO_SESS_SYNC(crp->crp_session); 152db6b5644SMark Johnston crp->crp_callback = async ? ktls_ocf_callback_async : 153db6b5644SMark Johnston ktls_ocf_callback_sync; 154db6b5644SMark Johnston 15570d1a435SJohn Baldwin error = crypto_dispatch(crp); 15670d1a435SJohn Baldwin if (error) 15770d1a435SJohn Baldwin break; 158db6b5644SMark Johnston if (async) { 15970d1a435SJohn Baldwin mtx_lock(&os->lock); 16070d1a435SJohn Baldwin while (!oo.done) 16170d1a435SJohn Baldwin mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0); 16270d1a435SJohn Baldwin mtx_unlock(&os->lock); 163db6b5644SMark Johnston } 16470d1a435SJohn Baldwin 16570d1a435SJohn Baldwin if (crp->crp_etype != EAGAIN) { 16670d1a435SJohn Baldwin error = crp->crp_etype; 16770d1a435SJohn Baldwin break; 16870d1a435SJohn Baldwin } 16970d1a435SJohn Baldwin 17070d1a435SJohn Baldwin crp->crp_etype = 0; 17170d1a435SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 17270d1a435SJohn Baldwin oo.done = false; 17370d1a435SJohn Baldwin counter_u64_add(ocf_retries, 1); 17470d1a435SJohn Baldwin } 17570d1a435SJohn Baldwin return (error); 17670d1a435SJohn Baldwin } 17770d1a435SJohn Baldwin 17870d1a435SJohn Baldwin static int 17947e2650eSJohn Baldwin ktls_ocf_tls_cbc_encrypt(struct ktls_session *tls, 18047e2650eSJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 18149f6925cSMark Johnston struct iovec *outiov, int iniovcnt, int outiovcnt, uint64_t seqno, 18247e2650eSJohn Baldwin uint8_t record_type __unused) 18347e2650eSJohn Baldwin { 18447e2650eSJohn Baldwin struct uio uio, out_uio; 18547e2650eSJohn Baldwin struct tls_mac_data ad; 18647e2650eSJohn Baldwin struct cryptop crp; 18747e2650eSJohn Baldwin struct ocf_session *os; 18849f6925cSMark Johnston struct iovec iov[iniovcnt + 2]; 18949f6925cSMark Johnston struct iovec out_iov[outiovcnt + 1]; 19047e2650eSJohn Baldwin int i, error; 19147e2650eSJohn Baldwin uint16_t tls_comp_len; 19247e2650eSJohn Baldwin uint8_t pad; 19347e2650eSJohn Baldwin bool inplace; 19447e2650eSJohn Baldwin 19547e2650eSJohn Baldwin os = tls->cipher; 19647e2650eSJohn Baldwin 19747e2650eSJohn Baldwin #ifdef INVARIANTS 19847e2650eSJohn Baldwin if (os->implicit_iv) { 19947e2650eSJohn Baldwin mtx_lock(&os->lock); 20047e2650eSJohn Baldwin KASSERT(!os->in_progress, 20147e2650eSJohn Baldwin ("concurrent implicit IV encryptions")); 20247e2650eSJohn Baldwin if (os->next_seqno != seqno) { 20347e2650eSJohn Baldwin printf("KTLS CBC: TLS records out of order. " 20447e2650eSJohn Baldwin "Expected %ju, got %ju\n", 20547e2650eSJohn Baldwin (uintmax_t)os->next_seqno, (uintmax_t)seqno); 20647e2650eSJohn Baldwin mtx_unlock(&os->lock); 20747e2650eSJohn Baldwin return (EINVAL); 20847e2650eSJohn Baldwin } 20947e2650eSJohn Baldwin os->in_progress = true; 21047e2650eSJohn Baldwin mtx_unlock(&os->lock); 21147e2650eSJohn Baldwin } 21247e2650eSJohn Baldwin #endif 21347e2650eSJohn Baldwin 21447e2650eSJohn Baldwin /* 21547e2650eSJohn Baldwin * Compute the payload length. 21647e2650eSJohn Baldwin * 21747e2650eSJohn Baldwin * XXX: This could be easily computed O(1) from the mbuf 21847e2650eSJohn Baldwin * fields, but we don't have those accessible here. Can 21947e2650eSJohn Baldwin * at least compute inplace as well while we are here. 22047e2650eSJohn Baldwin */ 22147e2650eSJohn Baldwin tls_comp_len = 0; 22249f6925cSMark Johnston inplace = iniovcnt == outiovcnt; 22349f6925cSMark Johnston for (i = 0; i < iniovcnt; i++) { 22447e2650eSJohn Baldwin tls_comp_len += iniov[i].iov_len; 22549f6925cSMark Johnston if (inplace && 22649f6925cSMark Johnston (i >= outiovcnt || iniov[i].iov_base != outiov[i].iov_base)) 22747e2650eSJohn Baldwin inplace = false; 22847e2650eSJohn Baldwin } 22947e2650eSJohn Baldwin 23047e2650eSJohn Baldwin /* Initialize the AAD. */ 23147e2650eSJohn Baldwin ad.seq = htobe64(seqno); 23247e2650eSJohn Baldwin ad.type = hdr->tls_type; 23347e2650eSJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 23447e2650eSJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 23547e2650eSJohn Baldwin ad.tls_length = htons(tls_comp_len); 23647e2650eSJohn Baldwin 23747e2650eSJohn Baldwin /* First, compute the MAC. */ 23847e2650eSJohn Baldwin iov[0].iov_base = &ad; 23947e2650eSJohn Baldwin iov[0].iov_len = sizeof(ad); 24049f6925cSMark Johnston memcpy(&iov[1], iniov, sizeof(*iniov) * iniovcnt); 24149f6925cSMark Johnston iov[iniovcnt + 1].iov_base = trailer; 24249f6925cSMark Johnston iov[iniovcnt + 1].iov_len = os->mac_len; 24347e2650eSJohn Baldwin uio.uio_iov = iov; 24449f6925cSMark Johnston uio.uio_iovcnt = iniovcnt + 2; 24547e2650eSJohn Baldwin uio.uio_offset = 0; 24647e2650eSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 24747e2650eSJohn Baldwin uio.uio_td = curthread; 24847e2650eSJohn Baldwin uio.uio_resid = sizeof(ad) + tls_comp_len + os->mac_len; 24947e2650eSJohn Baldwin 25047e2650eSJohn Baldwin crypto_initreq(&crp, os->mac_sid); 25147e2650eSJohn Baldwin crp.crp_payload_start = 0; 25247e2650eSJohn Baldwin crp.crp_payload_length = sizeof(ad) + tls_comp_len; 25347e2650eSJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 25447e2650eSJohn Baldwin crp.crp_op = CRYPTO_OP_COMPUTE_DIGEST; 25547e2650eSJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM; 25647e2650eSJohn Baldwin crypto_use_uio(&crp, &uio); 25747e2650eSJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 25847e2650eSJohn Baldwin 25947e2650eSJohn Baldwin crypto_destroyreq(&crp); 26047e2650eSJohn Baldwin if (error) { 26147e2650eSJohn Baldwin #ifdef INVARIANTS 26247e2650eSJohn Baldwin if (os->implicit_iv) { 26347e2650eSJohn Baldwin mtx_lock(&os->lock); 26447e2650eSJohn Baldwin os->in_progress = false; 26547e2650eSJohn Baldwin mtx_unlock(&os->lock); 26647e2650eSJohn Baldwin } 26747e2650eSJohn Baldwin #endif 26847e2650eSJohn Baldwin return (error); 26947e2650eSJohn Baldwin } 27047e2650eSJohn Baldwin 27147e2650eSJohn Baldwin /* Second, add the padding. */ 27247e2650eSJohn Baldwin pad = (unsigned)(AES_BLOCK_LEN - (tls_comp_len + os->mac_len + 1)) % 27347e2650eSJohn Baldwin AES_BLOCK_LEN; 27447e2650eSJohn Baldwin for (i = 0; i < pad + 1; i++) 27547e2650eSJohn Baldwin trailer[os->mac_len + i] = pad; 27647e2650eSJohn Baldwin 27747e2650eSJohn Baldwin /* Finally, encrypt the record. */ 27847e2650eSJohn Baldwin 27947e2650eSJohn Baldwin /* 28047e2650eSJohn Baldwin * Don't recopy the input iovec, instead just adjust the 28147e2650eSJohn Baldwin * trailer length and skip over the AAD vector in the uio. 28247e2650eSJohn Baldwin */ 28349f6925cSMark Johnston iov[iniovcnt + 1].iov_len += pad + 1; 28447e2650eSJohn Baldwin uio.uio_iov = iov + 1; 28549f6925cSMark Johnston uio.uio_iovcnt = iniovcnt + 1; 28649f6925cSMark Johnston uio.uio_resid = tls_comp_len + iov[iniovcnt + 1].iov_len; 28747e2650eSJohn Baldwin KASSERT(uio.uio_resid % AES_BLOCK_LEN == 0, 28847e2650eSJohn Baldwin ("invalid encryption size")); 28947e2650eSJohn Baldwin 29047e2650eSJohn Baldwin crypto_initreq(&crp, os->sid); 29147e2650eSJohn Baldwin crp.crp_payload_start = 0; 29247e2650eSJohn Baldwin crp.crp_payload_length = uio.uio_resid; 29347e2650eSJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT; 29447e2650eSJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 29547e2650eSJohn Baldwin if (os->implicit_iv) 29647e2650eSJohn Baldwin memcpy(crp.crp_iv, os->iv, AES_BLOCK_LEN); 29747e2650eSJohn Baldwin else 29847e2650eSJohn Baldwin memcpy(crp.crp_iv, hdr + 1, AES_BLOCK_LEN); 29947e2650eSJohn Baldwin crypto_use_uio(&crp, &uio); 30047e2650eSJohn Baldwin if (!inplace) { 301ff6a7e4bSMark Johnston memcpy(out_iov, outiov, sizeof(*outiov) * outiovcnt); 302ff6a7e4bSMark Johnston out_iov[outiovcnt] = iov[iniovcnt + 1]; 30347e2650eSJohn Baldwin out_uio.uio_iov = out_iov; 30449f6925cSMark Johnston out_uio.uio_iovcnt = outiovcnt + 1; 30547e2650eSJohn Baldwin out_uio.uio_offset = 0; 30647e2650eSJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 30747e2650eSJohn Baldwin out_uio.uio_td = curthread; 30847e2650eSJohn Baldwin out_uio.uio_resid = uio.uio_resid; 30947e2650eSJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 31047e2650eSJohn Baldwin } 31147e2650eSJohn Baldwin 31247e2650eSJohn Baldwin if (os->implicit_iv) 31347e2650eSJohn Baldwin counter_u64_add(ocf_tls10_cbc_crypts, 1); 31447e2650eSJohn Baldwin else 31547e2650eSJohn Baldwin counter_u64_add(ocf_tls11_cbc_crypts, 1); 31647e2650eSJohn Baldwin if (inplace) 31747e2650eSJohn Baldwin counter_u64_add(ocf_inplace, 1); 31847e2650eSJohn Baldwin else 31947e2650eSJohn Baldwin counter_u64_add(ocf_separate_output, 1); 32047e2650eSJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 32147e2650eSJohn Baldwin 32247e2650eSJohn Baldwin crypto_destroyreq(&crp); 32347e2650eSJohn Baldwin 32447e2650eSJohn Baldwin if (os->implicit_iv) { 32547e2650eSJohn Baldwin KASSERT(os->mac_len + pad + 1 >= AES_BLOCK_LEN, 32647e2650eSJohn Baldwin ("trailer too short to read IV")); 32747e2650eSJohn Baldwin memcpy(os->iv, trailer + os->mac_len + pad + 1 - AES_BLOCK_LEN, 32847e2650eSJohn Baldwin AES_BLOCK_LEN); 32947e2650eSJohn Baldwin #ifdef INVARIANTS 33047e2650eSJohn Baldwin mtx_lock(&os->lock); 33147e2650eSJohn Baldwin os->next_seqno = seqno + 1; 33247e2650eSJohn Baldwin os->in_progress = false; 33347e2650eSJohn Baldwin mtx_unlock(&os->lock); 33447e2650eSJohn Baldwin #endif 33547e2650eSJohn Baldwin } 33647e2650eSJohn Baldwin return (error); 33747e2650eSJohn Baldwin } 33847e2650eSJohn Baldwin 33947e2650eSJohn Baldwin static int 3404dd6800eSJohn Baldwin ktls_ocf_tls12_aead_encrypt(struct ktls_session *tls, 34155b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 34249f6925cSMark Johnston struct iovec *outiov, int iniovcnt, int outiovcnt, uint64_t seqno, 34355b7a0e1SJohn Baldwin uint8_t record_type __unused) 344b2e60773SJohn Baldwin { 345080933c0SJohn Baldwin struct uio uio, out_uio, *tag_uio; 346b2e60773SJohn Baldwin struct tls_aead_data ad; 34733a1a488SJohn Baldwin struct cryptop crp; 348b2e60773SJohn Baldwin struct ocf_session *os; 34949f6925cSMark Johnston struct iovec iov[outiovcnt + 1]; 350b2e60773SJohn Baldwin int i, error; 351b2e60773SJohn Baldwin uint16_t tls_comp_len; 352080933c0SJohn Baldwin bool inplace; 353b2e60773SJohn Baldwin 354b2e60773SJohn Baldwin os = tls->cipher; 355b2e60773SJohn Baldwin 3565b750b9aSJohn Baldwin uio.uio_iov = iniov; 35749f6925cSMark Johnston uio.uio_iovcnt = iniovcnt; 358080933c0SJohn Baldwin uio.uio_offset = 0; 359080933c0SJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 360080933c0SJohn Baldwin uio.uio_td = curthread; 361080933c0SJohn Baldwin 3625b750b9aSJohn Baldwin out_uio.uio_iov = outiov; 36349f6925cSMark Johnston out_uio.uio_iovcnt = outiovcnt; 364080933c0SJohn Baldwin out_uio.uio_offset = 0; 365080933c0SJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 366080933c0SJohn Baldwin out_uio.uio_td = curthread; 367b2e60773SJohn Baldwin 36833a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 369b2e60773SJohn Baldwin 370b2e60773SJohn Baldwin /* Setup the IV. */ 3714dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 37233a1a488SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 3734dd6800eSJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 3744dd6800eSJohn Baldwin sizeof(uint64_t)); 3754dd6800eSJohn Baldwin } else { 3764dd6800eSJohn Baldwin /* 3774dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 3784dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 3794dd6800eSJohn Baldwin * 1.3. 3804dd6800eSJohn Baldwin */ 3814dd6800eSJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 3824dd6800eSJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 3834dd6800eSJohn Baldwin } 384b2e60773SJohn Baldwin 385b2e60773SJohn Baldwin /* Setup the AAD. */ 3864dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 387b2e60773SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 388c0341432SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 3894dd6800eSJohn Baldwin else 3904dd6800eSJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - POLY1305_HASH_LEN; 391b2e60773SJohn Baldwin ad.seq = htobe64(seqno); 392b2e60773SJohn Baldwin ad.type = hdr->tls_type; 393b2e60773SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 394b2e60773SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 395b2e60773SJohn Baldwin ad.tls_length = htons(tls_comp_len); 39633a1a488SJohn Baldwin crp.crp_aad = &ad; 39733a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 398b2e60773SJohn Baldwin 399080933c0SJohn Baldwin /* Compute payload length and determine if encryption is in place. */ 40049f6925cSMark Johnston inplace = iniovcnt == outiovcnt; 40133a1a488SJohn Baldwin crp.crp_payload_start = 0; 40249f6925cSMark Johnston for (i = 0; i < iniovcnt; i++) { 40349f6925cSMark Johnston if (inplace && 40449f6925cSMark Johnston (i >= outiovcnt || iniov[i].iov_base != outiov[i].iov_base)) 405080933c0SJohn Baldwin inplace = false; 40633a1a488SJohn Baldwin crp.crp_payload_length += iniov[i].iov_len; 407b2e60773SJohn Baldwin } 40833a1a488SJohn Baldwin uio.uio_resid = crp.crp_payload_length; 40933a1a488SJohn Baldwin out_uio.uio_resid = crp.crp_payload_length; 410b2e60773SJohn Baldwin 411080933c0SJohn Baldwin if (inplace) 412080933c0SJohn Baldwin tag_uio = &uio; 413080933c0SJohn Baldwin else 414080933c0SJohn Baldwin tag_uio = &out_uio; 415b2e60773SJohn Baldwin 4165b750b9aSJohn Baldwin /* Duplicate iovec and append vector for tag. */ 41749f6925cSMark Johnston memcpy(iov, tag_uio->uio_iov, outiovcnt * sizeof(struct iovec)); 41849f6925cSMark Johnston iov[outiovcnt].iov_base = trailer; 419*4a92afaeSJohn Baldwin iov[outiovcnt].iov_len = tls->params.tls_tlen; 42033a1a488SJohn Baldwin tag_uio->uio_iov = iov; 421080933c0SJohn Baldwin tag_uio->uio_iovcnt++; 42233a1a488SJohn Baldwin crp.crp_digest_start = tag_uio->uio_resid; 423*4a92afaeSJohn Baldwin tag_uio->uio_resid += tls->params.tls_tlen; 424b2e60773SJohn Baldwin 42533a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 42633a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 42733a1a488SJohn Baldwin crypto_use_uio(&crp, &uio); 428080933c0SJohn Baldwin if (!inplace) 42933a1a488SJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 430b2e60773SJohn Baldwin 4314dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 43255b7a0e1SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 4334dd6800eSJohn Baldwin else 4344dd6800eSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_crypts, 1); 435080933c0SJohn Baldwin if (inplace) 436080933c0SJohn Baldwin counter_u64_add(ocf_inplace, 1); 437080933c0SJohn Baldwin else 438080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 43970d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 44055b7a0e1SJohn Baldwin 44133a1a488SJohn Baldwin crypto_destroyreq(&crp); 44255b7a0e1SJohn Baldwin return (error); 44355b7a0e1SJohn Baldwin } 44455b7a0e1SJohn Baldwin 44555b7a0e1SJohn Baldwin static int 4464dd6800eSJohn Baldwin ktls_ocf_tls12_aead_decrypt(struct ktls_session *tls, 4473c0e5685SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 4483c0e5685SJohn Baldwin int *trailer_len) 4493c0e5685SJohn Baldwin { 4503c0e5685SJohn Baldwin struct tls_aead_data ad; 4513c0e5685SJohn Baldwin struct cryptop crp; 4523c0e5685SJohn Baldwin struct ocf_session *os; 4533c0e5685SJohn Baldwin struct ocf_operation oo; 4543c0e5685SJohn Baldwin int error; 4553c0e5685SJohn Baldwin uint16_t tls_comp_len; 4563c0e5685SJohn Baldwin 4573c0e5685SJohn Baldwin os = tls->cipher; 4583c0e5685SJohn Baldwin 4593c0e5685SJohn Baldwin oo.os = os; 4603c0e5685SJohn Baldwin oo.done = false; 4613c0e5685SJohn Baldwin 4623c0e5685SJohn Baldwin crypto_initreq(&crp, os->sid); 4633c0e5685SJohn Baldwin 4643c0e5685SJohn Baldwin /* Setup the IV. */ 4654dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 4663c0e5685SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 4674dd6800eSJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 4684dd6800eSJohn Baldwin sizeof(uint64_t)); 4694dd6800eSJohn Baldwin } else { 4704dd6800eSJohn Baldwin /* 4714dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 4724dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 4734dd6800eSJohn Baldwin * 1.3. 4744dd6800eSJohn Baldwin */ 4754dd6800eSJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 4764dd6800eSJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 4774dd6800eSJohn Baldwin } 4783c0e5685SJohn Baldwin 4793c0e5685SJohn Baldwin /* Setup the AAD. */ 4804dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 4813c0e5685SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 4823c0e5685SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 4834dd6800eSJohn Baldwin else 4844dd6800eSJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - POLY1305_HASH_LEN; 4853c0e5685SJohn Baldwin ad.seq = htobe64(seqno); 4863c0e5685SJohn Baldwin ad.type = hdr->tls_type; 4873c0e5685SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 4883c0e5685SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 4893c0e5685SJohn Baldwin ad.tls_length = htons(tls_comp_len); 4903c0e5685SJohn Baldwin crp.crp_aad = &ad; 4913c0e5685SJohn Baldwin crp.crp_aad_length = sizeof(ad); 4923c0e5685SJohn Baldwin 4933c0e5685SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 4943c0e5685SJohn Baldwin crp.crp_payload_length = tls_comp_len; 4953c0e5685SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 4963c0e5685SJohn Baldwin 4973c0e5685SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 4983c0e5685SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 4993c0e5685SJohn Baldwin crypto_use_mbuf(&crp, m); 5003c0e5685SJohn Baldwin 5014dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 5023c0e5685SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 5034dd6800eSJohn Baldwin else 5044dd6800eSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_crypts, 1); 5053c0e5685SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 5063c0e5685SJohn Baldwin 5073c0e5685SJohn Baldwin crypto_destroyreq(&crp); 508*4a92afaeSJohn Baldwin *trailer_len = tls->params.tls_tlen; 5093c0e5685SJohn Baldwin return (error); 5103c0e5685SJohn Baldwin } 5113c0e5685SJohn Baldwin 5123c0e5685SJohn Baldwin static int 5134dd6800eSJohn Baldwin ktls_ocf_tls13_aead_encrypt(struct ktls_session *tls, 51455b7a0e1SJohn Baldwin const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov, 51549f6925cSMark Johnston struct iovec *outiov, int iniovcnt, int outiovcnt, uint64_t seqno, 51649f6925cSMark Johnston uint8_t record_type) 51755b7a0e1SJohn Baldwin { 518080933c0SJohn Baldwin struct uio uio, out_uio; 51955b7a0e1SJohn Baldwin struct tls_aead_data_13 ad; 52055b7a0e1SJohn Baldwin char nonce[12]; 52133a1a488SJohn Baldwin struct cryptop crp; 52255b7a0e1SJohn Baldwin struct ocf_session *os; 52349f6925cSMark Johnston struct iovec iov[iniovcnt + 1], out_iov[outiovcnt + 1]; 52455b7a0e1SJohn Baldwin int i, error; 525080933c0SJohn Baldwin bool inplace; 52655b7a0e1SJohn Baldwin 52755b7a0e1SJohn Baldwin os = tls->cipher; 52855b7a0e1SJohn Baldwin 52933a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 53055b7a0e1SJohn Baldwin 53155b7a0e1SJohn Baldwin /* Setup the nonce. */ 53255b7a0e1SJohn Baldwin memcpy(nonce, tls->params.iv, tls->params.iv_len); 53355b7a0e1SJohn Baldwin *(uint64_t *)(nonce + 4) ^= htobe64(seqno); 53455b7a0e1SJohn Baldwin 53555b7a0e1SJohn Baldwin /* Setup the AAD. */ 53655b7a0e1SJohn Baldwin ad.type = hdr->tls_type; 53755b7a0e1SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 53855b7a0e1SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 53955b7a0e1SJohn Baldwin ad.tls_length = hdr->tls_length; 54033a1a488SJohn Baldwin crp.crp_aad = &ad; 54133a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 542080933c0SJohn Baldwin 543080933c0SJohn Baldwin /* Compute payload length and determine if encryption is in place. */ 54449f6925cSMark Johnston inplace = iniovcnt == outiovcnt; 54533a1a488SJohn Baldwin crp.crp_payload_start = 0; 54649f6925cSMark Johnston for (i = 0; i < iniovcnt; i++) { 54749f6925cSMark Johnston if (inplace && (i >= outiovcnt || 54849f6925cSMark Johnston iniov[i].iov_base != outiov[i].iov_base)) 549080933c0SJohn Baldwin inplace = false; 55033a1a488SJohn Baldwin crp.crp_payload_length += iniov[i].iov_len; 551080933c0SJohn Baldwin } 55255b7a0e1SJohn Baldwin 5535b750b9aSJohn Baldwin /* Store the record type as the first byte of the trailer. */ 55455b7a0e1SJohn Baldwin trailer[0] = record_type; 55533a1a488SJohn Baldwin crp.crp_payload_length++; 55633a1a488SJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 5575b750b9aSJohn Baldwin 5585b750b9aSJohn Baldwin /* 5595b750b9aSJohn Baldwin * Duplicate the input iov to append the trailer. Always 5605b750b9aSJohn Baldwin * include the full trailer as input to get the record_type 5615b750b9aSJohn Baldwin * even if only the first byte is used. 5625b750b9aSJohn Baldwin */ 56349f6925cSMark Johnston memcpy(iov, iniov, iniovcnt * sizeof(*iov)); 56449f6925cSMark Johnston iov[iniovcnt].iov_base = trailer; 56549f6925cSMark Johnston iov[iniovcnt].iov_len = tls->params.tls_tlen; 5665b750b9aSJohn Baldwin uio.uio_iov = iov; 56749f6925cSMark Johnston uio.uio_iovcnt = iniovcnt + 1; 5685b750b9aSJohn Baldwin uio.uio_offset = 0; 5694dd6800eSJohn Baldwin uio.uio_resid = crp.crp_payload_length + tls->params.tls_tlen - 1; 5705b750b9aSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 5715b750b9aSJohn Baldwin uio.uio_td = curthread; 57233a1a488SJohn Baldwin crypto_use_uio(&crp, &uio); 5735b750b9aSJohn Baldwin 5745b750b9aSJohn Baldwin if (!inplace) { 5755b750b9aSJohn Baldwin /* Duplicate the output iov to append the trailer. */ 57649f6925cSMark Johnston memcpy(out_iov, outiov, outiovcnt * sizeof(*out_iov)); 5773fa03421SJohn Baldwin out_iov[outiovcnt] = iov[iniovcnt]; 5785b750b9aSJohn Baldwin 5795b750b9aSJohn Baldwin out_uio.uio_iov = out_iov; 58049f6925cSMark Johnston out_uio.uio_iovcnt = outiovcnt + 1; 5815b750b9aSJohn Baldwin out_uio.uio_offset = 0; 58233a1a488SJohn Baldwin out_uio.uio_resid = crp.crp_payload_length + 5834dd6800eSJohn Baldwin tls->params.tls_tlen - 1; 5845b750b9aSJohn Baldwin out_uio.uio_segflg = UIO_SYSSPACE; 5855b750b9aSJohn Baldwin out_uio.uio_td = curthread; 58633a1a488SJohn Baldwin crypto_use_output_uio(&crp, &out_uio); 587080933c0SJohn Baldwin } 58855b7a0e1SJohn Baldwin 58933a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 59033a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 59155b7a0e1SJohn Baldwin 59233a1a488SJohn Baldwin memcpy(crp.crp_iv, nonce, sizeof(nonce)); 59355b7a0e1SJohn Baldwin 5944dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 59555b7a0e1SJohn Baldwin counter_u64_add(ocf_tls13_gcm_crypts, 1); 5964dd6800eSJohn Baldwin else 5974dd6800eSJohn Baldwin counter_u64_add(ocf_tls13_chacha20_crypts, 1); 598080933c0SJohn Baldwin if (inplace) 599080933c0SJohn Baldwin counter_u64_add(ocf_inplace, 1); 600080933c0SJohn Baldwin else 601080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 60270d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 603b2e60773SJohn Baldwin 60433a1a488SJohn Baldwin crypto_destroyreq(&crp); 605b2e60773SJohn Baldwin return (error); 606b2e60773SJohn Baldwin } 607b2e60773SJohn Baldwin 608b2e60773SJohn Baldwin static void 609b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 610b2e60773SJohn Baldwin { 611b2e60773SJohn Baldwin struct ocf_session *os; 612b2e60773SJohn Baldwin 613b2e60773SJohn Baldwin os = tls->cipher; 614c0341432SJohn Baldwin crypto_freesession(os->sid); 615b2e60773SJohn Baldwin mtx_destroy(&os->lock); 6164a711b8dSJohn Baldwin zfree(os, M_KTLS_OCF); 617b2e60773SJohn Baldwin } 618b2e60773SJohn Baldwin 619b2e60773SJohn Baldwin static int 6203c0e5685SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction) 621b2e60773SJohn Baldwin { 62247e2650eSJohn Baldwin struct crypto_session_params csp, mac_csp; 623b2e60773SJohn Baldwin struct ocf_session *os; 62447e2650eSJohn Baldwin int error, mac_len; 625b2e60773SJohn Baldwin 626c0341432SJohn Baldwin memset(&csp, 0, sizeof(csp)); 62747e2650eSJohn Baldwin memset(&mac_csp, 0, sizeof(mac_csp)); 62847e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_NONE; 62947e2650eSJohn Baldwin mac_len = 0; 630b2e60773SJohn Baldwin 631b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 632b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 633b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 634b2e60773SJohn Baldwin case 128 / 8: 635b2e60773SJohn Baldwin case 256 / 8: 636b2e60773SJohn Baldwin break; 637b2e60773SJohn Baldwin default: 638b2e60773SJohn Baldwin return (EINVAL); 639b2e60773SJohn Baldwin } 640b2e60773SJohn Baldwin 64155b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 642b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 64355b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 64455b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 645b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 646b2e60773SJohn Baldwin 6473c0e5685SJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 6483c0e5685SJohn Baldwin if (direction == KTLS_RX && 6493c0e5685SJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 6503c0e5685SJohn Baldwin return (EPROTONOSUPPORT); 6513c0e5685SJohn Baldwin 65247e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 65347e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 65447e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16; 65547e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 65647e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 65747e2650eSJohn Baldwin csp.csp_ivlen = AES_GCM_IV_LEN; 65847e2650eSJohn Baldwin break; 65947e2650eSJohn Baldwin case CRYPTO_AES_CBC: 66047e2650eSJohn Baldwin switch (tls->params.cipher_key_len) { 66147e2650eSJohn Baldwin case 128 / 8: 66247e2650eSJohn Baldwin case 256 / 8: 66347e2650eSJohn Baldwin break; 66447e2650eSJohn Baldwin default: 66547e2650eSJohn Baldwin return (EINVAL); 66647e2650eSJohn Baldwin } 66747e2650eSJohn Baldwin 66847e2650eSJohn Baldwin switch (tls->params.auth_algorithm) { 66947e2650eSJohn Baldwin case CRYPTO_SHA1_HMAC: 67047e2650eSJohn Baldwin mac_len = SHA1_HASH_LEN; 67147e2650eSJohn Baldwin break; 67247e2650eSJohn Baldwin case CRYPTO_SHA2_256_HMAC: 67347e2650eSJohn Baldwin mac_len = SHA2_256_HASH_LEN; 67447e2650eSJohn Baldwin break; 67547e2650eSJohn Baldwin case CRYPTO_SHA2_384_HMAC: 67647e2650eSJohn Baldwin mac_len = SHA2_384_HASH_LEN; 67747e2650eSJohn Baldwin break; 67847e2650eSJohn Baldwin default: 67947e2650eSJohn Baldwin return (EINVAL); 68047e2650eSJohn Baldwin } 68147e2650eSJohn Baldwin 68247e2650eSJohn Baldwin /* Only TLS 1.0-1.2 are supported. */ 68347e2650eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 68447e2650eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_ZERO || 68547e2650eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_TWO) 68647e2650eSJohn Baldwin return (EPROTONOSUPPORT); 68747e2650eSJohn Baldwin 68847e2650eSJohn Baldwin /* AES-CBC is not supported for receive. */ 68947e2650eSJohn Baldwin if (direction == KTLS_RX) 69047e2650eSJohn Baldwin return (EPROTONOSUPPORT); 69147e2650eSJohn Baldwin 69247e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 69347e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_CIPHER; 69447e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_CBC; 69547e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 69647e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 69747e2650eSJohn Baldwin csp.csp_ivlen = AES_BLOCK_LEN; 69847e2650eSJohn Baldwin 69947e2650eSJohn Baldwin mac_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 70047e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_DIGEST; 70147e2650eSJohn Baldwin mac_csp.csp_auth_alg = tls->params.auth_algorithm; 70247e2650eSJohn Baldwin mac_csp.csp_auth_key = tls->params.auth_key; 70347e2650eSJohn Baldwin mac_csp.csp_auth_klen = tls->params.auth_key_len; 70447e2650eSJohn Baldwin break; 7054dd6800eSJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 7064dd6800eSJohn Baldwin switch (tls->params.cipher_key_len) { 7074dd6800eSJohn Baldwin case 256 / 8: 7084dd6800eSJohn Baldwin break; 7094dd6800eSJohn Baldwin default: 7104dd6800eSJohn Baldwin return (EINVAL); 7114dd6800eSJohn Baldwin } 7124dd6800eSJohn Baldwin 7134dd6800eSJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 7144dd6800eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 7154dd6800eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 7164dd6800eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 7174dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 7184dd6800eSJohn Baldwin 7194dd6800eSJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 7204dd6800eSJohn Baldwin if (direction == KTLS_RX && 7214dd6800eSJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 7224dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 7234dd6800eSJohn Baldwin 7244dd6800eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 7254dd6800eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 7264dd6800eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305; 7274dd6800eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 7284dd6800eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 7294dd6800eSJohn Baldwin csp.csp_ivlen = CHACHA20_POLY1305_IV_LEN; 7304dd6800eSJohn Baldwin break; 73147e2650eSJohn Baldwin default: 73247e2650eSJohn Baldwin return (EPROTONOSUPPORT); 73347e2650eSJohn Baldwin } 73447e2650eSJohn Baldwin 735b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 736b2e60773SJohn Baldwin if (os == NULL) 737b2e60773SJohn Baldwin return (ENOMEM); 738b2e60773SJohn Baldwin 739c0341432SJohn Baldwin error = crypto_newsession(&os->sid, &csp, 740b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 741b2e60773SJohn Baldwin if (error) { 742b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 743b2e60773SJohn Baldwin return (error); 744b2e60773SJohn Baldwin } 745b2e60773SJohn Baldwin 74647e2650eSJohn Baldwin if (mac_csp.csp_mode != CSP_MODE_NONE) { 74747e2650eSJohn Baldwin error = crypto_newsession(&os->mac_sid, &mac_csp, 74847e2650eSJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 74947e2650eSJohn Baldwin if (error) { 75047e2650eSJohn Baldwin crypto_freesession(os->sid); 75147e2650eSJohn Baldwin free(os, M_KTLS_OCF); 75247e2650eSJohn Baldwin return (error); 75347e2650eSJohn Baldwin } 75447e2650eSJohn Baldwin os->mac_len = mac_len; 75547e2650eSJohn Baldwin } 75647e2650eSJohn Baldwin 757b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 758b2e60773SJohn Baldwin tls->cipher = os; 7594dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16 || 7604dd6800eSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_CHACHA20_POLY1305) { 7613c0e5685SJohn Baldwin if (direction == KTLS_TX) { 76255b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 7634dd6800eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls13_aead_encrypt; 76455b7a0e1SJohn Baldwin else 7654dd6800eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls12_aead_encrypt; 7663c0e5685SJohn Baldwin } else { 7674dd6800eSJohn Baldwin tls->sw_decrypt = ktls_ocf_tls12_aead_decrypt; 7683c0e5685SJohn Baldwin } 76947e2650eSJohn Baldwin } else { 77047e2650eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls_cbc_encrypt; 77147e2650eSJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_ZERO) { 77247e2650eSJohn Baldwin os->implicit_iv = true; 77347e2650eSJohn Baldwin memcpy(os->iv, tls->params.iv, AES_BLOCK_LEN); 77447e2650eSJohn Baldwin } 77547e2650eSJohn Baldwin } 776b2e60773SJohn Baldwin tls->free = ktls_ocf_free; 777b2e60773SJohn Baldwin return (0); 778b2e60773SJohn Baldwin } 779b2e60773SJohn Baldwin 780b2e60773SJohn Baldwin struct ktls_crypto_backend ocf_backend = { 781b2e60773SJohn Baldwin .name = "OCF", 782b2e60773SJohn Baldwin .prio = 5, 783b2e60773SJohn Baldwin .api_version = KTLS_API_VERSION, 784b2e60773SJohn Baldwin .try = ktls_ocf_try, 785b2e60773SJohn Baldwin }; 786b2e60773SJohn Baldwin 787b2e60773SJohn Baldwin static int 788b2e60773SJohn Baldwin ktls_ocf_modevent(module_t mod, int what, void *arg) 789b2e60773SJohn Baldwin { 790b2e60773SJohn Baldwin switch (what) { 791b2e60773SJohn Baldwin case MOD_LOAD: 792b2e60773SJohn Baldwin return (ktls_crypto_backend_register(&ocf_backend)); 793b2e60773SJohn Baldwin case MOD_UNLOAD: 7941755b2b9SMark Johnston return (ktls_crypto_backend_deregister(&ocf_backend)); 795b2e60773SJohn Baldwin default: 796b2e60773SJohn Baldwin return (EOPNOTSUPP); 797b2e60773SJohn Baldwin } 798b2e60773SJohn Baldwin } 799b2e60773SJohn Baldwin 800b2e60773SJohn Baldwin static moduledata_t ktls_ocf_moduledata = { 801b2e60773SJohn Baldwin "ktls_ocf", 802b2e60773SJohn Baldwin ktls_ocf_modevent, 803b2e60773SJohn Baldwin NULL 804b2e60773SJohn Baldwin }; 805b2e60773SJohn Baldwin 806b2e60773SJohn Baldwin DECLARE_MODULE(ktls_ocf, ktls_ocf_moduledata, SI_SUB_PROTO_END, SI_ORDER_ANY); 807