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 50b33ff941SJohn Baldwin struct ktls_ocf_session { 51b2e60773SJohn Baldwin crypto_session_t sid; 5247e2650eSJohn Baldwin crypto_session_t mac_sid; 53b2e60773SJohn Baldwin struct mtx lock; 5421e3c1fbSJohn Baldwin int mac_len; 5547e2650eSJohn Baldwin bool implicit_iv; 5647e2650eSJohn Baldwin 5747e2650eSJohn Baldwin /* Only used for TLS 1.0 with the implicit IV. */ 5847e2650eSJohn Baldwin #ifdef INVARIANTS 5947e2650eSJohn Baldwin bool in_progress; 6047e2650eSJohn Baldwin uint64_t next_seqno; 6147e2650eSJohn Baldwin #endif 6247e2650eSJohn Baldwin char iv[AES_BLOCK_LEN]; 63b2e60773SJohn Baldwin }; 64b2e60773SJohn Baldwin 65b2e60773SJohn Baldwin struct ocf_operation { 66b33ff941SJohn Baldwin struct ktls_ocf_session *os; 67b2e60773SJohn Baldwin bool done; 68b2e60773SJohn Baldwin }; 69b2e60773SJohn Baldwin 70b2e60773SJohn Baldwin static MALLOC_DEFINE(M_KTLS_OCF, "ktls_ocf", "OCF KTLS"); 71b2e60773SJohn Baldwin 72b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls); 73b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls_stats); 74b2e60773SJohn Baldwin 757029da5cSPawel Biernacki static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf, 767029da5cSPawel Biernacki CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 7755b7a0e1SJohn Baldwin "Kernel TLS offload via OCF stats"); 7855b7a0e1SJohn Baldwin 79*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls10_cbc_encrypts); 80*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls10_cbc_encrypts, 81*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls10_cbc_encrypts, 8247e2650eSJohn Baldwin "Total number of OCF TLS 1.0 CBC encryption operations"); 8347e2650eSJohn Baldwin 84*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_encrypts); 85*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_encrypts, 86*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls11_cbc_encrypts, 8747e2650eSJohn Baldwin "Total number of OCF TLS 1.1/1.2 CBC encryption operations"); 8847e2650eSJohn Baldwin 89*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_decrypts); 90*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_decrypts, 91*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_decrypts, 92*16bea05aSJohn Baldwin "Total number of OCF TLS 1.2 GCM decryption operations"); 93*16bea05aSJohn Baldwin 94*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_encrypts); 95*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_encrypts, 96*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_encrypts, 9755b7a0e1SJohn Baldwin "Total number of OCF TLS 1.2 GCM encryption operations"); 9855b7a0e1SJohn Baldwin 99*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_decrypts); 100*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_decrypts, 101*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_decrypts, 102*16bea05aSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 decryption operations"); 103*16bea05aSJohn Baldwin 104*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_encrypts); 105*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_encrypts, 106*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_encrypts, 1074dd6800eSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 encryption operations"); 1084dd6800eSJohn Baldwin 109*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_encrypts); 110*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_encrypts, 111*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_encrypts, 11255b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 113b2e60773SJohn Baldwin 114*16bea05aSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_encrypts); 115*16bea05aSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_encrypts, 116*16bea05aSJohn Baldwin CTLFLAG_RD, &ocf_tls13_chacha20_encrypts, 1174dd6800eSJohn Baldwin "Total number of OCF TLS 1.3 Chacha20-Poly1305 encryption operations"); 1184dd6800eSJohn Baldwin 1191755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_inplace); 120080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace, 121080933c0SJohn Baldwin CTLFLAG_RD, &ocf_inplace, 122080933c0SJohn Baldwin "Total number of OCF in-place operations"); 123080933c0SJohn Baldwin 1241755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_separate_output); 125080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output, 126080933c0SJohn Baldwin CTLFLAG_RD, &ocf_separate_output, 127080933c0SJohn Baldwin "Total number of OCF operations with a separate output buffer"); 128080933c0SJohn Baldwin 1291755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_retries); 13055b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 131b2e60773SJohn Baldwin &ocf_retries, 132b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 133b2e60773SJohn Baldwin 134b2e60773SJohn Baldwin static int 135db6b5644SMark Johnston ktls_ocf_callback_sync(struct cryptop *crp __unused) 136db6b5644SMark Johnston { 137db6b5644SMark Johnston return (0); 138db6b5644SMark Johnston } 139db6b5644SMark Johnston 140db6b5644SMark Johnston static int 141db6b5644SMark Johnston ktls_ocf_callback_async(struct cryptop *crp) 142b2e60773SJohn Baldwin { 143b2e60773SJohn Baldwin struct ocf_operation *oo; 144b2e60773SJohn Baldwin 145b2e60773SJohn Baldwin oo = crp->crp_opaque; 146b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 147b2e60773SJohn Baldwin oo->done = true; 148b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 149b2e60773SJohn Baldwin wakeup(oo); 150b2e60773SJohn Baldwin return (0); 151b2e60773SJohn Baldwin } 152b2e60773SJohn Baldwin 153b2e60773SJohn Baldwin static int 154b33ff941SJohn Baldwin ktls_ocf_dispatch(struct ktls_ocf_session *os, struct cryptop *crp) 15570d1a435SJohn Baldwin { 15670d1a435SJohn Baldwin struct ocf_operation oo; 15770d1a435SJohn Baldwin int error; 158db6b5644SMark Johnston bool async; 15970d1a435SJohn Baldwin 16070d1a435SJohn Baldwin oo.os = os; 16170d1a435SJohn Baldwin oo.done = false; 16270d1a435SJohn Baldwin 16370d1a435SJohn Baldwin crp->crp_opaque = &oo; 16470d1a435SJohn Baldwin for (;;) { 165db6b5644SMark Johnston async = !CRYPTO_SESS_SYNC(crp->crp_session); 166db6b5644SMark Johnston crp->crp_callback = async ? ktls_ocf_callback_async : 167db6b5644SMark Johnston ktls_ocf_callback_sync; 168db6b5644SMark Johnston 16970d1a435SJohn Baldwin error = crypto_dispatch(crp); 17070d1a435SJohn Baldwin if (error) 17170d1a435SJohn Baldwin break; 172db6b5644SMark Johnston if (async) { 17370d1a435SJohn Baldwin mtx_lock(&os->lock); 17470d1a435SJohn Baldwin while (!oo.done) 17570d1a435SJohn Baldwin mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0); 17670d1a435SJohn Baldwin mtx_unlock(&os->lock); 177db6b5644SMark Johnston } 17870d1a435SJohn Baldwin 17970d1a435SJohn Baldwin if (crp->crp_etype != EAGAIN) { 18070d1a435SJohn Baldwin error = crp->crp_etype; 18170d1a435SJohn Baldwin break; 18270d1a435SJohn Baldwin } 18370d1a435SJohn Baldwin 18470d1a435SJohn Baldwin crp->crp_etype = 0; 18570d1a435SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 18670d1a435SJohn Baldwin oo.done = false; 18770d1a435SJohn Baldwin counter_u64_add(ocf_retries, 1); 18870d1a435SJohn Baldwin } 18970d1a435SJohn Baldwin return (error); 19070d1a435SJohn Baldwin } 19170d1a435SJohn Baldwin 19270d1a435SJohn Baldwin static int 193470e851cSJohn Baldwin ktls_ocf_dispatch_async_cb(struct cryptop *crp) 194470e851cSJohn Baldwin { 195470e851cSJohn Baldwin struct ktls_ocf_encrypt_state *state; 196470e851cSJohn Baldwin int error; 197470e851cSJohn Baldwin 198470e851cSJohn Baldwin state = crp->crp_opaque; 199470e851cSJohn Baldwin if (crp->crp_etype == EAGAIN) { 200470e851cSJohn Baldwin crp->crp_etype = 0; 201470e851cSJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 202470e851cSJohn Baldwin counter_u64_add(ocf_retries, 1); 203470e851cSJohn Baldwin error = crypto_dispatch(crp); 204470e851cSJohn Baldwin if (error != 0) { 205470e851cSJohn Baldwin crypto_destroyreq(crp); 206470e851cSJohn Baldwin ktls_encrypt_cb(state, error); 207470e851cSJohn Baldwin } 208470e851cSJohn Baldwin return (0); 209470e851cSJohn Baldwin } 210470e851cSJohn Baldwin 211470e851cSJohn Baldwin error = crp->crp_etype; 212470e851cSJohn Baldwin crypto_destroyreq(crp); 213470e851cSJohn Baldwin ktls_encrypt_cb(state, error); 214470e851cSJohn Baldwin return (0); 215470e851cSJohn Baldwin } 216470e851cSJohn Baldwin 217470e851cSJohn Baldwin static int 218470e851cSJohn Baldwin ktls_ocf_dispatch_async(struct ktls_ocf_encrypt_state *state, 219470e851cSJohn Baldwin struct cryptop *crp) 220470e851cSJohn Baldwin { 221470e851cSJohn Baldwin int error; 222470e851cSJohn Baldwin 223470e851cSJohn Baldwin crp->crp_opaque = state; 224470e851cSJohn Baldwin crp->crp_callback = ktls_ocf_dispatch_async_cb; 225470e851cSJohn Baldwin error = crypto_dispatch(crp); 226470e851cSJohn Baldwin if (error != 0) 227470e851cSJohn Baldwin crypto_destroyreq(crp); 228470e851cSJohn Baldwin return (error); 229470e851cSJohn Baldwin } 230470e851cSJohn Baldwin 231470e851cSJohn Baldwin static int 232470e851cSJohn Baldwin ktls_ocf_tls_cbc_encrypt(struct ktls_ocf_encrypt_state *state, 233470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 234470e851cSJohn Baldwin int outiovcnt) 23547e2650eSJohn Baldwin { 23621e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 237470e851cSJohn Baldwin struct uio *uio; 238470e851cSJohn Baldwin struct tls_mac_data *ad; 239470e851cSJohn Baldwin struct cryptop *crp; 240b33ff941SJohn Baldwin struct ktls_ocf_session *os; 24121e3c1fbSJohn Baldwin struct iovec iov[m->m_epg_npgs + 2]; 24221e3c1fbSJohn Baldwin u_int pgoff; 24347e2650eSJohn Baldwin int i, error; 24447e2650eSJohn Baldwin uint16_t tls_comp_len; 24547e2650eSJohn Baldwin uint8_t pad; 24621e3c1fbSJohn Baldwin 24721e3c1fbSJohn Baldwin MPASS(outiovcnt + 1 <= nitems(iov)); 24847e2650eSJohn Baldwin 249b33ff941SJohn Baldwin os = tls->ocf_session; 25021e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 251470e851cSJohn Baldwin crp = &state->crp; 252470e851cSJohn Baldwin uio = &state->uio; 253470e851cSJohn Baldwin MPASS(tls->sync_dispatch); 25447e2650eSJohn Baldwin 25547e2650eSJohn Baldwin #ifdef INVARIANTS 25647e2650eSJohn Baldwin if (os->implicit_iv) { 25747e2650eSJohn Baldwin mtx_lock(&os->lock); 25847e2650eSJohn Baldwin KASSERT(!os->in_progress, 25947e2650eSJohn Baldwin ("concurrent implicit IV encryptions")); 26021e3c1fbSJohn Baldwin if (os->next_seqno != m->m_epg_seqno) { 26147e2650eSJohn Baldwin printf("KTLS CBC: TLS records out of order. " 26247e2650eSJohn Baldwin "Expected %ju, got %ju\n", 26321e3c1fbSJohn Baldwin (uintmax_t)os->next_seqno, 26421e3c1fbSJohn Baldwin (uintmax_t)m->m_epg_seqno); 26547e2650eSJohn Baldwin mtx_unlock(&os->lock); 26647e2650eSJohn Baldwin return (EINVAL); 26747e2650eSJohn Baldwin } 26847e2650eSJohn Baldwin os->in_progress = true; 26947e2650eSJohn Baldwin mtx_unlock(&os->lock); 27047e2650eSJohn Baldwin } 27147e2650eSJohn Baldwin #endif 27247e2650eSJohn Baldwin 27321e3c1fbSJohn Baldwin /* Payload length. */ 27421e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 27547e2650eSJohn Baldwin 27647e2650eSJohn Baldwin /* Initialize the AAD. */ 277470e851cSJohn Baldwin ad = &state->mac; 278470e851cSJohn Baldwin ad->seq = htobe64(m->m_epg_seqno); 279470e851cSJohn Baldwin ad->type = hdr->tls_type; 280470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 281470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 282470e851cSJohn Baldwin ad->tls_length = htons(tls_comp_len); 28347e2650eSJohn Baldwin 28447e2650eSJohn Baldwin /* First, compute the MAC. */ 285470e851cSJohn Baldwin iov[0].iov_base = ad; 286470e851cSJohn Baldwin iov[0].iov_len = sizeof(*ad); 28721e3c1fbSJohn Baldwin pgoff = m->m_epg_1st_off; 28821e3c1fbSJohn Baldwin for (i = 0; i < m->m_epg_npgs; i++, pgoff = 0) { 28921e3c1fbSJohn Baldwin iov[i + 1].iov_base = (void *)PHYS_TO_DMAP(m->m_epg_pa[i] + 29021e3c1fbSJohn Baldwin pgoff); 29121e3c1fbSJohn Baldwin iov[i + 1].iov_len = m_epg_pagelen(m, i, pgoff); 29221e3c1fbSJohn Baldwin } 29321e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_base = m->m_epg_trail; 29421e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_len = os->mac_len; 295470e851cSJohn Baldwin uio->uio_iov = iov; 296470e851cSJohn Baldwin uio->uio_iovcnt = m->m_epg_npgs + 2; 297470e851cSJohn Baldwin uio->uio_offset = 0; 298470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 299470e851cSJohn Baldwin uio->uio_td = curthread; 300470e851cSJohn Baldwin uio->uio_resid = sizeof(*ad) + tls_comp_len + os->mac_len; 30147e2650eSJohn Baldwin 302470e851cSJohn Baldwin crypto_initreq(crp, os->mac_sid); 303470e851cSJohn Baldwin crp->crp_payload_start = 0; 304470e851cSJohn Baldwin crp->crp_payload_length = sizeof(*ad) + tls_comp_len; 305470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 306470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST; 307470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM; 308470e851cSJohn Baldwin crypto_use_uio(crp, uio); 309470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 31047e2650eSJohn Baldwin 311470e851cSJohn Baldwin crypto_destroyreq(crp); 31247e2650eSJohn Baldwin if (error) { 31347e2650eSJohn Baldwin #ifdef INVARIANTS 31447e2650eSJohn Baldwin if (os->implicit_iv) { 31547e2650eSJohn Baldwin mtx_lock(&os->lock); 31647e2650eSJohn Baldwin os->in_progress = false; 31747e2650eSJohn Baldwin mtx_unlock(&os->lock); 31847e2650eSJohn Baldwin } 31947e2650eSJohn Baldwin #endif 32047e2650eSJohn Baldwin return (error); 32147e2650eSJohn Baldwin } 32247e2650eSJohn Baldwin 32347e2650eSJohn Baldwin /* Second, add the padding. */ 32421e3c1fbSJohn Baldwin pad = m->m_epg_trllen - os->mac_len - 1; 32547e2650eSJohn Baldwin for (i = 0; i < pad + 1; i++) 32621e3c1fbSJohn Baldwin m->m_epg_trail[os->mac_len + i] = pad; 32747e2650eSJohn Baldwin 32847e2650eSJohn Baldwin /* Finally, encrypt the record. */ 329470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 330470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 331470e851cSJohn Baldwin crp->crp_payload_length = tls_comp_len + m->m_epg_trllen; 332470e851cSJohn Baldwin KASSERT(crp->crp_payload_length % AES_BLOCK_LEN == 0, 33321e3c1fbSJohn Baldwin ("invalid encryption size")); 334470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 335470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT; 336470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 33747e2650eSJohn Baldwin if (os->implicit_iv) 338470e851cSJohn Baldwin memcpy(crp->crp_iv, os->iv, AES_BLOCK_LEN); 33947e2650eSJohn Baldwin else 340470e851cSJohn Baldwin memcpy(crp->crp_iv, hdr + 1, AES_BLOCK_LEN); 34121e3c1fbSJohn Baldwin 34221e3c1fbSJohn Baldwin if (outiov != NULL) { 343470e851cSJohn Baldwin uio->uio_iov = outiov; 344470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 345470e851cSJohn Baldwin uio->uio_offset = 0; 346470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 347470e851cSJohn Baldwin uio->uio_td = curthread; 348470e851cSJohn Baldwin uio->uio_resid = crp->crp_payload_length; 349470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 35047e2650eSJohn Baldwin } 35147e2650eSJohn Baldwin 35247e2650eSJohn Baldwin if (os->implicit_iv) 353*16bea05aSJohn Baldwin counter_u64_add(ocf_tls10_cbc_encrypts, 1); 35447e2650eSJohn Baldwin else 355*16bea05aSJohn Baldwin counter_u64_add(ocf_tls11_cbc_encrypts, 1); 35621e3c1fbSJohn Baldwin if (outiov != NULL) 35747e2650eSJohn Baldwin counter_u64_add(ocf_separate_output, 1); 35821e3c1fbSJohn Baldwin else 35921e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 360470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 36147e2650eSJohn Baldwin 362470e851cSJohn Baldwin crypto_destroyreq(crp); 36347e2650eSJohn Baldwin 36447e2650eSJohn Baldwin if (os->implicit_iv) { 36547e2650eSJohn Baldwin KASSERT(os->mac_len + pad + 1 >= AES_BLOCK_LEN, 36647e2650eSJohn Baldwin ("trailer too short to read IV")); 36721e3c1fbSJohn Baldwin memcpy(os->iv, m->m_epg_trail + m->m_epg_trllen - AES_BLOCK_LEN, 36847e2650eSJohn Baldwin AES_BLOCK_LEN); 36947e2650eSJohn Baldwin #ifdef INVARIANTS 37047e2650eSJohn Baldwin mtx_lock(&os->lock); 37121e3c1fbSJohn Baldwin os->next_seqno = m->m_epg_seqno + 1; 37247e2650eSJohn Baldwin os->in_progress = false; 37347e2650eSJohn Baldwin mtx_unlock(&os->lock); 37447e2650eSJohn Baldwin #endif 37547e2650eSJohn Baldwin } 37647e2650eSJohn Baldwin return (error); 37747e2650eSJohn Baldwin } 37847e2650eSJohn Baldwin 37947e2650eSJohn Baldwin static int 380470e851cSJohn Baldwin ktls_ocf_tls12_aead_encrypt(struct ktls_ocf_encrypt_state *state, 381470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 382470e851cSJohn Baldwin int outiovcnt) 383b2e60773SJohn Baldwin { 38421e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 385470e851cSJohn Baldwin struct uio *uio; 386470e851cSJohn Baldwin struct tls_aead_data *ad; 387470e851cSJohn Baldwin struct cryptop *crp; 388b33ff941SJohn Baldwin struct ktls_ocf_session *os; 38921e3c1fbSJohn Baldwin int error; 390b2e60773SJohn Baldwin uint16_t tls_comp_len; 391b2e60773SJohn Baldwin 392b33ff941SJohn Baldwin os = tls->ocf_session; 39321e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 394470e851cSJohn Baldwin crp = &state->crp; 395470e851cSJohn Baldwin uio = &state->uio; 396b2e60773SJohn Baldwin 397470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 398b2e60773SJohn Baldwin 399b2e60773SJohn Baldwin /* Setup the IV. */ 4004dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 401470e851cSJohn Baldwin memcpy(crp->crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 402470e851cSJohn Baldwin memcpy(crp->crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 4034dd6800eSJohn Baldwin sizeof(uint64_t)); 4044dd6800eSJohn Baldwin } else { 4054dd6800eSJohn Baldwin /* 4064dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 4074dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 4084dd6800eSJohn Baldwin * 1.3. 4094dd6800eSJohn Baldwin */ 410470e851cSJohn Baldwin memcpy(crp->crp_iv, tls->params.iv, tls->params.iv_len); 411470e851cSJohn Baldwin *(uint64_t *)(crp->crp_iv + 4) ^= htobe64(m->m_epg_seqno); 4124dd6800eSJohn Baldwin } 413b2e60773SJohn Baldwin 414b2e60773SJohn Baldwin /* Setup the AAD. */ 415470e851cSJohn Baldwin ad = &state->aead; 41621e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 417470e851cSJohn Baldwin ad->seq = htobe64(m->m_epg_seqno); 418470e851cSJohn Baldwin ad->type = hdr->tls_type; 419470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 420470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 421470e851cSJohn Baldwin ad->tls_length = htons(tls_comp_len); 422470e851cSJohn Baldwin crp->crp_aad = ad; 423470e851cSJohn Baldwin crp->crp_aad_length = sizeof(*ad); 424b2e60773SJohn Baldwin 42521e3c1fbSJohn Baldwin /* Set fields for input payload. */ 426470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 427470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 428470e851cSJohn Baldwin crp->crp_payload_length = tls_comp_len; 429b2e60773SJohn Baldwin 43021e3c1fbSJohn Baldwin if (outiov != NULL) { 431470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 43221e3c1fbSJohn Baldwin 433470e851cSJohn Baldwin uio->uio_iov = outiov; 434470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 435470e851cSJohn Baldwin uio->uio_offset = 0; 436470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 437470e851cSJohn Baldwin uio->uio_td = curthread; 438470e851cSJohn Baldwin uio->uio_resid = crp->crp_payload_length + tls->params.tls_tlen; 439470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 44021e3c1fbSJohn Baldwin } else 441470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_start + 442470e851cSJohn Baldwin crp->crp_payload_length; 443b2e60773SJohn Baldwin 444470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 445470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 4464dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 447*16bea05aSJohn Baldwin counter_u64_add(ocf_tls12_gcm_encrypts, 1); 4484dd6800eSJohn Baldwin else 449*16bea05aSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_encrypts, 1); 45021e3c1fbSJohn Baldwin if (outiov != NULL) 451080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 45221e3c1fbSJohn Baldwin else 45321e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 454470e851cSJohn Baldwin if (tls->sync_dispatch) { 455470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 456470e851cSJohn Baldwin crypto_destroyreq(crp); 457470e851cSJohn Baldwin } else 458470e851cSJohn Baldwin error = ktls_ocf_dispatch_async(state, crp); 45955b7a0e1SJohn Baldwin return (error); 46055b7a0e1SJohn Baldwin } 46155b7a0e1SJohn Baldwin 46255b7a0e1SJohn Baldwin static int 4634dd6800eSJohn Baldwin ktls_ocf_tls12_aead_decrypt(struct ktls_session *tls, 4643c0e5685SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 4653c0e5685SJohn Baldwin int *trailer_len) 4663c0e5685SJohn Baldwin { 4673c0e5685SJohn Baldwin struct tls_aead_data ad; 4683c0e5685SJohn Baldwin struct cryptop crp; 469b33ff941SJohn Baldwin struct ktls_ocf_session *os; 4703c0e5685SJohn Baldwin int error; 4713c0e5685SJohn Baldwin uint16_t tls_comp_len; 4723c0e5685SJohn Baldwin 473b33ff941SJohn Baldwin os = tls->ocf_session; 4743c0e5685SJohn Baldwin 4753c0e5685SJohn Baldwin crypto_initreq(&crp, os->sid); 4763c0e5685SJohn Baldwin 4773c0e5685SJohn Baldwin /* Setup the IV. */ 4784dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 4793c0e5685SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 4804dd6800eSJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 4814dd6800eSJohn Baldwin sizeof(uint64_t)); 4824dd6800eSJohn Baldwin } else { 4834dd6800eSJohn Baldwin /* 4844dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 4854dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 4864dd6800eSJohn Baldwin * 1.3. 4874dd6800eSJohn Baldwin */ 4884dd6800eSJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 4894dd6800eSJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 4904dd6800eSJohn Baldwin } 4913c0e5685SJohn Baldwin 4923c0e5685SJohn Baldwin /* Setup the AAD. */ 4934dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 4943c0e5685SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 4953c0e5685SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 4964dd6800eSJohn Baldwin else 4974dd6800eSJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - POLY1305_HASH_LEN; 4983c0e5685SJohn Baldwin ad.seq = htobe64(seqno); 4993c0e5685SJohn Baldwin ad.type = hdr->tls_type; 5003c0e5685SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 5013c0e5685SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 5023c0e5685SJohn Baldwin ad.tls_length = htons(tls_comp_len); 5033c0e5685SJohn Baldwin crp.crp_aad = &ad; 5043c0e5685SJohn Baldwin crp.crp_aad_length = sizeof(ad); 5053c0e5685SJohn Baldwin 5063c0e5685SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 5073c0e5685SJohn Baldwin crp.crp_payload_length = tls_comp_len; 5083c0e5685SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 5093c0e5685SJohn Baldwin 5103c0e5685SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 5113c0e5685SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 5123c0e5685SJohn Baldwin crypto_use_mbuf(&crp, m); 5133c0e5685SJohn Baldwin 5144dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 515*16bea05aSJohn Baldwin counter_u64_add(ocf_tls12_gcm_decrypts, 1); 5164dd6800eSJohn Baldwin else 517*16bea05aSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_decrypts, 1); 5183c0e5685SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 5193c0e5685SJohn Baldwin 5203c0e5685SJohn Baldwin crypto_destroyreq(&crp); 5214a92afaeSJohn Baldwin *trailer_len = tls->params.tls_tlen; 5223c0e5685SJohn Baldwin return (error); 5233c0e5685SJohn Baldwin } 5243c0e5685SJohn Baldwin 5253c0e5685SJohn Baldwin static int 526470e851cSJohn Baldwin ktls_ocf_tls13_aead_encrypt(struct ktls_ocf_encrypt_state *state, 527470e851cSJohn Baldwin struct ktls_session *tls, struct mbuf *m, struct iovec *outiov, 528470e851cSJohn Baldwin int outiovcnt) 52955b7a0e1SJohn Baldwin { 53021e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 531470e851cSJohn Baldwin struct uio *uio; 532470e851cSJohn Baldwin struct tls_aead_data_13 *ad; 533470e851cSJohn Baldwin struct cryptop *crp; 534b33ff941SJohn Baldwin struct ktls_ocf_session *os; 535470e851cSJohn Baldwin char nonce[12]; 53621e3c1fbSJohn Baldwin int error; 53755b7a0e1SJohn Baldwin 538b33ff941SJohn Baldwin os = tls->ocf_session; 53921e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 540470e851cSJohn Baldwin crp = &state->crp; 541470e851cSJohn Baldwin uio = &state->uio; 54255b7a0e1SJohn Baldwin 543470e851cSJohn Baldwin crypto_initreq(crp, os->sid); 54455b7a0e1SJohn Baldwin 54555b7a0e1SJohn Baldwin /* Setup the nonce. */ 54655b7a0e1SJohn Baldwin memcpy(nonce, tls->params.iv, tls->params.iv_len); 54721e3c1fbSJohn Baldwin *(uint64_t *)(nonce + 4) ^= htobe64(m->m_epg_seqno); 54855b7a0e1SJohn Baldwin 54955b7a0e1SJohn Baldwin /* Setup the AAD. */ 550470e851cSJohn Baldwin ad = &state->aead13; 551470e851cSJohn Baldwin ad->type = hdr->tls_type; 552470e851cSJohn Baldwin ad->tls_vmajor = hdr->tls_vmajor; 553470e851cSJohn Baldwin ad->tls_vminor = hdr->tls_vminor; 554470e851cSJohn Baldwin ad->tls_length = hdr->tls_length; 555470e851cSJohn Baldwin crp->crp_aad = ad; 556470e851cSJohn Baldwin crp->crp_aad_length = sizeof(*ad); 557080933c0SJohn Baldwin 55821e3c1fbSJohn Baldwin /* Set fields for input payload. */ 559470e851cSJohn Baldwin crypto_use_single_mbuf(crp, m); 560470e851cSJohn Baldwin crp->crp_payload_start = m->m_epg_hdrlen; 561470e851cSJohn Baldwin crp->crp_payload_length = m->m_len - 562470e851cSJohn Baldwin (m->m_epg_hdrlen + m->m_epg_trllen); 56355b7a0e1SJohn Baldwin 5645b750b9aSJohn Baldwin /* Store the record type as the first byte of the trailer. */ 56521e3c1fbSJohn Baldwin m->m_epg_trail[0] = m->m_epg_record_type; 566470e851cSJohn Baldwin crp->crp_payload_length++; 56721e3c1fbSJohn Baldwin 56821e3c1fbSJohn Baldwin if (outiov != NULL) { 569470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_length; 5705b750b9aSJohn Baldwin 571470e851cSJohn Baldwin uio->uio_iov = outiov; 572470e851cSJohn Baldwin uio->uio_iovcnt = outiovcnt; 573470e851cSJohn Baldwin uio->uio_offset = 0; 574470e851cSJohn Baldwin uio->uio_segflg = UIO_SYSSPACE; 575470e851cSJohn Baldwin uio->uio_td = curthread; 576470e851cSJohn Baldwin uio->uio_resid = m->m_len - m->m_epg_hdrlen; 577470e851cSJohn Baldwin crypto_use_output_uio(crp, uio); 57821e3c1fbSJohn Baldwin } else 579470e851cSJohn Baldwin crp->crp_digest_start = crp->crp_payload_start + 580470e851cSJohn Baldwin crp->crp_payload_length; 58155b7a0e1SJohn Baldwin 582470e851cSJohn Baldwin crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 583470e851cSJohn Baldwin crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 58455b7a0e1SJohn Baldwin 585470e851cSJohn Baldwin memcpy(crp->crp_iv, nonce, sizeof(nonce)); 58655b7a0e1SJohn Baldwin 5874dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 588*16bea05aSJohn Baldwin counter_u64_add(ocf_tls13_gcm_encrypts, 1); 5894dd6800eSJohn Baldwin else 590*16bea05aSJohn Baldwin counter_u64_add(ocf_tls13_chacha20_encrypts, 1); 59121e3c1fbSJohn Baldwin if (outiov != NULL) 592080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 59321e3c1fbSJohn Baldwin else 59421e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 595470e851cSJohn Baldwin if (tls->sync_dispatch) { 596470e851cSJohn Baldwin error = ktls_ocf_dispatch(os, crp); 597470e851cSJohn Baldwin crypto_destroyreq(crp); 598470e851cSJohn Baldwin } else 599470e851cSJohn Baldwin error = ktls_ocf_dispatch_async(state, crp); 600b2e60773SJohn Baldwin return (error); 601b2e60773SJohn Baldwin } 602b2e60773SJohn Baldwin 60321e3c1fbSJohn Baldwin void 604b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 605b2e60773SJohn Baldwin { 606b33ff941SJohn Baldwin struct ktls_ocf_session *os; 607b2e60773SJohn Baldwin 608b33ff941SJohn Baldwin os = tls->ocf_session; 609c0341432SJohn Baldwin crypto_freesession(os->sid); 610b2e60773SJohn Baldwin mtx_destroy(&os->lock); 6114a711b8dSJohn Baldwin zfree(os, M_KTLS_OCF); 612b2e60773SJohn Baldwin } 613b2e60773SJohn Baldwin 61421e3c1fbSJohn Baldwin int 6153c0e5685SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction) 616b2e60773SJohn Baldwin { 61747e2650eSJohn Baldwin struct crypto_session_params csp, mac_csp; 618b33ff941SJohn Baldwin struct ktls_ocf_session *os; 61947e2650eSJohn Baldwin int error, mac_len; 620b2e60773SJohn Baldwin 621c0341432SJohn Baldwin memset(&csp, 0, sizeof(csp)); 62247e2650eSJohn Baldwin memset(&mac_csp, 0, sizeof(mac_csp)); 62347e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_NONE; 62447e2650eSJohn Baldwin mac_len = 0; 625b2e60773SJohn Baldwin 626b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 627b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 628b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 629b2e60773SJohn Baldwin case 128 / 8: 630b2e60773SJohn Baldwin case 256 / 8: 631b2e60773SJohn Baldwin break; 632b2e60773SJohn Baldwin default: 633b2e60773SJohn Baldwin return (EINVAL); 634b2e60773SJohn Baldwin } 635b2e60773SJohn Baldwin 63655b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 637b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 63855b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 63955b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 640b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 641b2e60773SJohn Baldwin 6423c0e5685SJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 6433c0e5685SJohn Baldwin if (direction == KTLS_RX && 6443c0e5685SJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 6453c0e5685SJohn Baldwin return (EPROTONOSUPPORT); 6463c0e5685SJohn Baldwin 64747e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 64847e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 64947e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16; 65047e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 65147e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 65247e2650eSJohn Baldwin csp.csp_ivlen = AES_GCM_IV_LEN; 65347e2650eSJohn Baldwin break; 65447e2650eSJohn Baldwin case CRYPTO_AES_CBC: 65547e2650eSJohn Baldwin switch (tls->params.cipher_key_len) { 65647e2650eSJohn Baldwin case 128 / 8: 65747e2650eSJohn Baldwin case 256 / 8: 65847e2650eSJohn Baldwin break; 65947e2650eSJohn Baldwin default: 66047e2650eSJohn Baldwin return (EINVAL); 66147e2650eSJohn Baldwin } 66247e2650eSJohn Baldwin 66347e2650eSJohn Baldwin switch (tls->params.auth_algorithm) { 66447e2650eSJohn Baldwin case CRYPTO_SHA1_HMAC: 66547e2650eSJohn Baldwin mac_len = SHA1_HASH_LEN; 66647e2650eSJohn Baldwin break; 66747e2650eSJohn Baldwin case CRYPTO_SHA2_256_HMAC: 66847e2650eSJohn Baldwin mac_len = SHA2_256_HASH_LEN; 66947e2650eSJohn Baldwin break; 67047e2650eSJohn Baldwin case CRYPTO_SHA2_384_HMAC: 67147e2650eSJohn Baldwin mac_len = SHA2_384_HASH_LEN; 67247e2650eSJohn Baldwin break; 67347e2650eSJohn Baldwin default: 67447e2650eSJohn Baldwin return (EINVAL); 67547e2650eSJohn Baldwin } 67647e2650eSJohn Baldwin 67747e2650eSJohn Baldwin /* Only TLS 1.0-1.2 are supported. */ 67847e2650eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 67947e2650eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_ZERO || 68047e2650eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_TWO) 68147e2650eSJohn Baldwin return (EPROTONOSUPPORT); 68247e2650eSJohn Baldwin 68347e2650eSJohn Baldwin /* AES-CBC is not supported for receive. */ 68447e2650eSJohn Baldwin if (direction == KTLS_RX) 68547e2650eSJohn Baldwin return (EPROTONOSUPPORT); 68647e2650eSJohn Baldwin 68747e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 68847e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_CIPHER; 68947e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_CBC; 69047e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 69147e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 69247e2650eSJohn Baldwin csp.csp_ivlen = AES_BLOCK_LEN; 69347e2650eSJohn Baldwin 69447e2650eSJohn Baldwin mac_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 69547e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_DIGEST; 69647e2650eSJohn Baldwin mac_csp.csp_auth_alg = tls->params.auth_algorithm; 69747e2650eSJohn Baldwin mac_csp.csp_auth_key = tls->params.auth_key; 69847e2650eSJohn Baldwin mac_csp.csp_auth_klen = tls->params.auth_key_len; 69947e2650eSJohn Baldwin break; 7004dd6800eSJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 7014dd6800eSJohn Baldwin switch (tls->params.cipher_key_len) { 7024dd6800eSJohn Baldwin case 256 / 8: 7034dd6800eSJohn Baldwin break; 7044dd6800eSJohn Baldwin default: 7054dd6800eSJohn Baldwin return (EINVAL); 7064dd6800eSJohn Baldwin } 7074dd6800eSJohn Baldwin 7084dd6800eSJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 7094dd6800eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 7104dd6800eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 7114dd6800eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 7124dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 7134dd6800eSJohn Baldwin 7144dd6800eSJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 7154dd6800eSJohn Baldwin if (direction == KTLS_RX && 7164dd6800eSJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 7174dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 7184dd6800eSJohn Baldwin 7194dd6800eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 7204dd6800eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 7214dd6800eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305; 7224dd6800eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 7234dd6800eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 7244dd6800eSJohn Baldwin csp.csp_ivlen = CHACHA20_POLY1305_IV_LEN; 7254dd6800eSJohn Baldwin break; 72647e2650eSJohn Baldwin default: 72747e2650eSJohn Baldwin return (EPROTONOSUPPORT); 72847e2650eSJohn Baldwin } 72947e2650eSJohn Baldwin 730b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 731b2e60773SJohn Baldwin if (os == NULL) 732b2e60773SJohn Baldwin return (ENOMEM); 733b2e60773SJohn Baldwin 734c0341432SJohn Baldwin error = crypto_newsession(&os->sid, &csp, 735b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 736b2e60773SJohn Baldwin if (error) { 737b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 738b2e60773SJohn Baldwin return (error); 739b2e60773SJohn Baldwin } 740b2e60773SJohn Baldwin 74147e2650eSJohn Baldwin if (mac_csp.csp_mode != CSP_MODE_NONE) { 74247e2650eSJohn Baldwin error = crypto_newsession(&os->mac_sid, &mac_csp, 74347e2650eSJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 74447e2650eSJohn Baldwin if (error) { 74547e2650eSJohn Baldwin crypto_freesession(os->sid); 74647e2650eSJohn Baldwin free(os, M_KTLS_OCF); 74747e2650eSJohn Baldwin return (error); 74847e2650eSJohn Baldwin } 74947e2650eSJohn Baldwin os->mac_len = mac_len; 75047e2650eSJohn Baldwin } 75147e2650eSJohn Baldwin 752b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 753b33ff941SJohn Baldwin tls->ocf_session = os; 7544dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16 || 7554dd6800eSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_CHACHA20_POLY1305) { 7563c0e5685SJohn Baldwin if (direction == KTLS_TX) { 75755b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 7584dd6800eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls13_aead_encrypt; 75955b7a0e1SJohn Baldwin else 7604dd6800eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls12_aead_encrypt; 7613c0e5685SJohn Baldwin } else { 7624dd6800eSJohn Baldwin tls->sw_decrypt = ktls_ocf_tls12_aead_decrypt; 7633c0e5685SJohn Baldwin } 76447e2650eSJohn Baldwin } else { 76547e2650eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls_cbc_encrypt; 76647e2650eSJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_ZERO) { 76747e2650eSJohn Baldwin os->implicit_iv = true; 76847e2650eSJohn Baldwin memcpy(os->iv, tls->params.iv, AES_BLOCK_LEN); 7694827bf76SJohn Baldwin #ifdef INVARIANTS 7704827bf76SJohn Baldwin os->next_seqno = tls->next_seqno; 7714827bf76SJohn Baldwin #endif 77247e2650eSJohn Baldwin } 77347e2650eSJohn Baldwin } 774470e851cSJohn Baldwin 775470e851cSJohn Baldwin /* 776470e851cSJohn Baldwin * AES-CBC is always synchronous currently. Asynchronous 777470e851cSJohn Baldwin * operation would require multiple callbacks and an additional 778470e851cSJohn Baldwin * iovec array in ktls_ocf_encrypt_state. 779470e851cSJohn Baldwin */ 780470e851cSJohn Baldwin tls->sync_dispatch = CRYPTO_SESS_SYNC(os->sid) || 781470e851cSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_AES_CBC; 782b2e60773SJohn Baldwin return (0); 783b2e60773SJohn Baldwin } 784