xref: /freebsd/sys/opencrypto/cryptosoft.c (revision d8787d4f7848bad8bd69325969806e1a76d0c3df)
1091d81d1SSam Leffler /*	$OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $	*/
2091d81d1SSam Leffler 
360727d8bSWarner Losh /*-
4091d81d1SSam Leffler  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
56810ad6fSSam Leffler  * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
6091d81d1SSam Leffler  *
7091d81d1SSam Leffler  * This code was written by Angelos D. Keromytis in Athens, Greece, in
8091d81d1SSam Leffler  * February 2000. Network Security Technologies Inc. (NSTI) kindly
9091d81d1SSam Leffler  * supported the development of this code.
10091d81d1SSam Leffler  *
11091d81d1SSam Leffler  * Copyright (c) 2000, 2001 Angelos D. Keromytis
1208fca7a5SJohn-Mark Gurney  * Copyright (c) 2014 The FreeBSD Foundation
1308fca7a5SJohn-Mark Gurney  * All rights reserved.
1408fca7a5SJohn-Mark Gurney  *
1508fca7a5SJohn-Mark Gurney  * Portions of this software were developed by John-Mark Gurney
1608fca7a5SJohn-Mark Gurney  * under sponsorship of the FreeBSD Foundation and
1708fca7a5SJohn-Mark Gurney  * Rubicon Communications, LLC (Netgate).
18091d81d1SSam Leffler  *
19091d81d1SSam Leffler  * Permission to use, copy, and modify this software with or without fee
20091d81d1SSam Leffler  * is hereby granted, provided that this entire notice is included in
21091d81d1SSam Leffler  * all source code copies of any software which is or includes a copy or
22091d81d1SSam Leffler  * modification of this software.
23091d81d1SSam Leffler  *
24091d81d1SSam Leffler  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
25091d81d1SSam Leffler  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
26091d81d1SSam Leffler  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
27091d81d1SSam Leffler  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
28091d81d1SSam Leffler  * PURPOSE.
29091d81d1SSam Leffler  */
30091d81d1SSam Leffler 
312c446514SDavid E. O'Brien #include <sys/cdefs.h>
322c446514SDavid E. O'Brien __FBSDID("$FreeBSD$");
332c446514SDavid E. O'Brien 
34091d81d1SSam Leffler #include <sys/param.h>
35091d81d1SSam Leffler #include <sys/systm.h>
36091d81d1SSam Leffler #include <sys/malloc.h>
37091d81d1SSam Leffler #include <sys/mbuf.h>
386810ad6fSSam Leffler #include <sys/module.h>
39091d81d1SSam Leffler #include <sys/sysctl.h>
40091d81d1SSam Leffler #include <sys/errno.h>
41091d81d1SSam Leffler #include <sys/random.h>
42091d81d1SSam Leffler #include <sys/kernel.h>
43091d81d1SSam Leffler #include <sys/uio.h>
44109919c6SBenno Rice #include <sys/lock.h>
45109919c6SBenno Rice #include <sys/rwlock.h>
4608fca7a5SJohn-Mark Gurney #include <sys/endian.h>
4708fca7a5SJohn-Mark Gurney #include <sys/limits.h>
48a7fcb1afSSean Eric Fagan #include <sys/mutex.h>
49091d81d1SSam Leffler 
50091d81d1SSam Leffler #include <crypto/sha1.h>
51091d81d1SSam Leffler #include <opencrypto/rmd160.h>
52091d81d1SSam Leffler 
53091d81d1SSam Leffler #include <opencrypto/cryptodev.h>
54091d81d1SSam Leffler #include <opencrypto/xform.h>
55091d81d1SSam Leffler 
566810ad6fSSam Leffler #include <sys/kobj.h>
576810ad6fSSam Leffler #include <sys/bus.h>
586810ad6fSSam Leffler #include "cryptodev_if.h"
59091d81d1SSam Leffler 
60c0341432SJohn Baldwin struct swcr_auth {
61c0341432SJohn Baldwin 	void		*sw_ictx;
62c0341432SJohn Baldwin 	void		*sw_octx;
63*d8787d4fSMark Johnston 	const struct auth_hash *sw_axf;
64c0341432SJohn Baldwin 	uint16_t	sw_mlen;
65c0341432SJohn Baldwin };
66c0341432SJohn Baldwin 
67c0341432SJohn Baldwin struct swcr_encdec {
683e947048SJohn Baldwin 	void		*sw_kschedule;
69*d8787d4fSMark Johnston 	const struct enc_xform *sw_exf;
70c0341432SJohn Baldwin };
71c0341432SJohn Baldwin 
72c0341432SJohn Baldwin struct swcr_compdec {
73*d8787d4fSMark Johnston 	const struct comp_algo *sw_cxf;
74c0341432SJohn Baldwin };
75c0341432SJohn Baldwin 
76c0341432SJohn Baldwin struct swcr_session {
77c0341432SJohn Baldwin 	struct mtx	swcr_lock;
78c0341432SJohn Baldwin 	int	(*swcr_process)(struct swcr_session *, struct cryptop *);
79c0341432SJohn Baldwin 
80c0341432SJohn Baldwin 	struct swcr_auth swcr_auth;
81c0341432SJohn Baldwin 	struct swcr_encdec swcr_encdec;
82c0341432SJohn Baldwin 	struct swcr_compdec swcr_compdec;
83c0341432SJohn Baldwin };
84507281e5SSean Eric Fagan 
856810ad6fSSam Leffler static	int32_t swcr_id;
866810ad6fSSam Leffler 
871b0909d5SConrad Meyer static	void swcr_freesession(device_t dev, crypto_session_t cses);
88091d81d1SSam Leffler 
89c0341432SJohn Baldwin /* Used for CRYPTO_NULL_CBC. */
90c0341432SJohn Baldwin static int
91c0341432SJohn Baldwin swcr_null(struct swcr_session *ses, struct cryptop *crp)
92c0341432SJohn Baldwin {
93c0341432SJohn Baldwin 
94c0341432SJohn Baldwin 	return (0);
95c0341432SJohn Baldwin }
96c0341432SJohn Baldwin 
97091d81d1SSam Leffler /*
98091d81d1SSam Leffler  * Apply a symmetric encryption/decryption algorithm.
99091d81d1SSam Leffler  */
100091d81d1SSam Leffler static int
101c0341432SJohn Baldwin swcr_encdec(struct swcr_session *ses, struct cryptop *crp)
102091d81d1SSam Leffler {
1035d7ae54aSConrad Meyer 	unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN];
10408fca7a5SJohn-Mark Gurney 	unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN];
105c0341432SJohn Baldwin 	const struct crypto_session_params *csp;
106*d8787d4fSMark Johnston 	const struct enc_xform *exf;
107c0341432SJohn Baldwin 	struct swcr_encdec *sw;
10886be314dSJohn Baldwin 	size_t inlen, outlen;
10986be314dSJohn Baldwin 	int i, blks, ivlen, resid;
1109c0e3d3aSJohn Baldwin 	struct crypto_buffer_cursor cc_in, cc_out;
11126d292d3SJohn Baldwin 	const unsigned char *inblk;
11226d292d3SJohn Baldwin 	unsigned char *outblk;
11308fca7a5SJohn-Mark Gurney 	int error;
114c0341432SJohn Baldwin 	bool encrypting;
11508fca7a5SJohn-Mark Gurney 
11608fca7a5SJohn-Mark Gurney 	error = 0;
117091d81d1SSam Leffler 
118c0341432SJohn Baldwin 	sw = &ses->swcr_encdec;
119091d81d1SSam Leffler 	exf = sw->sw_exf;
12008fca7a5SJohn-Mark Gurney 	ivlen = exf->ivsize;
121091d81d1SSam Leffler 
122723d8764SJohn Baldwin 	if (exf->native_blocksize == 0) {
123091d81d1SSam Leffler 		/* Check for non-padded data */
124723d8764SJohn Baldwin 		if ((crp->crp_payload_length % exf->blocksize) != 0)
125723d8764SJohn Baldwin 			return (EINVAL);
126723d8764SJohn Baldwin 
127723d8764SJohn Baldwin 		blks = exf->blocksize;
128723d8764SJohn Baldwin 	} else
129723d8764SJohn Baldwin 		blks = exf->native_blocksize;
130091d81d1SSam Leffler 
131c0341432SJohn Baldwin 	if (exf == &enc_xform_aes_icm &&
132c0341432SJohn Baldwin 	    (crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
13308fca7a5SJohn-Mark Gurney 		return (EINVAL);
13408fca7a5SJohn-Mark Gurney 
135c0341432SJohn Baldwin 	if (crp->crp_cipher_key != NULL) {
136c0341432SJohn Baldwin 		csp = crypto_get_params(crp->crp_session);
1373e947048SJohn Baldwin 		error = exf->setkey(sw->sw_kschedule,
138c0341432SJohn Baldwin 		    crp->crp_cipher_key, csp->csp_cipher_klen);
139c740ae4bSPoul-Henning Kamp 		if (error)
140c740ae4bSPoul-Henning Kamp 			return (error);
141c740ae4bSPoul-Henning Kamp 	}
142d295bdeeSPawel Jakub Dawidek 
14320c128daSJohn Baldwin 	crypto_read_iv(crp, iv);
14420c128daSJohn Baldwin 
14508fca7a5SJohn-Mark Gurney 	if (exf->reinit) {
146d295bdeeSPawel Jakub Dawidek 		/*
147d295bdeeSPawel Jakub Dawidek 		 * xforms that provide a reinit method perform all IV
148d295bdeeSPawel Jakub Dawidek 		 * handling themselves.
149d295bdeeSPawel Jakub Dawidek 		 */
150d295bdeeSPawel Jakub Dawidek 		exf->reinit(sw->sw_kschedule, iv);
151091d81d1SSam Leffler 	}
152091d81d1SSam Leffler 
1539c0e3d3aSJohn Baldwin 	ivp = iv;
154091d81d1SSam Leffler 
1559c0e3d3aSJohn Baldwin 	crypto_cursor_init(&cc_in, &crp->crp_buf);
1569c0e3d3aSJohn Baldwin 	crypto_cursor_advance(&cc_in, crp->crp_payload_start);
15786be314dSJohn Baldwin 	inblk = crypto_cursor_segment(&cc_in, &inlen);
1589c0e3d3aSJohn Baldwin 	if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
1599c0e3d3aSJohn Baldwin 		crypto_cursor_init(&cc_out, &crp->crp_obuf);
1609c0e3d3aSJohn Baldwin 		crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
1619c0e3d3aSJohn Baldwin 	} else
1629c0e3d3aSJohn Baldwin 		cc_out = cc_in;
16386be314dSJohn Baldwin 	outblk = crypto_cursor_segment(&cc_out, &outlen);
1649c0e3d3aSJohn Baldwin 
1659c0e3d3aSJohn Baldwin 	resid = crp->crp_payload_length;
166c0341432SJohn Baldwin 	encrypting = CRYPTO_OP_IS_ENCRYPT(crp->crp_op);
167091d81d1SSam Leffler 
168091d81d1SSam Leffler 	/*
1699c0e3d3aSJohn Baldwin 	 * Loop through encrypting blocks.  'inlen' is the remaining
1709c0e3d3aSJohn Baldwin 	 * length of the current segment in the input buffer.
1719c0e3d3aSJohn Baldwin 	 * 'outlen' is the remaining length of current segment in the
1729c0e3d3aSJohn Baldwin 	 * output buffer.
173091d81d1SSam Leffler 	 */
1749c0e3d3aSJohn Baldwin 	while (resid >= blks) {
1759c0e3d3aSJohn Baldwin 		/*
1769c0e3d3aSJohn Baldwin 		 * If the current block is not contained within the
1779c0e3d3aSJohn Baldwin 		 * current input/output segment, use 'blk' as a local
1789c0e3d3aSJohn Baldwin 		 * buffer.
1799c0e3d3aSJohn Baldwin 		 */
1809c0e3d3aSJohn Baldwin 		if (inlen < blks) {
1819c0e3d3aSJohn Baldwin 			crypto_cursor_copydata(&cc_in, blks, blk);
1829c0e3d3aSJohn Baldwin 			inblk = blk;
183d295bdeeSPawel Jakub Dawidek 		}
1849c0e3d3aSJohn Baldwin 		if (outlen < blks)
1859c0e3d3aSJohn Baldwin 			outblk = blk;
1869c0e3d3aSJohn Baldwin 
1879c0e3d3aSJohn Baldwin 		/*
1889c0e3d3aSJohn Baldwin 		 * Ciphers without a 'reinit' hook are assumed to be
1899c0e3d3aSJohn Baldwin 		 * used in CBC mode where the chaining is done here.
1909c0e3d3aSJohn Baldwin 		 */
1919c0e3d3aSJohn Baldwin 		if (exf->reinit != NULL) {
1929c0e3d3aSJohn Baldwin 			if (encrypting)
1939c0e3d3aSJohn Baldwin 				exf->encrypt(sw->sw_kschedule, inblk, outblk);
1949c0e3d3aSJohn Baldwin 			else
1959c0e3d3aSJohn Baldwin 				exf->decrypt(sw->sw_kschedule, inblk, outblk);
196c0341432SJohn Baldwin 		} else if (encrypting) {
197091d81d1SSam Leffler 			/* XOR with previous block */
1989c0e3d3aSJohn Baldwin 			for (i = 0; i < blks; i++)
1999c0e3d3aSJohn Baldwin 				outblk[i] = inblk[i] ^ ivp[i];
200091d81d1SSam Leffler 
2019c0e3d3aSJohn Baldwin 			exf->encrypt(sw->sw_kschedule, outblk, outblk);
202091d81d1SSam Leffler 
203091d81d1SSam Leffler 			/*
204091d81d1SSam Leffler 			 * Keep encrypted block for XOR'ing
205091d81d1SSam Leffler 			 * with next block
206091d81d1SSam Leffler 			 */
2079c0e3d3aSJohn Baldwin 			memcpy(iv, outblk, blks);
208091d81d1SSam Leffler 			ivp = iv;
209091d81d1SSam Leffler 		} else {	/* decrypt */
210091d81d1SSam Leffler 			/*
211091d81d1SSam Leffler 			 * Keep encrypted block for XOR'ing
212091d81d1SSam Leffler 			 * with next block
213091d81d1SSam Leffler 			 */
21408fca7a5SJohn-Mark Gurney 			nivp = (ivp == iv) ? iv2 : iv;
2159c0e3d3aSJohn Baldwin 			memcpy(nivp, inblk, blks);
216091d81d1SSam Leffler 
2179c0e3d3aSJohn Baldwin 			exf->decrypt(sw->sw_kschedule, inblk, outblk);
218091d81d1SSam Leffler 
219091d81d1SSam Leffler 			/* XOR with previous block */
2209c0e3d3aSJohn Baldwin 			for (i = 0; i < blks; i++)
2219c0e3d3aSJohn Baldwin 				outblk[i] ^= ivp[i];
222091d81d1SSam Leffler 
22308fca7a5SJohn-Mark Gurney 			ivp = nivp;
224091d81d1SSam Leffler 		}
225091d81d1SSam Leffler 
2269c0e3d3aSJohn Baldwin 		if (inlen < blks) {
22786be314dSJohn Baldwin 			inblk = crypto_cursor_segment(&cc_in, &inlen);
2289c0e3d3aSJohn Baldwin 		} else {
2299c0e3d3aSJohn Baldwin 			crypto_cursor_advance(&cc_in, blks);
2309c0e3d3aSJohn Baldwin 			inlen -= blks;
2319c0e3d3aSJohn Baldwin 			inblk += blks;
23208fca7a5SJohn-Mark Gurney 		}
233091d81d1SSam Leffler 
2349c0e3d3aSJohn Baldwin 		if (outlen < blks) {
2359c0e3d3aSJohn Baldwin 			crypto_cursor_copyback(&cc_out, blks, blk);
23686be314dSJohn Baldwin 			outblk = crypto_cursor_segment(&cc_out, &outlen);
2379c0e3d3aSJohn Baldwin 		} else {
2389c0e3d3aSJohn Baldwin 			crypto_cursor_advance(&cc_out, blks);
2399c0e3d3aSJohn Baldwin 			outlen -= blks;
2409c0e3d3aSJohn Baldwin 			outblk += blks;
241091d81d1SSam Leffler 		}
242091d81d1SSam Leffler 
2439c0e3d3aSJohn Baldwin 		resid -= blks;
244f34a967bSPawel Jakub Dawidek 	}
245f34a967bSPawel Jakub Dawidek 
246723d8764SJohn Baldwin 	/* Handle trailing partial block for stream ciphers. */
2479c0e3d3aSJohn Baldwin 	if (resid > 0) {
248723d8764SJohn Baldwin 		KASSERT(exf->native_blocksize != 0,
249723d8764SJohn Baldwin 		    ("%s: partial block of %d bytes for cipher %s",
250723d8764SJohn Baldwin 		    __func__, i, exf->name));
251723d8764SJohn Baldwin 		KASSERT(exf->reinit != NULL,
252723d8764SJohn Baldwin 		    ("%s: partial block cipher %s without reinit hook",
253723d8764SJohn Baldwin 		    __func__, exf->name));
2549c0e3d3aSJohn Baldwin 		KASSERT(resid < blks, ("%s: partial block too big", __func__));
255723d8764SJohn Baldwin 
25686be314dSJohn Baldwin 		inblk = crypto_cursor_segment(&cc_in, &inlen);
25786be314dSJohn Baldwin 		outblk = crypto_cursor_segment(&cc_out, &outlen);
2589c0e3d3aSJohn Baldwin 		if (inlen < resid) {
2599c0e3d3aSJohn Baldwin 			crypto_cursor_copydata(&cc_in, resid, blk);
2609c0e3d3aSJohn Baldwin 			inblk = blk;
26186be314dSJohn Baldwin 		}
2629c0e3d3aSJohn Baldwin 		if (outlen < resid)
2639c0e3d3aSJohn Baldwin 			outblk = blk;
2649c0e3d3aSJohn Baldwin 		if (encrypting)
2659c0e3d3aSJohn Baldwin 			exf->encrypt_last(sw->sw_kschedule, inblk, outblk,
2669c0e3d3aSJohn Baldwin 			    resid);
2679c0e3d3aSJohn Baldwin 		else
2689c0e3d3aSJohn Baldwin 			exf->decrypt_last(sw->sw_kschedule, inblk, outblk,
2699c0e3d3aSJohn Baldwin 			    resid);
2709c0e3d3aSJohn Baldwin 		if (outlen < resid)
2719c0e3d3aSJohn Baldwin 			crypto_cursor_copyback(&cc_out, resid, blk);
272723d8764SJohn Baldwin 	}
273723d8764SJohn Baldwin 
27420c128daSJohn Baldwin 	explicit_bzero(blk, sizeof(blk));
27520c128daSJohn Baldwin 	explicit_bzero(iv, sizeof(iv));
27620c128daSJohn Baldwin 	explicit_bzero(iv2, sizeof(iv2));
2779c0e3d3aSJohn Baldwin 	return (0);
278091d81d1SSam Leffler }
279091d81d1SSam Leffler 
280c0341432SJohn Baldwin static void
281*d8787d4fSMark Johnston swcr_authprepare(const struct auth_hash *axf, struct swcr_auth *sw,
282c0341432SJohn Baldwin     const uint8_t *key, int klen)
283f6c4bc3bSPawel Jakub Dawidek {
284f6c4bc3bSPawel Jakub Dawidek 
285f6c4bc3bSPawel Jakub Dawidek 	switch (axf->type) {
286f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA1_HMAC:
287c97f39ceSConrad Meyer 	case CRYPTO_SHA2_224_HMAC:
288f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_256_HMAC:
289f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_384_HMAC:
290f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_512_HMAC:
291f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_NULL_HMAC:
292f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_RIPEMD160_HMAC:
293c0341432SJohn Baldwin 		hmac_init_ipad(axf, key, klen, sw->sw_ictx);
294c0341432SJohn Baldwin 		hmac_init_opad(axf, key, klen, sw->sw_octx);
295f6c4bc3bSPawel Jakub Dawidek 		break;
29625b7033bSConrad Meyer 	case CRYPTO_POLY1305:
2970e33efe4SConrad Meyer 	case CRYPTO_BLAKE2B:
2980e33efe4SConrad Meyer 	case CRYPTO_BLAKE2S:
2990e33efe4SConrad Meyer 		axf->Setkey(sw->sw_ictx, key, klen);
3000e33efe4SConrad Meyer 		axf->Init(sw->sw_ictx);
3010e33efe4SConrad Meyer 		break;
302f6c4bc3bSPawel Jakub Dawidek 	default:
303c0341432SJohn Baldwin 		panic("%s: algorithm %d doesn't use keys", __func__, axf->type);
304f6c4bc3bSPawel Jakub Dawidek 	}
305f6c4bc3bSPawel Jakub Dawidek }
306f6c4bc3bSPawel Jakub Dawidek 
307091d81d1SSam Leffler /*
308c0341432SJohn Baldwin  * Compute or verify hash.
309091d81d1SSam Leffler  */
310091d81d1SSam Leffler static int
311c0341432SJohn Baldwin swcr_authcompute(struct swcr_session *ses, struct cryptop *crp)
312091d81d1SSam Leffler {
313c0341432SJohn Baldwin 	u_char aalg[HASH_MAX_LEN];
314c0341432SJohn Baldwin 	const struct crypto_session_params *csp;
315c0341432SJohn Baldwin 	struct swcr_auth *sw;
316*d8787d4fSMark Johnston 	const struct auth_hash *axf;
317091d81d1SSam Leffler 	union authctx ctx;
318091d81d1SSam Leffler 	int err;
319091d81d1SSam Leffler 
320c0341432SJohn Baldwin 	sw = &ses->swcr_auth;
321091d81d1SSam Leffler 
322091d81d1SSam Leffler 	axf = sw->sw_axf;
323091d81d1SSam Leffler 
324c0341432SJohn Baldwin 	csp = crypto_get_params(crp->crp_session);
3256038018aSMarcin Wojtas 	if (crp->crp_auth_key != NULL) {
326c0341432SJohn Baldwin 		swcr_authprepare(axf, sw, crp->crp_auth_key,
327c0341432SJohn Baldwin 		    csp->csp_auth_klen);
32825b7033bSConrad Meyer 	}
329f6c4bc3bSPawel Jakub Dawidek 
330091d81d1SSam Leffler 	bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
331091d81d1SSam Leffler 
3329b774dc0SJohn Baldwin 	if (crp->crp_aad != NULL)
3339b774dc0SJohn Baldwin 		err = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
3349b774dc0SJohn Baldwin 	else
335c0341432SJohn Baldwin 		err = crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length,
3369b6b2f86SJohn Baldwin 		    axf->Update, &ctx);
337091d81d1SSam Leffler 	if (err)
338e0b155feSJohn Baldwin 		goto out;
339091d81d1SSam Leffler 
3409c0e3d3aSJohn Baldwin 	if (CRYPTO_HAS_OUTPUT_BUFFER(crp) &&
3419c0e3d3aSJohn Baldwin 	    CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
3429c0e3d3aSJohn Baldwin 		err = crypto_apply_buf(&crp->crp_obuf,
3439c0e3d3aSJohn Baldwin 		    crp->crp_payload_output_start, crp->crp_payload_length,
3449b6b2f86SJohn Baldwin 		    axf->Update, &ctx);
3459c0e3d3aSJohn Baldwin 	else
3469c0e3d3aSJohn Baldwin 		err = crypto_apply(crp, crp->crp_payload_start,
3479b6b2f86SJohn Baldwin 		    crp->crp_payload_length, axf->Update, &ctx);
348c0341432SJohn Baldwin 	if (err)
349e0b155feSJohn Baldwin 		goto out;
350091d81d1SSam Leffler 
3516038018aSMarcin Wojtas 	if (csp->csp_flags & CSP_F_ESN)
3526038018aSMarcin Wojtas 		axf->Update(&ctx, crp->crp_esn, 4);
3536038018aSMarcin Wojtas 
354091d81d1SSam Leffler 	axf->Final(aalg, &ctx);
355e0b155feSJohn Baldwin 	if (sw->sw_octx != NULL) {
356091d81d1SSam Leffler 		bcopy(sw->sw_octx, &ctx, axf->ctxsize);
357091d81d1SSam Leffler 		axf->Update(&ctx, aalg, axf->hashsize);
358091d81d1SSam Leffler 		axf->Final(aalg, &ctx);
359091d81d1SSam Leffler 	}
360091d81d1SSam Leffler 
361c0341432SJohn Baldwin 	if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
36220c128daSJohn Baldwin 		u_char uaalg[HASH_MAX_LEN];
36320c128daSJohn Baldwin 
364c0341432SJohn Baldwin 		crypto_copydata(crp, crp->crp_digest_start, sw->sw_mlen, uaalg);
365c0341432SJohn Baldwin 		if (timingsafe_bcmp(aalg, uaalg, sw->sw_mlen) != 0)
36620c128daSJohn Baldwin 			err = EBADMSG;
36720c128daSJohn Baldwin 		explicit_bzero(uaalg, sizeof(uaalg));
368c0341432SJohn Baldwin 	} else {
369091d81d1SSam Leffler 		/* Inject the authentication data */
370c0341432SJohn Baldwin 		crypto_copyback(crp, crp->crp_digest_start, sw->sw_mlen, aalg);
371c0341432SJohn Baldwin 	}
37220c128daSJohn Baldwin 	explicit_bzero(aalg, sizeof(aalg));
373e0b155feSJohn Baldwin out:
374e0b155feSJohn Baldwin 	explicit_bzero(&ctx, sizeof(ctx));
37520c128daSJohn Baldwin 	return (err);
376091d81d1SSam Leffler }
377091d81d1SSam Leffler 
37808fca7a5SJohn-Mark Gurney CTASSERT(INT_MAX <= (1ll<<39) - 256);	/* GCM: plain text < 2^39-256 */
37908fca7a5SJohn-Mark Gurney CTASSERT(INT_MAX <= (uint64_t)-1);	/* GCM: associated data <= 2^64-1 */
38008fca7a5SJohn-Mark Gurney 
38108fca7a5SJohn-Mark Gurney static int
382c0341432SJohn Baldwin swcr_gmac(struct swcr_session *ses, struct cryptop *crp)
38308fca7a5SJohn-Mark Gurney {
38426d292d3SJohn Baldwin 	uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))];
38508fca7a5SJohn-Mark Gurney 	u_char *blk = (u_char *)blkbuf;
38626d292d3SJohn Baldwin 	u_char tag[GMAC_DIGEST_LEN];
38726d292d3SJohn Baldwin 	u_char iv[AES_BLOCK_LEN];
3889c0e3d3aSJohn Baldwin 	struct crypto_buffer_cursor cc;
38926d292d3SJohn Baldwin 	const u_char *inblk;
39008fca7a5SJohn-Mark Gurney 	union authctx ctx;
391c0341432SJohn Baldwin 	struct swcr_auth *swa;
392*d8787d4fSMark Johnston 	const struct auth_hash *axf;
39308fca7a5SJohn-Mark Gurney 	uint32_t *blkp;
39486be314dSJohn Baldwin 	size_t len;
39586be314dSJohn Baldwin 	int blksz, error, ivlen, resid;
39608fca7a5SJohn-Mark Gurney 
397c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
39808fca7a5SJohn-Mark Gurney 	axf = swa->sw_axf;
399c0341432SJohn Baldwin 
40008fca7a5SJohn-Mark Gurney 	bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
40126d292d3SJohn Baldwin 	blksz = GMAC_BLOCK_LEN;
40226d292d3SJohn Baldwin 	KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch",
40326d292d3SJohn Baldwin 	    __func__));
40408fca7a5SJohn-Mark Gurney 
40508fca7a5SJohn-Mark Gurney 	/* Initialize the IV */
406c0341432SJohn Baldwin 	ivlen = AES_GCM_IV_LEN;
40729fe41ddSJohn Baldwin 	crypto_read_iv(crp, iv);
40808fca7a5SJohn-Mark Gurney 
40908fca7a5SJohn-Mark Gurney 	axf->Reinit(&ctx, iv, ivlen);
4109c0e3d3aSJohn Baldwin 	crypto_cursor_init(&cc, &crp->crp_buf);
4119c0e3d3aSJohn Baldwin 	crypto_cursor_advance(&cc, crp->crp_payload_start);
41226d292d3SJohn Baldwin 	for (resid = crp->crp_payload_length; resid >= blksz; resid -= len) {
41386be314dSJohn Baldwin 		inblk = crypto_cursor_segment(&cc, &len);
41426d292d3SJohn Baldwin 		if (len >= blksz) {
41526d292d3SJohn Baldwin 			len = rounddown(MIN(len, resid), blksz);
41626d292d3SJohn Baldwin 			crypto_cursor_advance(&cc, len);
41726d292d3SJohn Baldwin 		} else {
41826d292d3SJohn Baldwin 			len = blksz;
4199c0e3d3aSJohn Baldwin 			crypto_cursor_copydata(&cc, len, blk);
42026d292d3SJohn Baldwin 			inblk = blk;
42126d292d3SJohn Baldwin 		}
42226d292d3SJohn Baldwin 		axf->Update(&ctx, inblk, len);
42326d292d3SJohn Baldwin 	}
42426d292d3SJohn Baldwin 	if (resid > 0) {
42526d292d3SJohn Baldwin 		memset(blk, 0, blksz);
42626d292d3SJohn Baldwin 		crypto_cursor_copydata(&cc, resid, blk);
42708fca7a5SJohn-Mark Gurney 		axf->Update(&ctx, blk, blksz);
42808fca7a5SJohn-Mark Gurney 	}
42908fca7a5SJohn-Mark Gurney 
43008fca7a5SJohn-Mark Gurney 	/* length block */
43126d292d3SJohn Baldwin 	memset(blk, 0, blksz);
43208fca7a5SJohn-Mark Gurney 	blkp = (uint32_t *)blk + 1;
433c0341432SJohn Baldwin 	*blkp = htobe32(crp->crp_payload_length * 8);
43408fca7a5SJohn-Mark Gurney 	axf->Update(&ctx, blk, blksz);
435c0341432SJohn Baldwin 
436c0341432SJohn Baldwin 	/* Finalize MAC */
43726d292d3SJohn Baldwin 	axf->Final(tag, &ctx);
438c0341432SJohn Baldwin 
43920c128daSJohn Baldwin 	error = 0;
440c0341432SJohn Baldwin 	if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
44126d292d3SJohn Baldwin 		u_char tag2[GMAC_DIGEST_LEN];
44220c128daSJohn Baldwin 
443c0341432SJohn Baldwin 		crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen,
44426d292d3SJohn Baldwin 		    tag2);
44526d292d3SJohn Baldwin 		if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0)
44620c128daSJohn Baldwin 			error = EBADMSG;
44726d292d3SJohn Baldwin 		explicit_bzero(tag2, sizeof(tag2));
448c0341432SJohn Baldwin 	} else {
449c0341432SJohn Baldwin 		/* Inject the authentication data */
45026d292d3SJohn Baldwin 		crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
451c0341432SJohn Baldwin 	}
45220c128daSJohn Baldwin 	explicit_bzero(blkbuf, sizeof(blkbuf));
45326d292d3SJohn Baldwin 	explicit_bzero(tag, sizeof(tag));
45420c128daSJohn Baldwin 	explicit_bzero(iv, sizeof(iv));
45520c128daSJohn Baldwin 	return (error);
456c0341432SJohn Baldwin }
457c0341432SJohn Baldwin 
458c0341432SJohn Baldwin static int
459c0341432SJohn Baldwin swcr_gcm(struct swcr_session *ses, struct cryptop *crp)
460c0341432SJohn Baldwin {
46126d292d3SJohn Baldwin 	uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))];
462c0341432SJohn Baldwin 	u_char *blk = (u_char *)blkbuf;
46326d292d3SJohn Baldwin 	u_char tag[GMAC_DIGEST_LEN];
46426d292d3SJohn Baldwin 	u_char iv[AES_BLOCK_LEN];
4659c0e3d3aSJohn Baldwin 	struct crypto_buffer_cursor cc_in, cc_out;
46626d292d3SJohn Baldwin 	const u_char *inblk;
46726d292d3SJohn Baldwin 	u_char *outblk;
468c0341432SJohn Baldwin 	union authctx ctx;
469c0341432SJohn Baldwin 	struct swcr_auth *swa;
470c0341432SJohn Baldwin 	struct swcr_encdec *swe;
471*d8787d4fSMark Johnston 	const struct auth_hash *axf;
472*d8787d4fSMark Johnston 	const struct enc_xform *exf;
473c0341432SJohn Baldwin 	uint32_t *blkp;
47486be314dSJohn Baldwin 	size_t len;
47586be314dSJohn Baldwin 	int blksz, error, ivlen, r, resid;
476c0341432SJohn Baldwin 
477c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
478c0341432SJohn Baldwin 	axf = swa->sw_axf;
479c0341432SJohn Baldwin 
480c0341432SJohn Baldwin 	bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
48126d292d3SJohn Baldwin 	blksz = GMAC_BLOCK_LEN;
48226d292d3SJohn Baldwin 	KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch",
48326d292d3SJohn Baldwin 	    __func__));
484c0341432SJohn Baldwin 
485c0341432SJohn Baldwin 	swe = &ses->swcr_encdec;
486c0341432SJohn Baldwin 	exf = swe->sw_exf;
487723d8764SJohn Baldwin 	KASSERT(axf->blocksize == exf->native_blocksize,
488723d8764SJohn Baldwin 	    ("%s: blocksize mismatch", __func__));
489c0341432SJohn Baldwin 
490c0341432SJohn Baldwin 	if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
491c0341432SJohn Baldwin 		return (EINVAL);
492c0341432SJohn Baldwin 
493c0341432SJohn Baldwin 	/* Initialize the IV */
494c0341432SJohn Baldwin 	ivlen = AES_GCM_IV_LEN;
495c0341432SJohn Baldwin 	bcopy(crp->crp_iv, iv, ivlen);
496c0341432SJohn Baldwin 
497c0341432SJohn Baldwin 	/* Supply MAC with IV */
498c0341432SJohn Baldwin 	axf->Reinit(&ctx, iv, ivlen);
499c0341432SJohn Baldwin 
500c0341432SJohn Baldwin 	/* Supply MAC with AAD */
5019b774dc0SJohn Baldwin 	if (crp->crp_aad != NULL) {
5029b774dc0SJohn Baldwin 		len = rounddown(crp->crp_aad_length, blksz);
5039b774dc0SJohn Baldwin 		if (len != 0)
5049b774dc0SJohn Baldwin 			axf->Update(&ctx, crp->crp_aad, len);
5059b774dc0SJohn Baldwin 		if (crp->crp_aad_length != len) {
5069b774dc0SJohn Baldwin 			memset(blk, 0, blksz);
5079b774dc0SJohn Baldwin 			memcpy(blk, (char *)crp->crp_aad + len,
5089b774dc0SJohn Baldwin 			    crp->crp_aad_length - len);
5099b774dc0SJohn Baldwin 			axf->Update(&ctx, blk, blksz);
5109b774dc0SJohn Baldwin 		}
5119b774dc0SJohn Baldwin 	} else {
5129c0e3d3aSJohn Baldwin 		crypto_cursor_init(&cc_in, &crp->crp_buf);
5139c0e3d3aSJohn Baldwin 		crypto_cursor_advance(&cc_in, crp->crp_aad_start);
5149b774dc0SJohn Baldwin 		for (resid = crp->crp_aad_length; resid >= blksz;
5159b774dc0SJohn Baldwin 		     resid -= len) {
51686be314dSJohn Baldwin 			inblk = crypto_cursor_segment(&cc_in, &len);
51726d292d3SJohn Baldwin 			if (len >= blksz) {
51826d292d3SJohn Baldwin 				len = rounddown(MIN(len, resid), blksz);
51926d292d3SJohn Baldwin 				crypto_cursor_advance(&cc_in, len);
52026d292d3SJohn Baldwin 			} else {
52126d292d3SJohn Baldwin 				len = blksz;
5229c0e3d3aSJohn Baldwin 				crypto_cursor_copydata(&cc_in, len, blk);
52326d292d3SJohn Baldwin 				inblk = blk;
52426d292d3SJohn Baldwin 			}
52526d292d3SJohn Baldwin 			axf->Update(&ctx, inblk, len);
52626d292d3SJohn Baldwin 		}
52726d292d3SJohn Baldwin 		if (resid > 0) {
52826d292d3SJohn Baldwin 			memset(blk, 0, blksz);
52926d292d3SJohn Baldwin 			crypto_cursor_copydata(&cc_in, resid, blk);
530c0341432SJohn Baldwin 			axf->Update(&ctx, blk, blksz);
531c0341432SJohn Baldwin 		}
5329b774dc0SJohn Baldwin 	}
533c0341432SJohn Baldwin 
534a10020cfSJohn Baldwin 	if (crp->crp_cipher_key != NULL)
535a10020cfSJohn Baldwin 		exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
536a10020cfSJohn Baldwin 		    crypto_get_params(crp->crp_session)->csp_cipher_klen);
537c0341432SJohn Baldwin 	exf->reinit(swe->sw_kschedule, iv);
538c0341432SJohn Baldwin 
539c0341432SJohn Baldwin 	/* Do encryption with MAC */
5409c0e3d3aSJohn Baldwin 	crypto_cursor_init(&cc_in, &crp->crp_buf);
5419c0e3d3aSJohn Baldwin 	crypto_cursor_advance(&cc_in, crp->crp_payload_start);
5429c0e3d3aSJohn Baldwin 	if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
5439c0e3d3aSJohn Baldwin 		crypto_cursor_init(&cc_out, &crp->crp_obuf);
5449c0e3d3aSJohn Baldwin 		crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
5459c0e3d3aSJohn Baldwin 	} else
5469c0e3d3aSJohn Baldwin 		cc_out = cc_in;
54726d292d3SJohn Baldwin 	for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) {
54886be314dSJohn Baldwin 		inblk = crypto_cursor_segment(&cc_in, &len);
54986be314dSJohn Baldwin 		if (len < blksz) {
55026d292d3SJohn Baldwin 			crypto_cursor_copydata(&cc_in, blksz, blk);
55126d292d3SJohn Baldwin 			inblk = blk;
552c0341432SJohn Baldwin 		} else {
55326d292d3SJohn Baldwin 			crypto_cursor_advance(&cc_in, blksz);
554c0341432SJohn Baldwin 		}
55526d292d3SJohn Baldwin 		if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
55686be314dSJohn Baldwin 			outblk = crypto_cursor_segment(&cc_out, &len);
55786be314dSJohn Baldwin 			if (len < blksz)
55826d292d3SJohn Baldwin 				outblk = blk;
55926d292d3SJohn Baldwin 			exf->encrypt(swe->sw_kschedule, inblk, outblk);
56026d292d3SJohn Baldwin 			axf->Update(&ctx, outblk, blksz);
56126d292d3SJohn Baldwin 			if (outblk == blk)
56226d292d3SJohn Baldwin 				crypto_cursor_copyback(&cc_out, blksz, blk);
56326d292d3SJohn Baldwin 			else
56426d292d3SJohn Baldwin 				crypto_cursor_advance(&cc_out, blksz);
56526d292d3SJohn Baldwin 		} else {
56626d292d3SJohn Baldwin 			axf->Update(&ctx, inblk, blksz);
56726d292d3SJohn Baldwin 		}
56826d292d3SJohn Baldwin 	}
56926d292d3SJohn Baldwin 	if (resid > 0) {
57026d292d3SJohn Baldwin 		crypto_cursor_copydata(&cc_in, resid, blk);
57126d292d3SJohn Baldwin 		if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
57226d292d3SJohn Baldwin 			exf->encrypt_last(swe->sw_kschedule, blk, blk, resid);
57326d292d3SJohn Baldwin 			crypto_cursor_copyback(&cc_out, resid, blk);
57426d292d3SJohn Baldwin 		}
57526d292d3SJohn Baldwin 		axf->Update(&ctx, blk, resid);
576c0341432SJohn Baldwin 	}
577c0341432SJohn Baldwin 
578c0341432SJohn Baldwin 	/* length block */
57926d292d3SJohn Baldwin 	memset(blk, 0, blksz);
580c0341432SJohn Baldwin 	blkp = (uint32_t *)blk + 1;
581c0341432SJohn Baldwin 	*blkp = htobe32(crp->crp_aad_length * 8);
582c0341432SJohn Baldwin 	blkp = (uint32_t *)blk + 3;
583c0341432SJohn Baldwin 	*blkp = htobe32(crp->crp_payload_length * 8);
584c0341432SJohn Baldwin 	axf->Update(&ctx, blk, blksz);
585c0341432SJohn Baldwin 
586c0341432SJohn Baldwin 	/* Finalize MAC */
58726d292d3SJohn Baldwin 	axf->Final(tag, &ctx);
588c0341432SJohn Baldwin 
589c0341432SJohn Baldwin 	/* Validate tag */
59020c128daSJohn Baldwin 	error = 0;
591c0341432SJohn Baldwin 	if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
59226d292d3SJohn Baldwin 		u_char tag2[GMAC_DIGEST_LEN];
59320c128daSJohn Baldwin 
59426d292d3SJohn Baldwin 		crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2);
595c0341432SJohn Baldwin 
59626d292d3SJohn Baldwin 		r = timingsafe_bcmp(tag, tag2, swa->sw_mlen);
59726d292d3SJohn Baldwin 		explicit_bzero(tag2, sizeof(tag2));
59820c128daSJohn Baldwin 		if (r != 0) {
59920c128daSJohn Baldwin 			error = EBADMSG;
60020c128daSJohn Baldwin 			goto out;
60120c128daSJohn Baldwin 		}
602c0341432SJohn Baldwin 
603c0341432SJohn Baldwin 		/* tag matches, decrypt data */
6049c0e3d3aSJohn Baldwin 		crypto_cursor_init(&cc_in, &crp->crp_buf);
6059c0e3d3aSJohn Baldwin 		crypto_cursor_advance(&cc_in, crp->crp_payload_start);
60626d292d3SJohn Baldwin 		for (resid = crp->crp_payload_length; resid > blksz;
60726d292d3SJohn Baldwin 		     resid -= blksz) {
60886be314dSJohn Baldwin 			inblk = crypto_cursor_segment(&cc_in, &len);
60986be314dSJohn Baldwin 			if (len < blksz) {
61026d292d3SJohn Baldwin 				crypto_cursor_copydata(&cc_in, blksz, blk);
61126d292d3SJohn Baldwin 				inblk = blk;
61286be314dSJohn Baldwin 			} else
61326d292d3SJohn Baldwin 				crypto_cursor_advance(&cc_in, blksz);
61486be314dSJohn Baldwin 			outblk = crypto_cursor_segment(&cc_out, &len);
61586be314dSJohn Baldwin 			if (len < blksz)
61626d292d3SJohn Baldwin 				outblk = blk;
61726d292d3SJohn Baldwin 			exf->decrypt(swe->sw_kschedule, inblk, outblk);
61826d292d3SJohn Baldwin 			if (outblk == blk)
61926d292d3SJohn Baldwin 				crypto_cursor_copyback(&cc_out, blksz, blk);
62026d292d3SJohn Baldwin 			else
62126d292d3SJohn Baldwin 				crypto_cursor_advance(&cc_out, blksz);
62226d292d3SJohn Baldwin 		}
62326d292d3SJohn Baldwin 		if (resid > 0) {
62426d292d3SJohn Baldwin 			crypto_cursor_copydata(&cc_in, resid, blk);
62526d292d3SJohn Baldwin 			exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
62626d292d3SJohn Baldwin 			crypto_cursor_copyback(&cc_out, resid, blk);
627c0341432SJohn Baldwin 		}
628c0341432SJohn Baldwin 	} else {
629c0341432SJohn Baldwin 		/* Inject the authentication data */
63026d292d3SJohn Baldwin 		crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
631c0341432SJohn Baldwin 	}
632c0341432SJohn Baldwin 
63320c128daSJohn Baldwin out:
63420c128daSJohn Baldwin 	explicit_bzero(blkbuf, sizeof(blkbuf));
63526d292d3SJohn Baldwin 	explicit_bzero(tag, sizeof(tag));
63620c128daSJohn Baldwin 	explicit_bzero(iv, sizeof(iv));
63720c128daSJohn Baldwin 
63820c128daSJohn Baldwin 	return (error);
639c0341432SJohn Baldwin }
640c0341432SJohn Baldwin 
641c0341432SJohn Baldwin static int
642c0341432SJohn Baldwin swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp)
643c0341432SJohn Baldwin {
64426d292d3SJohn Baldwin 	u_char tag[AES_CBC_MAC_HASH_LEN];
64526d292d3SJohn Baldwin 	u_char iv[AES_BLOCK_LEN];
646c0341432SJohn Baldwin 	union authctx ctx;
647c0341432SJohn Baldwin 	struct swcr_auth *swa;
648*d8787d4fSMark Johnston 	const struct auth_hash *axf;
64926d292d3SJohn Baldwin 	int error, ivlen;
650c0341432SJohn Baldwin 
651c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
652c0341432SJohn Baldwin 	axf = swa->sw_axf;
653c0341432SJohn Baldwin 
654c0341432SJohn Baldwin 	bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
655c0341432SJohn Baldwin 
656c0341432SJohn Baldwin 	/* Initialize the IV */
657c0341432SJohn Baldwin 	ivlen = AES_CCM_IV_LEN;
65829fe41ddSJohn Baldwin 	crypto_read_iv(crp, iv);
659c0341432SJohn Baldwin 
660c0341432SJohn Baldwin 	/*
661c0341432SJohn Baldwin 	 * AES CCM-CBC-MAC needs to know the length of both the auth
662c0341432SJohn Baldwin 	 * data and payload data before doing the auth computation.
663c0341432SJohn Baldwin 	 */
664c0341432SJohn Baldwin 	ctx.aes_cbc_mac_ctx.authDataLength = crp->crp_payload_length;
665c0341432SJohn Baldwin 	ctx.aes_cbc_mac_ctx.cryptDataLength = 0;
666c0341432SJohn Baldwin 
667c0341432SJohn Baldwin 	axf->Reinit(&ctx, iv, ivlen);
6689b774dc0SJohn Baldwin 	if (crp->crp_aad != NULL)
6699b774dc0SJohn Baldwin 		error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
6709b774dc0SJohn Baldwin 	else
67126d292d3SJohn Baldwin 		error = crypto_apply(crp, crp->crp_payload_start,
67226d292d3SJohn Baldwin 		    crp->crp_payload_length, axf->Update, &ctx);
67326d292d3SJohn Baldwin 	if (error)
67426d292d3SJohn Baldwin 		return (error);
675c0341432SJohn Baldwin 
676c0341432SJohn Baldwin 	/* Finalize MAC */
67726d292d3SJohn Baldwin 	axf->Final(tag, &ctx);
678c0341432SJohn Baldwin 
679c0341432SJohn Baldwin 	if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
68026d292d3SJohn Baldwin 		u_char tag2[AES_CBC_MAC_HASH_LEN];
68120c128daSJohn Baldwin 
682c0341432SJohn Baldwin 		crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen,
68326d292d3SJohn Baldwin 		    tag2);
68426d292d3SJohn Baldwin 		if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0)
68520c128daSJohn Baldwin 			error = EBADMSG;
68626d292d3SJohn Baldwin 		explicit_bzero(tag2, sizeof(tag));
687c0341432SJohn Baldwin 	} else {
688c0341432SJohn Baldwin 		/* Inject the authentication data */
68926d292d3SJohn Baldwin 		crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
690c0341432SJohn Baldwin 	}
69126d292d3SJohn Baldwin 	explicit_bzero(tag, sizeof(tag));
69220c128daSJohn Baldwin 	explicit_bzero(iv, sizeof(iv));
69320c128daSJohn Baldwin 	return (error);
694c0341432SJohn Baldwin }
695c0341432SJohn Baldwin 
696c0341432SJohn Baldwin static int
697c0341432SJohn Baldwin swcr_ccm(struct swcr_session *ses, struct cryptop *crp)
698c0341432SJohn Baldwin {
69926d292d3SJohn Baldwin 	uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))];
700c0341432SJohn Baldwin 	u_char *blk = (u_char *)blkbuf;
70126d292d3SJohn Baldwin 	u_char tag[AES_CBC_MAC_HASH_LEN];
70226d292d3SJohn Baldwin 	u_char iv[AES_BLOCK_LEN];
7039c0e3d3aSJohn Baldwin 	struct crypto_buffer_cursor cc_in, cc_out;
70426d292d3SJohn Baldwin 	const u_char *inblk;
70526d292d3SJohn Baldwin 	u_char *outblk;
706c0341432SJohn Baldwin 	union authctx ctx;
707c0341432SJohn Baldwin 	struct swcr_auth *swa;
708c0341432SJohn Baldwin 	struct swcr_encdec *swe;
709*d8787d4fSMark Johnston 	const struct auth_hash *axf;
710*d8787d4fSMark Johnston 	const struct enc_xform *exf;
71186be314dSJohn Baldwin 	size_t len;
71226d292d3SJohn Baldwin 	int blksz, error, ivlen, r, resid;
713c0341432SJohn Baldwin 
714c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
715c0341432SJohn Baldwin 	axf = swa->sw_axf;
716c0341432SJohn Baldwin 
717c0341432SJohn Baldwin 	bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
71826d292d3SJohn Baldwin 	blksz = AES_BLOCK_LEN;
71926d292d3SJohn Baldwin 	KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch",
72026d292d3SJohn Baldwin 	    __func__));
721c0341432SJohn Baldwin 
722c0341432SJohn Baldwin 	swe = &ses->swcr_encdec;
723c0341432SJohn Baldwin 	exf = swe->sw_exf;
724723d8764SJohn Baldwin 	KASSERT(axf->blocksize == exf->native_blocksize,
725723d8764SJohn Baldwin 	    ("%s: blocksize mismatch", __func__));
726c0341432SJohn Baldwin 
727c0341432SJohn Baldwin 	if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
728c0341432SJohn Baldwin 		return (EINVAL);
729c0341432SJohn Baldwin 
730c0341432SJohn Baldwin 	/* Initialize the IV */
731c0341432SJohn Baldwin 	ivlen = AES_CCM_IV_LEN;
732c0341432SJohn Baldwin 	bcopy(crp->crp_iv, iv, ivlen);
733c0341432SJohn Baldwin 
734c0341432SJohn Baldwin 	/*
735c0341432SJohn Baldwin 	 * AES CCM-CBC-MAC needs to know the length of both the auth
736c0341432SJohn Baldwin 	 * data and payload data before doing the auth computation.
737c0341432SJohn Baldwin 	 */
738c0341432SJohn Baldwin 	ctx.aes_cbc_mac_ctx.authDataLength = crp->crp_aad_length;
739c0341432SJohn Baldwin 	ctx.aes_cbc_mac_ctx.cryptDataLength = crp->crp_payload_length;
740c0341432SJohn Baldwin 
741c0341432SJohn Baldwin 	/* Supply MAC with IV */
742c0341432SJohn Baldwin 	axf->Reinit(&ctx, iv, ivlen);
743c0341432SJohn Baldwin 
744c0341432SJohn Baldwin 	/* Supply MAC with AAD */
7459b774dc0SJohn Baldwin 	if (crp->crp_aad != NULL)
7469b774dc0SJohn Baldwin 		error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
7479b774dc0SJohn Baldwin 	else
7489b774dc0SJohn Baldwin 		error = crypto_apply(crp, crp->crp_aad_start,
7499b774dc0SJohn Baldwin 		    crp->crp_aad_length, axf->Update, &ctx);
75026d292d3SJohn Baldwin 	if (error)
75126d292d3SJohn Baldwin 		return (error);
752c0341432SJohn Baldwin 
753a10020cfSJohn Baldwin 	if (crp->crp_cipher_key != NULL)
754a10020cfSJohn Baldwin 		exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
755a10020cfSJohn Baldwin 		    crypto_get_params(crp->crp_session)->csp_cipher_klen);
756c0341432SJohn Baldwin 	exf->reinit(swe->sw_kschedule, iv);
757c0341432SJohn Baldwin 
758c0341432SJohn Baldwin 	/* Do encryption/decryption with MAC */
7599c0e3d3aSJohn Baldwin 	crypto_cursor_init(&cc_in, &crp->crp_buf);
7609c0e3d3aSJohn Baldwin 	crypto_cursor_advance(&cc_in, crp->crp_payload_start);
7619c0e3d3aSJohn Baldwin 	if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
7629c0e3d3aSJohn Baldwin 		crypto_cursor_init(&cc_out, &crp->crp_obuf);
7639c0e3d3aSJohn Baldwin 		crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
7649c0e3d3aSJohn Baldwin 	} else
7659c0e3d3aSJohn Baldwin 		cc_out = cc_in;
76626d292d3SJohn Baldwin 	for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) {
76786be314dSJohn Baldwin 		inblk = crypto_cursor_segment(&cc_in, &len);
76886be314dSJohn Baldwin 		if (len < blksz) {
76926d292d3SJohn Baldwin 			crypto_cursor_copydata(&cc_in, blksz, blk);
77026d292d3SJohn Baldwin 			inblk = blk;
77186be314dSJohn Baldwin 		} else
77226d292d3SJohn Baldwin 			crypto_cursor_advance(&cc_in, blksz);
773c0341432SJohn Baldwin 		if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
77486be314dSJohn Baldwin 			outblk = crypto_cursor_segment(&cc_out, &len);
77586be314dSJohn Baldwin 			if (len < blksz)
77626d292d3SJohn Baldwin 				outblk = blk;
77726d292d3SJohn Baldwin 			axf->Update(&ctx, inblk, blksz);
77826d292d3SJohn Baldwin 			exf->encrypt(swe->sw_kschedule, inblk, outblk);
77926d292d3SJohn Baldwin 			if (outblk == blk)
78026d292d3SJohn Baldwin 				crypto_cursor_copyback(&cc_out, blksz, blk);
78126d292d3SJohn Baldwin 			else
78226d292d3SJohn Baldwin 				crypto_cursor_advance(&cc_out, blksz);
783c0341432SJohn Baldwin 		} else {
784c0341432SJohn Baldwin 			/*
785c0341432SJohn Baldwin 			 * One of the problems with CCM+CBC is that
786c0341432SJohn Baldwin 			 * the authentication is done on the
78726d292d3SJohn Baldwin 			 * unencrypted data.  As a result, we have to
788c0341432SJohn Baldwin 			 * decrypt the data twice: once to generate
789c0341432SJohn Baldwin 			 * the tag and a second time after the tag is
790c0341432SJohn Baldwin 			 * verified.
791c0341432SJohn Baldwin 			 */
79226d292d3SJohn Baldwin 			exf->decrypt(swe->sw_kschedule, inblk, blk);
79326d292d3SJohn Baldwin 			axf->Update(&ctx, blk, blksz);
79426d292d3SJohn Baldwin 		}
79526d292d3SJohn Baldwin 	}
79626d292d3SJohn Baldwin 	if (resid > 0) {
79726d292d3SJohn Baldwin 		crypto_cursor_copydata(&cc_in, resid, blk);
79826d292d3SJohn Baldwin 		if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
79926d292d3SJohn Baldwin 			axf->Update(&ctx, blk, resid);
80026d292d3SJohn Baldwin 			exf->encrypt_last(swe->sw_kschedule, blk, blk, resid);
80126d292d3SJohn Baldwin 			crypto_cursor_copyback(&cc_out, resid, blk);
80226d292d3SJohn Baldwin 		} else {
80326d292d3SJohn Baldwin 			exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
80426d292d3SJohn Baldwin 			axf->Update(&ctx, blk, resid);
805c0341432SJohn Baldwin 		}
80608fca7a5SJohn-Mark Gurney 	}
80708fca7a5SJohn-Mark Gurney 
80808fca7a5SJohn-Mark Gurney 	/* Finalize MAC */
80926d292d3SJohn Baldwin 	axf->Final(tag, &ctx);
81008fca7a5SJohn-Mark Gurney 
81108fca7a5SJohn-Mark Gurney 	/* Validate tag */
81220c128daSJohn Baldwin 	error = 0;
813c0341432SJohn Baldwin 	if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
81426d292d3SJohn Baldwin 		u_char tag2[AES_CBC_MAC_HASH_LEN];
81520c128daSJohn Baldwin 
816c0341432SJohn Baldwin 		crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen,
81726d292d3SJohn Baldwin 		    tag2);
81808fca7a5SJohn-Mark Gurney 
81926d292d3SJohn Baldwin 		r = timingsafe_bcmp(tag, tag2, swa->sw_mlen);
82026d292d3SJohn Baldwin 		explicit_bzero(tag2, sizeof(tag2));
82120c128daSJohn Baldwin 		if (r != 0) {
82220c128daSJohn Baldwin 			error = EBADMSG;
82320c128daSJohn Baldwin 			goto out;
82420c128daSJohn Baldwin 		}
825c0341432SJohn Baldwin 
82608fca7a5SJohn-Mark Gurney 		/* tag matches, decrypt data */
827507281e5SSean Eric Fagan 		exf->reinit(swe->sw_kschedule, iv);
8289c0e3d3aSJohn Baldwin 		crypto_cursor_init(&cc_in, &crp->crp_buf);
8299c0e3d3aSJohn Baldwin 		crypto_cursor_advance(&cc_in, crp->crp_payload_start);
83026d292d3SJohn Baldwin 		for (resid = crp->crp_payload_length; resid > blksz;
83126d292d3SJohn Baldwin 		     resid -= blksz) {
83286be314dSJohn Baldwin 			inblk = crypto_cursor_segment(&cc_in, &len);
83386be314dSJohn Baldwin 			if (len < blksz) {
83426d292d3SJohn Baldwin 				crypto_cursor_copydata(&cc_in, blksz, blk);
83526d292d3SJohn Baldwin 				inblk = blk;
83686be314dSJohn Baldwin 			} else
83726d292d3SJohn Baldwin 				crypto_cursor_advance(&cc_in, blksz);
83886be314dSJohn Baldwin 			outblk = crypto_cursor_segment(&cc_out, &len);
83986be314dSJohn Baldwin 			if (len < blksz)
84026d292d3SJohn Baldwin 				outblk = blk;
84126d292d3SJohn Baldwin 			exf->decrypt(swe->sw_kschedule, inblk, outblk);
84226d292d3SJohn Baldwin 			if (outblk == blk)
84326d292d3SJohn Baldwin 				crypto_cursor_copyback(&cc_out, blksz, blk);
84426d292d3SJohn Baldwin 			else
84526d292d3SJohn Baldwin 				crypto_cursor_advance(&cc_out, blksz);
84626d292d3SJohn Baldwin 		}
84726d292d3SJohn Baldwin 		if (resid > 0) {
84826d292d3SJohn Baldwin 			crypto_cursor_copydata(&cc_in, resid, blk);
84926d292d3SJohn Baldwin 			exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
85026d292d3SJohn Baldwin 			crypto_cursor_copyback(&cc_out, resid, blk);
85108fca7a5SJohn-Mark Gurney 		}
85208fca7a5SJohn-Mark Gurney 	} else {
85308fca7a5SJohn-Mark Gurney 		/* Inject the authentication data */
85426d292d3SJohn Baldwin 		crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
85508fca7a5SJohn-Mark Gurney 	}
85608fca7a5SJohn-Mark Gurney 
85720c128daSJohn Baldwin out:
85820c128daSJohn Baldwin 	explicit_bzero(blkbuf, sizeof(blkbuf));
85926d292d3SJohn Baldwin 	explicit_bzero(tag, sizeof(tag));
86020c128daSJohn Baldwin 	explicit_bzero(iv, sizeof(iv));
86120c128daSJohn Baldwin 	return (error);
86208fca7a5SJohn-Mark Gurney }
86308fca7a5SJohn-Mark Gurney 
864dd2e1352SJohn Baldwin static int
865dd2e1352SJohn Baldwin swcr_chacha20_poly1305(struct swcr_session *ses, struct cryptop *crp)
866dd2e1352SJohn Baldwin {
867dd2e1352SJohn Baldwin 	const struct crypto_session_params *csp;
868dd2e1352SJohn Baldwin 	uint64_t blkbuf[howmany(CHACHA20_NATIVE_BLOCK_LEN, sizeof(uint64_t))];
869dd2e1352SJohn Baldwin 	u_char *blk = (u_char *)blkbuf;
870dd2e1352SJohn Baldwin 	u_char tag[POLY1305_HASH_LEN];
871dd2e1352SJohn Baldwin 	struct crypto_buffer_cursor cc_in, cc_out;
872dd2e1352SJohn Baldwin 	const u_char *inblk;
873dd2e1352SJohn Baldwin 	u_char *outblk;
874dd2e1352SJohn Baldwin 	uint64_t *blkp;
875dd2e1352SJohn Baldwin 	union authctx ctx;
876dd2e1352SJohn Baldwin 	struct swcr_auth *swa;
877dd2e1352SJohn Baldwin 	struct swcr_encdec *swe;
878*d8787d4fSMark Johnston 	const struct auth_hash *axf;
879*d8787d4fSMark Johnston 	const struct enc_xform *exf;
88086be314dSJohn Baldwin 	size_t len;
881dd2e1352SJohn Baldwin 	int blksz, error, r, resid;
882dd2e1352SJohn Baldwin 
883dd2e1352SJohn Baldwin 	swa = &ses->swcr_auth;
884dd2e1352SJohn Baldwin 	axf = swa->sw_axf;
885dd2e1352SJohn Baldwin 
886dd2e1352SJohn Baldwin 	swe = &ses->swcr_encdec;
887dd2e1352SJohn Baldwin 	exf = swe->sw_exf;
888dd2e1352SJohn Baldwin 	blksz = exf->native_blocksize;
889dd2e1352SJohn Baldwin 	KASSERT(blksz <= sizeof(blkbuf), ("%s: blocksize mismatch", __func__));
890dd2e1352SJohn Baldwin 
891dd2e1352SJohn Baldwin 	if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
892dd2e1352SJohn Baldwin 		return (EINVAL);
893dd2e1352SJohn Baldwin 
894dd2e1352SJohn Baldwin 	csp = crypto_get_params(crp->crp_session);
895dd2e1352SJohn Baldwin 
896dd2e1352SJohn Baldwin 	/* Generate Poly1305 key. */
897dd2e1352SJohn Baldwin 	if (crp->crp_cipher_key != NULL)
898dd2e1352SJohn Baldwin 		axf->Setkey(&ctx, crp->crp_cipher_key, csp->csp_cipher_klen);
899dd2e1352SJohn Baldwin 	else
900dd2e1352SJohn Baldwin 		axf->Setkey(&ctx, csp->csp_cipher_key, csp->csp_cipher_klen);
901dd2e1352SJohn Baldwin 	axf->Reinit(&ctx, crp->crp_iv, csp->csp_ivlen);
902dd2e1352SJohn Baldwin 
903dd2e1352SJohn Baldwin 	/* Supply MAC with AAD */
904dd2e1352SJohn Baldwin 	if (crp->crp_aad != NULL)
905dd2e1352SJohn Baldwin 		axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
906dd2e1352SJohn Baldwin 	else
907dd2e1352SJohn Baldwin 		crypto_apply(crp, crp->crp_aad_start,
908dd2e1352SJohn Baldwin 		    crp->crp_aad_length, axf->Update, &ctx);
909dd2e1352SJohn Baldwin 	if (crp->crp_aad_length % 16 != 0) {
910dd2e1352SJohn Baldwin 		/* padding1 */
911dd2e1352SJohn Baldwin 		memset(blk, 0, 16);
912dd2e1352SJohn Baldwin 		axf->Update(&ctx, blk, 16 - crp->crp_aad_length % 16);
913dd2e1352SJohn Baldwin 	}
914dd2e1352SJohn Baldwin 
915dd2e1352SJohn Baldwin 	if (crp->crp_cipher_key != NULL)
916dd2e1352SJohn Baldwin 		exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
917dd2e1352SJohn Baldwin 		    csp->csp_cipher_klen);
918dd2e1352SJohn Baldwin 	exf->reinit(swe->sw_kschedule, crp->crp_iv);
919dd2e1352SJohn Baldwin 
920dd2e1352SJohn Baldwin 	/* Do encryption with MAC */
921dd2e1352SJohn Baldwin 	crypto_cursor_init(&cc_in, &crp->crp_buf);
922dd2e1352SJohn Baldwin 	crypto_cursor_advance(&cc_in, crp->crp_payload_start);
923dd2e1352SJohn Baldwin 	if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
924dd2e1352SJohn Baldwin 		crypto_cursor_init(&cc_out, &crp->crp_obuf);
925dd2e1352SJohn Baldwin 		crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
926dd2e1352SJohn Baldwin 	} else
927dd2e1352SJohn Baldwin 		cc_out = cc_in;
928dd2e1352SJohn Baldwin 	for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) {
92986be314dSJohn Baldwin 		inblk = crypto_cursor_segment(&cc_in, &len);
93086be314dSJohn Baldwin 		if (len < blksz) {
931dd2e1352SJohn Baldwin 			crypto_cursor_copydata(&cc_in, blksz, blk);
932dd2e1352SJohn Baldwin 			inblk = blk;
93386be314dSJohn Baldwin 		} else
934dd2e1352SJohn Baldwin 			crypto_cursor_advance(&cc_in, blksz);
935dd2e1352SJohn Baldwin 		if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
93686be314dSJohn Baldwin 			outblk = crypto_cursor_segment(&cc_out, &len);
93786be314dSJohn Baldwin 			if (len < blksz)
938dd2e1352SJohn Baldwin 				outblk = blk;
939dd2e1352SJohn Baldwin 			exf->encrypt(swe->sw_kschedule, inblk, outblk);
940dd2e1352SJohn Baldwin 			axf->Update(&ctx, outblk, blksz);
941dd2e1352SJohn Baldwin 			if (outblk == blk)
942dd2e1352SJohn Baldwin 				crypto_cursor_copyback(&cc_out, blksz, blk);
943dd2e1352SJohn Baldwin 			else
944dd2e1352SJohn Baldwin 				crypto_cursor_advance(&cc_out, blksz);
945dd2e1352SJohn Baldwin 		} else {
946dd2e1352SJohn Baldwin 			axf->Update(&ctx, inblk, blksz);
947dd2e1352SJohn Baldwin 		}
948dd2e1352SJohn Baldwin 	}
949dd2e1352SJohn Baldwin 	if (resid > 0) {
950dd2e1352SJohn Baldwin 		crypto_cursor_copydata(&cc_in, resid, blk);
951dd2e1352SJohn Baldwin 		if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
952dd2e1352SJohn Baldwin 			exf->encrypt_last(swe->sw_kschedule, blk, blk, resid);
953dd2e1352SJohn Baldwin 			crypto_cursor_copyback(&cc_out, resid, blk);
954dd2e1352SJohn Baldwin 		}
955dd2e1352SJohn Baldwin 		axf->Update(&ctx, blk, resid);
956dd2e1352SJohn Baldwin 		if (resid % 16 != 0) {
957dd2e1352SJohn Baldwin 			/* padding2 */
958dd2e1352SJohn Baldwin 			memset(blk, 0, 16);
959dd2e1352SJohn Baldwin 			axf->Update(&ctx, blk, 16 - resid % 16);
960dd2e1352SJohn Baldwin 		}
961dd2e1352SJohn Baldwin 	}
962dd2e1352SJohn Baldwin 
963dd2e1352SJohn Baldwin 	/* lengths */
964dd2e1352SJohn Baldwin 	blkp = (uint64_t *)blk;
965dd2e1352SJohn Baldwin 	blkp[0] = htole64(crp->crp_aad_length);
966dd2e1352SJohn Baldwin 	blkp[1] = htole64(crp->crp_payload_length);
967dd2e1352SJohn Baldwin 	axf->Update(&ctx, blk, sizeof(uint64_t) * 2);
968dd2e1352SJohn Baldwin 
969dd2e1352SJohn Baldwin 	/* Finalize MAC */
970dd2e1352SJohn Baldwin 	axf->Final(tag, &ctx);
971dd2e1352SJohn Baldwin 
972dd2e1352SJohn Baldwin 	/* Validate tag */
973dd2e1352SJohn Baldwin 	error = 0;
974dd2e1352SJohn Baldwin 	if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
975dd2e1352SJohn Baldwin 		u_char tag2[POLY1305_HASH_LEN];
976dd2e1352SJohn Baldwin 
977dd2e1352SJohn Baldwin 		crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2);
978dd2e1352SJohn Baldwin 
979dd2e1352SJohn Baldwin 		r = timingsafe_bcmp(tag, tag2, swa->sw_mlen);
980dd2e1352SJohn Baldwin 		explicit_bzero(tag2, sizeof(tag2));
981dd2e1352SJohn Baldwin 		if (r != 0) {
982dd2e1352SJohn Baldwin 			error = EBADMSG;
983dd2e1352SJohn Baldwin 			goto out;
984dd2e1352SJohn Baldwin 		}
985dd2e1352SJohn Baldwin 
986dd2e1352SJohn Baldwin 		/* tag matches, decrypt data */
987dd2e1352SJohn Baldwin 		crypto_cursor_init(&cc_in, &crp->crp_buf);
988dd2e1352SJohn Baldwin 		crypto_cursor_advance(&cc_in, crp->crp_payload_start);
989dd2e1352SJohn Baldwin 		for (resid = crp->crp_payload_length; resid > blksz;
990dd2e1352SJohn Baldwin 		     resid -= blksz) {
99186be314dSJohn Baldwin 			inblk = crypto_cursor_segment(&cc_in, &len);
99286be314dSJohn Baldwin 			if (len < blksz) {
993dd2e1352SJohn Baldwin 				crypto_cursor_copydata(&cc_in, blksz, blk);
994dd2e1352SJohn Baldwin 				inblk = blk;
99586be314dSJohn Baldwin 			} else
996dd2e1352SJohn Baldwin 				crypto_cursor_advance(&cc_in, blksz);
99786be314dSJohn Baldwin 			outblk = crypto_cursor_segment(&cc_out, &len);
99886be314dSJohn Baldwin 			if (len < blksz)
999dd2e1352SJohn Baldwin 				outblk = blk;
1000dd2e1352SJohn Baldwin 			exf->decrypt(swe->sw_kschedule, inblk, outblk);
1001dd2e1352SJohn Baldwin 			if (outblk == blk)
1002dd2e1352SJohn Baldwin 				crypto_cursor_copyback(&cc_out, blksz, blk);
1003dd2e1352SJohn Baldwin 			else
1004dd2e1352SJohn Baldwin 				crypto_cursor_advance(&cc_out, blksz);
1005dd2e1352SJohn Baldwin 		}
1006dd2e1352SJohn Baldwin 		if (resid > 0) {
1007dd2e1352SJohn Baldwin 			crypto_cursor_copydata(&cc_in, resid, blk);
1008dd2e1352SJohn Baldwin 			exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
1009dd2e1352SJohn Baldwin 			crypto_cursor_copyback(&cc_out, resid, blk);
1010dd2e1352SJohn Baldwin 		}
1011dd2e1352SJohn Baldwin 	} else {
1012dd2e1352SJohn Baldwin 		/* Inject the authentication data */
1013dd2e1352SJohn Baldwin 		crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
1014dd2e1352SJohn Baldwin 	}
1015dd2e1352SJohn Baldwin 
1016dd2e1352SJohn Baldwin out:
1017dd2e1352SJohn Baldwin 	explicit_bzero(blkbuf, sizeof(blkbuf));
1018dd2e1352SJohn Baldwin 	explicit_bzero(tag, sizeof(tag));
1019dd2e1352SJohn Baldwin 	explicit_bzero(&ctx, sizeof(ctx));
1020dd2e1352SJohn Baldwin 	return (error);
1021dd2e1352SJohn Baldwin }
1022dd2e1352SJohn Baldwin 
1023091d81d1SSam Leffler /*
1024c0341432SJohn Baldwin  * Apply a cipher and a digest to perform EtA.
1025c0341432SJohn Baldwin  */
1026c0341432SJohn Baldwin static int
1027c0341432SJohn Baldwin swcr_eta(struct swcr_session *ses, struct cryptop *crp)
1028c0341432SJohn Baldwin {
1029c0341432SJohn Baldwin 	int error;
1030c0341432SJohn Baldwin 
1031c0341432SJohn Baldwin 	if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
1032c0341432SJohn Baldwin 		error = swcr_encdec(ses, crp);
1033c0341432SJohn Baldwin 		if (error == 0)
1034c0341432SJohn Baldwin 			error = swcr_authcompute(ses, crp);
1035c0341432SJohn Baldwin 	} else {
1036c0341432SJohn Baldwin 		error = swcr_authcompute(ses, crp);
1037c0341432SJohn Baldwin 		if (error == 0)
1038c0341432SJohn Baldwin 			error = swcr_encdec(ses, crp);
1039c0341432SJohn Baldwin 	}
1040c0341432SJohn Baldwin 	return (error);
1041c0341432SJohn Baldwin }
1042c0341432SJohn Baldwin 
1043c0341432SJohn Baldwin /*
1044091d81d1SSam Leffler  * Apply a compression/decompression algorithm
1045091d81d1SSam Leffler  */
1046091d81d1SSam Leffler static int
1047c0341432SJohn Baldwin swcr_compdec(struct swcr_session *ses, struct cryptop *crp)
1048091d81d1SSam Leffler {
1049*d8787d4fSMark Johnston 	const struct comp_algo *cxf;
1050d3d79e96SJohn Baldwin 	uint8_t *data, *out;
1051091d81d1SSam Leffler 	int adj;
1052d3d79e96SJohn Baldwin 	uint32_t result;
1053091d81d1SSam Leffler 
1054c0341432SJohn Baldwin 	cxf = ses->swcr_compdec.sw_cxf;
1055091d81d1SSam Leffler 
1056091d81d1SSam Leffler 	/* We must handle the whole buffer of data in one time
1057091d81d1SSam Leffler 	 * then if there is not all the data in the mbuf, we must
1058091d81d1SSam Leffler 	 * copy in a buffer.
1059091d81d1SSam Leffler 	 */
1060091d81d1SSam Leffler 
1061c0341432SJohn Baldwin 	data = malloc(crp->crp_payload_length, M_CRYPTO_DATA,  M_NOWAIT);
1062091d81d1SSam Leffler 	if (data == NULL)
1063091d81d1SSam Leffler 		return (EINVAL);
1064c0341432SJohn Baldwin 	crypto_copydata(crp, crp->crp_payload_start, crp->crp_payload_length,
1065c0341432SJohn Baldwin 	    data);
1066091d81d1SSam Leffler 
1067c0341432SJohn Baldwin 	if (CRYPTO_OP_IS_COMPRESS(crp->crp_op))
1068c0341432SJohn Baldwin 		result = cxf->compress(data, crp->crp_payload_length, &out);
1069091d81d1SSam Leffler 	else
1070c0341432SJohn Baldwin 		result = cxf->decompress(data, crp->crp_payload_length, &out);
1071091d81d1SSam Leffler 
10721ede983cSDag-Erling Smørgrav 	free(data, M_CRYPTO_DATA);
1073091d81d1SSam Leffler 	if (result == 0)
1074c0341432SJohn Baldwin 		return (EINVAL);
1075c0341432SJohn Baldwin 	crp->crp_olen = result;
1076c0341432SJohn Baldwin 
1077c0341432SJohn Baldwin 	/* Check the compressed size when doing compression */
1078c0341432SJohn Baldwin 	if (CRYPTO_OP_IS_COMPRESS(crp->crp_op)) {
1079c0341432SJohn Baldwin 		if (result >= crp->crp_payload_length) {
1080c0341432SJohn Baldwin 			/* Compression was useless, we lost time */
1081c0341432SJohn Baldwin 			free(out, M_CRYPTO_DATA);
1082c0341432SJohn Baldwin 			return (0);
1083c0341432SJohn Baldwin 		}
1084c0341432SJohn Baldwin 	}
1085091d81d1SSam Leffler 
1086091d81d1SSam Leffler 	/* Copy back the (de)compressed data. m_copyback is
1087091d81d1SSam Leffler 	 * extending the mbuf as necessary.
1088091d81d1SSam Leffler 	 */
1089c0341432SJohn Baldwin 	crypto_copyback(crp, crp->crp_payload_start, result, out);
1090c0341432SJohn Baldwin 	if (result < crp->crp_payload_length) {
10919c0e3d3aSJohn Baldwin 		switch (crp->crp_buf.cb_type) {
1092c0341432SJohn Baldwin 		case CRYPTO_BUF_MBUF:
1093883a0196SJohn Baldwin 		case CRYPTO_BUF_SINGLE_MBUF:
1094c0341432SJohn Baldwin 			adj = result - crp->crp_payload_length;
10959c0e3d3aSJohn Baldwin 			m_adj(crp->crp_buf.cb_mbuf, adj);
1096c0341432SJohn Baldwin 			break;
1097c0341432SJohn Baldwin 		case CRYPTO_BUF_UIO: {
10989c0e3d3aSJohn Baldwin 			struct uio *uio = crp->crp_buf.cb_uio;
1099091d81d1SSam Leffler 			int ind;
1100091d81d1SSam Leffler 
1101c0341432SJohn Baldwin 			adj = crp->crp_payload_length - result;
1102091d81d1SSam Leffler 			ind = uio->uio_iovcnt - 1;
1103091d81d1SSam Leffler 
1104091d81d1SSam Leffler 			while (adj > 0 && ind >= 0) {
1105091d81d1SSam Leffler 				if (adj < uio->uio_iov[ind].iov_len) {
1106091d81d1SSam Leffler 					uio->uio_iov[ind].iov_len -= adj;
1107091d81d1SSam Leffler 					break;
1108091d81d1SSam Leffler 				}
1109091d81d1SSam Leffler 
1110091d81d1SSam Leffler 				adj -= uio->uio_iov[ind].iov_len;
1111091d81d1SSam Leffler 				uio->uio_iov[ind].iov_len = 0;
1112091d81d1SSam Leffler 				ind--;
1113091d81d1SSam Leffler 				uio->uio_iovcnt--;
1114091d81d1SSam Leffler 			}
1115091d81d1SSam Leffler 			}
1116c0341432SJohn Baldwin 			break;
1117e6f6d0c9SAlan Somers 		case CRYPTO_BUF_VMPAGE:
1118e6f6d0c9SAlan Somers 			adj = crp->crp_payload_length - result;
1119e6f6d0c9SAlan Somers 			crp->crp_buf.cb_vm_page_len -= adj;
1120e6f6d0c9SAlan Somers 			break;
11219c0e3d3aSJohn Baldwin 		default:
11229c0e3d3aSJohn Baldwin 			break;
1123c0341432SJohn Baldwin 		}
1124091d81d1SSam Leffler 	}
11251ede983cSDag-Erling Smørgrav 	free(out, M_CRYPTO_DATA);
1126091d81d1SSam Leffler 	return 0;
1127091d81d1SSam Leffler }
1128091d81d1SSam Leffler 
1129091d81d1SSam Leffler static int
11303e947048SJohn Baldwin swcr_setup_cipher(struct swcr_session *ses,
1131c0341432SJohn Baldwin     const struct crypto_session_params *csp)
1132091d81d1SSam Leffler {
1133c0341432SJohn Baldwin 	struct swcr_encdec *swe;
1134*d8787d4fSMark Johnston 	const struct enc_xform *txf;
1135f6c4bc3bSPawel Jakub Dawidek 	int error;
1136091d81d1SSam Leffler 
1137c0341432SJohn Baldwin 	swe = &ses->swcr_encdec;
1138c0341432SJohn Baldwin 	txf = crypto_cipher(csp);
1139c0341432SJohn Baldwin 	MPASS(txf->ivsize == csp->csp_ivlen);
11403e947048SJohn Baldwin 	if (txf->ctxsize != 0) {
11413e947048SJohn Baldwin 		swe->sw_kschedule = malloc(txf->ctxsize, M_CRYPTO_DATA,
11423e947048SJohn Baldwin 		    M_NOWAIT);
11433e947048SJohn Baldwin 		if (swe->sw_kschedule == NULL)
11443e947048SJohn Baldwin 			return (ENOMEM);
11453e947048SJohn Baldwin 	}
1146c0341432SJohn Baldwin 	if (csp->csp_cipher_key != NULL) {
11473e947048SJohn Baldwin 		error = txf->setkey(swe->sw_kschedule,
1148c0341432SJohn Baldwin 		    csp->csp_cipher_key, csp->csp_cipher_klen);
1149c0341432SJohn Baldwin 		if (error)
1150c0341432SJohn Baldwin 			return (error);
1151091d81d1SSam Leffler 	}
1152c0341432SJohn Baldwin 	swe->sw_exf = txf;
1153c0341432SJohn Baldwin 	return (0);
1154f6c4bc3bSPawel Jakub Dawidek }
1155091d81d1SSam Leffler 
1156c0341432SJohn Baldwin static int
1157c0341432SJohn Baldwin swcr_setup_auth(struct swcr_session *ses,
1158c0341432SJohn Baldwin     const struct crypto_session_params *csp)
1159c0341432SJohn Baldwin {
1160c0341432SJohn Baldwin 	struct swcr_auth *swa;
1161*d8787d4fSMark Johnston 	const struct auth_hash *axf;
1162c0341432SJohn Baldwin 
1163c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
1164c0341432SJohn Baldwin 
1165c0341432SJohn Baldwin 	axf = crypto_auth_hash(csp);
1166c0341432SJohn Baldwin 	swa->sw_axf = axf;
1167c0341432SJohn Baldwin 	if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1168c0341432SJohn Baldwin 		return (EINVAL);
1169c0341432SJohn Baldwin 	if (csp->csp_auth_mlen == 0)
1170c0341432SJohn Baldwin 		swa->sw_mlen = axf->hashsize;
1171c0341432SJohn Baldwin 	else
1172c0341432SJohn Baldwin 		swa->sw_mlen = csp->csp_auth_mlen;
1173c0341432SJohn Baldwin 	swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT);
1174c0341432SJohn Baldwin 	if (swa->sw_ictx == NULL)
1175c0341432SJohn Baldwin 		return (ENOBUFS);
1176c0341432SJohn Baldwin 
1177c0341432SJohn Baldwin 	switch (csp->csp_auth_alg) {
1178091d81d1SSam Leffler 	case CRYPTO_SHA1_HMAC:
1179c97f39ceSConrad Meyer 	case CRYPTO_SHA2_224_HMAC:
1180f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_256_HMAC:
1181f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_384_HMAC:
1182f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_512_HMAC:
1183091d81d1SSam Leffler 	case CRYPTO_NULL_HMAC:
1184091d81d1SSam Leffler 	case CRYPTO_RIPEMD160_HMAC:
11853a0b6a93SJohn Baldwin 		swa->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
1186091d81d1SSam Leffler 		    M_NOWAIT);
1187c0341432SJohn Baldwin 		if (swa->sw_octx == NULL)
1188c0341432SJohn Baldwin 			return (ENOBUFS);
1189c0341432SJohn Baldwin 
1190c0341432SJohn Baldwin 		if (csp->csp_auth_key != NULL) {
1191c0341432SJohn Baldwin 			swcr_authprepare(axf, swa, csp->csp_auth_key,
1192c0341432SJohn Baldwin 			    csp->csp_auth_klen);
1193091d81d1SSam Leffler 		}
1194091d81d1SSam Leffler 
1195c0341432SJohn Baldwin 		if (csp->csp_mode == CSP_MODE_DIGEST)
1196c0341432SJohn Baldwin 			ses->swcr_process = swcr_authcompute;
1197091d81d1SSam Leffler 		break;
1198091d81d1SSam Leffler 	case CRYPTO_SHA1:
1199c4729f6eSConrad Meyer 	case CRYPTO_SHA2_224:
1200c4729f6eSConrad Meyer 	case CRYPTO_SHA2_256:
1201c4729f6eSConrad Meyer 	case CRYPTO_SHA2_384:
1202c4729f6eSConrad Meyer 	case CRYPTO_SHA2_512:
1203c0341432SJohn Baldwin 		axf->Init(swa->sw_ictx);
1204c0341432SJohn Baldwin 		if (csp->csp_mode == CSP_MODE_DIGEST)
1205c0341432SJohn Baldwin 			ses->swcr_process = swcr_authcompute;
1206c0341432SJohn Baldwin 		break;
1207c0341432SJohn Baldwin 	case CRYPTO_AES_NIST_GMAC:
1208c0341432SJohn Baldwin 		axf->Init(swa->sw_ictx);
1209c0341432SJohn Baldwin 		axf->Setkey(swa->sw_ictx, csp->csp_auth_key,
1210c0341432SJohn Baldwin 		    csp->csp_auth_klen);
1211c0341432SJohn Baldwin 		if (csp->csp_mode == CSP_MODE_DIGEST)
1212c0341432SJohn Baldwin 			ses->swcr_process = swcr_gmac;
1213c0341432SJohn Baldwin 		break;
1214c0341432SJohn Baldwin 	case CRYPTO_POLY1305:
1215c0341432SJohn Baldwin 	case CRYPTO_BLAKE2B:
1216c0341432SJohn Baldwin 	case CRYPTO_BLAKE2S:
1217c0341432SJohn Baldwin 		/*
1218c0341432SJohn Baldwin 		 * Blake2b and Blake2s support an optional key but do
1219c0341432SJohn Baldwin 		 * not require one.
1220c0341432SJohn Baldwin 		 */
1221c0341432SJohn Baldwin 		if (csp->csp_auth_klen == 0 || csp->csp_auth_key != NULL)
1222c0341432SJohn Baldwin 			axf->Setkey(swa->sw_ictx, csp->csp_auth_key,
1223c0341432SJohn Baldwin 			    csp->csp_auth_klen);
1224c0341432SJohn Baldwin 		axf->Init(swa->sw_ictx);
1225c0341432SJohn Baldwin 		if (csp->csp_mode == CSP_MODE_DIGEST)
1226c0341432SJohn Baldwin 			ses->swcr_process = swcr_authcompute;
1227c0341432SJohn Baldwin 		break;
1228c0341432SJohn Baldwin 	case CRYPTO_AES_CCM_CBC_MAC:
1229c0341432SJohn Baldwin 		axf->Init(swa->sw_ictx);
1230c0341432SJohn Baldwin 		axf->Setkey(swa->sw_ictx, csp->csp_auth_key,
1231c0341432SJohn Baldwin 		    csp->csp_auth_klen);
1232c0341432SJohn Baldwin 		if (csp->csp_mode == CSP_MODE_DIGEST)
1233c0341432SJohn Baldwin 			ses->swcr_process = swcr_ccm_cbc_mac;
1234c0341432SJohn Baldwin 		break;
1235091d81d1SSam Leffler 	}
1236091d81d1SSam Leffler 
1237c0341432SJohn Baldwin 	return (0);
1238c0341432SJohn Baldwin }
123908fca7a5SJohn-Mark Gurney 
1240c0341432SJohn Baldwin static int
1241c0341432SJohn Baldwin swcr_setup_gcm(struct swcr_session *ses,
1242c0341432SJohn Baldwin     const struct crypto_session_params *csp)
1243c0341432SJohn Baldwin {
1244c0341432SJohn Baldwin 	struct swcr_auth *swa;
1245*d8787d4fSMark Johnston 	const struct auth_hash *axf;
1246c0341432SJohn Baldwin 
1247c0341432SJohn Baldwin 	if (csp->csp_ivlen != AES_GCM_IV_LEN)
1248c0341432SJohn Baldwin 		return (EINVAL);
1249c0341432SJohn Baldwin 
1250c0341432SJohn Baldwin 	/* First, setup the auth side. */
1251c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
1252c0341432SJohn Baldwin 	switch (csp->csp_cipher_klen * 8) {
1253c0341432SJohn Baldwin 	case 128:
1254c0341432SJohn Baldwin 		axf = &auth_hash_nist_gmac_aes_128;
1255c0341432SJohn Baldwin 		break;
1256c0341432SJohn Baldwin 	case 192:
1257c0341432SJohn Baldwin 		axf = &auth_hash_nist_gmac_aes_192;
1258c0341432SJohn Baldwin 		break;
1259c0341432SJohn Baldwin 	case 256:
1260c0341432SJohn Baldwin 		axf = &auth_hash_nist_gmac_aes_256;
1261c0341432SJohn Baldwin 		break;
1262c0341432SJohn Baldwin 	default:
1263c0341432SJohn Baldwin 		return (EINVAL);
1264c0341432SJohn Baldwin 	}
1265c0341432SJohn Baldwin 	swa->sw_axf = axf;
1266c0341432SJohn Baldwin 	if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1267c0341432SJohn Baldwin 		return (EINVAL);
1268c0341432SJohn Baldwin 	if (csp->csp_auth_mlen == 0)
1269c0341432SJohn Baldwin 		swa->sw_mlen = axf->hashsize;
1270c0341432SJohn Baldwin 	else
1271c0341432SJohn Baldwin 		swa->sw_mlen = csp->csp_auth_mlen;
1272c0341432SJohn Baldwin 	swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT);
1273c0341432SJohn Baldwin 	if (swa->sw_ictx == NULL)
1274c0341432SJohn Baldwin 		return (ENOBUFS);
1275c0341432SJohn Baldwin 	axf->Init(swa->sw_ictx);
1276c0341432SJohn Baldwin 	if (csp->csp_cipher_key != NULL)
1277c0341432SJohn Baldwin 		axf->Setkey(swa->sw_ictx, csp->csp_cipher_key,
1278c0341432SJohn Baldwin 		    csp->csp_cipher_klen);
1279c0341432SJohn Baldwin 
1280c0341432SJohn Baldwin 	/* Second, setup the cipher side. */
12813e947048SJohn Baldwin 	return (swcr_setup_cipher(ses, csp));
1282c0341432SJohn Baldwin }
1283c0341432SJohn Baldwin 
1284c0341432SJohn Baldwin static int
1285c0341432SJohn Baldwin swcr_setup_ccm(struct swcr_session *ses,
1286c0341432SJohn Baldwin     const struct crypto_session_params *csp)
1287c0341432SJohn Baldwin {
1288c0341432SJohn Baldwin 	struct swcr_auth *swa;
1289*d8787d4fSMark Johnston 	const struct auth_hash *axf;
1290c0341432SJohn Baldwin 
1291c0341432SJohn Baldwin 	if (csp->csp_ivlen != AES_CCM_IV_LEN)
1292c0341432SJohn Baldwin 		return (EINVAL);
1293c0341432SJohn Baldwin 
1294c0341432SJohn Baldwin 	/* First, setup the auth side. */
1295c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
1296c0341432SJohn Baldwin 	switch (csp->csp_cipher_klen * 8) {
1297507281e5SSean Eric Fagan 	case 128:
1298507281e5SSean Eric Fagan 		axf = &auth_hash_ccm_cbc_mac_128;
1299507281e5SSean Eric Fagan 		break;
1300507281e5SSean Eric Fagan 	case 192:
1301507281e5SSean Eric Fagan 		axf = &auth_hash_ccm_cbc_mac_192;
1302507281e5SSean Eric Fagan 		break;
1303507281e5SSean Eric Fagan 	case 256:
1304507281e5SSean Eric Fagan 		axf = &auth_hash_ccm_cbc_mac_256;
1305507281e5SSean Eric Fagan 		break;
1306507281e5SSean Eric Fagan 	default:
1307c0341432SJohn Baldwin 		return (EINVAL);
1308507281e5SSean Eric Fagan 	}
1309c0341432SJohn Baldwin 	swa->sw_axf = axf;
1310c0341432SJohn Baldwin 	if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1311c0341432SJohn Baldwin 		return (EINVAL);
1312c0341432SJohn Baldwin 	if (csp->csp_auth_mlen == 0)
1313c0341432SJohn Baldwin 		swa->sw_mlen = axf->hashsize;
1314c0341432SJohn Baldwin 	else
1315c0341432SJohn Baldwin 		swa->sw_mlen = csp->csp_auth_mlen;
1316c0341432SJohn Baldwin 	swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT);
1317c0341432SJohn Baldwin 	if (swa->sw_ictx == NULL)
1318c0341432SJohn Baldwin 		return (ENOBUFS);
1319c0341432SJohn Baldwin 	axf->Init(swa->sw_ictx);
1320c0341432SJohn Baldwin 	if (csp->csp_cipher_key != NULL)
1321c0341432SJohn Baldwin 		axf->Setkey(swa->sw_ictx, csp->csp_cipher_key,
1322c0341432SJohn Baldwin 		    csp->csp_cipher_klen);
132308fca7a5SJohn-Mark Gurney 
1324c0341432SJohn Baldwin 	/* Second, setup the cipher side. */
13253e947048SJohn Baldwin 	return (swcr_setup_cipher(ses, csp));
13262e2e26d1SJohn Baldwin }
1327a2bc81bfSJohn-Mark Gurney 
1328dd2e1352SJohn Baldwin static int
1329dd2e1352SJohn Baldwin swcr_setup_chacha20_poly1305(struct swcr_session *ses,
1330dd2e1352SJohn Baldwin     const struct crypto_session_params *csp)
1331dd2e1352SJohn Baldwin {
1332dd2e1352SJohn Baldwin 	struct swcr_auth *swa;
1333*d8787d4fSMark Johnston 	const struct auth_hash *axf;
1334dd2e1352SJohn Baldwin 
1335dd2e1352SJohn Baldwin 	if (csp->csp_ivlen != CHACHA20_POLY1305_IV_LEN)
1336dd2e1352SJohn Baldwin 		return (EINVAL);
1337dd2e1352SJohn Baldwin 
1338dd2e1352SJohn Baldwin 	/* First, setup the auth side. */
1339dd2e1352SJohn Baldwin 	swa = &ses->swcr_auth;
1340dd2e1352SJohn Baldwin 	axf = &auth_hash_chacha20_poly1305;
1341dd2e1352SJohn Baldwin 	swa->sw_axf = axf;
1342dd2e1352SJohn Baldwin 	if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1343dd2e1352SJohn Baldwin 		return (EINVAL);
1344dd2e1352SJohn Baldwin 	if (csp->csp_auth_mlen == 0)
1345dd2e1352SJohn Baldwin 		swa->sw_mlen = axf->hashsize;
1346dd2e1352SJohn Baldwin 	else
1347dd2e1352SJohn Baldwin 		swa->sw_mlen = csp->csp_auth_mlen;
1348dd2e1352SJohn Baldwin 
1349dd2e1352SJohn Baldwin 	/* The auth state is regenerated for each nonce. */
1350dd2e1352SJohn Baldwin 
1351dd2e1352SJohn Baldwin 	/* Second, setup the cipher side. */
1352dd2e1352SJohn Baldwin 	return (swcr_setup_cipher(ses, csp));
1353dd2e1352SJohn Baldwin }
1354dd2e1352SJohn Baldwin 
1355c0341432SJohn Baldwin static bool
1356c0341432SJohn Baldwin swcr_auth_supported(const struct crypto_session_params *csp)
1357109919c6SBenno Rice {
1358*d8787d4fSMark Johnston 	const struct auth_hash *axf;
1359091d81d1SSam Leffler 
1360c0341432SJohn Baldwin 	axf = crypto_auth_hash(csp);
1361c0341432SJohn Baldwin 	if (axf == NULL)
1362c0341432SJohn Baldwin 		return (false);
1363c0341432SJohn Baldwin 	switch (csp->csp_auth_alg) {
1364091d81d1SSam Leffler 	case CRYPTO_SHA1_HMAC:
1365c97f39ceSConrad Meyer 	case CRYPTO_SHA2_224_HMAC:
1366f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_256_HMAC:
1367f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_384_HMAC:
1368f6c4bc3bSPawel Jakub Dawidek 	case CRYPTO_SHA2_512_HMAC:
1369091d81d1SSam Leffler 	case CRYPTO_NULL_HMAC:
1370c0341432SJohn Baldwin 	case CRYPTO_RIPEMD160_HMAC:
1371091d81d1SSam Leffler 		break;
1372c0341432SJohn Baldwin 	case CRYPTO_AES_NIST_GMAC:
1373c0341432SJohn Baldwin 		switch (csp->csp_auth_klen * 8) {
1374c0341432SJohn Baldwin 		case 128:
1375c0341432SJohn Baldwin 		case 192:
1376c0341432SJohn Baldwin 		case 256:
1377c0341432SJohn Baldwin 			break;
1378c0341432SJohn Baldwin 		default:
1379c0341432SJohn Baldwin 			return (false);
1380c0341432SJohn Baldwin 		}
1381c0341432SJohn Baldwin 		if (csp->csp_auth_key == NULL)
1382c0341432SJohn Baldwin 			return (false);
1383c0341432SJohn Baldwin 		if (csp->csp_ivlen != AES_GCM_IV_LEN)
1384c0341432SJohn Baldwin 			return (false);
1385c0341432SJohn Baldwin 		break;
138625b7033bSConrad Meyer 	case CRYPTO_POLY1305:
1387c0341432SJohn Baldwin 		if (csp->csp_auth_klen != POLY1305_KEY_LEN)
1388c0341432SJohn Baldwin 			return (false);
1389c0341432SJohn Baldwin 		break;
1390c0341432SJohn Baldwin 	case CRYPTO_AES_CCM_CBC_MAC:
1391c0341432SJohn Baldwin 		switch (csp->csp_auth_klen * 8) {
1392c0341432SJohn Baldwin 		case 128:
1393c0341432SJohn Baldwin 		case 192:
1394c0341432SJohn Baldwin 		case 256:
1395c0341432SJohn Baldwin 			break;
1396c0341432SJohn Baldwin 		default:
1397c0341432SJohn Baldwin 			return (false);
1398c0341432SJohn Baldwin 		}
1399c0341432SJohn Baldwin 		if (csp->csp_auth_key == NULL)
1400c0341432SJohn Baldwin 			return (false);
1401c0341432SJohn Baldwin 		if (csp->csp_ivlen != AES_CCM_IV_LEN)
1402c0341432SJohn Baldwin 			return (false);
1403c0341432SJohn Baldwin 		break;
1404c0341432SJohn Baldwin 	}
1405c0341432SJohn Baldwin 	return (true);
1406c0341432SJohn Baldwin }
1407091d81d1SSam Leffler 
1408c0341432SJohn Baldwin static bool
1409c0341432SJohn Baldwin swcr_cipher_supported(const struct crypto_session_params *csp)
1410c0341432SJohn Baldwin {
1411*d8787d4fSMark Johnston 	const struct enc_xform *txf;
1412c0341432SJohn Baldwin 
1413c0341432SJohn Baldwin 	txf = crypto_cipher(csp);
1414c0341432SJohn Baldwin 	if (txf == NULL)
1415c0341432SJohn Baldwin 		return (false);
1416c0341432SJohn Baldwin 	if (csp->csp_cipher_alg != CRYPTO_NULL_CBC &&
1417c0341432SJohn Baldwin 	    txf->ivsize != csp->csp_ivlen)
1418c0341432SJohn Baldwin 		return (false);
1419c0341432SJohn Baldwin 	return (true);
1420c0341432SJohn Baldwin }
1421c0341432SJohn Baldwin 
14226038018aSMarcin Wojtas #define SUPPORTED_SES (CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD | CSP_F_ESN)
14236038018aSMarcin Wojtas 
1424c0341432SJohn Baldwin static int
1425c0341432SJohn Baldwin swcr_probesession(device_t dev, const struct crypto_session_params *csp)
1426c0341432SJohn Baldwin {
14276038018aSMarcin Wojtas 	if ((csp->csp_flags & ~(SUPPORTED_SES)) != 0)
1428c0341432SJohn Baldwin 		return (EINVAL);
1429c0341432SJohn Baldwin 	switch (csp->csp_mode) {
1430c0341432SJohn Baldwin 	case CSP_MODE_COMPRESS:
1431c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1432c0341432SJohn Baldwin 		case CRYPTO_DEFLATE_COMP:
1433c0341432SJohn Baldwin 			break;
1434c0341432SJohn Baldwin 		default:
1435c0341432SJohn Baldwin 			return (EINVAL);
14365fbc5b5aSConrad Meyer 		}
1437091d81d1SSam Leffler 		break;
1438c0341432SJohn Baldwin 	case CSP_MODE_CIPHER:
1439c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1440c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GCM_16:
1441c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_16:
1442dd2e1352SJohn Baldwin 		case CRYPTO_CHACHA20_POLY1305:
1443c0341432SJohn Baldwin 			return (EINVAL);
1444c0341432SJohn Baldwin 		default:
1445c0341432SJohn Baldwin 			if (!swcr_cipher_supported(csp))
1446c0341432SJohn Baldwin 				return (EINVAL);
1447091d81d1SSam Leffler 			break;
1448091d81d1SSam Leffler 		}
1449c0341432SJohn Baldwin 		break;
1450c0341432SJohn Baldwin 	case CSP_MODE_DIGEST:
1451c0341432SJohn Baldwin 		if (!swcr_auth_supported(csp))
1452c0341432SJohn Baldwin 			return (EINVAL);
1453c0341432SJohn Baldwin 		break;
1454c0341432SJohn Baldwin 	case CSP_MODE_AEAD:
1455c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1456c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GCM_16:
1457c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_16:
1458dd2e1352SJohn Baldwin 		case CRYPTO_CHACHA20_POLY1305:
1459c0341432SJohn Baldwin 			break;
1460c0341432SJohn Baldwin 		default:
1461c0341432SJohn Baldwin 			return (EINVAL);
1462c0341432SJohn Baldwin 		}
1463c0341432SJohn Baldwin 		break;
1464c0341432SJohn Baldwin 	case CSP_MODE_ETA:
1465c0341432SJohn Baldwin 		/* AEAD algorithms cannot be used for EtA. */
1466c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1467c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GCM_16:
1468c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_16:
1469dd2e1352SJohn Baldwin 		case CRYPTO_CHACHA20_POLY1305:
1470c0341432SJohn Baldwin 			return (EINVAL);
1471c0341432SJohn Baldwin 		}
1472c0341432SJohn Baldwin 		switch (csp->csp_auth_alg) {
1473c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GMAC:
1474c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_CBC_MAC:
1475c0341432SJohn Baldwin 			return (EINVAL);
1476c0341432SJohn Baldwin 		}
1477c0341432SJohn Baldwin 
1478c0341432SJohn Baldwin 		if (!swcr_cipher_supported(csp) ||
1479c0341432SJohn Baldwin 		    !swcr_auth_supported(csp))
1480c0341432SJohn Baldwin 			return (EINVAL);
1481c0341432SJohn Baldwin 		break;
1482c0341432SJohn Baldwin 	default:
1483c0341432SJohn Baldwin 		return (EINVAL);
1484c0341432SJohn Baldwin 	}
1485c0341432SJohn Baldwin 
1486c0341432SJohn Baldwin 	return (CRYPTODEV_PROBE_SOFTWARE);
1487c0341432SJohn Baldwin }
1488c0341432SJohn Baldwin 
1489c0341432SJohn Baldwin /*
1490c0341432SJohn Baldwin  * Generate a new software session.
1491c0341432SJohn Baldwin  */
1492c0341432SJohn Baldwin static int
1493c0341432SJohn Baldwin swcr_newsession(device_t dev, crypto_session_t cses,
1494c0341432SJohn Baldwin     const struct crypto_session_params *csp)
1495c0341432SJohn Baldwin {
1496c0341432SJohn Baldwin 	struct swcr_session *ses;
1497c0341432SJohn Baldwin 	struct swcr_encdec *swe;
1498c0341432SJohn Baldwin 	struct swcr_auth *swa;
1499*d8787d4fSMark Johnston 	const struct comp_algo *cxf;
1500c0341432SJohn Baldwin 	int error;
1501c0341432SJohn Baldwin 
1502c0341432SJohn Baldwin 	ses = crypto_get_driver_session(cses);
1503c0341432SJohn Baldwin 	mtx_init(&ses->swcr_lock, "swcr session lock", NULL, MTX_DEF);
1504c0341432SJohn Baldwin 
1505c0341432SJohn Baldwin 	error = 0;
1506c0341432SJohn Baldwin 	swe = &ses->swcr_encdec;
1507c0341432SJohn Baldwin 	swa = &ses->swcr_auth;
1508c0341432SJohn Baldwin 	switch (csp->csp_mode) {
1509c0341432SJohn Baldwin 	case CSP_MODE_COMPRESS:
1510c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1511c0341432SJohn Baldwin 		case CRYPTO_DEFLATE_COMP:
1512c0341432SJohn Baldwin 			cxf = &comp_algo_deflate;
1513c0341432SJohn Baldwin 			break;
1514c0341432SJohn Baldwin #ifdef INVARIANTS
1515c0341432SJohn Baldwin 		default:
1516c0341432SJohn Baldwin 			panic("bad compression algo");
1517c0341432SJohn Baldwin #endif
1518c0341432SJohn Baldwin 		}
1519c0341432SJohn Baldwin 		ses->swcr_compdec.sw_cxf = cxf;
1520c0341432SJohn Baldwin 		ses->swcr_process = swcr_compdec;
1521c0341432SJohn Baldwin 		break;
1522c0341432SJohn Baldwin 	case CSP_MODE_CIPHER:
1523c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1524c0341432SJohn Baldwin 		case CRYPTO_NULL_CBC:
1525c0341432SJohn Baldwin 			ses->swcr_process = swcr_null;
1526c0341432SJohn Baldwin 			break;
1527c0341432SJohn Baldwin #ifdef INVARIANTS
1528c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GCM_16:
1529c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_16:
1530dd2e1352SJohn Baldwin 		case CRYPTO_CHACHA20_POLY1305:
1531c0341432SJohn Baldwin 			panic("bad cipher algo");
1532c0341432SJohn Baldwin #endif
1533c0341432SJohn Baldwin 		default:
15343e947048SJohn Baldwin 			error = swcr_setup_cipher(ses, csp);
1535c0341432SJohn Baldwin 			if (error == 0)
1536c0341432SJohn Baldwin 				ses->swcr_process = swcr_encdec;
1537c0341432SJohn Baldwin 		}
1538c0341432SJohn Baldwin 		break;
1539c0341432SJohn Baldwin 	case CSP_MODE_DIGEST:
1540c0341432SJohn Baldwin 		error = swcr_setup_auth(ses, csp);
1541c0341432SJohn Baldwin 		break;
1542c0341432SJohn Baldwin 	case CSP_MODE_AEAD:
1543c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1544c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GCM_16:
1545c0341432SJohn Baldwin 			error = swcr_setup_gcm(ses, csp);
1546c0341432SJohn Baldwin 			if (error == 0)
1547c0341432SJohn Baldwin 				ses->swcr_process = swcr_gcm;
1548c0341432SJohn Baldwin 			break;
1549c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_16:
1550c0341432SJohn Baldwin 			error = swcr_setup_ccm(ses, csp);
1551c0341432SJohn Baldwin 			if (error == 0)
1552c0341432SJohn Baldwin 				ses->swcr_process = swcr_ccm;
1553c0341432SJohn Baldwin 			break;
1554dd2e1352SJohn Baldwin 		case CRYPTO_CHACHA20_POLY1305:
1555dd2e1352SJohn Baldwin 			error = swcr_setup_chacha20_poly1305(ses, csp);
1556dd2e1352SJohn Baldwin 			if (error == 0)
1557dd2e1352SJohn Baldwin 				ses->swcr_process = swcr_chacha20_poly1305;
1558dd2e1352SJohn Baldwin 			break;
1559c0341432SJohn Baldwin #ifdef INVARIANTS
1560c0341432SJohn Baldwin 		default:
1561c0341432SJohn Baldwin 			panic("bad aead algo");
1562c0341432SJohn Baldwin #endif
1563c0341432SJohn Baldwin 		}
1564c0341432SJohn Baldwin 		break;
1565c0341432SJohn Baldwin 	case CSP_MODE_ETA:
1566c0341432SJohn Baldwin #ifdef INVARIANTS
1567c0341432SJohn Baldwin 		switch (csp->csp_cipher_alg) {
1568c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GCM_16:
1569c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_16:
1570dd2e1352SJohn Baldwin 		case CRYPTO_CHACHA20_POLY1305:
1571c0341432SJohn Baldwin 			panic("bad eta cipher algo");
1572c0341432SJohn Baldwin 		}
1573c0341432SJohn Baldwin 		switch (csp->csp_auth_alg) {
1574c0341432SJohn Baldwin 		case CRYPTO_AES_NIST_GMAC:
1575c0341432SJohn Baldwin 		case CRYPTO_AES_CCM_CBC_MAC:
1576c0341432SJohn Baldwin 			panic("bad eta auth algo");
1577c0341432SJohn Baldwin 		}
1578c0341432SJohn Baldwin #endif
1579c0341432SJohn Baldwin 
1580c0341432SJohn Baldwin 		error = swcr_setup_auth(ses, csp);
1581c0341432SJohn Baldwin 		if (error)
1582c0341432SJohn Baldwin 			break;
1583c0341432SJohn Baldwin 		if (csp->csp_cipher_alg == CRYPTO_NULL_CBC) {
1584c0341432SJohn Baldwin 			/* Effectively degrade to digest mode. */
1585c0341432SJohn Baldwin 			ses->swcr_process = swcr_authcompute;
1586c0341432SJohn Baldwin 			break;
1587c0341432SJohn Baldwin 		}
1588c0341432SJohn Baldwin 
15893e947048SJohn Baldwin 		error = swcr_setup_cipher(ses, csp);
1590c0341432SJohn Baldwin 		if (error == 0)
1591c0341432SJohn Baldwin 			ses->swcr_process = swcr_eta;
1592c0341432SJohn Baldwin 		break;
1593c0341432SJohn Baldwin 	default:
1594c0341432SJohn Baldwin 		error = EINVAL;
1595c0341432SJohn Baldwin 	}
1596c0341432SJohn Baldwin 
1597c0341432SJohn Baldwin 	if (error)
1598c0341432SJohn Baldwin 		swcr_freesession(dev, cses);
1599c0341432SJohn Baldwin 	return (error);
1600c0341432SJohn Baldwin }
1601c0341432SJohn Baldwin 
1602c0341432SJohn Baldwin static void
1603c0341432SJohn Baldwin swcr_freesession(device_t dev, crypto_session_t cses)
1604c0341432SJohn Baldwin {
1605c0341432SJohn Baldwin 	struct swcr_session *ses;
1606c0341432SJohn Baldwin 
1607c0341432SJohn Baldwin 	ses = crypto_get_driver_session(cses);
1608c0341432SJohn Baldwin 
1609c0341432SJohn Baldwin 	mtx_destroy(&ses->swcr_lock);
1610c0341432SJohn Baldwin 
16113e947048SJohn Baldwin 	zfree(ses->swcr_encdec.sw_kschedule, M_CRYPTO_DATA);
16124a711b8dSJohn Baldwin 	zfree(ses->swcr_auth.sw_ictx, M_CRYPTO_DATA);
16134a711b8dSJohn Baldwin 	zfree(ses->swcr_auth.sw_octx, M_CRYPTO_DATA);
1614091d81d1SSam Leffler }
1615091d81d1SSam Leffler 
1616091d81d1SSam Leffler /*
1617091d81d1SSam Leffler  * Process a software request.
1618091d81d1SSam Leffler  */
1619091d81d1SSam Leffler static int
16206810ad6fSSam Leffler swcr_process(device_t dev, struct cryptop *crp, int hint)
1621091d81d1SSam Leffler {
1622c0341432SJohn Baldwin 	struct swcr_session *ses;
1623091d81d1SSam Leffler 
16241b0909d5SConrad Meyer 	ses = crypto_get_driver_session(crp->crp_session);
1625a7fcb1afSSean Eric Fagan 	mtx_lock(&ses->swcr_lock);
1626091d81d1SSam Leffler 
1627c0341432SJohn Baldwin 	crp->crp_etype = ses->swcr_process(ses, crp);
1628091d81d1SSam Leffler 
1629a7fcb1afSSean Eric Fagan 	mtx_unlock(&ses->swcr_lock);
1630091d81d1SSam Leffler 	crypto_done(crp);
1631c0341432SJohn Baldwin 	return (0);
1632091d81d1SSam Leffler }
1633091d81d1SSam Leffler 
1634091d81d1SSam Leffler static void
16353f147ab2SWarner Losh swcr_identify(driver_t *drv, device_t parent)
1636091d81d1SSam Leffler {
16376810ad6fSSam Leffler 	/* NB: order 10 is so we get attached after h/w devices */
16386810ad6fSSam Leffler 	if (device_find_child(parent, "cryptosoft", -1) == NULL &&
163986c585d9SMarius Strobl 	    BUS_ADD_CHILD(parent, 10, "cryptosoft", 0) == 0)
16406810ad6fSSam Leffler 		panic("cryptosoft: could not attach");
16416810ad6fSSam Leffler }
1642f6c4bc3bSPawel Jakub Dawidek 
16436810ad6fSSam Leffler static int
16446810ad6fSSam Leffler swcr_probe(device_t dev)
16456810ad6fSSam Leffler {
16466810ad6fSSam Leffler 	device_set_desc(dev, "software crypto");
16474fc60fa9SMark Johnston 	device_quiet(dev);
164886c585d9SMarius Strobl 	return (BUS_PROBE_NOWILDCARD);
16496810ad6fSSam Leffler }
1650f6c4bc3bSPawel Jakub Dawidek 
16516810ad6fSSam Leffler static int
16526810ad6fSSam Leffler swcr_attach(device_t dev)
16536810ad6fSSam Leffler {
16546810ad6fSSam Leffler 
16559ebbebe4SConrad Meyer 	swcr_id = crypto_get_driverid(dev, sizeof(struct swcr_session),
16566810ad6fSSam Leffler 			CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
16576810ad6fSSam Leffler 	if (swcr_id < 0) {
16586810ad6fSSam Leffler 		device_printf(dev, "cannot initialize!");
1659c0341432SJohn Baldwin 		return (ENXIO);
16606810ad6fSSam Leffler 	}
16616810ad6fSSam Leffler 
1662c0341432SJohn Baldwin 	return (0);
1663091d81d1SSam Leffler }
16644b465da2SPawel Jakub Dawidek 
16653f147ab2SWarner Losh static int
16666810ad6fSSam Leffler swcr_detach(device_t dev)
16674b465da2SPawel Jakub Dawidek {
16686810ad6fSSam Leffler 	crypto_unregister_all(swcr_id);
16693f147ab2SWarner Losh 	return 0;
16704b465da2SPawel Jakub Dawidek }
16716810ad6fSSam Leffler 
16726810ad6fSSam Leffler static device_method_t swcr_methods[] = {
16736810ad6fSSam Leffler 	DEVMETHOD(device_identify,	swcr_identify),
16746810ad6fSSam Leffler 	DEVMETHOD(device_probe,		swcr_probe),
16756810ad6fSSam Leffler 	DEVMETHOD(device_attach,	swcr_attach),
16766810ad6fSSam Leffler 	DEVMETHOD(device_detach,	swcr_detach),
16776810ad6fSSam Leffler 
1678c0341432SJohn Baldwin 	DEVMETHOD(cryptodev_probesession, swcr_probesession),
16796810ad6fSSam Leffler 	DEVMETHOD(cryptodev_newsession,	swcr_newsession),
16806810ad6fSSam Leffler 	DEVMETHOD(cryptodev_freesession,swcr_freesession),
16816810ad6fSSam Leffler 	DEVMETHOD(cryptodev_process,	swcr_process),
16826810ad6fSSam Leffler 
16836810ad6fSSam Leffler 	{0, 0},
16846810ad6fSSam Leffler };
16856810ad6fSSam Leffler 
16866810ad6fSSam Leffler static driver_t swcr_driver = {
16876810ad6fSSam Leffler 	"cryptosoft",
16886810ad6fSSam Leffler 	swcr_methods,
16896810ad6fSSam Leffler 	0,		/* NB: no softc */
16906810ad6fSSam Leffler };
16916810ad6fSSam Leffler static devclass_t swcr_devclass;
16926810ad6fSSam Leffler 
16936810ad6fSSam Leffler /*
16946810ad6fSSam Leffler  * NB: We explicitly reference the crypto module so we
16956810ad6fSSam Leffler  * get the necessary ordering when built as a loadable
16966810ad6fSSam Leffler  * module.  This is required because we bundle the crypto
16976810ad6fSSam Leffler  * module code together with the cryptosoft driver (otherwise
16986810ad6fSSam Leffler  * normal module dependencies would handle things).
16996810ad6fSSam Leffler  */
17006810ad6fSSam Leffler extern int crypto_modevent(struct module *, int, void *);
17016810ad6fSSam Leffler /* XXX where to attach */
17026810ad6fSSam Leffler DRIVER_MODULE(cryptosoft, nexus, swcr_driver, swcr_devclass, crypto_modevent,0);
17036810ad6fSSam Leffler MODULE_VERSION(cryptosoft, 1);
17046810ad6fSSam Leffler MODULE_DEPEND(cryptosoft, crypto, 1, 1, 1);
1705