1b2e60773SJohn Baldwin /*- 2b2e60773SJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause 3b2e60773SJohn Baldwin * 4b2e60773SJohn Baldwin * Copyright (c) 2019 Netflix Inc. 5b2e60773SJohn Baldwin * 6b2e60773SJohn Baldwin * Redistribution and use in source and binary forms, with or without 7b2e60773SJohn Baldwin * modification, are permitted provided that the following conditions 8b2e60773SJohn Baldwin * are met: 9b2e60773SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 10b2e60773SJohn Baldwin * notice, this list of conditions and the following disclaimer. 11b2e60773SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 12b2e60773SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 13b2e60773SJohn Baldwin * documentation and/or other materials provided with the distribution. 14b2e60773SJohn Baldwin * 15b2e60773SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16b2e60773SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17b2e60773SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18b2e60773SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 19b2e60773SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20b2e60773SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21b2e60773SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22b2e60773SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23b2e60773SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24b2e60773SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25b2e60773SJohn Baldwin * SUCH DAMAGE. 26b2e60773SJohn Baldwin */ 27b2e60773SJohn Baldwin 28b2e60773SJohn Baldwin #include <sys/cdefs.h> 29b2e60773SJohn Baldwin __FBSDID("$FreeBSD$"); 30b2e60773SJohn Baldwin 31b2e60773SJohn Baldwin #include <sys/param.h> 32b2e60773SJohn Baldwin #include <sys/systm.h> 33b2e60773SJohn Baldwin #include <sys/counter.h> 34b2e60773SJohn Baldwin #include <sys/endian.h> 35b2e60773SJohn Baldwin #include <sys/kernel.h> 36b2e60773SJohn Baldwin #include <sys/ktls.h> 37b2e60773SJohn Baldwin #include <sys/lock.h> 38b2e60773SJohn Baldwin #include <sys/malloc.h> 3921e3c1fbSJohn Baldwin #include <sys/mbuf.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> 4421e3c1fbSJohn Baldwin #include <vm/vm.h> 4521e3c1fbSJohn Baldwin #include <vm/pmap.h> 4621e3c1fbSJohn Baldwin #include <vm/vm_param.h> 47b2e60773SJohn Baldwin #include <opencrypto/cryptodev.h> 48470e851cSJohn Baldwin #include <opencrypto/ktls.h> 49b2e60773SJohn Baldwin 50*a4c5d490SJohn Baldwin struct ktls_ocf_sw { 51*a4c5d490SJohn Baldwin /* Encrypt a single outbound TLS record. */ 52*a4c5d490SJohn Baldwin int (*encrypt)(struct ktls_ocf_encrypt_state *state, 53*a4c5d490SJohn Baldwin struct ktls_session *tls, struct mbuf *m, 54*a4c5d490SJohn Baldwin struct iovec *outiov, int outiovcnt); 55*a4c5d490SJohn Baldwin 56*a4c5d490SJohn Baldwin /* Decrypt a received TLS record. */ 57*a4c5d490SJohn Baldwin int (*decrypt)(struct ktls_session *tls, 58*a4c5d490SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, 59*a4c5d490SJohn Baldwin uint64_t seqno, int *trailer_len); 60*a4c5d490SJohn Baldwin }; 61*a4c5d490SJohn Baldwin 62b33ff941SJohn Baldwin struct ktls_ocf_session { 63*a4c5d490SJohn Baldwin const struct ktls_ocf_sw *sw; 64b2e60773SJohn Baldwin crypto_session_t sid; 6547e2650eSJohn Baldwin crypto_session_t mac_sid; 66b2e60773SJohn Baldwin struct mtx lock; 6721e3c1fbSJohn Baldwin int mac_len; 6847e2650eSJohn Baldwin bool implicit_iv; 6947e2650eSJohn Baldwin 7047e2650eSJohn Baldwin /* Only used for TLS 1.0 with the implicit IV. */ 7147e2650eSJohn Baldwin #ifdef INVARIANTS 7247e2650eSJohn Baldwin bool in_progress; 7347e2650eSJohn Baldwin uint64_t next_seqno; 7447e2650eSJohn Baldwin #endif 7547e2650eSJohn Baldwin char iv[AES_BLOCK_LEN]; 76b2e60773SJohn Baldwin }; 77b2e60773SJohn Baldwin 78b2e60773SJohn Baldwin struct ocf_operation { 79b33ff941SJohn Baldwin struct ktls_ocf_session *os; 80b2e60773SJohn Baldwin bool done; 81b2e60773SJohn Baldwin }; 82b2e60773SJohn Baldwin 83b2e60773SJohn Baldwin static MALLOC_DEFINE(M_KTLS_OCF, "ktls_ocf", "OCF KTLS"); 84b2e60773SJohn Baldwin 85b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls); 86b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls_stats); 87b2e60773SJohn Baldwin 887029da5cSPawel Biernacki static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf, 897029da5cSPawel Biernacki CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 9055b7a0e1SJohn Baldwin "Kernel TLS offload via OCF stats"); 9155b7a0e1SJohn Baldwin 9216bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls10_cbc_encrypts); 9316bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls10_cbc_encrypts, 9416bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls10_cbc_encrypts, 9547e2650eSJohn Baldwin "Total number of OCF TLS 1.0 CBC encryption operations"); 9647e2650eSJohn Baldwin 9716bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_encrypts); 9816bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_encrypts, 9916bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls11_cbc_encrypts, 10047e2650eSJohn Baldwin "Total number of OCF TLS 1.1/1.2 CBC encryption operations"); 10147e2650eSJohn Baldwin 10216bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_decrypts); 10316bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_decrypts, 10416bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_decrypts, 10516bea05aSJohn Baldwin "Total number of OCF TLS 1.2 GCM decryption operations"); 10616bea05aSJohn Baldwin 10716bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_encrypts); 10816bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_encrypts, 10916bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_encrypts, 11055b7a0e1SJohn Baldwin "Total number of OCF TLS 1.2 GCM encryption operations"); 11155b7a0e1SJohn Baldwin 11216bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_decrypts); 11316bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_decrypts, 11416bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_decrypts, 11516bea05aSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 decryption operations"); 11616bea05aSJohn Baldwin 11716bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_encrypts); 11816bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_encrypts, 11916bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_encrypts, 1204dd6800eSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 encryption operations"); 1214dd6800eSJohn Baldwin 12205a1d0f5SJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_decrypts); 12305a1d0f5SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_decrypts, 12405a1d0f5SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_decrypts, 12505a1d0f5SJohn Baldwin "Total number of OCF TLS 1.3 GCM decryption operations"); 12605a1d0f5SJohn Baldwin 12716bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_encrypts); 12816bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_encrypts, 12916bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_encrypts, 13055b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 131b2e60773SJohn Baldwin 13205a1d0f5SJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_decrypts); 13305a1d0f5SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_decrypts, 13405a1d0f5SJohn Baldwin CTLFLAG_RD, &ocf_tls13_chacha20_decrypts, 13505a1d0f5SJohn Baldwin "Total number of OCF TLS 1.3 Chacha20-Poly1305 decryption operations"); 13605a1d0f5SJohn Baldwin 13716bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_encrypts); 13816bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_encrypts, 13916bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls13_chacha20_encrypts, 1404dd6800eSJohn Baldwin "Total number of OCF TLS 1.3 Chacha20-Poly1305 encryption operations"); 1414dd6800eSJohn Baldwin 1421755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_inplace); 143080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace, 144080933c0SJohn Baldwin CTLFLAG_RD, &ocf_inplace, 145080933c0SJohn Baldwin "Total number of OCF in-place operations"); 146080933c0SJohn Baldwin 1471755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_separate_output); 148080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output, 149080933c0SJohn Baldwin CTLFLAG_RD, &ocf_separate_output, 150080933c0SJohn Baldwin "Total number of OCF operations with a separate output buffer"); 151080933c0SJohn Baldwin 1521755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_retries); 15355b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 154b2e60773SJohn Baldwin &ocf_retries, 155b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 156b2e60773SJohn Baldwin 157b2e60773SJohn Baldwin static int 158db6b5644SMark Johnston ktls_ocf_callback_sync(struct cryptop *crp __unused) 159db6b5644SMark Johnston { 160db6b5644SMark Johnston return (0); 161db6b5644SMark Johnston } 162db6b5644SMark Johnston 163db6b5644SMark Johnston static int 164db6b5644SMark Johnston ktls_ocf_callback_async(struct cryptop *crp) 165b2e60773SJohn Baldwin { 166b2e60773SJohn Baldwin struct ocf_operation *oo; 167b2e60773SJohn Baldwin 168b2e60773SJohn Baldwin oo = crp->crp_opaque; 169b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 170b2e60773SJohn Baldwin oo->done = true; 171b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 172b2e60773SJohn Baldwin wakeup(oo); 173b2e60773SJohn Baldwin return (0); 174b2e60773SJohn Baldwin } 175b2e60773SJohn Baldwin 176b2e60773SJohn Baldwin static int 177b33ff941SJohn Baldwin ktls_ocf_dispatch(struct ktls_ocf_session *os, struct cryptop *crp) 17870d1a435SJohn Baldwin { 17970d1a435SJohn Baldwin struct ocf_operation oo; 18070d1a435SJohn Baldwin int error; 181db6b5644SMark Johnston bool async; 18270d1a435SJohn Baldwin 18370d1a435SJohn Baldwin oo.os = os; 18470d1a435SJohn Baldwin oo.done = false; 18570d1a435SJohn Baldwin 18670d1a435SJohn Baldwin crp->crp_opaque = &oo; 18770d1a435SJohn Baldwin for (;;) { 188db6b5644SMark Johnston async = !CRYPTO_SESS_SYNC(crp->crp_session); 189db6b5644SMark Johnston crp->crp_callback = async ? ktls_ocf_callback_async : 190db6b5644SMark Johnston ktls_ocf_callback_sync; 191db6b5644SMark Johnston 19270d1a435SJohn Baldwin error = crypto_dispatch(crp); 19370d1a435SJohn Baldwin if (error) 19470d1a435SJohn Baldwin break; 195db6b5644SMark Johnston if (async) { 19670d1a435SJohn Baldwin mtx_lock(&os->lock); 19770d1a435SJohn Baldwin while (!oo.done) 19870d1a435SJohn Baldwin mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0); 19970d1a435SJohn Baldwin mtx_unlock(&os->lock); 200db6b5644SMark Johnston } 20170d1a435SJohn Baldwin 20270d1a435SJohn Baldwin if (crp->crp_etype != EAGAIN) { 20370d1a435SJohn Baldwin error = crp->crp_etype; 20470d1a435SJohn Baldwin break; 20570d1a435SJohn Baldwin } 20670d1a435SJohn Baldwin 20770d1a435SJohn Baldwin crp->crp_etype = 0; 20870d1a435SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 20970d1a435SJohn Baldwin oo.done = false; 21070d1a435SJohn Baldwin counter_u64_add(ocf_retries, 1); 21170d1a435SJohn Baldwin } 21270d1a435SJohn Baldwin return (error); 21370d1a435SJohn Baldwin } 21470d1a435SJohn Baldwin 21570d1a435SJohn Baldwin static int 216470e851cSJohn Baldwin ktls_ocf_dispatch_async_cb(struct cryptop *crp) 217470e851cSJohn Baldwin { 218470e851cSJohn Baldwin struct ktls_ocf_encrypt_state *state; 219470e851cSJohn Baldwin int error; 220470e851cSJohn Baldwin 221470e851cSJohn Baldwin state = crp->crp_opaque; 222470e851cSJohn Baldwin if (crp->crp_etype == EAGAIN) { 223470e851cSJohn Baldwin crp->crp_etype = 0; 224470e851cSJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 225470e851cSJohn Baldwin counter_u64_add(ocf_retries, 1); 226470e851cSJohn Baldwin error = crypto_dispatch(crp); 227470e851cSJohn Baldwin if (error != 0) { 228470e851cSJohn Baldwin crypto_destroyreq(crp); 229470e851cSJohn Baldwin ktls_encrypt_cb(state, error); 230470e851cSJohn Baldwin } 231470e851cSJohn Baldwin return (0); 232470e851cSJohn Baldwin } 233470e851cSJohn Baldwin 234470e851cSJohn Baldwin error = crp->crp_etype; 235470e851cSJohn Baldwin crypto_destroyreq(crp); 236470e851cSJohn Baldwin ktls_encrypt_cb(state, error); 237470e851cSJohn Baldwin return (0); 238470e851cSJohn Baldwin } 239470e851cSJohn Baldwin 240470e851cSJohn Baldwin static int 241470e851cSJohn Baldwin ktls_ocf_dispatch_async(struct ktls_ocf_encrypt_state *state, 242470e851cSJohn Baldwin struct cryptop *crp) 243470e851cSJohn Baldwin { 244470e851cSJohn Baldwin int error; 245470e851cSJohn Baldwin 246470e851cSJohn Baldwin crp->crp_opaque = state; 247470e851cSJohn Baldwin crp->crp_callback = ktls_ocf_dispatch_async_cb; 248470e851cSJohn Baldwin error = crypto_dispatch(crp); 249470e851cSJohn Baldwin if (error != 0) 250470e851cSJohn Baldwin crypto_destroyreq(crp); 251470e851cSJohn Baldwin return (error); 252470e851cSJohn Baldwin } 253470e851cSJohn Baldwin 254470e851cSJohn Baldwin static int 255470e851cSJohn Baldwin ktls_ocf_tls_cbc_encrypt(struct ktls_ocf_encrypt_state *state, 256470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 257470e851cSJohn Baldwin int outiovcnt) 25847e2650eSJohn Baldwin { 25921e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 260470e851cSJohn Baldwin struct uio *uio; 261470e851cSJohn Baldwin struct tls_mac_data *ad; 262470e851cSJohn Baldwin struct cryptop *crp; 263b33ff941SJohn Baldwin struct ktls_ocf_session *os; 26421e3c1fbSJohn Baldwin struct iovec iov[m->m_epg_npgs + 2]; 26521e3c1fbSJohn Baldwin u_int pgoff; 26647e2650eSJohn Baldwin int i, error; 26747e2650eSJohn Baldwin uint16_t tls_comp_len; 26847e2650eSJohn Baldwin uint8_t pad; 26921e3c1fbSJohn Baldwin 27021e3c1fbSJohn Baldwin MPASS(outiovcnt + 1 <= nitems(iov)); 27147e2650eSJohn Baldwin 272b33ff941SJohn Baldwin os = tls->ocf_session; 27321e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 274470e851cSJohn Baldwin crp = &state->crp; 275470e851cSJohn Baldwin uio = &state->uio; 276470e851cSJohn Baldwin MPASS(tls->sync_dispatch); 27747e2650eSJohn Baldwin 27847e2650eSJohn Baldwin #ifdef INVARIANTS 27947e2650eSJohn Baldwin if (os->implicit_iv) { 28047e2650eSJohn Baldwin mtx_lock(&os->lock); 28147e2650eSJohn Baldwin KASSERT(!os->in_progress, 28247e2650eSJohn Baldwin ("concurrent implicit IV encryptions")); 28321e3c1fbSJohn Baldwin if (os->next_seqno != m->m_epg_seqno) { 28447e2650eSJohn Baldwin printf("KTLS CBC: TLS records out of order. " 28547e2650eSJohn Baldwin "Expected %ju, got %ju\n", 28621e3c1fbSJohn Baldwin (uintmax_t)os->next_seqno, 28721e3c1fbSJohn Baldwin (uintmax_t)m->m_epg_seqno); 28847e2650eSJohn Baldwin mtx_unlock(&os->lock); 28947e2650eSJohn Baldwin return (EINVAL); 29047e2650eSJohn Baldwin } 29147e2650eSJohn Baldwin os->in_progress = true; 29247e2650eSJohn Baldwin mtx_unlock(&os->lock); 29347e2650eSJohn Baldwin } 29447e2650eSJohn Baldwin #endif 29547e2650eSJohn Baldwin 29621e3c1fbSJohn Baldwin /* Payload length. */ 29721e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 29847e2650eSJohn Baldwin 29947e2650eSJohn Baldwin /* Initialize the AAD. */ 300470e851cSJohn Baldwin ad = &state->mac; 301470e851cSJohn Baldwin ad->seq = htobe64(m->m_epg_seqno); 302470e851cSJohn Baldwin ad->type = hdr->tls_type; 303470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 304470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 305470e851cSJohn Baldwin ad->tls_length = htons(tls_comp_len); 30647e2650eSJohn Baldwin 30747e2650eSJohn Baldwin /* First, compute the MAC. */ 308470e851cSJohn Baldwin iov[0].iov_base = ad; 309470e851cSJohn Baldwin iov[0].iov_len = sizeof(*ad); 31021e3c1fbSJohn Baldwin pgoff = m->m_epg_1st_off; 31121e3c1fbSJohn Baldwin for (i = 0; i < m->m_epg_npgs; i++, pgoff = 0) { 31221e3c1fbSJohn Baldwin iov[i + 1].iov_base = (void *)PHYS_TO_DMAP(m->m_epg_pa[i] + 31321e3c1fbSJohn Baldwin pgoff); 31421e3c1fbSJohn Baldwin iov[i + 1].iov_len = m_epg_pagelen(m, i, pgoff); 31521e3c1fbSJohn Baldwin } 31621e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_base = m->m_epg_trail; 31721e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_len = os->mac_len; 318470e851cSJohn Baldwin uio->uio_iov = iov; 319470e851cSJohn Baldwin uio->uio_iovcnt = m->m_epg_npgs + 2; 320470e851cSJohn Baldwin uio->uio_offset = 0; 321470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 322470e851cSJohn Baldwin uio->uio_td = curthread; 323470e851cSJohn Baldwin uio->uio_resid = sizeof(*ad) + tls_comp_len + os->mac_len; 32447e2650eSJohn Baldwin 325470e851cSJohn Baldwin crypto_initreq(crp, os->mac_sid); 326470e851cSJohn Baldwin crp->crp_payload_start = 0; 327470e851cSJohn Baldwin crp->crp_payload_length = sizeof(*ad) + tls_comp_len; 328470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 329470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST; 330470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM; 331470e851cSJohn Baldwin crypto_use_uio(crp, uio); 332470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 33347e2650eSJohn Baldwin 334470e851cSJohn Baldwin crypto_destroyreq(crp); 33547e2650eSJohn Baldwin if (error) { 33647e2650eSJohn Baldwin #ifdef INVARIANTS 33747e2650eSJohn Baldwin if (os->implicit_iv) { 33847e2650eSJohn Baldwin mtx_lock(&os->lock); 33947e2650eSJohn Baldwin os->in_progress = false; 34047e2650eSJohn Baldwin mtx_unlock(&os->lock); 34147e2650eSJohn Baldwin } 34247e2650eSJohn Baldwin #endif 34347e2650eSJohn Baldwin return (error); 34447e2650eSJohn Baldwin } 34547e2650eSJohn Baldwin 34647e2650eSJohn Baldwin /* Second, add the padding. */ 34721e3c1fbSJohn Baldwin pad = m->m_epg_trllen - os->mac_len - 1; 34847e2650eSJohn Baldwin for (i = 0; i < pad + 1; i++) 34921e3c1fbSJohn Baldwin m->m_epg_trail[os->mac_len + i] = pad; 35047e2650eSJohn Baldwin 35147e2650eSJohn Baldwin /* Finally, encrypt the record. */ 352470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 353470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 354470e851cSJohn Baldwin crp->crp_payload_length = tls_comp_len + m->m_epg_trllen; 355470e851cSJohn Baldwin KASSERT(crp->crp_payload_length % AES_BLOCK_LEN == 0, 35621e3c1fbSJohn Baldwin ("invalid encryption size")); 357470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 358470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT; 359470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 36047e2650eSJohn Baldwin if (os->implicit_iv) 361470e851cSJohn Baldwin memcpy(crp->crp_iv, os->iv, AES_BLOCK_LEN); 36247e2650eSJohn Baldwin else 363470e851cSJohn Baldwin memcpy(crp->crp_iv, hdr + 1, AES_BLOCK_LEN); 36421e3c1fbSJohn Baldwin 36521e3c1fbSJohn Baldwin if (outiov != NULL) { 366470e851cSJohn Baldwin uio->uio_iov = outiov; 367470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 368470e851cSJohn Baldwin uio->uio_offset = 0; 369470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 370470e851cSJohn Baldwin uio->uio_td = curthread; 371470e851cSJohn Baldwin uio->uio_resid = crp->crp_payload_length; 372470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 37347e2650eSJohn Baldwin } 37447e2650eSJohn Baldwin 37547e2650eSJohn Baldwin if (os->implicit_iv) 37616bea05aSJohn Baldwin counter_u64_add(ocf_tls10_cbc_encrypts, 1); 37747e2650eSJohn Baldwin else 37816bea05aSJohn Baldwin counter_u64_add(ocf_tls11_cbc_encrypts, 1); 37921e3c1fbSJohn Baldwin if (outiov != NULL) 38047e2650eSJohn Baldwin counter_u64_add(ocf_separate_output, 1); 38121e3c1fbSJohn Baldwin else 38221e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 383470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 38447e2650eSJohn Baldwin 385470e851cSJohn Baldwin crypto_destroyreq(crp); 38647e2650eSJohn Baldwin 38747e2650eSJohn Baldwin if (os->implicit_iv) { 38847e2650eSJohn Baldwin KASSERT(os->mac_len + pad + 1 >= AES_BLOCK_LEN, 38947e2650eSJohn Baldwin ("trailer too short to read IV")); 39021e3c1fbSJohn Baldwin memcpy(os->iv, m->m_epg_trail + m->m_epg_trllen - AES_BLOCK_LEN, 39147e2650eSJohn Baldwin AES_BLOCK_LEN); 39247e2650eSJohn Baldwin #ifdef INVARIANTS 39347e2650eSJohn Baldwin mtx_lock(&os->lock); 39421e3c1fbSJohn Baldwin os->next_seqno = m->m_epg_seqno + 1; 39547e2650eSJohn Baldwin os->in_progress = false; 39647e2650eSJohn Baldwin mtx_unlock(&os->lock); 39747e2650eSJohn Baldwin #endif 39847e2650eSJohn Baldwin } 39947e2650eSJohn Baldwin return (error); 40047e2650eSJohn Baldwin } 40147e2650eSJohn Baldwin 402*a4c5d490SJohn Baldwin static const struct ktls_ocf_sw ktls_ocf_tls_cbc_sw = { 403*a4c5d490SJohn Baldwin .encrypt = ktls_ocf_tls_cbc_encrypt 404*a4c5d490SJohn Baldwin }; 405*a4c5d490SJohn Baldwin 40647e2650eSJohn Baldwin static int 407470e851cSJohn Baldwin ktls_ocf_tls12_aead_encrypt(struct ktls_ocf_encrypt_state *state, 408470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 409470e851cSJohn Baldwin int outiovcnt) 410b2e60773SJohn Baldwin { 41121e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 412470e851cSJohn Baldwin struct uio *uio; 413470e851cSJohn Baldwin struct tls_aead_data *ad; 414470e851cSJohn Baldwin struct cryptop *crp; 415b33ff941SJohn Baldwin struct ktls_ocf_session *os; 41621e3c1fbSJohn Baldwin int error; 417b2e60773SJohn Baldwin uint16_t tls_comp_len; 418b2e60773SJohn Baldwin 419b33ff941SJohn Baldwin os = tls->ocf_session; 42021e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 421470e851cSJohn Baldwin crp = &state->crp; 422470e851cSJohn Baldwin uio = &state->uio; 423b2e60773SJohn Baldwin 424470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 425b2e60773SJohn Baldwin 426b2e60773SJohn Baldwin /* Setup the IV. */ 4274dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 428470e851cSJohn Baldwin memcpy(crp->crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 429470e851cSJohn Baldwin memcpy(crp->crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 4304dd6800eSJohn Baldwin sizeof(uint64_t)); 4314dd6800eSJohn Baldwin } else { 4324dd6800eSJohn Baldwin /* 4334dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 4344dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 4354dd6800eSJohn Baldwin * 1.3. 4364dd6800eSJohn Baldwin */ 437470e851cSJohn Baldwin memcpy(crp->crp_iv, tls->params.iv, tls->params.iv_len); 438470e851cSJohn Baldwin *(uint64_t *)(crp->crp_iv + 4) ^= htobe64(m->m_epg_seqno); 4394dd6800eSJohn Baldwin } 440b2e60773SJohn Baldwin 441b2e60773SJohn Baldwin /* Setup the AAD. */ 442470e851cSJohn Baldwin ad = &state->aead; 44321e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 444470e851cSJohn Baldwin ad->seq = htobe64(m->m_epg_seqno); 445470e851cSJohn Baldwin ad->type = hdr->tls_type; 446470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 447470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 448470e851cSJohn Baldwin ad->tls_length = htons(tls_comp_len); 449470e851cSJohn Baldwin crp->crp_aad = ad; 450470e851cSJohn Baldwin crp->crp_aad_length = sizeof(*ad); 451b2e60773SJohn Baldwin 45221e3c1fbSJohn Baldwin /* Set fields for input payload. */ 453470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 454470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 455470e851cSJohn Baldwin crp->crp_payload_length = tls_comp_len; 456b2e60773SJohn Baldwin 45721e3c1fbSJohn Baldwin if (outiov != NULL) { 458470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 45921e3c1fbSJohn Baldwin 460470e851cSJohn Baldwin uio->uio_iov = outiov; 461470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 462470e851cSJohn Baldwin uio->uio_offset = 0; 463470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 464470e851cSJohn Baldwin uio->uio_td = curthread; 465470e851cSJohn Baldwin uio->uio_resid = crp->crp_payload_length + tls->params.tls_tlen; 466470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 46721e3c1fbSJohn Baldwin } else 468470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_start + 469470e851cSJohn Baldwin crp->crp_payload_length; 470b2e60773SJohn Baldwin 471470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 472470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 4734dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 47416bea05aSJohn Baldwin counter_u64_add(ocf_tls12_gcm_encrypts, 1); 4754dd6800eSJohn Baldwin else 47616bea05aSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_encrypts, 1); 47721e3c1fbSJohn Baldwin if (outiov != NULL) 478080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 47921e3c1fbSJohn Baldwin else 48021e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 481470e851cSJohn Baldwin if (tls->sync_dispatch) { 482470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 483470e851cSJohn Baldwin crypto_destroyreq(crp); 484470e851cSJohn Baldwin } else 485470e851cSJohn Baldwin error = ktls_ocf_dispatch_async(state, crp); 48655b7a0e1SJohn Baldwin return (error); 48755b7a0e1SJohn Baldwin } 48855b7a0e1SJohn Baldwin 48955b7a0e1SJohn Baldwin static int 4904dd6800eSJohn Baldwin ktls_ocf_tls12_aead_decrypt(struct ktls_session *tls, 4913c0e5685SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 4923c0e5685SJohn Baldwin int *trailer_len) 4933c0e5685SJohn Baldwin { 4943c0e5685SJohn Baldwin struct tls_aead_data ad; 4953c0e5685SJohn Baldwin struct cryptop crp; 496b33ff941SJohn Baldwin struct ktls_ocf_session *os; 4973c0e5685SJohn Baldwin int error; 4983c0e5685SJohn Baldwin uint16_t tls_comp_len; 4993c0e5685SJohn Baldwin 500b33ff941SJohn Baldwin os = tls->ocf_session; 5013c0e5685SJohn Baldwin 5023c0e5685SJohn Baldwin crypto_initreq(&crp, os->sid); 5033c0e5685SJohn Baldwin 5043c0e5685SJohn Baldwin /* Setup the IV. */ 5054dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 5063c0e5685SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 5074dd6800eSJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 5084dd6800eSJohn Baldwin sizeof(uint64_t)); 5094dd6800eSJohn Baldwin } else { 5104dd6800eSJohn Baldwin /* 5114dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 5124dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 5134dd6800eSJohn Baldwin * 1.3. 5144dd6800eSJohn Baldwin */ 5154dd6800eSJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 5164dd6800eSJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 5174dd6800eSJohn Baldwin } 5183c0e5685SJohn Baldwin 5193c0e5685SJohn Baldwin /* Setup the AAD. */ 5204dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 5213c0e5685SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 5223c0e5685SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 5234dd6800eSJohn Baldwin else 5244dd6800eSJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - POLY1305_HASH_LEN; 5253c0e5685SJohn Baldwin ad.seq = htobe64(seqno); 5263c0e5685SJohn Baldwin ad.type = hdr->tls_type; 5273c0e5685SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 5283c0e5685SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 5293c0e5685SJohn Baldwin ad.tls_length = htons(tls_comp_len); 5303c0e5685SJohn Baldwin crp.crp_aad = &ad; 5313c0e5685SJohn Baldwin crp.crp_aad_length = sizeof(ad); 5323c0e5685SJohn Baldwin 5333c0e5685SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 5343c0e5685SJohn Baldwin crp.crp_payload_length = tls_comp_len; 5353c0e5685SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 5363c0e5685SJohn Baldwin 5373c0e5685SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 5383c0e5685SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 5393c0e5685SJohn Baldwin crypto_use_mbuf(&crp, m); 5403c0e5685SJohn Baldwin 5414dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 54216bea05aSJohn Baldwin counter_u64_add(ocf_tls12_gcm_decrypts, 1); 5434dd6800eSJohn Baldwin else 54416bea05aSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_decrypts, 1); 5453c0e5685SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 5463c0e5685SJohn Baldwin 5473c0e5685SJohn Baldwin crypto_destroyreq(&crp); 5484a92afaeSJohn Baldwin *trailer_len = tls->params.tls_tlen; 5493c0e5685SJohn Baldwin return (error); 5503c0e5685SJohn Baldwin } 5513c0e5685SJohn Baldwin 552*a4c5d490SJohn Baldwin static const struct ktls_ocf_sw ktls_ocf_tls12_aead_sw = { 553*a4c5d490SJohn Baldwin .encrypt = ktls_ocf_tls12_aead_encrypt, 554*a4c5d490SJohn Baldwin .decrypt = ktls_ocf_tls12_aead_decrypt, 555*a4c5d490SJohn Baldwin }; 556*a4c5d490SJohn Baldwin 5573c0e5685SJohn Baldwin static int 558470e851cSJohn Baldwin ktls_ocf_tls13_aead_encrypt(struct ktls_ocf_encrypt_state *state, 559470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 560470e851cSJohn Baldwin int outiovcnt) 56155b7a0e1SJohn Baldwin { 56221e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 563470e851cSJohn Baldwin struct uio *uio; 564470e851cSJohn Baldwin struct tls_aead_data_13 *ad; 565470e851cSJohn Baldwin struct cryptop *crp; 566b33ff941SJohn Baldwin struct ktls_ocf_session *os; 567470e851cSJohn Baldwin char nonce[12]; 56821e3c1fbSJohn Baldwin int error; 56955b7a0e1SJohn Baldwin 570b33ff941SJohn Baldwin os = tls->ocf_session; 57121e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 572470e851cSJohn Baldwin crp = &state->crp; 573470e851cSJohn Baldwin uio = &state->uio; 57455b7a0e1SJohn Baldwin 575470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 57655b7a0e1SJohn Baldwin 57755b7a0e1SJohn Baldwin /* Setup the nonce. */ 57855b7a0e1SJohn Baldwin memcpy(nonce, tls->params.iv, tls->params.iv_len); 57921e3c1fbSJohn Baldwin *(uint64_t *)(nonce + 4) ^= htobe64(m->m_epg_seqno); 58055b7a0e1SJohn Baldwin 58155b7a0e1SJohn Baldwin /* Setup the AAD. */ 582470e851cSJohn Baldwin ad = &state->aead13; 583470e851cSJohn Baldwin ad->type = hdr->tls_type; 584470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 585470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 586470e851cSJohn Baldwin ad->tls_length = hdr->tls_length; 587470e851cSJohn Baldwin crp->crp_aad = ad; 588470e851cSJohn Baldwin crp->crp_aad_length = sizeof(*ad); 589080933c0SJohn Baldwin 59021e3c1fbSJohn Baldwin /* Set fields for input payload. */ 591470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 592470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 593470e851cSJohn Baldwin crp->crp_payload_length = m->m_len - 594470e851cSJohn Baldwin (m->m_epg_hdrlen + m->m_epg_trllen); 59555b7a0e1SJohn Baldwin 5965b750b9aSJohn Baldwin /* Store the record type as the first byte of the trailer. */ 59721e3c1fbSJohn Baldwin m->m_epg_trail[0] = m->m_epg_record_type; 598470e851cSJohn Baldwin crp->crp_payload_length++; 59921e3c1fbSJohn Baldwin 60021e3c1fbSJohn Baldwin if (outiov != NULL) { 601470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 6025b750b9aSJohn Baldwin 603470e851cSJohn Baldwin uio->uio_iov = outiov; 604470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 605470e851cSJohn Baldwin uio->uio_offset = 0; 606470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 607470e851cSJohn Baldwin uio->uio_td = curthread; 608470e851cSJohn Baldwin uio->uio_resid = m->m_len - m->m_epg_hdrlen; 609470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 61021e3c1fbSJohn Baldwin } else 611470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_start + 612470e851cSJohn Baldwin crp->crp_payload_length; 61355b7a0e1SJohn Baldwin 614470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 615470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 61655b7a0e1SJohn Baldwin 617470e851cSJohn Baldwin memcpy(crp->crp_iv, nonce, sizeof(nonce)); 61855b7a0e1SJohn Baldwin 6194dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 62016bea05aSJohn Baldwin counter_u64_add(ocf_tls13_gcm_encrypts, 1); 6214dd6800eSJohn Baldwin else 62216bea05aSJohn Baldwin counter_u64_add(ocf_tls13_chacha20_encrypts, 1); 62321e3c1fbSJohn Baldwin if (outiov != NULL) 624080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 62521e3c1fbSJohn Baldwin else 62621e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 627470e851cSJohn Baldwin if (tls->sync_dispatch) { 628470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 629470e851cSJohn Baldwin crypto_destroyreq(crp); 630470e851cSJohn Baldwin } else 631470e851cSJohn Baldwin error = ktls_ocf_dispatch_async(state, crp); 632b2e60773SJohn Baldwin return (error); 633b2e60773SJohn Baldwin } 634b2e60773SJohn Baldwin 63505a1d0f5SJohn Baldwin static int 63605a1d0f5SJohn Baldwin ktls_ocf_tls13_aead_decrypt(struct ktls_session *tls, 63705a1d0f5SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 63805a1d0f5SJohn Baldwin int *trailer_len) 63905a1d0f5SJohn Baldwin { 64005a1d0f5SJohn Baldwin struct tls_aead_data_13 ad; 64105a1d0f5SJohn Baldwin struct cryptop crp; 64205a1d0f5SJohn Baldwin struct ktls_ocf_session *os; 64305a1d0f5SJohn Baldwin int error; 64405a1d0f5SJohn Baldwin u_int tag_len; 64505a1d0f5SJohn Baldwin 64605a1d0f5SJohn Baldwin os = tls->ocf_session; 64705a1d0f5SJohn Baldwin 64805a1d0f5SJohn Baldwin tag_len = tls->params.tls_tlen - 1; 64905a1d0f5SJohn Baldwin 65005a1d0f5SJohn Baldwin /* Payload must contain at least one byte for the record type. */ 65105a1d0f5SJohn Baldwin if (ntohs(hdr->tls_length) < tag_len + 1) 65205a1d0f5SJohn Baldwin return (EBADMSG); 65305a1d0f5SJohn Baldwin 65405a1d0f5SJohn Baldwin crypto_initreq(&crp, os->sid); 65505a1d0f5SJohn Baldwin 65605a1d0f5SJohn Baldwin /* Setup the nonce. */ 65705a1d0f5SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 65805a1d0f5SJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 65905a1d0f5SJohn Baldwin 66005a1d0f5SJohn Baldwin /* Setup the AAD. */ 66105a1d0f5SJohn Baldwin ad.type = hdr->tls_type; 66205a1d0f5SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 66305a1d0f5SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 66405a1d0f5SJohn Baldwin ad.tls_length = hdr->tls_length; 66505a1d0f5SJohn Baldwin crp.crp_aad = &ad; 66605a1d0f5SJohn Baldwin crp.crp_aad_length = sizeof(ad); 66705a1d0f5SJohn Baldwin 66805a1d0f5SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 66905a1d0f5SJohn Baldwin crp.crp_payload_length = ntohs(hdr->tls_length) - tag_len; 67005a1d0f5SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 67105a1d0f5SJohn Baldwin 67205a1d0f5SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 67305a1d0f5SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 67405a1d0f5SJohn Baldwin crypto_use_mbuf(&crp, m); 67505a1d0f5SJohn Baldwin 67605a1d0f5SJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 67705a1d0f5SJohn Baldwin counter_u64_add(ocf_tls13_gcm_decrypts, 1); 67805a1d0f5SJohn Baldwin else 67905a1d0f5SJohn Baldwin counter_u64_add(ocf_tls13_chacha20_decrypts, 1); 68005a1d0f5SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 68105a1d0f5SJohn Baldwin 68205a1d0f5SJohn Baldwin crypto_destroyreq(&crp); 68305a1d0f5SJohn Baldwin *trailer_len = tag_len; 68405a1d0f5SJohn Baldwin return (error); 68505a1d0f5SJohn Baldwin } 68605a1d0f5SJohn Baldwin 687*a4c5d490SJohn Baldwin static const struct ktls_ocf_sw ktls_ocf_tls13_aead_sw = { 688*a4c5d490SJohn Baldwin .encrypt = ktls_ocf_tls13_aead_encrypt, 689*a4c5d490SJohn Baldwin .decrypt = ktls_ocf_tls13_aead_decrypt, 690*a4c5d490SJohn Baldwin }; 691*a4c5d490SJohn Baldwin 69221e3c1fbSJohn Baldwin void 693b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 694b2e60773SJohn Baldwin { 695b33ff941SJohn Baldwin struct ktls_ocf_session *os; 696b2e60773SJohn Baldwin 697b33ff941SJohn Baldwin os = tls->ocf_session; 698c0341432SJohn Baldwin crypto_freesession(os->sid); 6994b337adaSJohn Baldwin crypto_freesession(os->mac_sid); 700b2e60773SJohn Baldwin mtx_destroy(&os->lock); 7014a711b8dSJohn Baldwin zfree(os, M_KTLS_OCF); 702b2e60773SJohn Baldwin } 703b2e60773SJohn Baldwin 70421e3c1fbSJohn Baldwin int 7053c0e5685SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction) 706b2e60773SJohn Baldwin { 70747e2650eSJohn Baldwin struct crypto_session_params csp, mac_csp; 708b33ff941SJohn Baldwin struct ktls_ocf_session *os; 70947e2650eSJohn Baldwin int error, mac_len; 710b2e60773SJohn Baldwin 711c0341432SJohn Baldwin memset(&csp, 0, sizeof(csp)); 71247e2650eSJohn Baldwin memset(&mac_csp, 0, sizeof(mac_csp)); 71347e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_NONE; 71447e2650eSJohn Baldwin mac_len = 0; 715b2e60773SJohn Baldwin 716b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 717b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 718b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 719b2e60773SJohn Baldwin case 128 / 8: 720b2e60773SJohn Baldwin case 256 / 8: 721b2e60773SJohn Baldwin break; 722b2e60773SJohn Baldwin default: 723b2e60773SJohn Baldwin return (EINVAL); 724b2e60773SJohn Baldwin } 725b2e60773SJohn Baldwin 72655b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 727b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 72855b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 72955b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 730b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 731b2e60773SJohn Baldwin 73247e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 73347e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 73447e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16; 73547e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 73647e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 73747e2650eSJohn Baldwin csp.csp_ivlen = AES_GCM_IV_LEN; 73847e2650eSJohn Baldwin break; 73947e2650eSJohn Baldwin case CRYPTO_AES_CBC: 74047e2650eSJohn Baldwin switch (tls->params.cipher_key_len) { 74147e2650eSJohn Baldwin case 128 / 8: 74247e2650eSJohn Baldwin case 256 / 8: 74347e2650eSJohn Baldwin break; 74447e2650eSJohn Baldwin default: 74547e2650eSJohn Baldwin return (EINVAL); 74647e2650eSJohn Baldwin } 74747e2650eSJohn Baldwin 74847e2650eSJohn Baldwin switch (tls->params.auth_algorithm) { 74947e2650eSJohn Baldwin case CRYPTO_SHA1_HMAC: 75047e2650eSJohn Baldwin mac_len = SHA1_HASH_LEN; 75147e2650eSJohn Baldwin break; 75247e2650eSJohn Baldwin case CRYPTO_SHA2_256_HMAC: 75347e2650eSJohn Baldwin mac_len = SHA2_256_HASH_LEN; 75447e2650eSJohn Baldwin break; 75547e2650eSJohn Baldwin case CRYPTO_SHA2_384_HMAC: 75647e2650eSJohn Baldwin mac_len = SHA2_384_HASH_LEN; 75747e2650eSJohn Baldwin break; 75847e2650eSJohn Baldwin default: 75947e2650eSJohn Baldwin return (EINVAL); 76047e2650eSJohn Baldwin } 76147e2650eSJohn Baldwin 76247e2650eSJohn Baldwin /* Only TLS 1.0-1.2 are supported. */ 76347e2650eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 76447e2650eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_ZERO || 76547e2650eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_TWO) 76647e2650eSJohn Baldwin return (EPROTONOSUPPORT); 76747e2650eSJohn Baldwin 76847e2650eSJohn Baldwin /* AES-CBC is not supported for receive. */ 76947e2650eSJohn Baldwin if (direction == KTLS_RX) 77047e2650eSJohn Baldwin return (EPROTONOSUPPORT); 77147e2650eSJohn Baldwin 77247e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 77347e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_CIPHER; 77447e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_CBC; 77547e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 77647e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 77747e2650eSJohn Baldwin csp.csp_ivlen = AES_BLOCK_LEN; 77847e2650eSJohn Baldwin 77947e2650eSJohn Baldwin mac_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 78047e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_DIGEST; 78147e2650eSJohn Baldwin mac_csp.csp_auth_alg = tls->params.auth_algorithm; 78247e2650eSJohn Baldwin mac_csp.csp_auth_key = tls->params.auth_key; 78347e2650eSJohn Baldwin mac_csp.csp_auth_klen = tls->params.auth_key_len; 78447e2650eSJohn Baldwin break; 7854dd6800eSJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 7864dd6800eSJohn Baldwin switch (tls->params.cipher_key_len) { 7874dd6800eSJohn Baldwin case 256 / 8: 7884dd6800eSJohn Baldwin break; 7894dd6800eSJohn Baldwin default: 7904dd6800eSJohn Baldwin return (EINVAL); 7914dd6800eSJohn Baldwin } 7924dd6800eSJohn Baldwin 7934dd6800eSJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 7944dd6800eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 7954dd6800eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 7964dd6800eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 7974dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 7984dd6800eSJohn Baldwin 7994dd6800eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 8004dd6800eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 8014dd6800eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305; 8024dd6800eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 8034dd6800eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 8044dd6800eSJohn Baldwin csp.csp_ivlen = CHACHA20_POLY1305_IV_LEN; 8054dd6800eSJohn Baldwin break; 80647e2650eSJohn Baldwin default: 80747e2650eSJohn Baldwin return (EPROTONOSUPPORT); 80847e2650eSJohn Baldwin } 80947e2650eSJohn Baldwin 810b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 811b2e60773SJohn Baldwin if (os == NULL) 812b2e60773SJohn Baldwin return (ENOMEM); 813b2e60773SJohn Baldwin 814c0341432SJohn Baldwin error = crypto_newsession(&os->sid, &csp, 815b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 816b2e60773SJohn Baldwin if (error) { 817b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 818b2e60773SJohn Baldwin return (error); 819b2e60773SJohn Baldwin } 820b2e60773SJohn Baldwin 82147e2650eSJohn Baldwin if (mac_csp.csp_mode != CSP_MODE_NONE) { 82247e2650eSJohn Baldwin error = crypto_newsession(&os->mac_sid, &mac_csp, 82347e2650eSJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 82447e2650eSJohn Baldwin if (error) { 82547e2650eSJohn Baldwin crypto_freesession(os->sid); 82647e2650eSJohn Baldwin free(os, M_KTLS_OCF); 82747e2650eSJohn Baldwin return (error); 82847e2650eSJohn Baldwin } 82947e2650eSJohn Baldwin os->mac_len = mac_len; 83047e2650eSJohn Baldwin } 83147e2650eSJohn Baldwin 832b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 833b33ff941SJohn Baldwin tls->ocf_session = os; 8344dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16 || 8354dd6800eSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_CHACHA20_POLY1305) { 83655b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 837*a4c5d490SJohn Baldwin os->sw = &ktls_ocf_tls13_aead_sw; 83855b7a0e1SJohn Baldwin else 839*a4c5d490SJohn Baldwin os->sw = &ktls_ocf_tls12_aead_sw; 8403c0e5685SJohn Baldwin } else { 841*a4c5d490SJohn Baldwin os->sw = &ktls_ocf_tls_cbc_sw; 84247e2650eSJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_ZERO) { 84347e2650eSJohn Baldwin os->implicit_iv = true; 84447e2650eSJohn Baldwin memcpy(os->iv, tls->params.iv, AES_BLOCK_LEN); 8454827bf76SJohn Baldwin #ifdef INVARIANTS 8464827bf76SJohn Baldwin os->next_seqno = tls->next_seqno; 8474827bf76SJohn Baldwin #endif 84847e2650eSJohn Baldwin } 84947e2650eSJohn Baldwin } 850470e851cSJohn Baldwin 851470e851cSJohn Baldwin /* 852470e851cSJohn Baldwin * AES-CBC is always synchronous currently. Asynchronous 853470e851cSJohn Baldwin * operation would require multiple callbacks and an additional 854470e851cSJohn Baldwin * iovec array in ktls_ocf_encrypt_state. 855470e851cSJohn Baldwin */ 856470e851cSJohn Baldwin tls->sync_dispatch = CRYPTO_SESS_SYNC(os->sid) || 857470e851cSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_AES_CBC; 858b2e60773SJohn Baldwin return (0); 859b2e60773SJohn Baldwin } 860*a4c5d490SJohn Baldwin 861*a4c5d490SJohn Baldwin int 862*a4c5d490SJohn Baldwin ktls_ocf_encrypt(struct ktls_ocf_encrypt_state *state, 863*a4c5d490SJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 864*a4c5d490SJohn Baldwin int outiovcnt) 865*a4c5d490SJohn Baldwin { 866*a4c5d490SJohn Baldwin return (tls->ocf_session->sw->encrypt(state, tls, m, outiov, 867*a4c5d490SJohn Baldwin outiovcnt)); 868*a4c5d490SJohn Baldwin } 869*a4c5d490SJohn Baldwin 870*a4c5d490SJohn Baldwin int 871*a4c5d490SJohn Baldwin ktls_ocf_decrypt(struct ktls_session *tls, const struct tls_record_layer *hdr, 872*a4c5d490SJohn Baldwin struct mbuf *m, uint64_t seqno, int *trailer_len) 873*a4c5d490SJohn Baldwin { 874*a4c5d490SJohn Baldwin return (tls->ocf_session->sw->decrypt(tls, hdr, m, seqno, trailer_len)); 875*a4c5d490SJohn Baldwin } 876