xref: /freebsd/sys/opencrypto/ktls_ocf.c (revision 3c0e5685051142f4125bf93d40a3e0b570e2327c)
1b2e60773SJohn Baldwin /*-
2b2e60773SJohn Baldwin  * SPDX-License-Identifier: BSD-2-Clause
3b2e60773SJohn Baldwin  *
4b2e60773SJohn Baldwin  * Copyright (c) 2019 Netflix Inc.
5b2e60773SJohn Baldwin  * All rights reserved.
6b2e60773SJohn Baldwin  *
7b2e60773SJohn Baldwin  * Redistribution and use in source and binary forms, with or without
8b2e60773SJohn Baldwin  * modification, are permitted provided that the following conditions
9b2e60773SJohn Baldwin  * are met:
10b2e60773SJohn Baldwin  * 1. Redistributions of source code must retain the above copyright
11b2e60773SJohn Baldwin  *    notice, this list of conditions and the following disclaimer.
12b2e60773SJohn Baldwin  * 2. Redistributions in binary form must reproduce the above copyright
13b2e60773SJohn Baldwin  *    notice, this list of conditions and the following disclaimer in the
14b2e60773SJohn Baldwin  *    documentation and/or other materials provided with the distribution.
15b2e60773SJohn Baldwin  *
16b2e60773SJohn Baldwin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17b2e60773SJohn Baldwin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18b2e60773SJohn Baldwin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19b2e60773SJohn Baldwin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20b2e60773SJohn Baldwin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21b2e60773SJohn Baldwin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22b2e60773SJohn Baldwin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23b2e60773SJohn Baldwin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24b2e60773SJohn Baldwin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25b2e60773SJohn Baldwin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26b2e60773SJohn Baldwin  * SUCH DAMAGE.
27b2e60773SJohn Baldwin  */
28b2e60773SJohn Baldwin 
29b2e60773SJohn Baldwin #include <sys/cdefs.h>
30b2e60773SJohn Baldwin __FBSDID("$FreeBSD$");
31b2e60773SJohn Baldwin 
32b2e60773SJohn Baldwin #include <sys/param.h>
33b2e60773SJohn Baldwin #include <sys/systm.h>
34b2e60773SJohn Baldwin #include <sys/counter.h>
35b2e60773SJohn Baldwin #include <sys/endian.h>
36b2e60773SJohn Baldwin #include <sys/kernel.h>
37b2e60773SJohn Baldwin #include <sys/ktls.h>
38b2e60773SJohn Baldwin #include <sys/lock.h>
39b2e60773SJohn Baldwin #include <sys/malloc.h>
40b2e60773SJohn Baldwin #include <sys/module.h>
41b2e60773SJohn Baldwin #include <sys/mutex.h>
42b2e60773SJohn Baldwin #include <sys/sysctl.h>
43b2e60773SJohn Baldwin #include <sys/uio.h>
44b2e60773SJohn Baldwin #include <opencrypto/cryptodev.h>
45b2e60773SJohn Baldwin 
46b2e60773SJohn Baldwin struct ocf_session {
47b2e60773SJohn Baldwin 	crypto_session_t sid;
48b2e60773SJohn Baldwin 	struct mtx lock;
49b2e60773SJohn Baldwin };
50b2e60773SJohn Baldwin 
51b2e60773SJohn Baldwin struct ocf_operation {
52b2e60773SJohn Baldwin 	struct ocf_session *os;
53b2e60773SJohn Baldwin 	bool done;
54b2e60773SJohn Baldwin };
55b2e60773SJohn Baldwin 
56b2e60773SJohn Baldwin static MALLOC_DEFINE(M_KTLS_OCF, "ktls_ocf", "OCF KTLS");
57b2e60773SJohn Baldwin 
58b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls);
59b2e60773SJohn Baldwin SYSCTL_DECL(_kern_ipc_tls_stats);
60b2e60773SJohn Baldwin 
617029da5cSPawel Biernacki static SYSCTL_NODE(_kern_ipc_tls_stats, OID_AUTO, ocf,
627029da5cSPawel Biernacki     CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
6355b7a0e1SJohn Baldwin     "Kernel TLS offload via OCF stats");
6455b7a0e1SJohn Baldwin 
6555b7a0e1SJohn Baldwin static counter_u64_t ocf_tls12_gcm_crypts;
6655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_crypts,
6755b7a0e1SJohn Baldwin     CTLFLAG_RD, &ocf_tls12_gcm_crypts,
6855b7a0e1SJohn Baldwin     "Total number of OCF TLS 1.2 GCM encryption operations");
6955b7a0e1SJohn Baldwin 
7055b7a0e1SJohn Baldwin static counter_u64_t ocf_tls13_gcm_crypts;
7155b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_crypts,
7255b7a0e1SJohn Baldwin     CTLFLAG_RD, &ocf_tls13_gcm_crypts,
7355b7a0e1SJohn Baldwin     "Total number of OCF TLS 1.3 GCM encryption operations");
74b2e60773SJohn Baldwin 
75080933c0SJohn Baldwin static counter_u64_t ocf_inplace;
76080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, inplace,
77080933c0SJohn Baldwin     CTLFLAG_RD, &ocf_inplace,
78080933c0SJohn Baldwin     "Total number of OCF in-place operations");
79080933c0SJohn Baldwin 
80080933c0SJohn Baldwin static counter_u64_t ocf_separate_output;
81080933c0SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, separate_output,
82080933c0SJohn Baldwin     CTLFLAG_RD, &ocf_separate_output,
83080933c0SJohn Baldwin     "Total number of OCF operations with a separate output buffer");
84080933c0SJohn Baldwin 
85b2e60773SJohn Baldwin static counter_u64_t ocf_retries;
8655b7a0e1SJohn Baldwin SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, retries, CTLFLAG_RD,
87b2e60773SJohn Baldwin     &ocf_retries,
88b2e60773SJohn Baldwin     "Number of OCF encryption operation retries");
89b2e60773SJohn Baldwin 
90b2e60773SJohn Baldwin static int
91b2e60773SJohn Baldwin ktls_ocf_callback(struct cryptop *crp)
92b2e60773SJohn Baldwin {
93b2e60773SJohn Baldwin 	struct ocf_operation *oo;
94b2e60773SJohn Baldwin 
95b2e60773SJohn Baldwin 	oo = crp->crp_opaque;
96b2e60773SJohn Baldwin 	mtx_lock(&oo->os->lock);
97b2e60773SJohn Baldwin 	oo->done = true;
98b2e60773SJohn Baldwin 	mtx_unlock(&oo->os->lock);
99b2e60773SJohn Baldwin 	wakeup(oo);
100b2e60773SJohn Baldwin 	return (0);
101b2e60773SJohn Baldwin }
102b2e60773SJohn Baldwin 
103b2e60773SJohn Baldwin static int
10470d1a435SJohn Baldwin ktls_ocf_dispatch(struct ocf_session *os, struct cryptop *crp)
10570d1a435SJohn Baldwin {
10670d1a435SJohn Baldwin 	struct ocf_operation oo;
10770d1a435SJohn Baldwin 	int error;
10870d1a435SJohn Baldwin 
10970d1a435SJohn Baldwin 	oo.os = os;
11070d1a435SJohn Baldwin 	oo.done = false;
11170d1a435SJohn Baldwin 
11270d1a435SJohn Baldwin 	crp->crp_opaque = &oo;
11370d1a435SJohn Baldwin 	crp->crp_callback = ktls_ocf_callback;
11470d1a435SJohn Baldwin 	for (;;) {
11570d1a435SJohn Baldwin 		error = crypto_dispatch(crp);
11670d1a435SJohn Baldwin 		if (error)
11770d1a435SJohn Baldwin 			break;
11870d1a435SJohn Baldwin 
11970d1a435SJohn Baldwin 		mtx_lock(&os->lock);
12070d1a435SJohn Baldwin 		while (!oo.done)
12170d1a435SJohn Baldwin 			mtx_sleep(&oo, &os->lock, 0, "ocfktls", 0);
12270d1a435SJohn Baldwin 		mtx_unlock(&os->lock);
12370d1a435SJohn Baldwin 
12470d1a435SJohn Baldwin 		if (crp->crp_etype != EAGAIN) {
12570d1a435SJohn Baldwin 			error = crp->crp_etype;
12670d1a435SJohn Baldwin 			break;
12770d1a435SJohn Baldwin 		}
12870d1a435SJohn Baldwin 
12970d1a435SJohn Baldwin 		crp->crp_etype = 0;
13070d1a435SJohn Baldwin 		crp->crp_flags &= ~CRYPTO_F_DONE;
13170d1a435SJohn Baldwin 		oo.done = false;
13270d1a435SJohn Baldwin 		counter_u64_add(ocf_retries, 1);
13370d1a435SJohn Baldwin 	}
13470d1a435SJohn Baldwin 	return (error);
13570d1a435SJohn Baldwin }
13670d1a435SJohn Baldwin 
13770d1a435SJohn Baldwin static int
13855b7a0e1SJohn Baldwin ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls,
13955b7a0e1SJohn Baldwin     const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov,
14055b7a0e1SJohn Baldwin     struct iovec *outiov, int iovcnt, uint64_t seqno,
14155b7a0e1SJohn Baldwin     uint8_t record_type __unused)
142b2e60773SJohn Baldwin {
143080933c0SJohn Baldwin 	struct uio uio, out_uio, *tag_uio;
144b2e60773SJohn Baldwin 	struct tls_aead_data ad;
14533a1a488SJohn Baldwin 	struct cryptop crp;
146b2e60773SJohn Baldwin 	struct ocf_session *os;
14733a1a488SJohn Baldwin 	struct iovec iov[iovcnt + 1];
148b2e60773SJohn Baldwin 	int i, error;
149b2e60773SJohn Baldwin 	uint16_t tls_comp_len;
150080933c0SJohn Baldwin 	bool inplace;
151b2e60773SJohn Baldwin 
152b2e60773SJohn Baldwin 	os = tls->cipher;
153b2e60773SJohn Baldwin 
1545b750b9aSJohn Baldwin 	uio.uio_iov = iniov;
1555b750b9aSJohn Baldwin 	uio.uio_iovcnt = iovcnt;
156080933c0SJohn Baldwin 	uio.uio_offset = 0;
157080933c0SJohn Baldwin 	uio.uio_segflg = UIO_SYSSPACE;
158080933c0SJohn Baldwin 	uio.uio_td = curthread;
159080933c0SJohn Baldwin 
1605b750b9aSJohn Baldwin 	out_uio.uio_iov = outiov;
1615b750b9aSJohn Baldwin 	out_uio.uio_iovcnt = iovcnt;
162080933c0SJohn Baldwin 	out_uio.uio_offset = 0;
163080933c0SJohn Baldwin 	out_uio.uio_segflg = UIO_SYSSPACE;
164080933c0SJohn Baldwin 	out_uio.uio_td = curthread;
165b2e60773SJohn Baldwin 
16633a1a488SJohn Baldwin 	crypto_initreq(&crp, os->sid);
167b2e60773SJohn Baldwin 
168b2e60773SJohn Baldwin 	/* Setup the IV. */
16933a1a488SJohn Baldwin 	memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN);
17033a1a488SJohn Baldwin 	memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t));
171b2e60773SJohn Baldwin 
172b2e60773SJohn Baldwin 	/* Setup the AAD. */
173b2e60773SJohn Baldwin 	tls_comp_len = ntohs(hdr->tls_length) -
174c0341432SJohn Baldwin 	    (AES_GMAC_HASH_LEN + sizeof(uint64_t));
175b2e60773SJohn Baldwin 	ad.seq = htobe64(seqno);
176b2e60773SJohn Baldwin 	ad.type = hdr->tls_type;
177b2e60773SJohn Baldwin 	ad.tls_vmajor = hdr->tls_vmajor;
178b2e60773SJohn Baldwin 	ad.tls_vminor = hdr->tls_vminor;
179b2e60773SJohn Baldwin 	ad.tls_length = htons(tls_comp_len);
18033a1a488SJohn Baldwin 	crp.crp_aad = &ad;
18133a1a488SJohn Baldwin 	crp.crp_aad_length = sizeof(ad);
182b2e60773SJohn Baldwin 
183080933c0SJohn Baldwin 	/* Compute payload length and determine if encryption is in place. */
184080933c0SJohn Baldwin 	inplace = true;
18533a1a488SJohn Baldwin 	crp.crp_payload_start = 0;
186b2e60773SJohn Baldwin 	for (i = 0; i < iovcnt; i++) {
187b2e60773SJohn Baldwin 		if (iniov[i].iov_base != outiov[i].iov_base)
188080933c0SJohn Baldwin 			inplace = false;
18933a1a488SJohn Baldwin 		crp.crp_payload_length += iniov[i].iov_len;
190b2e60773SJohn Baldwin 	}
19133a1a488SJohn Baldwin 	uio.uio_resid = crp.crp_payload_length;
19233a1a488SJohn Baldwin 	out_uio.uio_resid = crp.crp_payload_length;
193b2e60773SJohn Baldwin 
194080933c0SJohn Baldwin 	if (inplace)
195080933c0SJohn Baldwin 		tag_uio = &uio;
196080933c0SJohn Baldwin 	else
197080933c0SJohn Baldwin 		tag_uio = &out_uio;
198b2e60773SJohn Baldwin 
1995b750b9aSJohn Baldwin 	/* Duplicate iovec and append vector for tag. */
20033a1a488SJohn Baldwin 	memcpy(iov, tag_uio->uio_iov, iovcnt * sizeof(struct iovec));
20133a1a488SJohn Baldwin 	iov[iovcnt].iov_base = trailer;
20233a1a488SJohn Baldwin 	iov[iovcnt].iov_len = AES_GMAC_HASH_LEN;
20333a1a488SJohn Baldwin 	tag_uio->uio_iov = iov;
204080933c0SJohn Baldwin 	tag_uio->uio_iovcnt++;
20533a1a488SJohn Baldwin 	crp.crp_digest_start = tag_uio->uio_resid;
206080933c0SJohn Baldwin 	tag_uio->uio_resid += AES_GMAC_HASH_LEN;
207b2e60773SJohn Baldwin 
20833a1a488SJohn Baldwin 	crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST;
20933a1a488SJohn Baldwin 	crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
21033a1a488SJohn Baldwin 	crypto_use_uio(&crp, &uio);
211080933c0SJohn Baldwin 	if (!inplace)
21233a1a488SJohn Baldwin 		crypto_use_output_uio(&crp, &out_uio);
213b2e60773SJohn Baldwin 
21455b7a0e1SJohn Baldwin 	counter_u64_add(ocf_tls12_gcm_crypts, 1);
215080933c0SJohn Baldwin 	if (inplace)
216080933c0SJohn Baldwin 		counter_u64_add(ocf_inplace, 1);
217080933c0SJohn Baldwin 	else
218080933c0SJohn Baldwin 		counter_u64_add(ocf_separate_output, 1);
21970d1a435SJohn Baldwin 	error = ktls_ocf_dispatch(os, &crp);
22055b7a0e1SJohn Baldwin 
22133a1a488SJohn Baldwin 	crypto_destroyreq(&crp);
22255b7a0e1SJohn Baldwin 	return (error);
22355b7a0e1SJohn Baldwin }
22455b7a0e1SJohn Baldwin 
22555b7a0e1SJohn Baldwin static int
226*3c0e5685SJohn Baldwin ktls_ocf_tls12_gcm_decrypt(struct ktls_session *tls,
227*3c0e5685SJohn Baldwin     const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno,
228*3c0e5685SJohn Baldwin     int *trailer_len)
229*3c0e5685SJohn Baldwin {
230*3c0e5685SJohn Baldwin 	struct tls_aead_data ad;
231*3c0e5685SJohn Baldwin 	struct cryptop crp;
232*3c0e5685SJohn Baldwin 	struct ocf_session *os;
233*3c0e5685SJohn Baldwin 	struct ocf_operation oo;
234*3c0e5685SJohn Baldwin 	int error;
235*3c0e5685SJohn Baldwin 	uint16_t tls_comp_len;
236*3c0e5685SJohn Baldwin 
237*3c0e5685SJohn Baldwin 	os = tls->cipher;
238*3c0e5685SJohn Baldwin 
239*3c0e5685SJohn Baldwin 	oo.os = os;
240*3c0e5685SJohn Baldwin 	oo.done = false;
241*3c0e5685SJohn Baldwin 
242*3c0e5685SJohn Baldwin 	crypto_initreq(&crp, os->sid);
243*3c0e5685SJohn Baldwin 
244*3c0e5685SJohn Baldwin 	/* Setup the IV. */
245*3c0e5685SJohn Baldwin 	memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN);
246*3c0e5685SJohn Baldwin 	memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t));
247*3c0e5685SJohn Baldwin 
248*3c0e5685SJohn Baldwin 	/* Setup the AAD. */
249*3c0e5685SJohn Baldwin 	tls_comp_len = ntohs(hdr->tls_length) -
250*3c0e5685SJohn Baldwin 	    (AES_GMAC_HASH_LEN + sizeof(uint64_t));
251*3c0e5685SJohn Baldwin 	ad.seq = htobe64(seqno);
252*3c0e5685SJohn Baldwin 	ad.type = hdr->tls_type;
253*3c0e5685SJohn Baldwin 	ad.tls_vmajor = hdr->tls_vmajor;
254*3c0e5685SJohn Baldwin 	ad.tls_vminor = hdr->tls_vminor;
255*3c0e5685SJohn Baldwin 	ad.tls_length = htons(tls_comp_len);
256*3c0e5685SJohn Baldwin 	crp.crp_aad = &ad;
257*3c0e5685SJohn Baldwin 	crp.crp_aad_length = sizeof(ad);
258*3c0e5685SJohn Baldwin 
259*3c0e5685SJohn Baldwin 	crp.crp_payload_start = tls->params.tls_hlen;
260*3c0e5685SJohn Baldwin 	crp.crp_payload_length = tls_comp_len;
261*3c0e5685SJohn Baldwin 	crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length;
262*3c0e5685SJohn Baldwin 
263*3c0e5685SJohn Baldwin 	crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST;
264*3c0e5685SJohn Baldwin 	crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
265*3c0e5685SJohn Baldwin 	crypto_use_mbuf(&crp, m);
266*3c0e5685SJohn Baldwin 
267*3c0e5685SJohn Baldwin 	counter_u64_add(ocf_tls12_gcm_crypts, 1);
268*3c0e5685SJohn Baldwin 	error = ktls_ocf_dispatch(os, &crp);
269*3c0e5685SJohn Baldwin 
270*3c0e5685SJohn Baldwin 	crypto_destroyreq(&crp);
271*3c0e5685SJohn Baldwin 	*trailer_len = AES_GMAC_HASH_LEN;
272*3c0e5685SJohn Baldwin 	return (error);
273*3c0e5685SJohn Baldwin }
274*3c0e5685SJohn Baldwin 
275*3c0e5685SJohn Baldwin static int
27655b7a0e1SJohn Baldwin ktls_ocf_tls13_gcm_encrypt(struct ktls_session *tls,
27755b7a0e1SJohn Baldwin     const struct tls_record_layer *hdr, uint8_t *trailer, struct iovec *iniov,
27855b7a0e1SJohn Baldwin     struct iovec *outiov, int iovcnt, uint64_t seqno, uint8_t record_type)
27955b7a0e1SJohn Baldwin {
280080933c0SJohn Baldwin 	struct uio uio, out_uio;
28155b7a0e1SJohn Baldwin 	struct tls_aead_data_13 ad;
28255b7a0e1SJohn Baldwin 	char nonce[12];
28333a1a488SJohn Baldwin 	struct cryptop crp;
28455b7a0e1SJohn Baldwin 	struct ocf_session *os;
28533a1a488SJohn Baldwin 	struct iovec iov[iovcnt + 1], out_iov[iovcnt + 1];
28655b7a0e1SJohn Baldwin 	int i, error;
287080933c0SJohn Baldwin 	bool inplace;
28855b7a0e1SJohn Baldwin 
28955b7a0e1SJohn Baldwin 	os = tls->cipher;
29055b7a0e1SJohn Baldwin 
29133a1a488SJohn Baldwin 	crypto_initreq(&crp, os->sid);
29255b7a0e1SJohn Baldwin 
29355b7a0e1SJohn Baldwin 	/* Setup the nonce. */
29455b7a0e1SJohn Baldwin 	memcpy(nonce, tls->params.iv, tls->params.iv_len);
29555b7a0e1SJohn Baldwin 	*(uint64_t *)(nonce + 4) ^= htobe64(seqno);
29655b7a0e1SJohn Baldwin 
29755b7a0e1SJohn Baldwin 	/* Setup the AAD. */
29855b7a0e1SJohn Baldwin 	ad.type = hdr->tls_type;
29955b7a0e1SJohn Baldwin 	ad.tls_vmajor = hdr->tls_vmajor;
30055b7a0e1SJohn Baldwin 	ad.tls_vminor = hdr->tls_vminor;
30155b7a0e1SJohn Baldwin 	ad.tls_length = hdr->tls_length;
30233a1a488SJohn Baldwin 	crp.crp_aad = &ad;
30333a1a488SJohn Baldwin 	crp.crp_aad_length = sizeof(ad);
304080933c0SJohn Baldwin 
305080933c0SJohn Baldwin 	/* Compute payload length and determine if encryption is in place. */
306080933c0SJohn Baldwin 	inplace = true;
30733a1a488SJohn Baldwin 	crp.crp_payload_start = 0;
308080933c0SJohn Baldwin 	for (i = 0; i < iovcnt; i++) {
309080933c0SJohn Baldwin 		if (iniov[i].iov_base != outiov[i].iov_base)
310080933c0SJohn Baldwin 			inplace = false;
31133a1a488SJohn Baldwin 		crp.crp_payload_length += iniov[i].iov_len;
312080933c0SJohn Baldwin 	}
31355b7a0e1SJohn Baldwin 
3145b750b9aSJohn Baldwin 	/* Store the record type as the first byte of the trailer. */
31555b7a0e1SJohn Baldwin 	trailer[0] = record_type;
31633a1a488SJohn Baldwin 	crp.crp_payload_length++;
31733a1a488SJohn Baldwin 	crp.crp_digest_start = crp.crp_payload_length;
3185b750b9aSJohn Baldwin 
3195b750b9aSJohn Baldwin 	/*
3205b750b9aSJohn Baldwin 	 * Duplicate the input iov to append the trailer.  Always
3215b750b9aSJohn Baldwin 	 * include the full trailer as input to get the record_type
3225b750b9aSJohn Baldwin 	 * even if only the first byte is used.
3235b750b9aSJohn Baldwin 	 */
3245b750b9aSJohn Baldwin 	memcpy(iov, iniov, iovcnt * sizeof(*iov));
3255b750b9aSJohn Baldwin 	iov[iovcnt].iov_base = trailer;
3265b750b9aSJohn Baldwin 	iov[iovcnt].iov_len = AES_GMAC_HASH_LEN + 1;
3275b750b9aSJohn Baldwin 	uio.uio_iov = iov;
3285b750b9aSJohn Baldwin 	uio.uio_iovcnt = iovcnt + 1;
3295b750b9aSJohn Baldwin 	uio.uio_offset = 0;
33033a1a488SJohn Baldwin 	uio.uio_resid = crp.crp_payload_length + AES_GMAC_HASH_LEN;
3315b750b9aSJohn Baldwin 	uio.uio_segflg = UIO_SYSSPACE;
3325b750b9aSJohn Baldwin 	uio.uio_td = curthread;
33333a1a488SJohn Baldwin 	crypto_use_uio(&crp, &uio);
3345b750b9aSJohn Baldwin 
3355b750b9aSJohn Baldwin 	if (!inplace) {
3365b750b9aSJohn Baldwin 		/* Duplicate the output iov to append the trailer. */
3375b750b9aSJohn Baldwin 		memcpy(out_iov, outiov, iovcnt * sizeof(*out_iov));
3385b750b9aSJohn Baldwin 		out_iov[iovcnt] = iov[iovcnt];
3395b750b9aSJohn Baldwin 
3405b750b9aSJohn Baldwin 		out_uio.uio_iov = out_iov;
3415b750b9aSJohn Baldwin 		out_uio.uio_iovcnt = iovcnt + 1;
3425b750b9aSJohn Baldwin 		out_uio.uio_offset = 0;
34333a1a488SJohn Baldwin 		out_uio.uio_resid = crp.crp_payload_length +
3445b750b9aSJohn Baldwin 		    AES_GMAC_HASH_LEN;
3455b750b9aSJohn Baldwin 		out_uio.uio_segflg = UIO_SYSSPACE;
3465b750b9aSJohn Baldwin 		out_uio.uio_td = curthread;
34733a1a488SJohn Baldwin 		crypto_use_output_uio(&crp, &out_uio);
348080933c0SJohn Baldwin 	}
34955b7a0e1SJohn Baldwin 
35033a1a488SJohn Baldwin 	crp.crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST;
35133a1a488SJohn Baldwin 	crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
35255b7a0e1SJohn Baldwin 
35333a1a488SJohn Baldwin 	memcpy(crp.crp_iv, nonce, sizeof(nonce));
35455b7a0e1SJohn Baldwin 
35555b7a0e1SJohn Baldwin 	counter_u64_add(ocf_tls13_gcm_crypts, 1);
356080933c0SJohn Baldwin 	if (inplace)
357080933c0SJohn Baldwin 		counter_u64_add(ocf_inplace, 1);
358080933c0SJohn Baldwin 	else
359080933c0SJohn Baldwin 		counter_u64_add(ocf_separate_output, 1);
36070d1a435SJohn Baldwin 	error = ktls_ocf_dispatch(os, &crp);
361b2e60773SJohn Baldwin 
36233a1a488SJohn Baldwin 	crypto_destroyreq(&crp);
363b2e60773SJohn Baldwin 	return (error);
364b2e60773SJohn Baldwin }
365b2e60773SJohn Baldwin 
366b2e60773SJohn Baldwin static void
367b2e60773SJohn Baldwin ktls_ocf_free(struct ktls_session *tls)
368b2e60773SJohn Baldwin {
369b2e60773SJohn Baldwin 	struct ocf_session *os;
370b2e60773SJohn Baldwin 
371b2e60773SJohn Baldwin 	os = tls->cipher;
372c0341432SJohn Baldwin 	crypto_freesession(os->sid);
373b2e60773SJohn Baldwin 	mtx_destroy(&os->lock);
3744a711b8dSJohn Baldwin 	zfree(os, M_KTLS_OCF);
375b2e60773SJohn Baldwin }
376b2e60773SJohn Baldwin 
377b2e60773SJohn Baldwin static int
378*3c0e5685SJohn Baldwin ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction)
379b2e60773SJohn Baldwin {
380c0341432SJohn Baldwin 	struct crypto_session_params csp;
381b2e60773SJohn Baldwin 	struct ocf_session *os;
382b2e60773SJohn Baldwin 	int error;
383b2e60773SJohn Baldwin 
384c0341432SJohn Baldwin 	memset(&csp, 0, sizeof(csp));
3855b750b9aSJohn Baldwin 	csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD;
386b2e60773SJohn Baldwin 
387b2e60773SJohn Baldwin 	switch (tls->params.cipher_algorithm) {
388b2e60773SJohn Baldwin 	case CRYPTO_AES_NIST_GCM_16:
389b2e60773SJohn Baldwin 		switch (tls->params.cipher_key_len) {
390b2e60773SJohn Baldwin 		case 128 / 8:
391b2e60773SJohn Baldwin 		case 256 / 8:
392b2e60773SJohn Baldwin 			break;
393b2e60773SJohn Baldwin 		default:
394b2e60773SJohn Baldwin 			return (EINVAL);
395b2e60773SJohn Baldwin 		}
396c0341432SJohn Baldwin 		csp.csp_mode = CSP_MODE_AEAD;
397c0341432SJohn Baldwin 		csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16;
398c0341432SJohn Baldwin 		csp.csp_cipher_key = tls->params.cipher_key;
399c0341432SJohn Baldwin 		csp.csp_cipher_klen = tls->params.cipher_key_len;
400c0341432SJohn Baldwin 		csp.csp_ivlen = AES_GCM_IV_LEN;
401b2e60773SJohn Baldwin 		break;
402b2e60773SJohn Baldwin 	default:
403b2e60773SJohn Baldwin 		return (EPROTONOSUPPORT);
404b2e60773SJohn Baldwin 	}
405b2e60773SJohn Baldwin 
40655b7a0e1SJohn Baldwin 	/* Only TLS 1.2 and 1.3 are supported. */
407b2e60773SJohn Baldwin 	if (tls->params.tls_vmajor != TLS_MAJOR_VER_ONE ||
40855b7a0e1SJohn Baldwin 	    tls->params.tls_vminor < TLS_MINOR_VER_TWO ||
40955b7a0e1SJohn Baldwin 	    tls->params.tls_vminor > TLS_MINOR_VER_THREE)
410b2e60773SJohn Baldwin 		return (EPROTONOSUPPORT);
411b2e60773SJohn Baldwin 
412*3c0e5685SJohn Baldwin 	/* TLS 1.3 is not yet supported for receive. */
413*3c0e5685SJohn Baldwin 	if (direction == KTLS_RX &&
414*3c0e5685SJohn Baldwin 	    tls->params.tls_vminor == TLS_MINOR_VER_THREE)
415*3c0e5685SJohn Baldwin 		return (EPROTONOSUPPORT);
416*3c0e5685SJohn Baldwin 
417b2e60773SJohn Baldwin 	os = malloc(sizeof(*os), M_KTLS_OCF, M_NOWAIT | M_ZERO);
418b2e60773SJohn Baldwin 	if (os == NULL)
419b2e60773SJohn Baldwin 		return (ENOMEM);
420b2e60773SJohn Baldwin 
421c0341432SJohn Baldwin 	error = crypto_newsession(&os->sid, &csp,
422b2e60773SJohn Baldwin 	    CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE);
423b2e60773SJohn Baldwin 	if (error) {
424b2e60773SJohn Baldwin 		free(os, M_KTLS_OCF);
425b2e60773SJohn Baldwin 		return (error);
426b2e60773SJohn Baldwin 	}
427b2e60773SJohn Baldwin 
428b2e60773SJohn Baldwin 	mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF);
429b2e60773SJohn Baldwin 	tls->cipher = os;
430*3c0e5685SJohn Baldwin 	if (direction == KTLS_TX) {
43155b7a0e1SJohn Baldwin 		if (tls->params.tls_vminor == TLS_MINOR_VER_THREE)
43255b7a0e1SJohn Baldwin 			tls->sw_encrypt = ktls_ocf_tls13_gcm_encrypt;
43355b7a0e1SJohn Baldwin 		else
43455b7a0e1SJohn Baldwin 			tls->sw_encrypt = ktls_ocf_tls12_gcm_encrypt;
435*3c0e5685SJohn Baldwin 	} else {
436*3c0e5685SJohn Baldwin 		tls->sw_decrypt = ktls_ocf_tls12_gcm_decrypt;
437*3c0e5685SJohn Baldwin 	}
438b2e60773SJohn Baldwin 	tls->free = ktls_ocf_free;
439b2e60773SJohn Baldwin 	return (0);
440b2e60773SJohn Baldwin }
441b2e60773SJohn Baldwin 
442b2e60773SJohn Baldwin struct ktls_crypto_backend ocf_backend = {
443b2e60773SJohn Baldwin 	.name = "OCF",
444b2e60773SJohn Baldwin 	.prio = 5,
445b2e60773SJohn Baldwin 	.api_version = KTLS_API_VERSION,
446b2e60773SJohn Baldwin 	.try = ktls_ocf_try,
447b2e60773SJohn Baldwin };
448b2e60773SJohn Baldwin 
449b2e60773SJohn Baldwin static int
450b2e60773SJohn Baldwin ktls_ocf_modevent(module_t mod, int what, void *arg)
451b2e60773SJohn Baldwin {
452b2e60773SJohn Baldwin 	int error;
453b2e60773SJohn Baldwin 
454b2e60773SJohn Baldwin 	switch (what) {
455b2e60773SJohn Baldwin 	case MOD_LOAD:
45655b7a0e1SJohn Baldwin 		ocf_tls12_gcm_crypts = counter_u64_alloc(M_WAITOK);
45755b7a0e1SJohn Baldwin 		ocf_tls13_gcm_crypts = counter_u64_alloc(M_WAITOK);
458080933c0SJohn Baldwin 		ocf_inplace = counter_u64_alloc(M_WAITOK);
459080933c0SJohn Baldwin 		ocf_separate_output = counter_u64_alloc(M_WAITOK);
460b2e60773SJohn Baldwin 		ocf_retries = counter_u64_alloc(M_WAITOK);
461b2e60773SJohn Baldwin 		return (ktls_crypto_backend_register(&ocf_backend));
462b2e60773SJohn Baldwin 	case MOD_UNLOAD:
463b2e60773SJohn Baldwin 		error = ktls_crypto_backend_deregister(&ocf_backend);
464b2e60773SJohn Baldwin 		if (error)
465b2e60773SJohn Baldwin 			return (error);
46655b7a0e1SJohn Baldwin 		counter_u64_free(ocf_tls12_gcm_crypts);
46755b7a0e1SJohn Baldwin 		counter_u64_free(ocf_tls13_gcm_crypts);
468080933c0SJohn Baldwin 		counter_u64_free(ocf_inplace);
469080933c0SJohn Baldwin 		counter_u64_free(ocf_separate_output);
470b2e60773SJohn Baldwin 		counter_u64_free(ocf_retries);
471b2e60773SJohn Baldwin 		return (0);
472b2e60773SJohn Baldwin 	default:
473b2e60773SJohn Baldwin 		return (EOPNOTSUPP);
474b2e60773SJohn Baldwin 	}
475b2e60773SJohn Baldwin }
476b2e60773SJohn Baldwin 
477b2e60773SJohn Baldwin static moduledata_t ktls_ocf_moduledata = {
478b2e60773SJohn Baldwin 	"ktls_ocf",
479b2e60773SJohn Baldwin 	ktls_ocf_modevent,
480b2e60773SJohn Baldwin 	NULL
481b2e60773SJohn Baldwin };
482b2e60773SJohn Baldwin 
483b2e60773SJohn Baldwin DECLARE_MODULE(ktls_ocf, ktls_ocf_moduledata, SI_SUB_PROTO_END, SI_ORDER_ANY);
484