1b2e60773SJohn Baldwin /*- 2b2e60773SJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause 3b2e60773SJohn Baldwin * 4b2e60773SJohn Baldwin * Copyright (c) 2019 Netflix Inc. 5b2e60773SJohn Baldwin * All rights reserved. 6b2e60773SJohn Baldwin * 7b2e60773SJohn Baldwin * Redistribution and use in source and binary forms, with or without 8b2e60773SJohn Baldwin * modification, are permitted provided that the following conditions 9b2e60773SJohn Baldwin * are met: 10b2e60773SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 11b2e60773SJohn Baldwin * notice, this list of conditions and the following disclaimer. 12b2e60773SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 13b2e60773SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 14b2e60773SJohn Baldwin * documentation and/or other materials provided with the distribution. 15b2e60773SJohn Baldwin * 16b2e60773SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17b2e60773SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18b2e60773SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19b2e60773SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20b2e60773SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21b2e60773SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22b2e60773SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23b2e60773SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24b2e60773SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25b2e60773SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26b2e60773SJohn Baldwin * SUCH DAMAGE. 27b2e60773SJohn Baldwin */ 28b2e60773SJohn Baldwin 29b2e60773SJohn Baldwin #include <sys/cdefs.h> 30b2e60773SJohn Baldwin __FBSDID("$FreeBSD$"); 31b2e60773SJohn Baldwin 32b2e60773SJohn Baldwin #include <sys/param.h> 33b2e60773SJohn Baldwin #include <sys/systm.h> 34b2e60773SJohn Baldwin #include <sys/counter.h> 35b2e60773SJohn Baldwin #include <sys/endian.h> 36b2e60773SJohn Baldwin #include <sys/kernel.h> 37b2e60773SJohn Baldwin #include <sys/ktls.h> 38b2e60773SJohn Baldwin #include <sys/lock.h> 39b2e60773SJohn Baldwin #include <sys/malloc.h> 40*21e3c1fbSJohn Baldwin #include <sys/mbuf.h> 41b2e60773SJohn Baldwin #include <sys/module.h> 42b2e60773SJohn Baldwin #include <sys/mutex.h> 43b2e60773SJohn Baldwin #include <sys/sysctl.h> 44b2e60773SJohn Baldwin #include <sys/uio.h> 45*21e3c1fbSJohn Baldwin #include <vm/vm.h> 46*21e3c1fbSJohn Baldwin #include <vm/pmap.h> 47*21e3c1fbSJohn Baldwin #include <vm/vm_param.h> 48b2e60773SJohn Baldwin #include <opencrypto/cryptodev.h> 49b2e60773SJohn Baldwin 50b2e60773SJohn Baldwin struct ocf_session { 51b2e60773SJohn Baldwin crypto_session_t sid; 5247e2650eSJohn Baldwin crypto_session_t mac_sid; 53b2e60773SJohn Baldwin struct mtx lock; 54*21e3c1fbSJohn 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 { 66b2e60773SJohn Baldwin struct 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 791755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls10_cbc_crypts); 8047e2650eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls10_cbc_crypts, 8147e2650eSJohn Baldwin CTLFLAG_RD, &ocf_tls10_cbc_crypts, 8247e2650eSJohn Baldwin "Total number of OCF TLS 1.0 CBC encryption operations"); 8347e2650eSJohn Baldwin 841755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_crypts); 8547e2650eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_crypts, 8647e2650eSJohn Baldwin CTLFLAG_RD, &ocf_tls11_cbc_crypts, 8747e2650eSJohn Baldwin "Total number of OCF TLS 1.1/1.2 CBC encryption operations"); 8847e2650eSJohn Baldwin 891755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_crypts); 9055b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_crypts, 9155b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls12_gcm_crypts, 9255b7a0e1SJohn Baldwin "Total number of OCF TLS 1.2 GCM encryption operations"); 9355b7a0e1SJohn Baldwin 944dd6800eSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_crypts); 954dd6800eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_crypts, 964dd6800eSJohn Baldwin CTLFLAG_RD, &ocf_tls12_chacha20_crypts, 974dd6800eSJohn Baldwin "Total number of OCF TLS 1.2 Chacha20-Poly1305 encryption operations"); 984dd6800eSJohn Baldwin 991755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_crypts); 10055b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_crypts, 10155b7a0e1SJohn Baldwin CTLFLAG_RD, &ocf_tls13_gcm_crypts, 10255b7a0e1SJohn Baldwin "Total number of OCF TLS 1.3 GCM encryption operations"); 103b2e60773SJohn Baldwin 1044dd6800eSJohn Baldwin static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_crypts); 1054dd6800eSJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_crypts, 1064dd6800eSJohn Baldwin CTLFLAG_RD, &ocf_tls13_chacha20_crypts, 1074dd6800eSJohn Baldwin "Total number of OCF TLS 1.3 Chacha20-Poly1305 encryption operations"); 1084dd6800eSJohn Baldwin 1091755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_inplace); 110080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace, 111080933c0SJohn Baldwin CTLFLAG_RD, &ocf_inplace, 112080933c0SJohn Baldwin "Total number of OCF in-place operations"); 113080933c0SJohn Baldwin 1141755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_separate_output); 115080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output, 116080933c0SJohn Baldwin CTLFLAG_RD, &ocf_separate_output, 117080933c0SJohn Baldwin "Total number of OCF operations with a separate output buffer"); 118080933c0SJohn Baldwin 1191755b2b9SMark Johnston static COUNTER_U64_DEFINE_EARLY(ocf_retries); 12055b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD, 121b2e60773SJohn Baldwin &ocf_retries, 122b2e60773SJohn Baldwin "Number of OCF encryption operation retries"); 123b2e60773SJohn Baldwin 124b2e60773SJohn Baldwin static int 125db6b5644SMark Johnston ktls_ocf_callback_sync(struct cryptop *crp __unused) 126db6b5644SMark Johnston { 127db6b5644SMark Johnston return (0); 128db6b5644SMark Johnston } 129db6b5644SMark Johnston 130db6b5644SMark Johnston static int 131db6b5644SMark Johnston ktls_ocf_callback_async(struct cryptop *crp) 132b2e60773SJohn Baldwin { 133b2e60773SJohn Baldwin struct ocf_operation *oo; 134b2e60773SJohn Baldwin 135b2e60773SJohn Baldwin oo = crp->crp_opaque; 136b2e60773SJohn Baldwin mtx_lock(&oo->os->lock); 137b2e60773SJohn Baldwin oo->done = true; 138b2e60773SJohn Baldwin mtx_unlock(&oo->os->lock); 139b2e60773SJohn Baldwin wakeup(oo); 140b2e60773SJohn Baldwin return (0); 141b2e60773SJohn Baldwin } 142b2e60773SJohn Baldwin 143b2e60773SJohn Baldwin static int 14470d1a435SJohn Baldwin ktls_ocf_dispatch(struct ocf_session *os, struct cryptop *crp) 14570d1a435SJohn Baldwin { 14670d1a435SJohn Baldwin struct ocf_operation oo; 14770d1a435SJohn Baldwin int error; 148db6b5644SMark Johnston bool async; 14970d1a435SJohn Baldwin 15070d1a435SJohn Baldwin oo.os = os; 15170d1a435SJohn Baldwin oo.done = false; 15270d1a435SJohn Baldwin 15370d1a435SJohn Baldwin crp->crp_opaque = &oo; 15470d1a435SJohn Baldwin for (;;) { 155db6b5644SMark Johnston async = !CRYPTO_SESS_SYNC(crp->crp_session); 156db6b5644SMark Johnston crp->crp_callback = async ? ktls_ocf_callback_async : 157db6b5644SMark Johnston ktls_ocf_callback_sync; 158db6b5644SMark Johnston 15970d1a435SJohn Baldwin error = crypto_dispatch(crp); 16070d1a435SJohn Baldwin if (error) 16170d1a435SJohn Baldwin break; 162db6b5644SMark Johnston if (async) { 16370d1a435SJohn Baldwin mtx_lock(&os->lock); 16470d1a435SJohn Baldwin while (!oo.done) 16570d1a435SJohn Baldwin mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0); 16670d1a435SJohn Baldwin mtx_unlock(&os->lock); 167db6b5644SMark Johnston } 16870d1a435SJohn Baldwin 16970d1a435SJohn Baldwin if (crp->crp_etype != EAGAIN) { 17070d1a435SJohn Baldwin error = crp->crp_etype; 17170d1a435SJohn Baldwin break; 17270d1a435SJohn Baldwin } 17370d1a435SJohn Baldwin 17470d1a435SJohn Baldwin crp->crp_etype = 0; 17570d1a435SJohn Baldwin crp->crp_flags &= ~CRYPTO_F_DONE; 17670d1a435SJohn Baldwin oo.done = false; 17770d1a435SJohn Baldwin counter_u64_add(ocf_retries, 1); 17870d1a435SJohn Baldwin } 17970d1a435SJohn Baldwin return (error); 18070d1a435SJohn Baldwin } 18170d1a435SJohn Baldwin 18270d1a435SJohn Baldwin static int 183*21e3c1fbSJohn Baldwin ktls_ocf_tls_cbc_encrypt(struct ktls_session *tls, struct mbuf *m, 184*21e3c1fbSJohn Baldwin struct iovec *outiov, int outiovcnt) 18547e2650eSJohn Baldwin { 186*21e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 187*21e3c1fbSJohn Baldwin struct uio uio; 18847e2650eSJohn Baldwin struct tls_mac_data ad; 18947e2650eSJohn Baldwin struct cryptop crp; 19047e2650eSJohn Baldwin struct ocf_session *os; 191*21e3c1fbSJohn Baldwin struct iovec iov[m->m_epg_npgs + 2]; 192*21e3c1fbSJohn Baldwin u_int pgoff; 19347e2650eSJohn Baldwin int i, error; 19447e2650eSJohn Baldwin uint16_t tls_comp_len; 19547e2650eSJohn Baldwin uint8_t pad; 196*21e3c1fbSJohn Baldwin 197*21e3c1fbSJohn Baldwin MPASS(outiovcnt + 1 <= nitems(iov)); 19847e2650eSJohn Baldwin 19947e2650eSJohn Baldwin os = tls->cipher; 200*21e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 20147e2650eSJohn Baldwin 20247e2650eSJohn Baldwin #ifdef INVARIANTS 20347e2650eSJohn Baldwin if (os->implicit_iv) { 20447e2650eSJohn Baldwin mtx_lock(&os->lock); 20547e2650eSJohn Baldwin KASSERT(!os->in_progress, 20647e2650eSJohn Baldwin ("concurrent implicit IV encryptions")); 207*21e3c1fbSJohn Baldwin if (os->next_seqno != m->m_epg_seqno) { 20847e2650eSJohn Baldwin printf("KTLS CBC: TLS records out of order. " 20947e2650eSJohn Baldwin "Expected %ju, got %ju\n", 210*21e3c1fbSJohn Baldwin (uintmax_t)os->next_seqno, 211*21e3c1fbSJohn Baldwin (uintmax_t)m->m_epg_seqno); 21247e2650eSJohn Baldwin mtx_unlock(&os->lock); 21347e2650eSJohn Baldwin return (EINVAL); 21447e2650eSJohn Baldwin } 21547e2650eSJohn Baldwin os->in_progress = true; 21647e2650eSJohn Baldwin mtx_unlock(&os->lock); 21747e2650eSJohn Baldwin } 21847e2650eSJohn Baldwin #endif 21947e2650eSJohn Baldwin 220*21e3c1fbSJohn Baldwin /* Payload length. */ 221*21e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 22247e2650eSJohn Baldwin 22347e2650eSJohn Baldwin /* Initialize the AAD. */ 224*21e3c1fbSJohn Baldwin ad.seq = htobe64(m->m_epg_seqno); 22547e2650eSJohn Baldwin ad.type = hdr->tls_type; 22647e2650eSJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 22747e2650eSJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 22847e2650eSJohn Baldwin ad.tls_length = htons(tls_comp_len); 22947e2650eSJohn Baldwin 23047e2650eSJohn Baldwin /* First, compute the MAC. */ 23147e2650eSJohn Baldwin iov[0].iov_base = &ad; 23247e2650eSJohn Baldwin iov[0].iov_len = sizeof(ad); 233*21e3c1fbSJohn Baldwin pgoff = m->m_epg_1st_off; 234*21e3c1fbSJohn Baldwin for (i = 0; i < m->m_epg_npgs; i++, pgoff = 0) { 235*21e3c1fbSJohn Baldwin iov[i + 1].iov_base = (void *)PHYS_TO_DMAP(m->m_epg_pa[i] + 236*21e3c1fbSJohn Baldwin pgoff); 237*21e3c1fbSJohn Baldwin iov[i + 1].iov_len = m_epg_pagelen(m, i, pgoff); 238*21e3c1fbSJohn Baldwin } 239*21e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_base = m->m_epg_trail; 240*21e3c1fbSJohn Baldwin iov[m->m_epg_npgs + 1].iov_len = os->mac_len; 24147e2650eSJohn Baldwin uio.uio_iov = iov; 242*21e3c1fbSJohn Baldwin uio.uio_iovcnt = m->m_epg_npgs + 2; 24347e2650eSJohn Baldwin uio.uio_offset = 0; 24447e2650eSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 24547e2650eSJohn Baldwin uio.uio_td = curthread; 24647e2650eSJohn Baldwin uio.uio_resid = sizeof(ad) + tls_comp_len + os->mac_len; 24747e2650eSJohn Baldwin 24847e2650eSJohn Baldwin crypto_initreq(&crp, os->mac_sid); 24947e2650eSJohn Baldwin crp.crp_payload_start = 0; 25047e2650eSJohn Baldwin crp.crp_payload_length = sizeof(ad) + tls_comp_len; 25147e2650eSJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 25247e2650eSJohn Baldwin crp.crp_op = CRYPTO_OP_COMPUTE_DIGEST; 25347e2650eSJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM; 25447e2650eSJohn Baldwin crypto_use_uio(&crp, &uio); 25547e2650eSJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 25647e2650eSJohn Baldwin 25747e2650eSJohn Baldwin crypto_destroyreq(&crp); 25847e2650eSJohn Baldwin if (error) { 25947e2650eSJohn Baldwin #ifdef INVARIANTS 26047e2650eSJohn Baldwin if (os->implicit_iv) { 26147e2650eSJohn Baldwin mtx_lock(&os->lock); 26247e2650eSJohn Baldwin os->in_progress = false; 26347e2650eSJohn Baldwin mtx_unlock(&os->lock); 26447e2650eSJohn Baldwin } 26547e2650eSJohn Baldwin #endif 26647e2650eSJohn Baldwin return (error); 26747e2650eSJohn Baldwin } 26847e2650eSJohn Baldwin 26947e2650eSJohn Baldwin /* Second, add the padding. */ 270*21e3c1fbSJohn Baldwin pad = m->m_epg_trllen - os->mac_len - 1; 27147e2650eSJohn Baldwin for (i = 0; i < pad + 1; i++) 272*21e3c1fbSJohn Baldwin m->m_epg_trail[os->mac_len + i] = pad; 27347e2650eSJohn Baldwin 27447e2650eSJohn Baldwin /* Finally, encrypt the record. */ 27547e2650eSJohn Baldwin crypto_initreq(&crp, os->sid); 276*21e3c1fbSJohn Baldwin crp.crp_payload_start = m->m_epg_hdrlen; 277*21e3c1fbSJohn Baldwin crp.crp_payload_length = tls_comp_len + m->m_epg_trllen; 278*21e3c1fbSJohn Baldwin KASSERT(crp.crp_payload_length % AES_BLOCK_LEN == 0, 279*21e3c1fbSJohn Baldwin ("invalid encryption size")); 280*21e3c1fbSJohn Baldwin crypto_use_single_mbuf(&crp, m); 28147e2650eSJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT; 28247e2650eSJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 28347e2650eSJohn Baldwin if (os->implicit_iv) 28447e2650eSJohn Baldwin memcpy(crp.crp_iv, os->iv, AES_BLOCK_LEN); 28547e2650eSJohn Baldwin else 28647e2650eSJohn Baldwin memcpy(crp.crp_iv, hdr + 1, AES_BLOCK_LEN); 287*21e3c1fbSJohn Baldwin 288*21e3c1fbSJohn Baldwin if (outiov != NULL) { 289*21e3c1fbSJohn Baldwin /* Duplicate iovec and append vector for trailer. */ 290*21e3c1fbSJohn Baldwin memcpy(iov, outiov, outiovcnt * sizeof(struct iovec)); 291*21e3c1fbSJohn Baldwin iov[outiovcnt].iov_base = m->m_epg_trail; 292*21e3c1fbSJohn Baldwin iov[outiovcnt].iov_len = m->m_epg_trllen; 293*21e3c1fbSJohn Baldwin 294*21e3c1fbSJohn Baldwin uio.uio_iov = iov; 295*21e3c1fbSJohn Baldwin uio.uio_iovcnt = outiovcnt + 1; 296*21e3c1fbSJohn Baldwin uio.uio_offset = 0; 297*21e3c1fbSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 298*21e3c1fbSJohn Baldwin uio.uio_td = curthread; 299*21e3c1fbSJohn Baldwin uio.uio_resid = crp.crp_payload_length; 300*21e3c1fbSJohn Baldwin crypto_use_output_uio(&crp, &uio); 30147e2650eSJohn Baldwin } 30247e2650eSJohn Baldwin 30347e2650eSJohn Baldwin if (os->implicit_iv) 30447e2650eSJohn Baldwin counter_u64_add(ocf_tls10_cbc_crypts, 1); 30547e2650eSJohn Baldwin else 30647e2650eSJohn Baldwin counter_u64_add(ocf_tls11_cbc_crypts, 1); 307*21e3c1fbSJohn Baldwin if (outiov != NULL) 30847e2650eSJohn Baldwin counter_u64_add(ocf_separate_output, 1); 309*21e3c1fbSJohn Baldwin else 310*21e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 31147e2650eSJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 31247e2650eSJohn Baldwin 31347e2650eSJohn Baldwin crypto_destroyreq(&crp); 31447e2650eSJohn Baldwin 31547e2650eSJohn Baldwin if (os->implicit_iv) { 31647e2650eSJohn Baldwin KASSERT(os->mac_len + pad + 1 >= AES_BLOCK_LEN, 31747e2650eSJohn Baldwin ("trailer too short to read IV")); 318*21e3c1fbSJohn Baldwin memcpy(os->iv, m->m_epg_trail + m->m_epg_trllen - AES_BLOCK_LEN, 31947e2650eSJohn Baldwin AES_BLOCK_LEN); 32047e2650eSJohn Baldwin #ifdef INVARIANTS 32147e2650eSJohn Baldwin mtx_lock(&os->lock); 322*21e3c1fbSJohn Baldwin os->next_seqno = m->m_epg_seqno + 1; 32347e2650eSJohn Baldwin os->in_progress = false; 32447e2650eSJohn Baldwin mtx_unlock(&os->lock); 32547e2650eSJohn Baldwin #endif 32647e2650eSJohn Baldwin } 32747e2650eSJohn Baldwin return (error); 32847e2650eSJohn Baldwin } 32947e2650eSJohn Baldwin 33047e2650eSJohn Baldwin static int 331*21e3c1fbSJohn Baldwin ktls_ocf_tls12_aead_encrypt(struct ktls_session *tls, struct mbuf *m, 332*21e3c1fbSJohn Baldwin struct iovec *outiov, int outiovcnt) 333b2e60773SJohn Baldwin { 334*21e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 335*21e3c1fbSJohn Baldwin struct uio uio; 336b2e60773SJohn Baldwin struct tls_aead_data ad; 33733a1a488SJohn Baldwin struct cryptop crp; 338b2e60773SJohn Baldwin struct ocf_session *os; 33949f6925cSMark Johnston struct iovec iov[outiovcnt + 1]; 340*21e3c1fbSJohn Baldwin int error; 341b2e60773SJohn Baldwin uint16_t tls_comp_len; 342b2e60773SJohn Baldwin 343b2e60773SJohn Baldwin os = tls->cipher; 344*21e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 345b2e60773SJohn Baldwin 34633a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 347b2e60773SJohn Baldwin 348b2e60773SJohn Baldwin /* Setup the IV. */ 3494dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 35033a1a488SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 3514dd6800eSJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 3524dd6800eSJohn Baldwin sizeof(uint64_t)); 3534dd6800eSJohn Baldwin } else { 3544dd6800eSJohn Baldwin /* 3554dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 3564dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 3574dd6800eSJohn Baldwin * 1.3. 3584dd6800eSJohn Baldwin */ 3594dd6800eSJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 360*21e3c1fbSJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(m->m_epg_seqno); 3614dd6800eSJohn Baldwin } 362b2e60773SJohn Baldwin 363b2e60773SJohn Baldwin /* Setup the AAD. */ 364*21e3c1fbSJohn Baldwin tls_comp_len = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 365*21e3c1fbSJohn Baldwin ad.seq = htobe64(m->m_epg_seqno); 366b2e60773SJohn Baldwin ad.type = hdr->tls_type; 367b2e60773SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 368b2e60773SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 369b2e60773SJohn Baldwin ad.tls_length = htons(tls_comp_len); 37033a1a488SJohn Baldwin crp.crp_aad = &ad; 37133a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 372b2e60773SJohn Baldwin 373*21e3c1fbSJohn Baldwin /* Set fields for input payload. */ 374*21e3c1fbSJohn Baldwin crypto_use_single_mbuf(&crp, m); 375*21e3c1fbSJohn Baldwin crp.crp_payload_start = m->m_epg_hdrlen; 376*21e3c1fbSJohn Baldwin crp.crp_payload_length = tls_comp_len; 377b2e60773SJohn Baldwin 378*21e3c1fbSJohn Baldwin if (outiov != NULL) { 3795b750b9aSJohn Baldwin /* Duplicate iovec and append vector for tag. */ 380*21e3c1fbSJohn Baldwin memcpy(iov, outiov, outiovcnt * sizeof(struct iovec)); 381*21e3c1fbSJohn Baldwin iov[outiovcnt].iov_base = m->m_epg_trail; 3824a92afaeSJohn Baldwin iov[outiovcnt].iov_len = tls->params.tls_tlen; 383*21e3c1fbSJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 384*21e3c1fbSJohn Baldwin 385*21e3c1fbSJohn Baldwin uio.uio_iov = iov; 386*21e3c1fbSJohn Baldwin uio.uio_iovcnt = outiovcnt + 1; 387*21e3c1fbSJohn Baldwin uio.uio_offset = 0; 388*21e3c1fbSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 389*21e3c1fbSJohn Baldwin uio.uio_td = curthread; 390*21e3c1fbSJohn Baldwin uio.uio_resid = crp.crp_payload_length + tls->params.tls_tlen; 391*21e3c1fbSJohn Baldwin crypto_use_output_uio(&crp, &uio); 392*21e3c1fbSJohn Baldwin } else 393*21e3c1fbSJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + 394*21e3c1fbSJohn Baldwin crp.crp_payload_length; 395b2e60773SJohn Baldwin 39633a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 39733a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 3984dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 39955b7a0e1SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 4004dd6800eSJohn Baldwin else 4014dd6800eSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_crypts, 1); 402*21e3c1fbSJohn Baldwin if (outiov != NULL) 403080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 404*21e3c1fbSJohn Baldwin else 405*21e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 40670d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 40755b7a0e1SJohn Baldwin 40833a1a488SJohn Baldwin crypto_destroyreq(&crp); 40955b7a0e1SJohn Baldwin return (error); 41055b7a0e1SJohn Baldwin } 41155b7a0e1SJohn Baldwin 41255b7a0e1SJohn Baldwin static int 4134dd6800eSJohn Baldwin ktls_ocf_tls12_aead_decrypt(struct ktls_session *tls, 4143c0e5685SJohn Baldwin const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno, 4153c0e5685SJohn Baldwin int *trailer_len) 4163c0e5685SJohn Baldwin { 4173c0e5685SJohn Baldwin struct tls_aead_data ad; 4183c0e5685SJohn Baldwin struct cryptop crp; 4193c0e5685SJohn Baldwin struct ocf_session *os; 4203c0e5685SJohn Baldwin struct ocf_operation oo; 4213c0e5685SJohn Baldwin int error; 4223c0e5685SJohn Baldwin uint16_t tls_comp_len; 4233c0e5685SJohn Baldwin 4243c0e5685SJohn Baldwin os = tls->cipher; 4253c0e5685SJohn Baldwin 4263c0e5685SJohn Baldwin oo.os = os; 4273c0e5685SJohn Baldwin oo.done = false; 4283c0e5685SJohn Baldwin 4293c0e5685SJohn Baldwin crypto_initreq(&crp, os->sid); 4303c0e5685SJohn Baldwin 4313c0e5685SJohn Baldwin /* Setup the IV. */ 4324dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) { 4333c0e5685SJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); 4344dd6800eSJohn Baldwin memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, 4354dd6800eSJohn Baldwin sizeof(uint64_t)); 4364dd6800eSJohn Baldwin } else { 4374dd6800eSJohn Baldwin /* 4384dd6800eSJohn Baldwin * Chacha20-Poly1305 constructs the IV for TLS 1.2 4394dd6800eSJohn Baldwin * identically to constructing the IV for AEAD in TLS 4404dd6800eSJohn Baldwin * 1.3. 4414dd6800eSJohn Baldwin */ 4424dd6800eSJohn Baldwin memcpy(crp.crp_iv, tls->params.iv, tls->params.iv_len); 4434dd6800eSJohn Baldwin *(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno); 4444dd6800eSJohn Baldwin } 4453c0e5685SJohn Baldwin 4463c0e5685SJohn Baldwin /* Setup the AAD. */ 4474dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 4483c0e5685SJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - 4493c0e5685SJohn Baldwin (AES_GMAC_HASH_LEN + sizeof(uint64_t)); 4504dd6800eSJohn Baldwin else 4514dd6800eSJohn Baldwin tls_comp_len = ntohs(hdr->tls_length) - POLY1305_HASH_LEN; 4523c0e5685SJohn Baldwin ad.seq = htobe64(seqno); 4533c0e5685SJohn Baldwin ad.type = hdr->tls_type; 4543c0e5685SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 4553c0e5685SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 4563c0e5685SJohn Baldwin ad.tls_length = htons(tls_comp_len); 4573c0e5685SJohn Baldwin crp.crp_aad = &ad; 4583c0e5685SJohn Baldwin crp.crp_aad_length = sizeof(ad); 4593c0e5685SJohn Baldwin 4603c0e5685SJohn Baldwin crp.crp_payload_start = tls->params.tls_hlen; 4613c0e5685SJohn Baldwin crp.crp_payload_length = tls_comp_len; 4623c0e5685SJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length; 4633c0e5685SJohn Baldwin 4643c0e5685SJohn Baldwin crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST; 4653c0e5685SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 4663c0e5685SJohn Baldwin crypto_use_mbuf(&crp, m); 4673c0e5685SJohn Baldwin 4684dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 4693c0e5685SJohn Baldwin counter_u64_add(ocf_tls12_gcm_crypts, 1); 4704dd6800eSJohn Baldwin else 4714dd6800eSJohn Baldwin counter_u64_add(ocf_tls12_chacha20_crypts, 1); 4723c0e5685SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 4733c0e5685SJohn Baldwin 4743c0e5685SJohn Baldwin crypto_destroyreq(&crp); 4754a92afaeSJohn Baldwin *trailer_len = tls->params.tls_tlen; 4763c0e5685SJohn Baldwin return (error); 4773c0e5685SJohn Baldwin } 4783c0e5685SJohn Baldwin 4793c0e5685SJohn Baldwin static int 480*21e3c1fbSJohn Baldwin ktls_ocf_tls13_aead_encrypt(struct ktls_session *tls, struct mbuf *m, 481*21e3c1fbSJohn Baldwin struct iovec *outiov, int outiovcnt) 48255b7a0e1SJohn Baldwin { 483*21e3c1fbSJohn Baldwin const struct tls_record_layer *hdr; 484*21e3c1fbSJohn Baldwin struct uio uio; 48555b7a0e1SJohn Baldwin struct tls_aead_data_13 ad; 48655b7a0e1SJohn Baldwin char nonce[12]; 48733a1a488SJohn Baldwin struct cryptop crp; 48855b7a0e1SJohn Baldwin struct ocf_session *os; 489*21e3c1fbSJohn Baldwin struct iovec iov[outiovcnt + 1]; 490*21e3c1fbSJohn Baldwin int error; 49155b7a0e1SJohn Baldwin 49255b7a0e1SJohn Baldwin os = tls->cipher; 493*21e3c1fbSJohn Baldwin hdr = (const struct tls_record_layer *)m->m_epg_hdr; 49455b7a0e1SJohn Baldwin 49533a1a488SJohn Baldwin crypto_initreq(&crp, os->sid); 49655b7a0e1SJohn Baldwin 49755b7a0e1SJohn Baldwin /* Setup the nonce. */ 49855b7a0e1SJohn Baldwin memcpy(nonce, tls->params.iv, tls->params.iv_len); 499*21e3c1fbSJohn Baldwin *(uint64_t *)(nonce + 4) ^= htobe64(m->m_epg_seqno); 50055b7a0e1SJohn Baldwin 50155b7a0e1SJohn Baldwin /* Setup the AAD. */ 50255b7a0e1SJohn Baldwin ad.type = hdr->tls_type; 50355b7a0e1SJohn Baldwin ad.tls_vmajor = hdr->tls_vmajor; 50455b7a0e1SJohn Baldwin ad.tls_vminor = hdr->tls_vminor; 50555b7a0e1SJohn Baldwin ad.tls_length = hdr->tls_length; 50633a1a488SJohn Baldwin crp.crp_aad = &ad; 50733a1a488SJohn Baldwin crp.crp_aad_length = sizeof(ad); 508080933c0SJohn Baldwin 509*21e3c1fbSJohn Baldwin /* Set fields for input payload. */ 510*21e3c1fbSJohn Baldwin crypto_use_single_mbuf(&crp, m); 511*21e3c1fbSJohn Baldwin crp.crp_payload_start = m->m_epg_hdrlen; 512*21e3c1fbSJohn Baldwin crp.crp_payload_length = m->m_len - (m->m_epg_hdrlen + m->m_epg_trllen); 51355b7a0e1SJohn Baldwin 5145b750b9aSJohn Baldwin /* Store the record type as the first byte of the trailer. */ 515*21e3c1fbSJohn Baldwin m->m_epg_trail[0] = m->m_epg_record_type; 51633a1a488SJohn Baldwin crp.crp_payload_length++; 517*21e3c1fbSJohn Baldwin 518*21e3c1fbSJohn Baldwin if (outiov != NULL) { 519*21e3c1fbSJohn Baldwin /* Duplicate iovec and append vector for tag. */ 520*21e3c1fbSJohn Baldwin memcpy(iov, outiov, outiovcnt * sizeof(struct iovec)); 521*21e3c1fbSJohn Baldwin iov[outiovcnt].iov_base = m->m_epg_trail; 522*21e3c1fbSJohn Baldwin iov[outiovcnt].iov_len = tls->params.tls_tlen; 52333a1a488SJohn Baldwin crp.crp_digest_start = crp.crp_payload_length; 5245b750b9aSJohn Baldwin 5255b750b9aSJohn Baldwin uio.uio_iov = iov; 526*21e3c1fbSJohn Baldwin uio.uio_iovcnt = outiovcnt + 1; 5275b750b9aSJohn Baldwin uio.uio_offset = 0; 5285b750b9aSJohn Baldwin uio.uio_segflg = UIO_SYSSPACE; 5295b750b9aSJohn Baldwin uio.uio_td = curthread; 530*21e3c1fbSJohn Baldwin uio.uio_resid = m->m_len - m->m_epg_hdrlen; 531*21e3c1fbSJohn Baldwin crypto_use_output_uio(&crp, &uio); 532*21e3c1fbSJohn Baldwin } else 533*21e3c1fbSJohn Baldwin crp.crp_digest_start = crp.crp_payload_start + 534*21e3c1fbSJohn Baldwin crp.crp_payload_length; 53555b7a0e1SJohn Baldwin 53633a1a488SJohn Baldwin crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; 53733a1a488SJohn Baldwin crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; 53855b7a0e1SJohn Baldwin 53933a1a488SJohn Baldwin memcpy(crp.crp_iv, nonce, sizeof(nonce)); 54055b7a0e1SJohn Baldwin 5414dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16) 54255b7a0e1SJohn Baldwin counter_u64_add(ocf_tls13_gcm_crypts, 1); 5434dd6800eSJohn Baldwin else 5444dd6800eSJohn Baldwin counter_u64_add(ocf_tls13_chacha20_crypts, 1); 545*21e3c1fbSJohn Baldwin if (outiov != NULL) 546080933c0SJohn Baldwin counter_u64_add(ocf_separate_output, 1); 547*21e3c1fbSJohn Baldwin else 548*21e3c1fbSJohn Baldwin counter_u64_add(ocf_inplace, 1); 54970d1a435SJohn Baldwin error = ktls_ocf_dispatch(os, &crp); 550b2e60773SJohn Baldwin 55133a1a488SJohn Baldwin crypto_destroyreq(&crp); 552b2e60773SJohn Baldwin return (error); 553b2e60773SJohn Baldwin } 554b2e60773SJohn Baldwin 555*21e3c1fbSJohn Baldwin void 556b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls) 557b2e60773SJohn Baldwin { 558b2e60773SJohn Baldwin struct ocf_session *os; 559b2e60773SJohn Baldwin 560b2e60773SJohn Baldwin os = tls->cipher; 561c0341432SJohn Baldwin crypto_freesession(os->sid); 562b2e60773SJohn Baldwin mtx_destroy(&os->lock); 5634a711b8dSJohn Baldwin zfree(os, M_KTLS_OCF); 564b2e60773SJohn Baldwin } 565b2e60773SJohn Baldwin 566*21e3c1fbSJohn Baldwin int 5673c0e5685SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction) 568b2e60773SJohn Baldwin { 56947e2650eSJohn Baldwin struct crypto_session_params csp, mac_csp; 570b2e60773SJohn Baldwin struct ocf_session *os; 57147e2650eSJohn Baldwin int error, mac_len; 572b2e60773SJohn Baldwin 573c0341432SJohn Baldwin memset(&csp, 0, sizeof(csp)); 57447e2650eSJohn Baldwin memset(&mac_csp, 0, sizeof(mac_csp)); 57547e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_NONE; 57647e2650eSJohn Baldwin mac_len = 0; 577b2e60773SJohn Baldwin 578b2e60773SJohn Baldwin switch (tls->params.cipher_algorithm) { 579b2e60773SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 580b2e60773SJohn Baldwin switch (tls->params.cipher_key_len) { 581b2e60773SJohn Baldwin case 128 / 8: 582b2e60773SJohn Baldwin case 256 / 8: 583b2e60773SJohn Baldwin break; 584b2e60773SJohn Baldwin default: 585b2e60773SJohn Baldwin return (EINVAL); 586b2e60773SJohn Baldwin } 587b2e60773SJohn Baldwin 58855b7a0e1SJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 589b2e60773SJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 59055b7a0e1SJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 59155b7a0e1SJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 592b2e60773SJohn Baldwin return (EPROTONOSUPPORT); 593b2e60773SJohn Baldwin 5943c0e5685SJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 5953c0e5685SJohn Baldwin if (direction == KTLS_RX && 5963c0e5685SJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 5973c0e5685SJohn Baldwin return (EPROTONOSUPPORT); 5983c0e5685SJohn Baldwin 59947e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 60047e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 60147e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16; 60247e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 60347e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 60447e2650eSJohn Baldwin csp.csp_ivlen = AES_GCM_IV_LEN; 60547e2650eSJohn Baldwin break; 60647e2650eSJohn Baldwin case CRYPTO_AES_CBC: 60747e2650eSJohn Baldwin switch (tls->params.cipher_key_len) { 60847e2650eSJohn Baldwin case 128 / 8: 60947e2650eSJohn Baldwin case 256 / 8: 61047e2650eSJohn Baldwin break; 61147e2650eSJohn Baldwin default: 61247e2650eSJohn Baldwin return (EINVAL); 61347e2650eSJohn Baldwin } 61447e2650eSJohn Baldwin 61547e2650eSJohn Baldwin switch (tls->params.auth_algorithm) { 61647e2650eSJohn Baldwin case CRYPTO_SHA1_HMAC: 61747e2650eSJohn Baldwin mac_len = SHA1_HASH_LEN; 61847e2650eSJohn Baldwin break; 61947e2650eSJohn Baldwin case CRYPTO_SHA2_256_HMAC: 62047e2650eSJohn Baldwin mac_len = SHA2_256_HASH_LEN; 62147e2650eSJohn Baldwin break; 62247e2650eSJohn Baldwin case CRYPTO_SHA2_384_HMAC: 62347e2650eSJohn Baldwin mac_len = SHA2_384_HASH_LEN; 62447e2650eSJohn Baldwin break; 62547e2650eSJohn Baldwin default: 62647e2650eSJohn Baldwin return (EINVAL); 62747e2650eSJohn Baldwin } 62847e2650eSJohn Baldwin 62947e2650eSJohn Baldwin /* Only TLS 1.0-1.2 are supported. */ 63047e2650eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 63147e2650eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_ZERO || 63247e2650eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_TWO) 63347e2650eSJohn Baldwin return (EPROTONOSUPPORT); 63447e2650eSJohn Baldwin 63547e2650eSJohn Baldwin /* AES-CBC is not supported for receive. */ 63647e2650eSJohn Baldwin if (direction == KTLS_RX) 63747e2650eSJohn Baldwin return (EPROTONOSUPPORT); 63847e2650eSJohn Baldwin 63947e2650eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 64047e2650eSJohn Baldwin csp.csp_mode = CSP_MODE_CIPHER; 64147e2650eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_AES_CBC; 64247e2650eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 64347e2650eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 64447e2650eSJohn Baldwin csp.csp_ivlen = AES_BLOCK_LEN; 64547e2650eSJohn Baldwin 64647e2650eSJohn Baldwin mac_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; 64747e2650eSJohn Baldwin mac_csp.csp_mode = CSP_MODE_DIGEST; 64847e2650eSJohn Baldwin mac_csp.csp_auth_alg = tls->params.auth_algorithm; 64947e2650eSJohn Baldwin mac_csp.csp_auth_key = tls->params.auth_key; 65047e2650eSJohn Baldwin mac_csp.csp_auth_klen = tls->params.auth_key_len; 65147e2650eSJohn Baldwin break; 6524dd6800eSJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 6534dd6800eSJohn Baldwin switch (tls->params.cipher_key_len) { 6544dd6800eSJohn Baldwin case 256 / 8: 6554dd6800eSJohn Baldwin break; 6564dd6800eSJohn Baldwin default: 6574dd6800eSJohn Baldwin return (EINVAL); 6584dd6800eSJohn Baldwin } 6594dd6800eSJohn Baldwin 6604dd6800eSJohn Baldwin /* Only TLS 1.2 and 1.3 are supported. */ 6614dd6800eSJohn Baldwin if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE || 6624dd6800eSJohn Baldwin tls->params.tls_vminor < TLS_MINOR_VER_TWO || 6634dd6800eSJohn Baldwin tls->params.tls_vminor > TLS_MINOR_VER_THREE) 6644dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 6654dd6800eSJohn Baldwin 6664dd6800eSJohn Baldwin /* TLS 1.3 is not yet supported for receive. */ 6674dd6800eSJohn Baldwin if (direction == KTLS_RX && 6684dd6800eSJohn Baldwin tls->params.tls_vminor == TLS_MINOR_VER_THREE) 6694dd6800eSJohn Baldwin return (EPROTONOSUPPORT); 6704dd6800eSJohn Baldwin 6714dd6800eSJohn Baldwin csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD; 6724dd6800eSJohn Baldwin csp.csp_mode = CSP_MODE_AEAD; 6734dd6800eSJohn Baldwin csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305; 6744dd6800eSJohn Baldwin csp.csp_cipher_key = tls->params.cipher_key; 6754dd6800eSJohn Baldwin csp.csp_cipher_klen = tls->params.cipher_key_len; 6764dd6800eSJohn Baldwin csp.csp_ivlen = CHACHA20_POLY1305_IV_LEN; 6774dd6800eSJohn Baldwin break; 67847e2650eSJohn Baldwin default: 67947e2650eSJohn Baldwin return (EPROTONOSUPPORT); 68047e2650eSJohn Baldwin } 68147e2650eSJohn Baldwin 682b2e60773SJohn Baldwin os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO); 683b2e60773SJohn Baldwin if (os == NULL) 684b2e60773SJohn Baldwin return (ENOMEM); 685b2e60773SJohn Baldwin 686c0341432SJohn Baldwin error = crypto_newsession(&os->sid, &csp, 687b2e60773SJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 688b2e60773SJohn Baldwin if (error) { 689b2e60773SJohn Baldwin free(os, M_KTLS_OCF); 690b2e60773SJohn Baldwin return (error); 691b2e60773SJohn Baldwin } 692b2e60773SJohn Baldwin 69347e2650eSJohn Baldwin if (mac_csp.csp_mode != CSP_MODE_NONE) { 69447e2650eSJohn Baldwin error = crypto_newsession(&os->mac_sid, &mac_csp, 69547e2650eSJohn Baldwin CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE); 69647e2650eSJohn Baldwin if (error) { 69747e2650eSJohn Baldwin crypto_freesession(os->sid); 69847e2650eSJohn Baldwin free(os, M_KTLS_OCF); 69947e2650eSJohn Baldwin return (error); 70047e2650eSJohn Baldwin } 70147e2650eSJohn Baldwin os->mac_len = mac_len; 70247e2650eSJohn Baldwin } 70347e2650eSJohn Baldwin 704b2e60773SJohn Baldwin mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF); 705b2e60773SJohn Baldwin tls->cipher = os; 7064dd6800eSJohn Baldwin if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16 || 7074dd6800eSJohn Baldwin tls->params.cipher_algorithm == CRYPTO_CHACHA20_POLY1305) { 7083c0e5685SJohn Baldwin if (direction == KTLS_TX) { 70955b7a0e1SJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_THREE) 7104dd6800eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls13_aead_encrypt; 71155b7a0e1SJohn Baldwin else 7124dd6800eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls12_aead_encrypt; 7133c0e5685SJohn Baldwin } else { 7144dd6800eSJohn Baldwin tls->sw_decrypt = ktls_ocf_tls12_aead_decrypt; 7153c0e5685SJohn Baldwin } 71647e2650eSJohn Baldwin } else { 71747e2650eSJohn Baldwin tls->sw_encrypt = ktls_ocf_tls_cbc_encrypt; 71847e2650eSJohn Baldwin if (tls->params.tls_vminor == TLS_MINOR_VER_ZERO) { 71947e2650eSJohn Baldwin os->implicit_iv = true; 72047e2650eSJohn Baldwin memcpy(os->iv, tls->params.iv, AES_BLOCK_LEN); 72147e2650eSJohn Baldwin } 72247e2650eSJohn Baldwin } 723b2e60773SJohn Baldwin return (0); 724b2e60773SJohn Baldwin } 725