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/param.h> 29b2e60773SJohn Baldwin #include <sys/systm.h> 30b2e60773SJohn Baldwin #include <sys/counter.h> 31b2e60773SJohn Baldwin #include <sys/endian.h> 32b2e60773SJohn Baldwin #include <sys/kernel.h> 33b2e60773SJohn Baldwin #include <sys/ktls.h> 34b2e60773SJohn Baldwin #include <sys/lock.h> 35b2e60773SJohn Baldwin #include <sys/malloc.h> 3621e3c1fbSJohn Baldwin #include <sys/mbuf.h> 37b2e60773SJohn Baldwin #include <sys/module.h> 38b2e60773SJohn Baldwin #include <sys/mutex.h> 39b2e60773SJohn Baldwin #include <sys/sysctl.h> 40b2e60773SJohn Baldwin #include <sys/uio.h> 4121e3c1fbSJohn Baldwin #include <vm/vm.h> 4221e3c1fbSJohn Baldwin #include <vm/pmap.h> 4321e3c1fbSJohn Baldwin #include <vm/vm_param.h> 44a8280123SJohn Baldwin #include <netinet/in.h> 45b2e60773SJohn Baldwin #include <opencrypto/cryptodev.h> 46470e851cSJohn Baldwin #include <opencrypto/ktls.h> 47b2e60773SJohn Baldwin 48a4c5d490SJohn Baldwin struct ktls_ocf_sw { 49a4c5d490SJohn Baldwin /* Encrypt a single outbound TLS record. */ 50a4c5d490SJohn Baldwin int (*encrypt)(struct ktls_ocf_encrypt_state *state, 51a4c5d490SJohn Baldwin struct ktls_session *tls, struct mbuf *m, 52a4c5d490SJohn Baldwin struct iovec *outiov, int outiovcnt); 53a4c5d490SJohn Baldwin 54a8280123SJohn Baldwin /* Re-encrypt a received TLS record that is partially decrypted. */ 55a8280123SJohn Baldwin int (*recrypt)(struct ktls_session *tls, 56a8280123SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, 57a8280123SJohn Baldwin uint64_t seqno); 58a8280123SJohn Baldwin 59a4c5d490SJohn Baldwin /* Decrypt a received TLS record. */ 60a4c5d490SJohn Baldwin int (*decrypt)(struct ktls_session *tls, 61a4c5d490SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, 62a4c5d490SJohn Baldwin uint64_t seqno, int *trailer_len); 63a4c5d490SJohn Baldwin }; 64a4c5d490SJohn Baldwin 65b33ff941SJohn Baldwin struct ktls_ocf_session { 66a4c5d490SJohn Baldwin const struct ktls_ocf_sw *sw; 67b2e60773SJohn Baldwin crypto_session_t sid; 6847e2650eSJohn Baldwin crypto_session_t mac_sid; 69a8280123SJohn Baldwin crypto_session_t recrypt_sid; 70b2e60773SJohn Baldwin struct mtx lock; 7121e3c1fbSJohn Baldwin int mac_len; 7247e2650eSJohn Baldwin bool implicit_iv; 7347e2650eSJohn Baldwin 7447e2650eSJohn Baldwin /* Only used for TLS 1.0 with the implicit IV. */ 7547e2650eSJohn Baldwin #ifdef INVARIANTS 7647e2650eSJohn Baldwin bool in_progress; 7747e2650eSJohn Baldwin uint64_t next_seqno; 7847e2650eSJohn Baldwin #endif 7947e2650eSJohn Baldwin char iv[AES_BLOCK_LEN]; 80b2e60773SJohn Baldwin }; 81b2e60773SJohn Baldwin 82b2e60773SJohn Baldwin struct ocf_operation { 83b33ff941SJohn Baldwin struct ktls_ocf_session *os; 84b2e60773SJohn Baldwin bool done; 85b2e60773SJohn Baldwin }; 86b2e60773SJohn Baldwin 87b2e60773SJohn Baldwin static MALLOC_DEFINE(M_KTLS_OCF, "ktls_ocf", "OCF KTLS"); 88b2e60773SJohn Baldwin 89b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls); 90b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls_stats); 91b2e60773SJohn Baldwin 927029da5cSPawel Biernacki static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf, 937029da5cSPawel Biernacki CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 9455b7a0e1SJohn Baldwin "Kernel TLS offload via OCF stats"); 9555b7a0e1SJohn Baldwin 9616bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls10_cbc_encrypts); 9716bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls10_cbc_encrypts, 9816bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls10_cbc_encrypts, 9947e2650eSJohn Baldwin "Total number of OCF TLS 1.0 CBC encryption operations"); 10047e2650eSJohn Baldwin 1019a673b71SJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_decrypts); 1029a673b71SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_decrypts, 1039a673b71SJohn Baldwin CTLFLAG_RD, &ocf_tls11_cbc_decrypts, 1049a673b71SJohn Baldwin "Total number of OCF TLS 1.1/1.2 CBC decryption operations"); 1059a673b71SJohn Baldwin 10616bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_encrypts); 10716bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_encrypts, 10816bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls11_cbc_encrypts, 10947e2650eSJohn Baldwin "Total number of OCF TLS 1.1/1.2 CBC encryption operations"); 11047e2650eSJohn Baldwin 11116bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_decrypts); 11216bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_decrypts, 11316bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_decrypts, 11416bea05aSJohn Baldwin "Total number of OCF TLS 1.2 GCM decryption operations"); 11516bea05aSJohn Baldwin 11616bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_encrypts); 11716bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_encrypts, 11816bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_encrypts, 11955b7a0e1SJohn Baldwin "Total number of OCF TLS 1.2 GCM encryption operations"); 12055b7a0e1SJohn Baldwin 121a8280123SJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_recrypts); 122a8280123SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_recrypts, 123a8280123SJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_recrypts, 124a8280123SJohn Baldwin "Total number of OCF TLS 1.2 GCM re-encryption operations"); 125a8280123SJohn Baldwin 12616bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_decrypts); 12716bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_decrypts, 12816bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_decrypts, 12916bea05aSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 decryption operations"); 13016bea05aSJohn Baldwin 13116bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_encrypts); 13216bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_encrypts, 13316bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_encrypts, 1344dd6800eSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 encryption operations"); 1354dd6800eSJohn Baldwin 13605a1d0f5SJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_decrypts); 13705a1d0f5SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_decrypts, 13805a1d0f5SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_decrypts, 13905a1d0f5SJohn Baldwin "Total number of OCF TLS 1.3 GCM decryption operations"); 14005a1d0f5SJohn Baldwin 14116bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_encrypts); 14216bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_encrypts, 14316bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_encrypts, 14455b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 145b2e60773SJohn Baldwin 146a8280123SJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_recrypts); 147a8280123SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_recrypts, 148a8280123SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_recrypts, 149a8280123SJohn Baldwin "Total number of OCF TLS 1.3 GCM re-encryption operations"); 150a8280123SJohn Baldwin 15105a1d0f5SJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_decrypts); 15205a1d0f5SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_decrypts, 15305a1d0f5SJohn Baldwin CTLFLAG_RD, &ocf_tls13_chacha20_decrypts, 15405a1d0f5SJohn Baldwin "Total number of OCF TLS 1.3 Chacha20-Poly1305 decryption operations"); 15505a1d0f5SJohn Baldwin 15616bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_encrypts); 15716bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_encrypts, 15816bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls13_chacha20_encrypts, 1594dd6800eSJohn Baldwin "Total number of OCF TLS 1.3 Chacha20-Poly1305 encryption operations"); 1604dd6800eSJohn Baldwin 1611755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_inplace); 162080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace, 163080933c0SJohn Baldwin CTLFLAG_RD, &ocf_inplace, 164080933c0SJohn Baldwin "Total number of OCF in-place operations"); 165080933c0SJohn Baldwin 1661755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_separate_output); 167080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output, 168080933c0SJohn Baldwin CTLFLAG_RD, &ocf_separate_output, 169080933c0SJohn Baldwin "Total number of OCF operations with a separate output buffer"); 170080933c0SJohn Baldwin 1711755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_retries); 17255b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 173b2e60773SJohn Baldwin &ocf_retries, 174b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 175b2e60773SJohn Baldwin 176b2e60773SJohn Baldwin static int 177db6b5644SMark Johnston ktls_ocf_callback_sync(struct cryptop *crp __unused) 178db6b5644SMark Johnston { 179db6b5644SMark Johnston return (0); 180db6b5644SMark Johnston } 181db6b5644SMark Johnston 182db6b5644SMark Johnston static int 183db6b5644SMark Johnston ktls_ocf_callback_async(struct cryptop *crp) 184b2e60773SJohn Baldwin { 185b2e60773SJohn Baldwin struct ocf_operation *oo; 186b2e60773SJohn Baldwin 187b2e60773SJohn Baldwin oo = crp->crp_opaque; 188b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 189b2e60773SJohn Baldwin oo->done = true; 190b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 191b2e60773SJohn Baldwin wakeup(oo); 192b2e60773SJohn Baldwin return (0); 193b2e60773SJohn Baldwin } 194b2e60773SJohn Baldwin 195b2e60773SJohn Baldwin static int 196b33ff941SJohn Baldwin ktls_ocf_dispatch(struct ktls_ocf_session *os, struct cryptop *crp) 19770d1a435SJohn Baldwin { 19870d1a435SJohn Baldwin struct ocf_operation oo; 19970d1a435SJohn Baldwin int error; 200db6b5644SMark Johnston bool async; 20170d1a435SJohn Baldwin 20270d1a435SJohn Baldwin oo.os = os; 20370d1a435SJohn Baldwin oo.done = false; 20470d1a435SJohn Baldwin 20570d1a435SJohn Baldwin crp->crp_opaque = &oo; 20670d1a435SJohn Baldwin for (;;) { 207db6b5644SMark Johnston async = !CRYPTO_SESS_SYNC(crp->crp_session); 208db6b5644SMark Johnston crp->crp_callback = async ? ktls_ocf_callback_async : 209db6b5644SMark Johnston ktls_ocf_callback_sync; 210db6b5644SMark Johnston 21170d1a435SJohn Baldwin error = crypto_dispatch(crp); 21270d1a435SJohn Baldwin if (error) 21370d1a435SJohn Baldwin break; 214db6b5644SMark Johnston if (async) { 21570d1a435SJohn Baldwin mtx_lock(&os->lock); 21670d1a435SJohn Baldwin while (!oo.done) 21770d1a435SJohn Baldwin mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0); 21870d1a435SJohn Baldwin mtx_unlock(&os->lock); 219db6b5644SMark Johnston } 22070d1a435SJohn Baldwin 22170d1a435SJohn Baldwin if (crp->crp_etype != EAGAIN) { 22270d1a435SJohn Baldwin error = crp->crp_etype; 22370d1a435SJohn Baldwin break; 22470d1a435SJohn Baldwin } 22570d1a435SJohn Baldwin 22670d1a435SJohn Baldwin crp->crp_etype = 0; 22770d1a435SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 22870d1a435SJohn Baldwin oo.done = false; 22970d1a435SJohn Baldwin counter_u64_add(ocf_retries, 1); 23070d1a435SJohn Baldwin } 23170d1a435SJohn Baldwin return (error); 23270d1a435SJohn Baldwin } 23370d1a435SJohn Baldwin 23470d1a435SJohn Baldwin static int 235470e851cSJohn Baldwin ktls_ocf_dispatch_async_cb(struct cryptop *crp) 236470e851cSJohn Baldwin { 237470e851cSJohn Baldwin struct ktls_ocf_encrypt_state *state; 238470e851cSJohn Baldwin int error; 239470e851cSJohn Baldwin 240470e851cSJohn Baldwin state = crp->crp_opaque; 241470e851cSJohn Baldwin if (crp->crp_etype == EAGAIN) { 242470e851cSJohn Baldwin crp->crp_etype = 0; 243470e851cSJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 244470e851cSJohn Baldwin counter_u64_add(ocf_retries, 1); 245470e851cSJohn Baldwin error = crypto_dispatch(crp); 246470e851cSJohn Baldwin if (error != 0) { 247470e851cSJohn Baldwin crypto_destroyreq(crp); 248470e851cSJohn Baldwin ktls_encrypt_cb(state, error); 249470e851cSJohn Baldwin } 250470e851cSJohn Baldwin return (0); 251470e851cSJohn Baldwin } 252470e851cSJohn Baldwin 253470e851cSJohn Baldwin error = crp->crp_etype; 254470e851cSJohn Baldwin crypto_destroyreq(crp); 255470e851cSJohn Baldwin ktls_encrypt_cb(state, error); 256470e851cSJohn Baldwin return (0); 257470e851cSJohn Baldwin } 258470e851cSJohn Baldwin 259470e851cSJohn Baldwin static int 260470e851cSJohn Baldwin ktls_ocf_dispatch_async(struct ktls_ocf_encrypt_state *state, 261470e851cSJohn Baldwin struct cryptop *crp) 262470e851cSJohn Baldwin { 263470e851cSJohn Baldwin int error; 264470e851cSJohn Baldwin 265470e851cSJohn Baldwin crp->crp_opaque = state; 266470e851cSJohn Baldwin crp->crp_callback = ktls_ocf_dispatch_async_cb; 267470e851cSJohn Baldwin error = crypto_dispatch(crp); 268470e851cSJohn Baldwin if (error != 0) 269470e851cSJohn Baldwin crypto_destroyreq(crp); 270470e851cSJohn Baldwin return (error); 271470e851cSJohn Baldwin } 272470e851cSJohn Baldwin 273470e851cSJohn Baldwin static int 274470e851cSJohn Baldwin ktls_ocf_tls_cbc_encrypt(struct ktls_ocf_encrypt_state *state, 275470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 276470e851cSJohn Baldwin int outiovcnt) 27747e2650eSJohn Baldwin { 27821e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 279470e851cSJohn Baldwin struct uio *uio; 280470e851cSJohn Baldwin struct tls_mac_data *ad; 281470e851cSJohn Baldwin struct cryptop *crp; 282b33ff941SJohn Baldwin struct ktls_ocf_session *os; 28321e3c1fbSJohn Baldwin struct iovec iov[m->m_epg_npgs + 2]; 28421e3c1fbSJohn Baldwin u_int pgoff; 28547e2650eSJohn Baldwin int i, error; 28647e2650eSJohn Baldwin uint16_t tls_comp_len; 28747e2650eSJohn Baldwin uint8_t pad; 28821e3c1fbSJohn Baldwin 28921e3c1fbSJohn Baldwin MPASS(outiovcnt + 1 <= nitems(iov)); 29047e2650eSJohn Baldwin 291b33ff941SJohn Baldwin os = tls->ocf_session; 29221e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 293470e851cSJohn Baldwin crp = &state->crp; 294470e851cSJohn Baldwin uio = &state->uio; 295470e851cSJohn Baldwin MPASS(tls->sync_dispatch); 29647e2650eSJohn Baldwin 29747e2650eSJohn Baldwin #ifdef INVARIANTS 29847e2650eSJohn Baldwin if (os->implicit_iv) { 29947e2650eSJohn Baldwin mtx_lock(&os->lock); 30047e2650eSJohn Baldwin KASSERT(!os->in_progress, 30147e2650eSJohn Baldwin ("concurrent implicit IV encryptions")); 30221e3c1fbSJohn Baldwin if (os->next_seqno != m->m_epg_seqno) { 30347e2650eSJohn Baldwin printf("KTLS CBC: TLS records out of order. " 30447e2650eSJohn Baldwin "Expected %ju, got %ju\n", 30521e3c1fbSJohn Baldwin (uintmax_t)os->next_seqno, 30621e3c1fbSJohn Baldwin (uintmax_t)m->m_epg_seqno); 30747e2650eSJohn Baldwin mtx_unlock(&os->lock); 30847e2650eSJohn Baldwin return (EINVAL); 30947e2650eSJohn Baldwin } 31047e2650eSJohn Baldwin os->in_progress = true; 31147e2650eSJohn Baldwin mtx_unlock(&os->lock); 31247e2650eSJohn Baldwin } 31347e2650eSJohn Baldwin #endif 31447e2650eSJohn Baldwin 31521e3c1fbSJohn Baldwin /* Payload length. */ 31621e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 31747e2650eSJohn Baldwin 31847e2650eSJohn Baldwin /* Initialize the AAD. */ 319470e851cSJohn Baldwin ad = &state->mac; 320470e851cSJohn Baldwin ad->seq = htobe64(m->m_epg_seqno); 321470e851cSJohn Baldwin ad->type = hdr->tls_type; 322470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 323470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 324470e851cSJohn Baldwin ad->tls_length = htons(tls_comp_len); 32547e2650eSJohn Baldwin 32647e2650eSJohn Baldwin /* First, compute the MAC. */ 327470e851cSJohn Baldwin iov[0].iov_base = ad; 328470e851cSJohn Baldwin iov[0].iov_len = sizeof(*ad); 32921e3c1fbSJohn Baldwin pgoff = m->m_epg_1st_off; 33021e3c1fbSJohn Baldwin for (i = 0; i < m->m_epg_npgs; i++, pgoff = 0) { 33121e3c1fbSJohn Baldwin iov[i + 1].iov_base = (void *)PHYS_TO_DMAP(m->m_epg_pa[i] + 33221e3c1fbSJohn Baldwin pgoff); 33321e3c1fbSJohn Baldwin iov[i + 1].iov_len = m_epg_pagelen(m, i, pgoff); 33421e3c1fbSJohn Baldwin } 33521e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_base = m->m_epg_trail; 33621e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_len = os->mac_len; 337470e851cSJohn Baldwin uio->uio_iov = iov; 338470e851cSJohn Baldwin uio->uio_iovcnt = m->m_epg_npgs + 2; 339470e851cSJohn Baldwin uio->uio_offset = 0; 340470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 341470e851cSJohn Baldwin uio->uio_td = curthread; 342470e851cSJohn Baldwin uio->uio_resid = sizeof(*ad) + tls_comp_len + os->mac_len; 34347e2650eSJohn Baldwin 344470e851cSJohn Baldwin crypto_initreq(crp, os->mac_sid); 345470e851cSJohn Baldwin crp->crp_payload_start = 0; 346470e851cSJohn Baldwin crp->crp_payload_length = sizeof(*ad) + tls_comp_len; 347470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 348470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST; 349470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM; 350470e851cSJohn Baldwin crypto_use_uio(crp, uio); 351470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 35247e2650eSJohn Baldwin 353470e851cSJohn Baldwin crypto_destroyreq(crp); 35447e2650eSJohn Baldwin if (error) { 35547e2650eSJohn Baldwin #ifdef INVARIANTS 35647e2650eSJohn Baldwin if (os->implicit_iv) { 35747e2650eSJohn Baldwin mtx_lock(&os->lock); 35847e2650eSJohn Baldwin os->in_progress = false; 35947e2650eSJohn Baldwin mtx_unlock(&os->lock); 36047e2650eSJohn Baldwin } 36147e2650eSJohn Baldwin #endif 36247e2650eSJohn Baldwin return (error); 36347e2650eSJohn Baldwin } 36447e2650eSJohn Baldwin 36547e2650eSJohn Baldwin /* Second, add the padding. */ 36621e3c1fbSJohn Baldwin pad = m->m_epg_trllen - os->mac_len - 1; 36747e2650eSJohn Baldwin for (i = 0; i < pad + 1; i++) 36821e3c1fbSJohn Baldwin m->m_epg_trail[os->mac_len + i] = pad; 36947e2650eSJohn Baldwin 37047e2650eSJohn Baldwin /* Finally, encrypt the record. */ 371470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 372470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 373470e851cSJohn Baldwin crp->crp_payload_length = tls_comp_len + m->m_epg_trllen; 374470e851cSJohn Baldwin KASSERT(crp->crp_payload_length % AES_BLOCK_LEN == 0, 37521e3c1fbSJohn Baldwin ("invalid encryption size")); 376470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 377470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT; 378470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 37947e2650eSJohn Baldwin if (os->implicit_iv) 380470e851cSJohn Baldwin memcpy(crp->crp_iv, os->iv, AES_BLOCK_LEN); 38147e2650eSJohn Baldwin else 382470e851cSJohn Baldwin memcpy(crp->crp_iv, hdr + 1, AES_BLOCK_LEN); 38321e3c1fbSJohn Baldwin 38421e3c1fbSJohn Baldwin if (outiov != NULL) { 385470e851cSJohn Baldwin uio->uio_iov = outiov; 386470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 387470e851cSJohn Baldwin uio->uio_offset = 0; 388470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 389470e851cSJohn Baldwin uio->uio_td = curthread; 390470e851cSJohn Baldwin uio->uio_resid = crp->crp_payload_length; 391470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 39247e2650eSJohn Baldwin } 39347e2650eSJohn Baldwin 39447e2650eSJohn Baldwin if (os->implicit_iv) 39516bea05aSJohn Baldwin counter_u64_add(ocf_tls10_cbc_encrypts, 1); 39647e2650eSJohn Baldwin else 39716bea05aSJohn Baldwin counter_u64_add(ocf_tls11_cbc_encrypts, 1); 39821e3c1fbSJohn Baldwin if (outiov != NULL) 39947e2650eSJohn Baldwin counter_u64_add(ocf_separate_output, 1); 40021e3c1fbSJohn Baldwin else 40121e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 402470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 40347e2650eSJohn Baldwin 404470e851cSJohn Baldwin crypto_destroyreq(crp); 40547e2650eSJohn Baldwin 40647e2650eSJohn Baldwin if (os->implicit_iv) { 40747e2650eSJohn Baldwin KASSERT(os->mac_len + pad + 1 >= AES_BLOCK_LEN, 40847e2650eSJohn Baldwin ("trailer too short to read IV")); 40921e3c1fbSJohn Baldwin memcpy(os->iv, m->m_epg_trail + m->m_epg_trllen - AES_BLOCK_LEN, 41047e2650eSJohn Baldwin AES_BLOCK_LEN); 41147e2650eSJohn Baldwin #ifdef INVARIANTS 41247e2650eSJohn Baldwin mtx_lock(&os->lock); 41321e3c1fbSJohn Baldwin os->next_seqno = m->m_epg_seqno + 1; 41447e2650eSJohn Baldwin os->in_progress = false; 41547e2650eSJohn Baldwin mtx_unlock(&os->lock); 41647e2650eSJohn Baldwin #endif 41747e2650eSJohn Baldwin } 41847e2650eSJohn Baldwin return (error); 41947e2650eSJohn Baldwin } 42047e2650eSJohn Baldwin 4219a673b71SJohn Baldwin static int 4229a673b71SJohn Baldwin check_padding(void *arg, void *data, u_int len) 4239a673b71SJohn Baldwin { 4249a673b71SJohn Baldwin uint8_t pad = *(uint8_t *)arg; 4259a673b71SJohn Baldwin const char *cp = data; 4269a673b71SJohn Baldwin 4279a673b71SJohn Baldwin while (len > 0) { 4289a673b71SJohn Baldwin if (*cp != pad) 4299a673b71SJohn Baldwin return (EBADMSG); 4309a673b71SJohn Baldwin cp++; 4319a673b71SJohn Baldwin len--; 4329a673b71SJohn Baldwin } 4339a673b71SJohn Baldwin return (0); 4349a673b71SJohn Baldwin } 4359a673b71SJohn Baldwin 4369a673b71SJohn Baldwin static int 4379a673b71SJohn Baldwin ktls_ocf_tls_cbc_decrypt(struct ktls_session *tls, 4389a673b71SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 4399a673b71SJohn Baldwin int *trailer_len) 4409a673b71SJohn Baldwin { 4419a673b71SJohn Baldwin struct tls_mac_data ad; 4429a673b71SJohn Baldwin struct cryptop crp; 4439a673b71SJohn Baldwin struct uio uio; 4449a673b71SJohn Baldwin struct ktls_ocf_session *os; 4459a673b71SJohn Baldwin struct iovec *iov; 4469a673b71SJohn Baldwin struct mbuf *n; 4479a673b71SJohn Baldwin u_int iovcnt; 4489a673b71SJohn Baldwin int i, error, skip; 4499a673b71SJohn Baldwin uint16_t tls_len, tls_comp_len; 4509a673b71SJohn Baldwin uint8_t pad; 4519a673b71SJohn Baldwin 4529a673b71SJohn Baldwin os = tls->ocf_session; 4539a673b71SJohn Baldwin 4549a673b71SJohn Baldwin /* 4559a673b71SJohn Baldwin * Ensure record is a multiple of the cipher block size and 4569a673b71SJohn Baldwin * contains at least an explicit IV, MAC, and at least one 4579a673b71SJohn Baldwin * padding byte. 4589a673b71SJohn Baldwin */ 4599a673b71SJohn Baldwin tls_len = ntohs(hdr->tls_length); 4609a673b71SJohn Baldwin if (tls_len % AES_BLOCK_LEN != 0 || 4619a673b71SJohn Baldwin tls_len < AES_BLOCK_LEN + roundup2(os->mac_len + 1, AES_BLOCK_LEN)) 4629a673b71SJohn Baldwin return (EMSGSIZE); 4639a673b71SJohn Baldwin 4649a673b71SJohn Baldwin /* First, decrypt the record. */ 4659a673b71SJohn Baldwin crypto_initreq(&crp, os->sid); 4669a673b71SJohn Baldwin crp.crp_iv_start = sizeof(*hdr); 4679a673b71SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 4689a673b71SJohn Baldwin crp.crp_payload_length = tls_len - AES_BLOCK_LEN; 4699a673b71SJohn Baldwin crypto_use_mbuf(&crp, m); 4709a673b71SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT; 4719a673b71SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM; 4729a673b71SJohn Baldwin 4739a673b71SJohn Baldwin counter_u64_add(ocf_tls11_cbc_decrypts, 1); 4749a673b71SJohn Baldwin 4759a673b71SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 4769a673b71SJohn Baldwin crypto_destroyreq(&crp); 4779a673b71SJohn Baldwin if (error) 4789a673b71SJohn Baldwin return (error); 4799a673b71SJohn Baldwin 4809a673b71SJohn Baldwin /* Verify the padding. */ 4819a673b71SJohn Baldwin m_copydata(m, sizeof(*hdr) + tls_len - 1, 1, &pad); 4829a673b71SJohn Baldwin *trailer_len = os->mac_len + pad + 1; 4839a673b71SJohn Baldwin if (AES_BLOCK_LEN + *trailer_len > tls_len) 4849a673b71SJohn Baldwin return (EBADMSG); 4859a673b71SJohn Baldwin error = m_apply(m, sizeof(*hdr) + tls_len - (pad + 1), pad + 1, 4869a673b71SJohn Baldwin check_padding, &pad); 4879a673b71SJohn Baldwin if (error) 4889a673b71SJohn Baldwin return (error); 4899a673b71SJohn Baldwin 4909a673b71SJohn Baldwin /* Verify the MAC. */ 4919a673b71SJohn Baldwin tls_comp_len = tls_len - (AES_BLOCK_LEN + *trailer_len); 4929a673b71SJohn Baldwin memset(&uio, 0, sizeof(uio)); 4939a673b71SJohn Baldwin 4949a673b71SJohn Baldwin /* 4959a673b71SJohn Baldwin * Allocate and populate the iov. Have to skip over the TLS 4969a673b71SJohn Baldwin * header in 'm' as it is not part of the MAC input. 4979a673b71SJohn Baldwin */ 4989a673b71SJohn Baldwin iovcnt = 1; 4999a673b71SJohn Baldwin for (n = m; n != NULL; n = n->m_next) 5009a673b71SJohn Baldwin iovcnt++; 5019a673b71SJohn Baldwin iov = malloc(iovcnt * sizeof(*iov), M_KTLS_OCF, M_WAITOK); 5029a673b71SJohn Baldwin iov[0].iov_base = &ad; 5039a673b71SJohn Baldwin iov[0].iov_len = sizeof(ad); 5049a673b71SJohn Baldwin skip = sizeof(*hdr) + AES_BLOCK_LEN; 5059a673b71SJohn Baldwin for (i = 1, n = m; n != NULL; i++, n = n->m_next) { 5069a673b71SJohn Baldwin if (n->m_len < skip) { 5079a673b71SJohn Baldwin skip -= n->m_len; 5089a673b71SJohn Baldwin continue; 5099a673b71SJohn Baldwin } 5109a673b71SJohn Baldwin iov[i].iov_base = mtod(n, char *) + skip; 5119a673b71SJohn Baldwin iov[i].iov_len = n->m_len - skip; 5129a673b71SJohn Baldwin skip = 0; 5139a673b71SJohn Baldwin } 5149a673b71SJohn Baldwin uio.uio_iov = iov; 5159a673b71SJohn Baldwin uio.uio_iovcnt = i; 5169a673b71SJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 5179a673b71SJohn Baldwin uio.uio_td = curthread; 5189a673b71SJohn Baldwin uio.uio_resid = sizeof(ad) + tls_len - AES_BLOCK_LEN; 5199a673b71SJohn Baldwin 5209a673b71SJohn Baldwin /* Initialize the AAD. */ 5219a673b71SJohn Baldwin ad.seq = htobe64(seqno); 5229a673b71SJohn Baldwin ad.type = hdr->tls_type; 5239a673b71SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 5249a673b71SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 5259a673b71SJohn Baldwin ad.tls_length = htons(tls_comp_len); 5269a673b71SJohn Baldwin 5279a673b71SJohn Baldwin crypto_initreq(&crp, os->mac_sid); 5289a673b71SJohn Baldwin crp.crp_payload_start = 0; 5299a673b71SJohn Baldwin crp.crp_payload_length = sizeof(ad) + tls_comp_len; 5309a673b71SJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 5319a673b71SJohn Baldwin crp.crp_op = CRYPTO_OP_VERIFY_DIGEST; 5329a673b71SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM; 5339a673b71SJohn Baldwin crypto_use_uio(&crp, &uio); 5349a673b71SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 5359a673b71SJohn Baldwin 5369a673b71SJohn Baldwin crypto_destroyreq(&crp); 5379a673b71SJohn Baldwin free(iov, M_KTLS_OCF); 5389a673b71SJohn Baldwin return (error); 5399a673b71SJohn Baldwin } 5409a673b71SJohn Baldwin 541a4c5d490SJohn Baldwin static const struct ktls_ocf_sw ktls_ocf_tls_cbc_sw = { 5429a673b71SJohn Baldwin .encrypt = ktls_ocf_tls_cbc_encrypt, 5439a673b71SJohn Baldwin .decrypt = ktls_ocf_tls_cbc_decrypt 544a4c5d490SJohn Baldwin }; 545a4c5d490SJohn Baldwin 54647e2650eSJohn Baldwin static int 547470e851cSJohn Baldwin ktls_ocf_tls12_aead_encrypt(struct ktls_ocf_encrypt_state *state, 548470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 549470e851cSJohn Baldwin int outiovcnt) 550b2e60773SJohn Baldwin { 55121e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 552470e851cSJohn Baldwin struct uio *uio; 553470e851cSJohn Baldwin struct tls_aead_data *ad; 554470e851cSJohn Baldwin struct cryptop *crp; 555b33ff941SJohn Baldwin struct ktls_ocf_session *os; 55621e3c1fbSJohn Baldwin int error; 557b2e60773SJohn Baldwin uint16_t tls_comp_len; 558b2e60773SJohn Baldwin 559b33ff941SJohn Baldwin os = tls->ocf_session; 56021e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 561470e851cSJohn Baldwin crp = &state->crp; 562470e851cSJohn Baldwin uio = &state->uio; 563b2e60773SJohn Baldwin 564470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 565b2e60773SJohn Baldwin 566b2e60773SJohn Baldwin /* Setup the IV. */ 5674dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 568470e851cSJohn Baldwin memcpy(crp->crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 569470e851cSJohn Baldwin memcpy(crp->crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 5704dd6800eSJohn Baldwin sizeof(uint64_t)); 5714dd6800eSJohn Baldwin } else { 5724dd6800eSJohn Baldwin /* 5734dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 5744dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 5754dd6800eSJohn Baldwin * 1.3. 5764dd6800eSJohn Baldwin */ 577470e851cSJohn Baldwin memcpy(crp->crp_iv, tls->params.iv, tls->params.iv_len); 578470e851cSJohn Baldwin *(uint64_t *)(crp->crp_iv + 4) ^= htobe64(m->m_epg_seqno); 5794dd6800eSJohn Baldwin } 580b2e60773SJohn Baldwin 581b2e60773SJohn Baldwin /* Setup the AAD. */ 582470e851cSJohn Baldwin ad = &state->aead; 58321e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 584470e851cSJohn Baldwin ad->seq = htobe64(m->m_epg_seqno); 585470e851cSJohn Baldwin ad->type = hdr->tls_type; 586470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 587470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 588470e851cSJohn Baldwin ad->tls_length = htons(tls_comp_len); 589470e851cSJohn Baldwin crp->crp_aad = ad; 590470e851cSJohn Baldwin crp->crp_aad_length = sizeof(*ad); 591b2e60773SJohn Baldwin 59221e3c1fbSJohn Baldwin /* Set fields for input payload. */ 593470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 594470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 595470e851cSJohn Baldwin crp->crp_payload_length = tls_comp_len; 596b2e60773SJohn Baldwin 59721e3c1fbSJohn Baldwin if (outiov != NULL) { 598470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 59921e3c1fbSJohn Baldwin 600470e851cSJohn Baldwin uio->uio_iov = outiov; 601470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 602470e851cSJohn Baldwin uio->uio_offset = 0; 603470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 604470e851cSJohn Baldwin uio->uio_td = curthread; 605470e851cSJohn Baldwin uio->uio_resid = crp->crp_payload_length + tls->params.tls_tlen; 606470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 60721e3c1fbSJohn Baldwin } else 608470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_start + 609470e851cSJohn Baldwin crp->crp_payload_length; 610b2e60773SJohn Baldwin 611470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 612470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 6134dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 61416bea05aSJohn Baldwin counter_u64_add(ocf_tls12_gcm_encrypts, 1); 6154dd6800eSJohn Baldwin else 61616bea05aSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_encrypts, 1); 61721e3c1fbSJohn Baldwin if (outiov != NULL) 618080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 61921e3c1fbSJohn Baldwin else 62021e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 621470e851cSJohn Baldwin if (tls->sync_dispatch) { 622470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 623470e851cSJohn Baldwin crypto_destroyreq(crp); 624470e851cSJohn Baldwin } else 625470e851cSJohn Baldwin error = ktls_ocf_dispatch_async(state, crp); 62655b7a0e1SJohn Baldwin return (error); 62755b7a0e1SJohn Baldwin } 62855b7a0e1SJohn Baldwin 62955b7a0e1SJohn Baldwin static int 6304dd6800eSJohn Baldwin ktls_ocf_tls12_aead_decrypt(struct ktls_session *tls, 6313c0e5685SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 6323c0e5685SJohn Baldwin int *trailer_len) 6333c0e5685SJohn Baldwin { 6343c0e5685SJohn Baldwin struct tls_aead_data ad; 6353c0e5685SJohn Baldwin struct cryptop crp; 636b33ff941SJohn Baldwin struct ktls_ocf_session *os; 6373c0e5685SJohn Baldwin int error; 6384e474146SJohn Baldwin uint16_t tls_comp_len, tls_len; 6393c0e5685SJohn Baldwin 640b33ff941SJohn Baldwin os = tls->ocf_session; 6413c0e5685SJohn Baldwin 6424e474146SJohn Baldwin /* Ensure record contains at least an explicit IV and tag. */ 6434e474146SJohn Baldwin tls_len = ntohs(hdr->tls_length); 6444e474146SJohn Baldwin if (tls_len + sizeof(*hdr) < tls->params.tls_hlen + 6454e474146SJohn Baldwin tls->params.tls_tlen) 6464e474146SJohn Baldwin return (EMSGSIZE); 6474e474146SJohn Baldwin 6483c0e5685SJohn Baldwin crypto_initreq(&crp, os->sid); 6493c0e5685SJohn Baldwin 6503c0e5685SJohn Baldwin /* Setup the IV. */ 6514dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 6523c0e5685SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 6534dd6800eSJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 6544dd6800eSJohn Baldwin sizeof(uint64_t)); 6554dd6800eSJohn Baldwin } else { 6564dd6800eSJohn Baldwin /* 6574dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 6584dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 6594dd6800eSJohn Baldwin * 1.3. 6604dd6800eSJohn Baldwin */ 6614dd6800eSJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 6624dd6800eSJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 6634dd6800eSJohn Baldwin } 6643c0e5685SJohn Baldwin 6653c0e5685SJohn Baldwin /* Setup the AAD. */ 6664dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 6674e474146SJohn Baldwin tls_comp_len = tls_len - 6683c0e5685SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 6694dd6800eSJohn Baldwin else 6704e474146SJohn Baldwin tls_comp_len = tls_len - POLY1305_HASH_LEN; 6713c0e5685SJohn Baldwin ad.seq = htobe64(seqno); 6723c0e5685SJohn Baldwin ad.type = hdr->tls_type; 6733c0e5685SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 6743c0e5685SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 6753c0e5685SJohn Baldwin ad.tls_length = htons(tls_comp_len); 6763c0e5685SJohn Baldwin crp.crp_aad = &ad; 6773c0e5685SJohn Baldwin crp.crp_aad_length = sizeof(ad); 6783c0e5685SJohn Baldwin 6793c0e5685SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 6803c0e5685SJohn Baldwin crp.crp_payload_length = tls_comp_len; 6813c0e5685SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 6823c0e5685SJohn Baldwin 6833c0e5685SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 6843c0e5685SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 6853c0e5685SJohn Baldwin crypto_use_mbuf(&crp, m); 6863c0e5685SJohn Baldwin 6874dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 68816bea05aSJohn Baldwin counter_u64_add(ocf_tls12_gcm_decrypts, 1); 6894dd6800eSJohn Baldwin else 69016bea05aSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_decrypts, 1); 6913c0e5685SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 6923c0e5685SJohn Baldwin 6933c0e5685SJohn Baldwin crypto_destroyreq(&crp); 6944a92afaeSJohn Baldwin *trailer_len = tls->params.tls_tlen; 6953c0e5685SJohn Baldwin return (error); 6963c0e5685SJohn Baldwin } 6973c0e5685SJohn Baldwin 698a8280123SJohn Baldwin /* 699a8280123SJohn Baldwin * Reconstruct encrypted mbuf data in input buffer. 700a8280123SJohn Baldwin */ 701a8280123SJohn Baldwin static void 702a8280123SJohn Baldwin ktls_ocf_recrypt_fixup(struct mbuf *m, u_int skip, u_int len, char *buf) 703a8280123SJohn Baldwin { 704a8280123SJohn Baldwin const char *src = buf; 705a8280123SJohn Baldwin u_int todo; 706a8280123SJohn Baldwin 707a8280123SJohn Baldwin while (skip >= m->m_len) { 708a8280123SJohn Baldwin skip -= m->m_len; 709a8280123SJohn Baldwin m = m->m_next; 710a8280123SJohn Baldwin } 711a8280123SJohn Baldwin 712a8280123SJohn Baldwin while (len > 0) { 713a8280123SJohn Baldwin todo = m->m_len - skip; 714a8280123SJohn Baldwin if (todo > len) 715a8280123SJohn Baldwin todo = len; 716a8280123SJohn Baldwin 717a8280123SJohn Baldwin if (m->m_flags & M_DECRYPTED) 718a8280123SJohn Baldwin memcpy(mtod(m, char *) + skip, src, todo); 719a8280123SJohn Baldwin src += todo; 720a8280123SJohn Baldwin len -= todo; 721a8280123SJohn Baldwin skip = 0; 722a8280123SJohn Baldwin m = m->m_next; 723a8280123SJohn Baldwin } 724a8280123SJohn Baldwin } 725a8280123SJohn Baldwin 726a8280123SJohn Baldwin static int 727a8280123SJohn Baldwin ktls_ocf_tls12_aead_recrypt(struct ktls_session *tls, 728a8280123SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, 729a8280123SJohn Baldwin uint64_t seqno) 730a8280123SJohn Baldwin { 731a8280123SJohn Baldwin struct cryptop crp; 732a8280123SJohn Baldwin struct ktls_ocf_session *os; 733a8280123SJohn Baldwin char *buf; 734a8280123SJohn Baldwin u_int payload_len; 735a8280123SJohn Baldwin int error; 7364e474146SJohn Baldwin uint16_t tls_len; 737a8280123SJohn Baldwin 738a8280123SJohn Baldwin os = tls->ocf_session; 739a8280123SJohn Baldwin 7404e474146SJohn Baldwin /* Ensure record contains at least an explicit IV and tag. */ 7414e474146SJohn Baldwin tls_len = ntohs(hdr->tls_length); 7424e474146SJohn Baldwin if (tls_len < sizeof(uint64_t) + AES_GMAC_HASH_LEN) 7434e474146SJohn Baldwin return (EMSGSIZE); 7444e474146SJohn Baldwin 745a8280123SJohn Baldwin crypto_initreq(&crp, os->recrypt_sid); 746a8280123SJohn Baldwin 747a8280123SJohn Baldwin KASSERT(tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16, 748a8280123SJohn Baldwin ("%s: only AES-GCM is supported", __func__)); 749a8280123SJohn Baldwin 750a8280123SJohn Baldwin /* Setup the IV. */ 751a8280123SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 752a8280123SJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t)); 753a8280123SJohn Baldwin be32enc(crp.crp_iv + AES_GCM_IV_LEN, 2); 754a8280123SJohn Baldwin 7554e474146SJohn Baldwin payload_len = tls_len - (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 756a8280123SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT; 757a8280123SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 758a8280123SJohn Baldwin crypto_use_mbuf(&crp, m); 759a8280123SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 760a8280123SJohn Baldwin crp.crp_payload_length = payload_len; 761a8280123SJohn Baldwin 762a8280123SJohn Baldwin buf = malloc(payload_len, M_KTLS_OCF, M_WAITOK); 763a8280123SJohn Baldwin crypto_use_output_buf(&crp, buf, payload_len); 764a8280123SJohn Baldwin 765a8280123SJohn Baldwin counter_u64_add(ocf_tls12_gcm_recrypts, 1); 766a8280123SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 767a8280123SJohn Baldwin 768a8280123SJohn Baldwin crypto_destroyreq(&crp); 769a8280123SJohn Baldwin 770a8280123SJohn Baldwin if (error == 0) 771a8280123SJohn Baldwin ktls_ocf_recrypt_fixup(m, tls->params.tls_hlen, payload_len, 772a8280123SJohn Baldwin buf); 773a8280123SJohn Baldwin 774a8280123SJohn Baldwin free(buf, M_KTLS_OCF); 775a8280123SJohn Baldwin return (error); 776a8280123SJohn Baldwin } 777a8280123SJohn Baldwin 778a4c5d490SJohn Baldwin static const struct ktls_ocf_sw ktls_ocf_tls12_aead_sw = { 779a4c5d490SJohn Baldwin .encrypt = ktls_ocf_tls12_aead_encrypt, 780a8280123SJohn Baldwin .recrypt = ktls_ocf_tls12_aead_recrypt, 781a4c5d490SJohn Baldwin .decrypt = ktls_ocf_tls12_aead_decrypt, 782a4c5d490SJohn Baldwin }; 783a4c5d490SJohn Baldwin 7843c0e5685SJohn Baldwin static int 785470e851cSJohn Baldwin ktls_ocf_tls13_aead_encrypt(struct ktls_ocf_encrypt_state *state, 786470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 787470e851cSJohn Baldwin int outiovcnt) 78855b7a0e1SJohn Baldwin { 78921e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 790470e851cSJohn Baldwin struct uio *uio; 791470e851cSJohn Baldwin struct tls_aead_data_13 *ad; 792470e851cSJohn Baldwin struct cryptop *crp; 793b33ff941SJohn Baldwin struct ktls_ocf_session *os; 79421e3c1fbSJohn Baldwin int error; 79555b7a0e1SJohn Baldwin 796b33ff941SJohn Baldwin os = tls->ocf_session; 79721e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 798470e851cSJohn Baldwin crp = &state->crp; 799470e851cSJohn Baldwin uio = &state->uio; 80055b7a0e1SJohn Baldwin 801470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 80255b7a0e1SJohn Baldwin 80355b7a0e1SJohn Baldwin /* Setup the nonce. */ 804663ae8f7SJohn Baldwin memcpy(crp->crp_iv, tls->params.iv, tls->params.iv_len); 805663ae8f7SJohn Baldwin *(uint64_t *)(crp->crp_iv + 4) ^= htobe64(m->m_epg_seqno); 80655b7a0e1SJohn Baldwin 80755b7a0e1SJohn Baldwin /* Setup the AAD. */ 808470e851cSJohn Baldwin ad = &state->aead13; 809470e851cSJohn Baldwin ad->type = hdr->tls_type; 810470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 811470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 812470e851cSJohn Baldwin ad->tls_length = hdr->tls_length; 813470e851cSJohn Baldwin crp->crp_aad = ad; 814470e851cSJohn Baldwin crp->crp_aad_length = sizeof(*ad); 815080933c0SJohn Baldwin 81621e3c1fbSJohn Baldwin /* Set fields for input payload. */ 817470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 818470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 819470e851cSJohn Baldwin crp->crp_payload_length = m->m_len - 820470e851cSJohn Baldwin (m->m_epg_hdrlen + m->m_epg_trllen); 82155b7a0e1SJohn Baldwin 8225b750b9aSJohn Baldwin /* Store the record type as the first byte of the trailer. */ 82321e3c1fbSJohn Baldwin m->m_epg_trail[0] = m->m_epg_record_type; 824470e851cSJohn Baldwin crp->crp_payload_length++; 82521e3c1fbSJohn Baldwin 82621e3c1fbSJohn Baldwin if (outiov != NULL) { 827470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 8285b750b9aSJohn Baldwin 829470e851cSJohn Baldwin uio->uio_iov = outiov; 830470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 831470e851cSJohn Baldwin uio->uio_offset = 0; 832470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 833470e851cSJohn Baldwin uio->uio_td = curthread; 834470e851cSJohn Baldwin uio->uio_resid = m->m_len - m->m_epg_hdrlen; 835470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 83621e3c1fbSJohn Baldwin } else 837470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_start + 838470e851cSJohn Baldwin crp->crp_payload_length; 83955b7a0e1SJohn Baldwin 840470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 841470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 84255b7a0e1SJohn Baldwin 8434dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 84416bea05aSJohn Baldwin counter_u64_add(ocf_tls13_gcm_encrypts, 1); 8454dd6800eSJohn Baldwin else 84616bea05aSJohn Baldwin counter_u64_add(ocf_tls13_chacha20_encrypts, 1); 84721e3c1fbSJohn Baldwin if (outiov != NULL) 848080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 84921e3c1fbSJohn Baldwin else 85021e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 851470e851cSJohn Baldwin if (tls->sync_dispatch) { 852470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 853470e851cSJohn Baldwin crypto_destroyreq(crp); 854470e851cSJohn Baldwin } else 855470e851cSJohn Baldwin error = ktls_ocf_dispatch_async(state, crp); 856b2e60773SJohn Baldwin return (error); 857b2e60773SJohn Baldwin } 858b2e60773SJohn Baldwin 85905a1d0f5SJohn Baldwin static int 86005a1d0f5SJohn Baldwin ktls_ocf_tls13_aead_decrypt(struct ktls_session *tls, 86105a1d0f5SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 86205a1d0f5SJohn Baldwin int *trailer_len) 86305a1d0f5SJohn Baldwin { 86405a1d0f5SJohn Baldwin struct tls_aead_data_13 ad; 86505a1d0f5SJohn Baldwin struct cryptop crp; 86605a1d0f5SJohn Baldwin struct ktls_ocf_session *os; 86705a1d0f5SJohn Baldwin int error; 86805a1d0f5SJohn Baldwin u_int tag_len; 8694e474146SJohn Baldwin uint16_t tls_len; 87005a1d0f5SJohn Baldwin 87105a1d0f5SJohn Baldwin os = tls->ocf_session; 87205a1d0f5SJohn Baldwin 87305a1d0f5SJohn Baldwin tag_len = tls->params.tls_tlen - 1; 87405a1d0f5SJohn Baldwin 87505a1d0f5SJohn Baldwin /* Payload must contain at least one byte for the record type. */ 8764e474146SJohn Baldwin tls_len = ntohs(hdr->tls_length); 8774e474146SJohn Baldwin if (tls_len < tag_len + 1) 8784e474146SJohn Baldwin return (EMSGSIZE); 87905a1d0f5SJohn Baldwin 88005a1d0f5SJohn Baldwin crypto_initreq(&crp, os->sid); 88105a1d0f5SJohn Baldwin 88205a1d0f5SJohn Baldwin /* Setup the nonce. */ 88305a1d0f5SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 88405a1d0f5SJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 88505a1d0f5SJohn Baldwin 88605a1d0f5SJohn Baldwin /* Setup the AAD. */ 88705a1d0f5SJohn Baldwin ad.type = hdr->tls_type; 88805a1d0f5SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 88905a1d0f5SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 89005a1d0f5SJohn Baldwin ad.tls_length = hdr->tls_length; 89105a1d0f5SJohn Baldwin crp.crp_aad = &ad; 89205a1d0f5SJohn Baldwin crp.crp_aad_length = sizeof(ad); 89305a1d0f5SJohn Baldwin 89405a1d0f5SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 8954e474146SJohn Baldwin crp.crp_payload_length = tls_len - tag_len; 89605a1d0f5SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 89705a1d0f5SJohn Baldwin 89805a1d0f5SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 89905a1d0f5SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 90005a1d0f5SJohn Baldwin crypto_use_mbuf(&crp, m); 90105a1d0f5SJohn Baldwin 90205a1d0f5SJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 90305a1d0f5SJohn Baldwin counter_u64_add(ocf_tls13_gcm_decrypts, 1); 90405a1d0f5SJohn Baldwin else 90505a1d0f5SJohn Baldwin counter_u64_add(ocf_tls13_chacha20_decrypts, 1); 90605a1d0f5SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 90705a1d0f5SJohn Baldwin 90805a1d0f5SJohn Baldwin crypto_destroyreq(&crp); 90905a1d0f5SJohn Baldwin *trailer_len = tag_len; 91005a1d0f5SJohn Baldwin return (error); 91105a1d0f5SJohn Baldwin } 91205a1d0f5SJohn Baldwin 913a8280123SJohn Baldwin static int 914a8280123SJohn Baldwin ktls_ocf_tls13_aead_recrypt(struct ktls_session *tls, 915a8280123SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, 916a8280123SJohn Baldwin uint64_t seqno) 917a8280123SJohn Baldwin { 918a8280123SJohn Baldwin struct cryptop crp; 919a8280123SJohn Baldwin struct ktls_ocf_session *os; 920a8280123SJohn Baldwin char *buf; 921a8280123SJohn Baldwin u_int payload_len; 922a8280123SJohn Baldwin int error; 9234e474146SJohn Baldwin uint16_t tls_len; 924a8280123SJohn Baldwin 925a8280123SJohn Baldwin os = tls->ocf_session; 926a8280123SJohn Baldwin 9274e474146SJohn Baldwin /* Payload must contain at least one byte for the record type. */ 9284e474146SJohn Baldwin tls_len = ntohs(hdr->tls_length); 9294e474146SJohn Baldwin if (tls_len < AES_GMAC_HASH_LEN + 1) 9304e474146SJohn Baldwin return (EMSGSIZE); 9314e474146SJohn Baldwin 932a8280123SJohn Baldwin crypto_initreq(&crp, os->recrypt_sid); 933a8280123SJohn Baldwin 934a8280123SJohn Baldwin KASSERT(tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16, 935a8280123SJohn Baldwin ("%s: only AES-GCM is supported", __func__)); 936a8280123SJohn Baldwin 937a8280123SJohn Baldwin /* Setup the IV. */ 938a8280123SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 939a8280123SJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 940a8280123SJohn Baldwin be32enc(crp.crp_iv + 12, 2); 941a8280123SJohn Baldwin 9424e474146SJohn Baldwin payload_len = tls_len - AES_GMAC_HASH_LEN; 943a8280123SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT; 944a8280123SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 945a8280123SJohn Baldwin crypto_use_mbuf(&crp, m); 946a8280123SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 947a8280123SJohn Baldwin crp.crp_payload_length = payload_len; 948a8280123SJohn Baldwin 949a8280123SJohn Baldwin buf = malloc(payload_len, M_KTLS_OCF, M_WAITOK); 950a8280123SJohn Baldwin crypto_use_output_buf(&crp, buf, payload_len); 951a8280123SJohn Baldwin 952a8280123SJohn Baldwin counter_u64_add(ocf_tls13_gcm_recrypts, 1); 953a8280123SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 954a8280123SJohn Baldwin 955a8280123SJohn Baldwin crypto_destroyreq(&crp); 956a8280123SJohn Baldwin 957a8280123SJohn Baldwin if (error == 0) 958a8280123SJohn Baldwin ktls_ocf_recrypt_fixup(m, tls->params.tls_hlen, payload_len, 959a8280123SJohn Baldwin buf); 960a8280123SJohn Baldwin 961a8280123SJohn Baldwin free(buf, M_KTLS_OCF); 962a8280123SJohn Baldwin return (error); 963a8280123SJohn Baldwin } 964a8280123SJohn Baldwin 965a4c5d490SJohn Baldwin static const struct ktls_ocf_sw ktls_ocf_tls13_aead_sw = { 966a4c5d490SJohn Baldwin .encrypt = ktls_ocf_tls13_aead_encrypt, 967a8280123SJohn Baldwin .recrypt = ktls_ocf_tls13_aead_recrypt, 968a4c5d490SJohn Baldwin .decrypt = ktls_ocf_tls13_aead_decrypt, 969a4c5d490SJohn Baldwin }; 970a4c5d490SJohn Baldwin 97121e3c1fbSJohn Baldwin void 972b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 973b2e60773SJohn Baldwin { 974b33ff941SJohn Baldwin struct ktls_ocf_session *os; 975b2e60773SJohn Baldwin 976b33ff941SJohn Baldwin os = tls->ocf_session; 977c0341432SJohn Baldwin crypto_freesession(os->sid); 9784b337adaSJohn Baldwin crypto_freesession(os->mac_sid); 979a8280123SJohn Baldwin crypto_freesession(os->recrypt_sid); 980b2e60773SJohn Baldwin mtx_destroy(&os->lock); 9814a711b8dSJohn Baldwin zfree(os, M_KTLS_OCF); 982b2e60773SJohn Baldwin } 983b2e60773SJohn Baldwin 98421e3c1fbSJohn Baldwin int 985*5dfca6c3SMark Johnston ktls_ocf_try(struct ktls_session *tls, int direction) 986b2e60773SJohn Baldwin { 987a8280123SJohn Baldwin struct crypto_session_params csp, mac_csp, recrypt_csp; 988b33ff941SJohn Baldwin struct ktls_ocf_session *os; 98947e2650eSJohn Baldwin int error, mac_len; 990b2e60773SJohn Baldwin 991c0341432SJohn Baldwin memset(&csp, 0, sizeof(csp)); 99247e2650eSJohn Baldwin memset(&mac_csp, 0, sizeof(mac_csp)); 99347e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_NONE; 99447e2650eSJohn Baldwin mac_len = 0; 995a8280123SJohn Baldwin memset(&recrypt_csp, 0, sizeof(mac_csp)); 996a8280123SJohn Baldwin recrypt_csp.csp_mode = CSP_MODE_NONE; 997b2e60773SJohn Baldwin 998b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 999b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 1000b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 1001b2e60773SJohn Baldwin case 128 / 8: 1002b2e60773SJohn Baldwin case 256 / 8: 1003b2e60773SJohn Baldwin break; 1004b2e60773SJohn Baldwin default: 1005b2e60773SJohn Baldwin return (EINVAL); 1006b2e60773SJohn Baldwin } 1007b2e60773SJohn Baldwin 100855b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 1009b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 101055b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 101155b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 1012b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 1013b2e60773SJohn Baldwin 101447e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 101547e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 101647e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16; 101747e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 101847e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 101947e2650eSJohn Baldwin csp.csp_ivlen = AES_GCM_IV_LEN; 1020a8280123SJohn Baldwin 1021a8280123SJohn Baldwin recrypt_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 1022a8280123SJohn Baldwin recrypt_csp.csp_mode = CSP_MODE_CIPHER; 1023a8280123SJohn Baldwin recrypt_csp.csp_cipher_alg = CRYPTO_AES_ICM; 1024a8280123SJohn Baldwin recrypt_csp.csp_cipher_key = tls->params.cipher_key; 1025a8280123SJohn Baldwin recrypt_csp.csp_cipher_klen = tls->params.cipher_key_len; 1026a8280123SJohn Baldwin recrypt_csp.csp_ivlen = AES_BLOCK_LEN; 102747e2650eSJohn Baldwin break; 102847e2650eSJohn Baldwin case CRYPTO_AES_CBC: 102947e2650eSJohn Baldwin switch (tls->params.cipher_key_len) { 103047e2650eSJohn Baldwin case 128 / 8: 103147e2650eSJohn Baldwin case 256 / 8: 103247e2650eSJohn Baldwin break; 103347e2650eSJohn Baldwin default: 103447e2650eSJohn Baldwin return (EINVAL); 103547e2650eSJohn Baldwin } 103647e2650eSJohn Baldwin 103747e2650eSJohn Baldwin switch (tls->params.auth_algorithm) { 103847e2650eSJohn Baldwin case CRYPTO_SHA1_HMAC: 103947e2650eSJohn Baldwin mac_len = SHA1_HASH_LEN; 104047e2650eSJohn Baldwin break; 104147e2650eSJohn Baldwin case CRYPTO_SHA2_256_HMAC: 104247e2650eSJohn Baldwin mac_len = SHA2_256_HASH_LEN; 104347e2650eSJohn Baldwin break; 104447e2650eSJohn Baldwin case CRYPTO_SHA2_384_HMAC: 104547e2650eSJohn Baldwin mac_len = SHA2_384_HASH_LEN; 104647e2650eSJohn Baldwin break; 104747e2650eSJohn Baldwin default: 104847e2650eSJohn Baldwin return (EINVAL); 104947e2650eSJohn Baldwin } 105047e2650eSJohn Baldwin 105147e2650eSJohn Baldwin /* Only TLS 1.0-1.2 are supported. */ 105247e2650eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 105347e2650eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_ZERO || 105447e2650eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_TWO) 105547e2650eSJohn Baldwin return (EPROTONOSUPPORT); 105647e2650eSJohn Baldwin 10579a673b71SJohn Baldwin /* AES-CBC is not supported for receive for TLS 1.0. */ 10589a673b71SJohn Baldwin if (direction == KTLS_RX && 10599a673b71SJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_ZERO) 106047e2650eSJohn Baldwin return (EPROTONOSUPPORT); 106147e2650eSJohn Baldwin 106247e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 106347e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_CIPHER; 106447e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_CBC; 106547e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 106647e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 106747e2650eSJohn Baldwin csp.csp_ivlen = AES_BLOCK_LEN; 106847e2650eSJohn Baldwin 106947e2650eSJohn Baldwin mac_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 107047e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_DIGEST; 107147e2650eSJohn Baldwin mac_csp.csp_auth_alg = tls->params.auth_algorithm; 107247e2650eSJohn Baldwin mac_csp.csp_auth_key = tls->params.auth_key; 107347e2650eSJohn Baldwin mac_csp.csp_auth_klen = tls->params.auth_key_len; 107447e2650eSJohn Baldwin break; 10754dd6800eSJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 10764dd6800eSJohn Baldwin switch (tls->params.cipher_key_len) { 10774dd6800eSJohn Baldwin case 256 / 8: 10784dd6800eSJohn Baldwin break; 10794dd6800eSJohn Baldwin default: 10804dd6800eSJohn Baldwin return (EINVAL); 10814dd6800eSJohn Baldwin } 10824dd6800eSJohn Baldwin 10834dd6800eSJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 10844dd6800eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 10854dd6800eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 10864dd6800eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 10874dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 10884dd6800eSJohn Baldwin 10894dd6800eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 10904dd6800eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 10914dd6800eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305; 10924dd6800eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 10934dd6800eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 10944dd6800eSJohn Baldwin csp.csp_ivlen = CHACHA20_POLY1305_IV_LEN; 10954dd6800eSJohn Baldwin break; 109647e2650eSJohn Baldwin default: 109747e2650eSJohn Baldwin return (EPROTONOSUPPORT); 109847e2650eSJohn Baldwin } 109947e2650eSJohn Baldwin 1100b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 1101b2e60773SJohn Baldwin if (os == NULL) 1102b2e60773SJohn Baldwin return (ENOMEM); 1103b2e60773SJohn Baldwin 1104c0341432SJohn Baldwin error = crypto_newsession(&os->sid, &csp, 1105b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 1106b2e60773SJohn Baldwin if (error) { 1107b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 1108b2e60773SJohn Baldwin return (error); 1109b2e60773SJohn Baldwin } 1110b2e60773SJohn Baldwin 111147e2650eSJohn Baldwin if (mac_csp.csp_mode != CSP_MODE_NONE) { 111247e2650eSJohn Baldwin error = crypto_newsession(&os->mac_sid, &mac_csp, 111347e2650eSJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 111447e2650eSJohn Baldwin if (error) { 111547e2650eSJohn Baldwin crypto_freesession(os->sid); 111647e2650eSJohn Baldwin free(os, M_KTLS_OCF); 111747e2650eSJohn Baldwin return (error); 111847e2650eSJohn Baldwin } 111947e2650eSJohn Baldwin os->mac_len = mac_len; 112047e2650eSJohn Baldwin } 112147e2650eSJohn Baldwin 1122a8280123SJohn Baldwin if (recrypt_csp.csp_mode != CSP_MODE_NONE) { 1123a8280123SJohn Baldwin error = crypto_newsession(&os->recrypt_sid, &recrypt_csp, 1124a8280123SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 1125a8280123SJohn Baldwin if (error) { 1126a8280123SJohn Baldwin crypto_freesession(os->sid); 1127a8280123SJohn Baldwin free(os, M_KTLS_OCF); 1128a8280123SJohn Baldwin return (error); 1129a8280123SJohn Baldwin } 1130a8280123SJohn Baldwin } 1131a8280123SJohn Baldwin 1132b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 1133b33ff941SJohn Baldwin tls->ocf_session = os; 11344dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16 || 11354dd6800eSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_CHACHA20_POLY1305) { 113655b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 1137a4c5d490SJohn Baldwin os->sw = &ktls_ocf_tls13_aead_sw; 113855b7a0e1SJohn Baldwin else 1139a4c5d490SJohn Baldwin os->sw = &ktls_ocf_tls12_aead_sw; 11403c0e5685SJohn Baldwin } else { 1141a4c5d490SJohn Baldwin os->sw = &ktls_ocf_tls_cbc_sw; 114247e2650eSJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_ZERO) { 114347e2650eSJohn Baldwin os->implicit_iv = true; 114447e2650eSJohn Baldwin memcpy(os->iv, tls->params.iv, AES_BLOCK_LEN); 11454827bf76SJohn Baldwin #ifdef INVARIANTS 11464827bf76SJohn Baldwin os->next_seqno = tls->next_seqno; 11474827bf76SJohn Baldwin #endif 114847e2650eSJohn Baldwin } 114947e2650eSJohn Baldwin } 1150470e851cSJohn Baldwin 1151470e851cSJohn Baldwin /* 1152470e851cSJohn Baldwin * AES-CBC is always synchronous currently. Asynchronous 1153470e851cSJohn Baldwin * operation would require multiple callbacks and an additional 1154470e851cSJohn Baldwin * iovec array in ktls_ocf_encrypt_state. 1155470e851cSJohn Baldwin */ 1156470e851cSJohn Baldwin tls->sync_dispatch = CRYPTO_SESS_SYNC(os->sid) || 1157470e851cSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_AES_CBC; 1158b2e60773SJohn Baldwin return (0); 1159b2e60773SJohn Baldwin } 1160a4c5d490SJohn Baldwin 1161a4c5d490SJohn Baldwin int 1162a4c5d490SJohn Baldwin ktls_ocf_encrypt(struct ktls_ocf_encrypt_state *state, 1163a4c5d490SJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 1164a4c5d490SJohn Baldwin int outiovcnt) 1165a4c5d490SJohn Baldwin { 1166a4c5d490SJohn Baldwin return (tls->ocf_session->sw->encrypt(state, tls, m, outiov, 1167a4c5d490SJohn Baldwin outiovcnt)); 1168a4c5d490SJohn Baldwin } 1169a4c5d490SJohn Baldwin 1170a4c5d490SJohn Baldwin int 1171a4c5d490SJohn Baldwin ktls_ocf_decrypt(struct ktls_session *tls, const struct tls_record_layer *hdr, 1172a4c5d490SJohn Baldwin struct mbuf *m, uint64_t seqno, int *trailer_len) 1173a4c5d490SJohn Baldwin { 1174a4c5d490SJohn Baldwin return (tls->ocf_session->sw->decrypt(tls, hdr, m, seqno, trailer_len)); 1175a4c5d490SJohn Baldwin } 1176a8280123SJohn Baldwin 1177a8280123SJohn Baldwin int 1178a8280123SJohn Baldwin ktls_ocf_recrypt(struct ktls_session *tls, const struct tls_record_layer *hdr, 1179a8280123SJohn Baldwin struct mbuf *m, uint64_t seqno) 1180a8280123SJohn Baldwin { 1181a8280123SJohn Baldwin return (tls->ocf_session->sw->recrypt(tls, hdr, m, seqno)); 1182a8280123SJohn Baldwin } 1183a8280123SJohn Baldwin 1184a8280123SJohn Baldwin bool 1185a8280123SJohn Baldwin ktls_ocf_recrypt_supported(struct ktls_session *tls) 1186a8280123SJohn Baldwin { 1187a8280123SJohn Baldwin return (tls->ocf_session->sw->recrypt != NULL && 1188a8280123SJohn Baldwin tls->ocf_session->recrypt_sid != NULL); 1189a8280123SJohn Baldwin } 1190