xref: /openbsd-src/sys/arch/octeon/dev/octcrypto.c (revision 0cd0a70e4ce0c8e826455a0a4a676c68b67ec75d)
1*0cd0a70eSpatrick /*	$OpenBSD: octcrypto.c,v 1.8 2021/10/24 10:26:22 patrick Exp $	*/
2d4086a48Svisa 
3d4086a48Svisa /*
4d4086a48Svisa  * Copyright (c) 2018 Visa Hankala
5d4086a48Svisa  *
6d4086a48Svisa  * Permission to use, copy, modify, and/or distribute this software for any
7d4086a48Svisa  * purpose with or without fee is hereby granted, provided that the above
8d4086a48Svisa  * copyright notice and this permission notice appear in all copies.
9d4086a48Svisa  *
10d4086a48Svisa  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11d4086a48Svisa  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12d4086a48Svisa  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13d4086a48Svisa  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14d4086a48Svisa  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15d4086a48Svisa  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16d4086a48Svisa  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17d4086a48Svisa  */
18d4086a48Svisa 
19d4086a48Svisa /*
20d4086a48Svisa  * Driver for the OCTEON cryptographic unit.
21d4086a48Svisa  */
22d4086a48Svisa 
23d4086a48Svisa #include <sys/param.h>
24d4086a48Svisa #include <sys/systm.h>
25d4086a48Svisa #include <sys/atomic.h>
26d4086a48Svisa #include <sys/malloc.h>
27d4086a48Svisa #include <sys/mbuf.h>
28d4086a48Svisa #include <sys/pool.h>
2927b68cf7Svisa #include <sys/smr.h>
30d4086a48Svisa #include <sys/tree.h>
31d4086a48Svisa 
32d4086a48Svisa #include <crypto/cryptodev.h>
33d4086a48Svisa #include <crypto/cryptosoft.h>
34d4086a48Svisa #include <crypto/xform.h>
35d4086a48Svisa 
36d4086a48Svisa #include <mips64/mips_cpu.h>
37d4086a48Svisa 
38d4086a48Svisa #include <machine/octeonvar.h>
39d4086a48Svisa 
40d4086a48Svisa /* Maximum number of dwords in hash IV. */
41d4086a48Svisa #define MAX_IVNW		8
42d4086a48Svisa 
43d4086a48Svisa /* Number of dwords needed to cover `n' bytes. */
44d4086a48Svisa #define ndwords(n)		(roundup(n, 8) / (8))
45d4086a48Svisa 
46d4086a48Svisa struct octcrypto_softc;
47d4086a48Svisa 
48d4086a48Svisa struct octcrypto_hmac {
49d4086a48Svisa 	void			(*transform)(const void *, size_t);
50d4086a48Svisa 	void			(*get_iv)(uint64_t *);
51d4086a48Svisa 	void			(*set_iv)(const uint64_t *);
52d4086a48Svisa 	void			(*clear)(void);
53d4086a48Svisa 	uint16_t		 blocklen;
54d4086a48Svisa 	uint16_t		 taglen;
55d4086a48Svisa 	uint16_t		 countlen;
56d4086a48Svisa };
57d4086a48Svisa 
58d4086a48Svisa struct octcrypto_session {
59d4086a48Svisa 	uint32_t		 ses_sid;		/* RB key, keep first */
60d4086a48Svisa 	RBT_ENTRY(octrcypto_session)
61d4086a48Svisa 				 ses_entry;
62d4086a48Svisa 	struct octcrypto_softc	*ses_sc;
6327b68cf7Svisa 	struct smr_entry	 ses_smr;
64d4086a48Svisa 
65d4086a48Svisa 	/* AES parameters */
66d4086a48Svisa 	uint64_t		 ses_key[4];
67d4086a48Svisa 	int			 ses_klen;
68d4086a48Svisa 	uint8_t			 ses_nonce[AESCTR_NONCESIZE];
69d4086a48Svisa 
70d4086a48Svisa 	/* HMAC parameters */
71d4086a48Svisa 	const struct octcrypto_hmac
72d4086a48Svisa 				*ses_hmac;
73d4086a48Svisa 	uint64_t		 ses_iiv[MAX_IVNW];	/* HMAC inner IV */
74d4086a48Svisa 	uint64_t		 ses_oiv[MAX_IVNW];	/* HMAC outer IV */
75d4086a48Svisa 
76d4086a48Svisa 	/* GHASH parameters */
77d4086a48Svisa 	uint64_t		 ses_ghkey[2];
78d4086a48Svisa 
79d4086a48Svisa 	struct swcr_data	*ses_swd;
80d4086a48Svisa };
81d4086a48Svisa 
82d4086a48Svisa struct octcrypto_cpu {
83d4086a48Svisa 	uint8_t			*pcpu_buf;
84d4086a48Svisa 	size_t			 pcpu_buflen;
85d4086a48Svisa };
86d4086a48Svisa 
87d4086a48Svisa struct octcrypto_softc {
88d4086a48Svisa 	struct device		 sc_dev;
89d4086a48Svisa 	int32_t			 sc_cid;
90d4086a48Svisa 	uint32_t		 sc_sid;
91d4086a48Svisa 	struct mutex		 sc_mtx;
92d4086a48Svisa 	RBT_HEAD(octcrypto_tree, octcrypto_session)
93d4086a48Svisa 				 sc_sessions;
94d4086a48Svisa 	struct octcrypto_cpu	 sc_cpu[MAXCPUS];
95d4086a48Svisa };
96d4086a48Svisa 
97d4086a48Svisa int	octcrypto_match(struct device *, void *, void *);
98d4086a48Svisa void	octcrypto_attach(struct device *, struct device *, void *);
99d4086a48Svisa 
100d4086a48Svisa int	octcrypto_newsession(uint32_t *, struct cryptoini *);
101d4086a48Svisa int	octcrypto_freesession(uint64_t);
102d4086a48Svisa int	octcrypto_process(struct cryptop *);
103d4086a48Svisa 
104d4086a48Svisa struct octcrypto_session *
105d4086a48Svisa 	octcrypto_get(struct octcrypto_softc *, uint32_t);
10627b68cf7Svisa void	octcrypto_free(struct octcrypto_session *);
10727b68cf7Svisa void	octcrypto_free_smr(void *);
108d4086a48Svisa 
109d4086a48Svisa void	octcrypto_hmac(struct cryptodesc *, uint8_t *, size_t,
110d4086a48Svisa 	    struct octcrypto_session *, uint64_t *);
111d4086a48Svisa int	octcrypto_authenc_gmac(struct cryptop *, struct cryptodesc *,
112d4086a48Svisa 	    struct cryptodesc *, struct octcrypto_session *);
113d4086a48Svisa int	octcrypto_authenc_hmac(struct cryptop *, struct cryptodesc *,
114d4086a48Svisa 	    struct cryptodesc *, struct octcrypto_session *);
115d4086a48Svisa int	octcrypto_swauth(struct cryptop *, struct cryptodesc *,
116d4086a48Svisa 	    struct swcr_data *, uint8_t *);
117d4086a48Svisa 
118d4086a48Svisa void	octcrypto_ghash_update_md(GHASH_CTX *, uint8_t *, size_t);
119d4086a48Svisa 
120d4086a48Svisa void	octcrypto_aes_clear(void);
121d4086a48Svisa void	octcrypto_aes_cbc_dec(void *, size_t, const void *);
122d4086a48Svisa void	octcrypto_aes_cbc_enc(void *, size_t, const void *);
123d4086a48Svisa void	octcrypto_aes_ctr_enc(void *, size_t, const void *);
124d4086a48Svisa void	octcrypto_aes_enc(uint64_t *);
125d4086a48Svisa void	octcrypto_aes_set_key(const uint64_t *, int);
126d4086a48Svisa 
127d4086a48Svisa void	octcrypto_ghash_finish(uint64_t *);
128d4086a48Svisa void	octcrypto_ghash_init(const uint64_t *, const uint64_t *);
129d4086a48Svisa void	octcrypto_ghash_update(const void *, size_t);
130d4086a48Svisa 
131d4086a48Svisa void	octcrypto_hash_md5(const void *, size_t);
132d4086a48Svisa void	octcrypto_hash_sha1(const void *, size_t);
133d4086a48Svisa void	octcrypto_hash_sha256(const void *, size_t);
134d4086a48Svisa void	octcrypto_hash_sha512(const void *, size_t);
135d4086a48Svisa void	octcrypto_hash_clearn(void);
136d4086a48Svisa void	octcrypto_hash_clearw(void);
137d4086a48Svisa void	octcrypto_hash_get_ivn(uint64_t *);
138d4086a48Svisa void	octcrypto_hash_get_ivw(uint64_t *);
139d4086a48Svisa void	octcrypto_hash_set_ivn(const uint64_t *);
140d4086a48Svisa void	octcrypto_hash_set_ivw(const uint64_t *);
141d4086a48Svisa 
142d4086a48Svisa const struct cfattach octcrypto_ca = {
143d4086a48Svisa 	sizeof(struct octcrypto_softc), octcrypto_match, octcrypto_attach
144d4086a48Svisa };
145d4086a48Svisa 
146d4086a48Svisa struct cfdriver octcrypto_cd = {
147d4086a48Svisa 	NULL, "octcrypto", DV_DULL
148d4086a48Svisa };
149d4086a48Svisa 
150d4086a48Svisa static const struct octcrypto_hmac hmac_md5_96 = {
151d4086a48Svisa 	.transform = octcrypto_hash_md5,
152d4086a48Svisa 	.get_iv = octcrypto_hash_get_ivn,
153d4086a48Svisa 	.set_iv = octcrypto_hash_set_ivn,
154d4086a48Svisa 	.clear = octcrypto_hash_clearn,
155d4086a48Svisa 	.blocklen = 64,
156d4086a48Svisa 	.taglen = 12,
157d4086a48Svisa 	.countlen = 8
158d4086a48Svisa };
159d4086a48Svisa 
160d4086a48Svisa static const struct octcrypto_hmac hmac_sha1_96 = {
161d4086a48Svisa 	.transform = octcrypto_hash_sha1,
162d4086a48Svisa 	.get_iv = octcrypto_hash_get_ivn,
163d4086a48Svisa 	.set_iv = octcrypto_hash_set_ivn,
164d4086a48Svisa 	.clear = octcrypto_hash_clearn,
165d4086a48Svisa 	.blocklen = 64,
166d4086a48Svisa 	.taglen = 12,
167d4086a48Svisa 	.countlen = 8
168d4086a48Svisa };
169d4086a48Svisa 
170d4086a48Svisa static const struct octcrypto_hmac hmac_sha2_256_128 = {
171d4086a48Svisa 	.transform = octcrypto_hash_sha256,
172d4086a48Svisa 	.get_iv = octcrypto_hash_get_ivn,
173d4086a48Svisa 	.set_iv = octcrypto_hash_set_ivn,
174d4086a48Svisa 	.clear = octcrypto_hash_clearn,
175d4086a48Svisa 	.blocklen = 64,
176d4086a48Svisa 	.taglen = 16,
177d4086a48Svisa 	.countlen = 8
178d4086a48Svisa };
179d4086a48Svisa 
180d4086a48Svisa static const struct octcrypto_hmac hmac_sha2_384_192 = {
181d4086a48Svisa 	.transform = octcrypto_hash_sha512,
182d4086a48Svisa 	.get_iv = octcrypto_hash_get_ivw,
183d4086a48Svisa 	.set_iv = octcrypto_hash_set_ivw,
184d4086a48Svisa 	.clear = octcrypto_hash_clearw,
185d4086a48Svisa 	.blocklen = 128,
186d4086a48Svisa 	.taglen = 24,
187d4086a48Svisa 	.countlen = 16
188d4086a48Svisa };
189d4086a48Svisa 
190d4086a48Svisa static const struct octcrypto_hmac hmac_sha2_512_256 = {
191d4086a48Svisa 	.transform = octcrypto_hash_sha512,
192d4086a48Svisa 	.get_iv = octcrypto_hash_get_ivw,
193d4086a48Svisa 	.set_iv = octcrypto_hash_set_ivw,
194d4086a48Svisa 	.clear = octcrypto_hash_clearw,
195d4086a48Svisa 	.blocklen = 128,
196d4086a48Svisa 	.taglen = 32,
197d4086a48Svisa 	.countlen = 16
198d4086a48Svisa };
199d4086a48Svisa 
200d4086a48Svisa static struct pool		 octcryptopl;
201d4086a48Svisa static struct octcrypto_softc	*octcrypto_sc;
202d4086a48Svisa 
203d4086a48Svisa static inline int
octcrypto_cmp(const struct octcrypto_session * a,const struct octcrypto_session * b)204d4086a48Svisa octcrypto_cmp(const struct octcrypto_session *a,
205d4086a48Svisa     const struct octcrypto_session *b)
206d4086a48Svisa {
207d4086a48Svisa 	if (a->ses_sid < b->ses_sid)
208d4086a48Svisa 		return -1;
209d4086a48Svisa 	if (a->ses_sid > b->ses_sid)
210d4086a48Svisa 		return 1;
211d4086a48Svisa 	return 0;
212d4086a48Svisa }
213d4086a48Svisa 
214d4086a48Svisa RBT_PROTOTYPE(octcrypto_tree, octcrypto_session, sess_entry, octcrypto_cmp);
215d4086a48Svisa RBT_GENERATE(octcrypto_tree, octcrypto_session, ses_entry, octcrypto_cmp);
216d4086a48Svisa 
217d4086a48Svisa static inline void
cop2_enable(void)218d4086a48Svisa cop2_enable(void)
219d4086a48Svisa {
220d4086a48Svisa 	setsr(getsr() | SR_COP_2_BIT);
221d4086a48Svisa }
222d4086a48Svisa 
223d4086a48Svisa static inline void
cop2_disable(void)224d4086a48Svisa cop2_disable(void)
225d4086a48Svisa {
226d4086a48Svisa 	setsr(getsr() & ~SR_COP_2_BIT);
227d4086a48Svisa }
228d4086a48Svisa 
229d4086a48Svisa int
octcrypto_match(struct device * parent,void * match,void * aux)230d4086a48Svisa octcrypto_match(struct device *parent, void *match, void *aux)
231d4086a48Svisa {
232d4086a48Svisa 	return 1;
233d4086a48Svisa }
234d4086a48Svisa 
235d4086a48Svisa void
octcrypto_attach(struct device * parent,struct device * self,void * aux)236d4086a48Svisa octcrypto_attach(struct device *parent, struct device *self, void *aux)
237d4086a48Svisa {
238d4086a48Svisa 	int algs[CRYPTO_ALGORITHM_MAX + 1];
239d4086a48Svisa 	struct octcrypto_softc *sc = (struct octcrypto_softc *)self;
240d4086a48Svisa 
241ae2e3038Svisa 	pool_init(&octcryptopl, sizeof(struct octcrypto_session), 0, IPL_VM, 0,
242d4086a48Svisa 	    "octcrypto", NULL);
243d4086a48Svisa 	pool_setlowat(&octcryptopl, 2);
244d4086a48Svisa 
245d4086a48Svisa 	mtx_init(&sc->sc_mtx, IPL_VM);
246d4086a48Svisa 	RBT_INIT(octcrypto_tree, &sc->sc_sessions);
247d4086a48Svisa 
248d4086a48Svisa 	sc->sc_cid = crypto_get_driverid(CRYPTOCAP_F_MPSAFE);
249d4086a48Svisa 	if (sc->sc_cid < 0) {
250d4086a48Svisa 		printf(": could not get driver id\n");
251d4086a48Svisa 		return;
252d4086a48Svisa 	}
253d4086a48Svisa 
254d4086a48Svisa 	printf("\n");
255d4086a48Svisa 
256d4086a48Svisa 	memset(algs, 0, sizeof(algs));
257d4086a48Svisa 
258d4086a48Svisa 	algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
259d4086a48Svisa 	algs[CRYPTO_AES_CTR] = CRYPTO_ALG_FLAG_SUPPORTED;
260d4086a48Svisa 	algs[CRYPTO_AES_GCM_16] = CRYPTO_ALG_FLAG_SUPPORTED;
261d4086a48Svisa 
262d4086a48Svisa 	algs[CRYPTO_AES_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
263d4086a48Svisa 	algs[CRYPTO_AES_128_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
264d4086a48Svisa 	algs[CRYPTO_AES_192_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
265d4086a48Svisa 	algs[CRYPTO_AES_256_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
266d4086a48Svisa 
267d4086a48Svisa 	algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
268d4086a48Svisa 	algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
269d4086a48Svisa 	algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
270d4086a48Svisa 	algs[CRYPTO_SHA2_384_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
271d4086a48Svisa 	algs[CRYPTO_SHA2_512_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
272d4086a48Svisa 
273d4086a48Svisa 	algs[CRYPTO_RIPEMD160_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
274d4086a48Svisa 
275d4086a48Svisa 	algs[CRYPTO_ESN] = CRYPTO_ALG_FLAG_SUPPORTED;
276d4086a48Svisa 
277d4086a48Svisa 	octcrypto_sc = sc;
278d4086a48Svisa 
279d4086a48Svisa 	crypto_register(sc->sc_cid, algs, octcrypto_newsession,
280d4086a48Svisa 	    octcrypto_freesession, octcrypto_process);
281d4086a48Svisa 
282d4086a48Svisa 	ghash_update = octcrypto_ghash_update_md;
283d4086a48Svisa }
284d4086a48Svisa 
285d4086a48Svisa struct octcrypto_session *
octcrypto_get(struct octcrypto_softc * sc,uint32_t sid)286d4086a48Svisa octcrypto_get(struct octcrypto_softc *sc, uint32_t sid)
287d4086a48Svisa {
288d4086a48Svisa 	struct octcrypto_session *ses;
289d4086a48Svisa 
29027b68cf7Svisa 	SMR_ASSERT_CRITICAL();
29127b68cf7Svisa 
292d4086a48Svisa 	mtx_enter(&sc->sc_mtx);
293d4086a48Svisa 	ses = RBT_FIND(octcrypto_tree, &sc->sc_sessions,
294d4086a48Svisa 	    (struct octcrypto_session *)&sid);
295d4086a48Svisa 	mtx_leave(&sc->sc_mtx);
296d4086a48Svisa 	return ses;
297d4086a48Svisa }
298d4086a48Svisa 
299d4086a48Svisa void
octcrypto_free(struct octcrypto_session * ses)30027b68cf7Svisa octcrypto_free(struct octcrypto_session *ses)
301d4086a48Svisa {
3024d13edafSbluhm 	const struct auth_hash *axf;
303d4086a48Svisa 	struct swcr_data *swd;
304d4086a48Svisa 
305d4086a48Svisa 	if (ses->ses_swd != NULL) {
306d4086a48Svisa 		swd = ses->ses_swd;
307d4086a48Svisa 		axf = swd->sw_axf;
308d4086a48Svisa 
309d4086a48Svisa 		if (swd->sw_ictx != NULL) {
310d4086a48Svisa 			explicit_bzero(swd->sw_ictx, axf->ctxsize);
311d4086a48Svisa 			free(swd->sw_ictx, M_CRYPTO_DATA, axf->ctxsize);
312d4086a48Svisa 		}
313d4086a48Svisa 		if (swd->sw_octx != NULL) {
314d4086a48Svisa 			explicit_bzero(swd->sw_octx, axf->ctxsize);
315d4086a48Svisa 			free(swd->sw_octx, M_CRYPTO_DATA, axf->ctxsize);
316d4086a48Svisa 		}
317d4086a48Svisa 		free(swd, M_CRYPTO_DATA, sizeof(*swd));
318d4086a48Svisa 	}
319d4086a48Svisa 
320d4086a48Svisa 	explicit_bzero(ses, sizeof(*ses));
321d4086a48Svisa 	pool_put(&octcryptopl, ses);
322d4086a48Svisa }
323d4086a48Svisa 
32427b68cf7Svisa void
octcrypto_free_smr(void * arg)32527b68cf7Svisa octcrypto_free_smr(void *arg)
32627b68cf7Svisa {
32727b68cf7Svisa 	struct octcrypto_session *ses = arg;
32827b68cf7Svisa 
32927b68cf7Svisa 	octcrypto_free(ses);
33027b68cf7Svisa }
33127b68cf7Svisa 
332d4086a48Svisa int
octcrypto_newsession(uint32_t * sidp,struct cryptoini * cri)333d4086a48Svisa octcrypto_newsession(uint32_t *sidp, struct cryptoini *cri)
334d4086a48Svisa {
335d4086a48Svisa 	uint64_t block[ndwords(HMAC_MAX_BLOCK_LEN)];
3364d13edafSbluhm 	const struct auth_hash *axf;
337d4086a48Svisa 	struct cryptoini *c;
338d4086a48Svisa 	const struct octcrypto_hmac *hmac = NULL;
339d4086a48Svisa 	struct octcrypto_softc *sc = octcrypto_sc;
340d4086a48Svisa 	struct octcrypto_session *ses = NULL;
341d4086a48Svisa 	struct swcr_data *swd;
342d4086a48Svisa 	uint8_t *bptr;
343d4086a48Svisa 	size_t klen;
344d4086a48Svisa 	int i;
345d4086a48Svisa 	uint32_t sid;
346d4086a48Svisa 
347d4086a48Svisa 	if (sidp == NULL || cri == NULL)
348d4086a48Svisa 		return EINVAL;
349d4086a48Svisa 
350d4086a48Svisa 	ses = pool_get(&octcryptopl, PR_NOWAIT | PR_ZERO);
351d4086a48Svisa 	if (ses == NULL)
352d4086a48Svisa 		return ENOMEM;
353d4086a48Svisa 	ses->ses_sc = sc;
35427b68cf7Svisa 	smr_init(&ses->ses_smr);
355d4086a48Svisa 
356d4086a48Svisa 	for (c = cri; c != NULL; c = c->cri_next) {
357d4086a48Svisa 		switch (c->cri_alg) {
358d4086a48Svisa 		case CRYPTO_AES_CBC:
359d4086a48Svisa 			ses->ses_klen = c->cri_klen / 8;
360d4086a48Svisa 			memcpy(ses->ses_key, c->cri_key, ses->ses_klen);
361d4086a48Svisa 			break;
362d4086a48Svisa 
363d4086a48Svisa 		case CRYPTO_AES_CTR:
364d4086a48Svisa 		case CRYPTO_AES_GCM_16:
365d4086a48Svisa 		case CRYPTO_AES_GMAC:
366d4086a48Svisa 			ses->ses_klen = c->cri_klen / 8 - AESCTR_NONCESIZE;
367d4086a48Svisa 			memcpy(ses->ses_key, c->cri_key, ses->ses_klen);
368d4086a48Svisa 			memcpy(ses->ses_nonce, c->cri_key + ses->ses_klen,
369d4086a48Svisa 			    AESCTR_NONCESIZE);
370d4086a48Svisa 			break;
371d4086a48Svisa 
372d4086a48Svisa 		case CRYPTO_AES_128_GMAC:
373d4086a48Svisa 		case CRYPTO_AES_192_GMAC:
374d4086a48Svisa 		case CRYPTO_AES_256_GMAC:
375d4086a48Svisa 			cop2_enable();
376d4086a48Svisa 			octcrypto_aes_set_key(ses->ses_key, ses->ses_klen);
377d4086a48Svisa 			octcrypto_aes_enc(ses->ses_ghkey);
378d4086a48Svisa 			octcrypto_aes_clear();
379d4086a48Svisa 			cop2_disable();
380d4086a48Svisa 			break;
381d4086a48Svisa 
382d4086a48Svisa 		case CRYPTO_MD5_HMAC:
383d4086a48Svisa 			ses->ses_iiv[0] = 0x0123456789abcdefULL;
384d4086a48Svisa 			ses->ses_iiv[1] = 0xfedcba9876543210ULL;
385d4086a48Svisa 			ses->ses_hmac = &hmac_md5_96;
386d4086a48Svisa 			goto hwauthcommon;
387d4086a48Svisa 
388d4086a48Svisa 		case CRYPTO_SHA1_HMAC:
389d4086a48Svisa 			ses->ses_iiv[0] = 0x67452301efcdab89ULL;
390d4086a48Svisa 			ses->ses_iiv[1] = 0x98badcfe10325476ULL;
391d4086a48Svisa 			ses->ses_iiv[2] = 0xc3d2e1f000000000ULL;
392d4086a48Svisa 			ses->ses_hmac = &hmac_sha1_96;
393d4086a48Svisa 			goto hwauthcommon;
394d4086a48Svisa 
395d4086a48Svisa 		case CRYPTO_SHA2_256_HMAC:
396d4086a48Svisa 			ses->ses_iiv[0] = 0x6a09e667bb67ae85ULL;
397d4086a48Svisa 			ses->ses_iiv[1] = 0x3c6ef372a54ff53aULL;
398d4086a48Svisa 			ses->ses_iiv[2] = 0x510e527f9b05688cULL;
399d4086a48Svisa 			ses->ses_iiv[3] = 0x1f83d9ab5be0cd19ULL;
400d4086a48Svisa 			ses->ses_hmac = &hmac_sha2_256_128;
401d4086a48Svisa 			goto hwauthcommon;
402d4086a48Svisa 
403d4086a48Svisa 		case CRYPTO_SHA2_384_HMAC:
404d4086a48Svisa 			ses->ses_iiv[0] = 0xcbbb9d5dc1059ed8ULL;
405d4086a48Svisa 			ses->ses_iiv[1] = 0x629a292a367cd507ULL;
406d4086a48Svisa 			ses->ses_iiv[2] = 0x9159015a3070dd17ULL;
407d4086a48Svisa 			ses->ses_iiv[3] = 0x152fecd8f70e5939ULL;
408d4086a48Svisa 			ses->ses_iiv[4] = 0x67332667ffc00b31ULL;
409d4086a48Svisa 			ses->ses_iiv[5] = 0x8eb44a8768581511ULL;
410d4086a48Svisa 			ses->ses_iiv[6] = 0xdb0c2e0d64f98fa7ULL;
411d4086a48Svisa 			ses->ses_iiv[7] = 0x47b5481dbefa4fa4ULL;
412d4086a48Svisa 			ses->ses_hmac = &hmac_sha2_384_192;
413d4086a48Svisa 			goto hwauthcommon;
414d4086a48Svisa 
415d4086a48Svisa 		case CRYPTO_SHA2_512_HMAC:
416d4086a48Svisa 			ses->ses_iiv[0] = 0x6a09e667f3bcc908ULL;
417d4086a48Svisa 			ses->ses_iiv[1] = 0xbb67ae8584caa73bULL;
418d4086a48Svisa 			ses->ses_iiv[2] = 0x3c6ef372fe94f82bULL;
419d4086a48Svisa 			ses->ses_iiv[3] = 0xa54ff53a5f1d36f1ULL;
420d4086a48Svisa 			ses->ses_iiv[4] = 0x510e527fade682d1ULL;
421d4086a48Svisa 			ses->ses_iiv[5] = 0x9b05688c2b3e6c1fULL;
422d4086a48Svisa 			ses->ses_iiv[6] = 0x1f83d9abfb41bd6bULL;
423d4086a48Svisa 			ses->ses_iiv[7] = 0x5be0cd19137e2179ULL;
424d4086a48Svisa 			ses->ses_hmac = &hmac_sha2_512_256;
425d4086a48Svisa 
426d4086a48Svisa 		hwauthcommon:
427d4086a48Svisa 			memcpy(ses->ses_oiv, ses->ses_iiv,
428d4086a48Svisa 			    sizeof(uint64_t) * MAX_IVNW);
429d4086a48Svisa 
430d4086a48Svisa 			bptr = (char *)block;
431d4086a48Svisa 			klen = c->cri_klen / 8;
432d4086a48Svisa 			hmac = ses->ses_hmac;
433d4086a48Svisa 
434d4086a48Svisa 			memcpy(bptr, c->cri_key, klen);
435d4086a48Svisa 			memset(bptr + klen, 0, hmac->blocklen - klen);
436d4086a48Svisa 			for (i = 0; i < hmac->blocklen; i++)
437d4086a48Svisa 				bptr[i] ^= HMAC_IPAD_VAL;
438d4086a48Svisa 
439d4086a48Svisa 			cop2_enable();
440d4086a48Svisa 			hmac->set_iv(ses->ses_iiv);
441d4086a48Svisa 			hmac->transform(block, hmac->blocklen);
442d4086a48Svisa 			hmac->get_iv(ses->ses_iiv);
443d4086a48Svisa 
444d4086a48Svisa 			for (i = 0; i < hmac->blocklen; i++)
445d4086a48Svisa 				bptr[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
446d4086a48Svisa 
447d4086a48Svisa 			hmac->set_iv(ses->ses_oiv);
448d4086a48Svisa 			hmac->transform(block, hmac->blocklen);
449d4086a48Svisa 			hmac->get_iv(ses->ses_oiv);
450d4086a48Svisa 			hmac->clear();
451d4086a48Svisa 			cop2_disable();
452d4086a48Svisa 
453d4086a48Svisa 			explicit_bzero(block, hmac->blocklen);
454d4086a48Svisa 			break;
455d4086a48Svisa 
456d4086a48Svisa 		case CRYPTO_RIPEMD160_HMAC:
457d4086a48Svisa 			axf = &auth_hash_hmac_ripemd_160_96;
458d4086a48Svisa 			goto swauthcommon;
459d4086a48Svisa 
460d4086a48Svisa 		swauthcommon:
461d4086a48Svisa 			swd = malloc(sizeof(struct swcr_data), M_CRYPTO_DATA,
462d4086a48Svisa 			    M_NOWAIT | M_ZERO);
463d4086a48Svisa 			if (swd == NULL) {
46427b68cf7Svisa 				octcrypto_free(ses);
465d4086a48Svisa 				return ENOMEM;
466d4086a48Svisa 			}
467d4086a48Svisa 			ses->ses_swd = swd;
468d4086a48Svisa 
469d4086a48Svisa 			swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
470d4086a48Svisa 			    M_NOWAIT);
471d4086a48Svisa 			if (swd->sw_ictx == NULL) {
47227b68cf7Svisa 				octcrypto_free(ses);
473d4086a48Svisa 				return ENOMEM;
474d4086a48Svisa 			}
475d4086a48Svisa 
476d4086a48Svisa 			swd->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
477d4086a48Svisa 			    M_NOWAIT);
478d4086a48Svisa 			if (swd->sw_octx == NULL) {
47927b68cf7Svisa 				octcrypto_free(ses);
480d4086a48Svisa 				return ENOMEM;
481d4086a48Svisa 			}
482d4086a48Svisa 
483d4086a48Svisa 			for (i = 0; i < c->cri_klen / 8; i++)
484d4086a48Svisa 				c->cri_key[i] ^= HMAC_IPAD_VAL;
485d4086a48Svisa 
486d4086a48Svisa 			axf->Init(swd->sw_ictx);
487d4086a48Svisa 			axf->Update(swd->sw_ictx, c->cri_key, c->cri_klen / 8);
488d4086a48Svisa 			axf->Update(swd->sw_ictx, hmac_ipad_buffer,
489d4086a48Svisa 			    axf->blocksize - (c->cri_klen / 8));
490d4086a48Svisa 
491d4086a48Svisa 			for (i = 0; i < c->cri_klen / 8; i++)
492d4086a48Svisa 				c->cri_key[i] ^= (HMAC_IPAD_VAL ^
493d4086a48Svisa 				    HMAC_OPAD_VAL);
494d4086a48Svisa 
495d4086a48Svisa 			axf->Init(swd->sw_octx);
496d4086a48Svisa 			axf->Update(swd->sw_octx, c->cri_key, c->cri_klen / 8);
497d4086a48Svisa 			axf->Update(swd->sw_octx, hmac_opad_buffer,
498d4086a48Svisa 			    axf->blocksize - (c->cri_klen / 8));
499d4086a48Svisa 
500d4086a48Svisa 			for (i = 0; i < c->cri_klen / 8; i++)
501d4086a48Svisa 				c->cri_key[i] ^= HMAC_OPAD_VAL;
502d4086a48Svisa 
503d4086a48Svisa 			swd->sw_axf = axf;
504d4086a48Svisa 			swd->sw_alg = c->cri_alg;
505d4086a48Svisa 
506d4086a48Svisa 			break;
507d4086a48Svisa 
508d4086a48Svisa 		case CRYPTO_ESN:
509d4086a48Svisa 			/* nothing to do */
510d4086a48Svisa 			break;
511d4086a48Svisa 
512d4086a48Svisa 		default:
51327b68cf7Svisa 			octcrypto_free(ses);
514d4086a48Svisa 			return EINVAL;
515d4086a48Svisa 		}
516d4086a48Svisa 	}
517d4086a48Svisa 
518d4086a48Svisa 	mtx_enter(&sc->sc_mtx);
519d4086a48Svisa 	/* Find a free session ID. Assume there is one. */
520d4086a48Svisa 	do {
521d4086a48Svisa 		sc->sc_sid++;
522d4086a48Svisa 		if (sc->sc_sid == 0)
523d4086a48Svisa 			sc->sc_sid = 1;
524d4086a48Svisa 		sid = sc->sc_sid;
525d4086a48Svisa 	} while (RBT_FIND(octcrypto_tree, &sc->sc_sessions,
526d4086a48Svisa 	    (struct octcrypto_session *)&sid) != NULL);
527d4086a48Svisa 	ses->ses_sid = sid;
528d4086a48Svisa 	RBT_INSERT(octcrypto_tree, &sc->sc_sessions, ses);
529d4086a48Svisa 	mtx_leave(&sc->sc_mtx);
530d4086a48Svisa 
531d4086a48Svisa 	*sidp = ses->ses_sid;
532d4086a48Svisa 	return 0;
533d4086a48Svisa }
534d4086a48Svisa 
535d4086a48Svisa int
octcrypto_freesession(uint64_t tid)536d4086a48Svisa octcrypto_freesession(uint64_t tid)
537d4086a48Svisa {
538d4086a48Svisa 	struct octcrypto_softc *sc = octcrypto_sc;
539d4086a48Svisa 	struct octcrypto_session *ses;
540d4086a48Svisa 	uint32_t sid = (uint32_t)tid;
541d4086a48Svisa 
542d4086a48Svisa 	mtx_enter(&sc->sc_mtx);
543d4086a48Svisa 	ses = RBT_FIND(octcrypto_tree, &sc->sc_sessions,
544d4086a48Svisa 	    (struct octcrypto_session *)&sid);
545d4086a48Svisa 	if (ses != NULL)
546d4086a48Svisa 		RBT_REMOVE(octcrypto_tree, &sc->sc_sessions, ses);
547d4086a48Svisa 	mtx_leave(&sc->sc_mtx);
548d4086a48Svisa 
549d4086a48Svisa 	if (ses == NULL)
550d4086a48Svisa 		return EINVAL;
551d4086a48Svisa 
55227b68cf7Svisa 	smr_call(&ses->ses_smr, octcrypto_free_smr, ses);
553d4086a48Svisa 
554d4086a48Svisa 	return 0;
555d4086a48Svisa }
556d4086a48Svisa 
557d4086a48Svisa enum {
558d4086a48Svisa 	ALG_UNHANDLED,
559d4086a48Svisa 	ALG_AES,
560d4086a48Svisa 	ALG_AES_GHASH,
561d4086a48Svisa 	ALG_GMAC,
562d4086a48Svisa 	ALG_HMAC
563d4086a48Svisa };
564d4086a48Svisa 
565d4086a48Svisa static int
alg_class(int alg)566d4086a48Svisa alg_class(int alg)
567d4086a48Svisa {
568d4086a48Svisa 	switch (alg) {
569d4086a48Svisa 	case CRYPTO_AES_CBC:
570d4086a48Svisa 	case CRYPTO_AES_CTR:
571d4086a48Svisa 		return ALG_AES;
572d4086a48Svisa 	case CRYPTO_AES_GCM_16:
573d4086a48Svisa 	case CRYPTO_AES_GMAC:
574d4086a48Svisa 		return ALG_AES_GHASH;
575d4086a48Svisa 	case CRYPTO_AES_128_GMAC:
576d4086a48Svisa 	case CRYPTO_AES_192_GMAC:
577d4086a48Svisa 	case CRYPTO_AES_256_GMAC:
578d4086a48Svisa 		return ALG_GMAC;
579d4086a48Svisa 	case CRYPTO_MD5_HMAC:
580d4086a48Svisa 	case CRYPTO_SHA1_HMAC:
581d4086a48Svisa 	case CRYPTO_SHA2_256_HMAC:
582d4086a48Svisa 	case CRYPTO_SHA2_384_HMAC:
583d4086a48Svisa 	case CRYPTO_SHA2_512_HMAC:
584d4086a48Svisa 		return ALG_HMAC;
585d4086a48Svisa 	default:
586d4086a48Svisa 		return ALG_UNHANDLED;
587d4086a48Svisa 	}
588d4086a48Svisa }
589d4086a48Svisa 
590d4086a48Svisa int
octcrypto_process(struct cryptop * crp)591d4086a48Svisa octcrypto_process(struct cryptop *crp)
592d4086a48Svisa {
593d4086a48Svisa 	struct cryptodesc *crd, *crd2;
594d4086a48Svisa 	struct octcrypto_softc *sc = octcrypto_sc;
595d4086a48Svisa 	struct octcrypto_session *ses = NULL;
596d4086a48Svisa 	int alg, alg2;
597d4086a48Svisa 	int error = 0;
598d4086a48Svisa 	int i;
599d4086a48Svisa 
600d4086a48Svisa 	KASSERT(crp->crp_ndesc >= 1);
601d4086a48Svisa 
60227b68cf7Svisa 	smr_read_enter();
603d4086a48Svisa 	ses = octcrypto_get(sc, (uint32_t)crp->crp_sid);
604d4086a48Svisa 	if (ses == NULL) {
605d4086a48Svisa 		error = EINVAL;
606d4086a48Svisa 		goto out;
607d4086a48Svisa 	}
608d4086a48Svisa 
609d4086a48Svisa 	if (crp->crp_ndesc == 2) {
610d4086a48Svisa 		crd = &crp->crp_desc[0];
611d4086a48Svisa 		crd2 = &crp->crp_desc[1];
612d4086a48Svisa 		alg = alg_class(crd->crd_alg);
613d4086a48Svisa 		alg2 = alg_class(crd2->crd_alg);
614d4086a48Svisa 
615d4086a48Svisa 		if ((alg == ALG_AES) && (alg2 == ALG_HMAC)) {
616d4086a48Svisa 			error = octcrypto_authenc_hmac(crp, crd, crd2, ses);
617d4086a48Svisa 			goto out;
618d4086a48Svisa 		} else if ((alg2 == ALG_AES) && (alg == ALG_HMAC)) {
619d4086a48Svisa 			error = octcrypto_authenc_hmac(crp, crd2, crd, ses);
620d4086a48Svisa 			goto out;
621d4086a48Svisa 		} else if ((alg == ALG_AES_GHASH) && (alg2 == ALG_GMAC)) {
622d4086a48Svisa 			error = octcrypto_authenc_gmac(crp, crd, crd2, ses);
623d4086a48Svisa 			goto out;
624d4086a48Svisa 		} else if ((alg2 == ALG_AES_GHASH) && (alg == ALG_GMAC)) {
625d4086a48Svisa 			error = octcrypto_authenc_gmac(crp, crd2, crd, ses);
626d4086a48Svisa 			goto out;
627d4086a48Svisa 		}
628d4086a48Svisa 	}
629d4086a48Svisa 
630d4086a48Svisa 	for (i = 0; i < crp->crp_ndesc; i++) {
631d4086a48Svisa 		crd = &crp->crp_desc[i];
632d4086a48Svisa 		switch (crd->crd_alg) {
633d4086a48Svisa 		case CRYPTO_AES_CBC:
634d4086a48Svisa 		case CRYPTO_AES_CTR:
635d4086a48Svisa 			error = octcrypto_authenc_hmac(crp, crd, NULL, ses);
636d4086a48Svisa 			break;
637d4086a48Svisa 
638d4086a48Svisa 		case CRYPTO_MD5_HMAC:
639d4086a48Svisa 		case CRYPTO_SHA1_HMAC:
640d4086a48Svisa 		case CRYPTO_SHA2_256_HMAC:
641d4086a48Svisa 		case CRYPTO_SHA2_384_HMAC:
642d4086a48Svisa 		case CRYPTO_SHA2_512_HMAC:
643d4086a48Svisa 			error = octcrypto_authenc_hmac(crp, NULL, crd, ses);
644d4086a48Svisa 			break;
645d4086a48Svisa 
646d4086a48Svisa 		case CRYPTO_RIPEMD160_HMAC:
647d4086a48Svisa 			error = octcrypto_swauth(crp, crd, ses->ses_swd,
648d4086a48Svisa 			    crp->crp_buf);
649d4086a48Svisa 			break;
650d4086a48Svisa 
651d4086a48Svisa 		default:
652d4086a48Svisa 			error = EINVAL;
653d4086a48Svisa 			break;
654d4086a48Svisa 		}
655d4086a48Svisa 	}
656d4086a48Svisa 
657d4086a48Svisa out:
65827b68cf7Svisa 	smr_read_leave();
659d4086a48Svisa 	return error;
660d4086a48Svisa }
661d4086a48Svisa 
662d4086a48Svisa int
octcrypto_swauth(struct cryptop * crp,struct cryptodesc * crd,struct swcr_data * sw,uint8_t * buf)663d4086a48Svisa octcrypto_swauth(struct cryptop *crp, struct cryptodesc *crd,
664d4086a48Svisa     struct swcr_data *sw, uint8_t *buf)
665d4086a48Svisa {
666d4086a48Svisa 	int type;
667d4086a48Svisa 
668d4086a48Svisa 	if (crp->crp_flags & CRYPTO_F_IMBUF)
669d4086a48Svisa 		type = CRYPTO_BUF_MBUF;
670d4086a48Svisa 	else
671d4086a48Svisa 		type = CRYPTO_BUF_IOV;
672d4086a48Svisa 
673d4086a48Svisa 	return swcr_authcompute(crp, crd, sw, buf, type);
674d4086a48Svisa }
675d4086a48Svisa 
676d4086a48Svisa int
octcrypto_authenc_gmac(struct cryptop * crp,struct cryptodesc * crde,struct cryptodesc * crda,struct octcrypto_session * ses)677d4086a48Svisa octcrypto_authenc_gmac(struct cryptop *crp, struct cryptodesc *crde,
678d4086a48Svisa     struct cryptodesc *crda, struct octcrypto_session *ses)
679d4086a48Svisa {
680d4086a48Svisa 	uint64_t block[ndwords(AESCTR_BLOCKSIZE)];
681d4086a48Svisa 	uint64_t icb[ndwords(AESCTR_BLOCKSIZE)];
682d4086a48Svisa 	uint64_t iv[ndwords(AESCTR_BLOCKSIZE)];
683d4086a48Svisa 	uint64_t tag[ndwords(GMAC_BLOCK_LEN)];
684d4086a48Svisa 	uint8_t *buf;
685d4086a48Svisa 	struct octcrypto_cpu *pcpu = &ses->ses_sc->sc_cpu[cpu_number()];
686d4086a48Svisa 	size_t aadlen;
687d4086a48Svisa 	size_t ivlen = 8;
688d4086a48Svisa 	size_t rlen;
689d4086a48Svisa 	int error = 0;
690d4086a48Svisa 	unsigned int iskip = 0;
691d4086a48Svisa 	unsigned int oskip = 0;
692d4086a48Svisa 
693d4086a48Svisa 	KASSERT(crda != NULL);
694d4086a48Svisa 	KASSERT(crde != NULL);
695d4086a48Svisa 
696d4086a48Svisa 	rlen = roundup(crde->crd_len, AESCTR_BLOCKSIZE);
697d4086a48Svisa 	if (rlen > pcpu->pcpu_buflen) {
698d4086a48Svisa 		if (pcpu->pcpu_buf != NULL) {
699d4086a48Svisa 			explicit_bzero(pcpu->pcpu_buf, pcpu->pcpu_buflen);
700d4086a48Svisa 			free(pcpu->pcpu_buf, M_DEVBUF, pcpu->pcpu_buflen);
701d4086a48Svisa 		}
702d4086a48Svisa 		pcpu->pcpu_buflen = 0;
703d4086a48Svisa 		pcpu->pcpu_buf = malloc(rlen, M_DEVBUF, M_NOWAIT | M_ZERO);
704d4086a48Svisa 		if (pcpu->pcpu_buf == NULL)
705d4086a48Svisa 			return ENOMEM;
706d4086a48Svisa 		pcpu->pcpu_buflen = rlen;
707d4086a48Svisa 	}
708d4086a48Svisa 	buf = pcpu->pcpu_buf;
709d4086a48Svisa 
710d4086a48Svisa 	/* Prepare the IV. */
711d4086a48Svisa 	if (crde->crd_flags & CRD_F_ENCRYPT) {
712d4086a48Svisa 		if (crde->crd_flags & CRD_F_IV_EXPLICIT)
713d4086a48Svisa 			memcpy(iv, crde->crd_iv, ivlen);
714d4086a48Svisa 		else
715d4086a48Svisa 			arc4random_buf(iv, ivlen);
716d4086a48Svisa 
717d4086a48Svisa 		if ((crde->crd_flags & CRD_F_IV_PRESENT) == 0) {
718d4086a48Svisa 			if (crp->crp_flags & CRYPTO_F_IMBUF) {
719d4086a48Svisa 				if (m_copyback((struct mbuf *)crp->crp_buf,
720d4086a48Svisa 				    crde->crd_inject, ivlen, (uint8_t *)iv,
721d4086a48Svisa 				    M_NOWAIT)) {
722d4086a48Svisa 					error = ENOMEM;
723d4086a48Svisa 					goto out;
724d4086a48Svisa 				}
725d4086a48Svisa 			} else {
726d4086a48Svisa 				cuio_copyback((struct uio *)crp->crp_buf,
727d4086a48Svisa 				    crde->crd_inject, ivlen, (uint8_t *)iv);
728d4086a48Svisa 			}
729d4086a48Svisa 		}
730d4086a48Svisa 	} else {
731d4086a48Svisa 		if (crde->crd_flags & CRD_F_IV_EXPLICIT) {
732d4086a48Svisa 			memcpy(iv, crde->crd_iv, ivlen);
733d4086a48Svisa 		} else {
734d4086a48Svisa 			if (crp->crp_flags & CRYPTO_F_IMBUF)
735d4086a48Svisa 				m_copydata((struct mbuf *)crp->crp_buf,
7365c7fed39Sdlg 				    crde->crd_inject, ivlen, iv);
737d4086a48Svisa 			else
738d4086a48Svisa 				cuio_copydata((struct uio *)crp->crp_buf,
739d4086a48Svisa 				    crde->crd_inject, ivlen, (uint8_t *)iv);
740d4086a48Svisa 		}
741d4086a48Svisa 	}
742d4086a48Svisa 
743d4086a48Svisa 	memset(icb, 0, sizeof(icb));
744d4086a48Svisa 	memcpy(icb, ses->ses_nonce, AESCTR_NONCESIZE);
745d4086a48Svisa 	memcpy((uint8_t *)icb + AESCTR_NONCESIZE, iv, AESCTR_IVSIZE);
746d4086a48Svisa 	((uint8_t *)icb)[AESCTR_BLOCKSIZE - 1] = 1;
747d4086a48Svisa 
748d4086a48Svisa 	/* Prepare the AAD. */
749d4086a48Svisa 	aadlen = crda->crd_len;
750d4086a48Svisa 	if (crda->crd_flags & CRD_F_ESN) {
751d4086a48Svisa 		aadlen += 4;
752d4086a48Svisa 		if (crp->crp_flags & CRYPTO_F_IMBUF)
753d4086a48Svisa 			m_copydata((struct mbuf *)crp->crp_buf,
754d4086a48Svisa 			    crda->crd_skip, 4, buf);
755d4086a48Svisa 		else
756d4086a48Svisa 			cuio_copydata((struct uio *)crp->crp_buf,
757d4086a48Svisa 			    crda->crd_skip, 4, buf);
758d4086a48Svisa 		memcpy(buf + 4, crda->crd_esn, 4);
759d4086a48Svisa 		iskip = 4;
760d4086a48Svisa 		oskip = 8;
761d4086a48Svisa 	}
762d4086a48Svisa 	if (crp->crp_flags & CRYPTO_F_IMBUF)
763d4086a48Svisa 		m_copydata((struct mbuf *)crp->crp_buf,
764d4086a48Svisa 		    crda->crd_skip + iskip, crda->crd_len - iskip, buf + oskip);
765d4086a48Svisa 	else
766d4086a48Svisa 		cuio_copydata((struct uio *)crp->crp_buf,
767d4086a48Svisa 		    crda->crd_skip + iskip, crda->crd_len - iskip, buf + oskip);
768d4086a48Svisa 
769d4086a48Svisa 	cop2_enable();
770d4086a48Svisa 	octcrypto_ghash_init(ses->ses_ghkey, NULL);
771d4086a48Svisa 	octcrypto_ghash_update(buf, roundup(aadlen, GMAC_BLOCK_LEN));
772d4086a48Svisa 	cop2_disable();
773d4086a48Svisa 
774d4086a48Svisa 	memset(buf, 0, aadlen);
775d4086a48Svisa 
776d4086a48Svisa 	/* Copy input to the working buffer. */
777d4086a48Svisa 	if (crp->crp_flags & CRYPTO_F_IMBUF)
778d4086a48Svisa 		m_copydata((struct mbuf *)crp->crp_buf, crde->crd_skip,
779d4086a48Svisa 		    crde->crd_len, buf);
780d4086a48Svisa 	else
781d4086a48Svisa 		cuio_copydata((struct uio *)crp->crp_buf, crde->crd_skip,
782d4086a48Svisa 		    crde->crd_len, buf);
783d4086a48Svisa 
784d4086a48Svisa 	cop2_enable();
785d4086a48Svisa 	octcrypto_aes_set_key(ses->ses_key, ses->ses_klen);
786d4086a48Svisa 
787d4086a48Svisa 	switch (crde->crd_alg) {
788d4086a48Svisa 	case CRYPTO_AES_GCM_16:
789d4086a48Svisa 		if (crde->crd_flags & CRD_F_ENCRYPT) {
790d4086a48Svisa 			octcrypto_aes_ctr_enc(buf, rlen, icb);
791d4086a48Svisa 			memset(buf + crde->crd_len, 0, rlen - crde->crd_len);
792d4086a48Svisa 			octcrypto_ghash_update(buf, rlen);
793d4086a48Svisa 		} else {
794d4086a48Svisa 			octcrypto_ghash_update(buf, rlen);
795d4086a48Svisa 			octcrypto_aes_ctr_enc(buf, rlen, icb);
796d4086a48Svisa 		}
797d4086a48Svisa 		break;
798d4086a48Svisa 
799d4086a48Svisa 	case CRYPTO_AES_GMAC:
800d4086a48Svisa 		octcrypto_ghash_update(buf, rlen);
801d4086a48Svisa 		break;
802d4086a48Svisa 	}
803d4086a48Svisa 
804d4086a48Svisa 	block[0] = htobe64(aadlen * 8);
805d4086a48Svisa 	block[1] = htobe64(crde->crd_len * 8);
806d4086a48Svisa 	octcrypto_ghash_update(block, GMAC_BLOCK_LEN);
807d4086a48Svisa 	octcrypto_ghash_finish(tag);
808d4086a48Svisa 
809d4086a48Svisa 	block[0] = icb[0];
810d4086a48Svisa 	block[1] = icb[1];
811d4086a48Svisa 	octcrypto_aes_enc(block);
812d4086a48Svisa 	tag[0] ^= block[0];
813d4086a48Svisa 	tag[1] ^= block[1];
814d4086a48Svisa 
815d4086a48Svisa 	octcrypto_aes_clear();
816d4086a48Svisa 	cop2_disable();
817d4086a48Svisa 
818d4086a48Svisa 	/* Copy back the output. */
819d4086a48Svisa 	if (crp->crp_flags & CRYPTO_F_IMBUF) {
820d4086a48Svisa 		if (m_copyback((struct mbuf *)crp->crp_buf,
821d4086a48Svisa 		    crde->crd_skip, crde->crd_len, buf, M_NOWAIT)) {
822d4086a48Svisa 			error = ENOMEM;
823d4086a48Svisa 			goto out;
824d4086a48Svisa 		}
825d4086a48Svisa 	} else {
826d4086a48Svisa 		cuio_copyback((struct uio *)crp->crp_buf,
827d4086a48Svisa 		    crde->crd_skip, crde->crd_len, buf);
828d4086a48Svisa 	}
829d4086a48Svisa 
830d4086a48Svisa 	/* Copy back the authentication tag. */
831d4086a48Svisa 	if (crp->crp_flags & CRYPTO_F_IMBUF) {
832d4086a48Svisa 		if (m_copyback((struct mbuf *)crp->crp_buf, crda->crd_inject,
833d4086a48Svisa 		    GMAC_DIGEST_LEN, tag, M_NOWAIT)) {
834d4086a48Svisa 			error = ENOMEM;
835d4086a48Svisa 			goto out;
836d4086a48Svisa 		}
837d4086a48Svisa 	} else {
838d4086a48Svisa 		memcpy(crp->crp_mac, tag, GMAC_DIGEST_LEN);
839d4086a48Svisa 	}
840d4086a48Svisa 
841d4086a48Svisa out:
842d4086a48Svisa 	explicit_bzero(buf, rlen);
843d4086a48Svisa 	explicit_bzero(icb, sizeof(icb));
844d4086a48Svisa 	explicit_bzero(tag, sizeof(tag));
845d4086a48Svisa 
846d4086a48Svisa 	return error;
847d4086a48Svisa }
848d4086a48Svisa 
849d4086a48Svisa void
octcrypto_hmac(struct cryptodesc * crda,uint8_t * buf,size_t len,struct octcrypto_session * ses,uint64_t * res)850d4086a48Svisa octcrypto_hmac(struct cryptodesc *crda, uint8_t *buf, size_t len,
851d4086a48Svisa     struct octcrypto_session *ses, uint64_t *res)
852d4086a48Svisa {
853d4086a48Svisa 	uint64_t block[ndwords(HMAC_MAX_BLOCK_LEN)];
854d4086a48Svisa 	uint8_t *bptr = (uint8_t *)block;
855d4086a48Svisa 	const struct octcrypto_hmac *hmac = ses->ses_hmac;
856d4086a48Svisa 	size_t left;
857d4086a48Svisa 
858d4086a48Svisa 	cop2_enable();
859d4086a48Svisa 
860d4086a48Svisa 	/*
861d4086a48Svisa 	 * Compute the inner hash.
862d4086a48Svisa 	 */
863d4086a48Svisa 
864d4086a48Svisa 	hmac->set_iv(ses->ses_iiv);
865d4086a48Svisa 	hmac->transform(buf, len);
866d4086a48Svisa 
867d4086a48Svisa 	memset(block, 0, hmac->blocklen);
868d4086a48Svisa 	left = len & (hmac->blocklen - 1);
869d4086a48Svisa 	bptr[left] = 0x80;
870d4086a48Svisa 	if (left > 0) {
871d4086a48Svisa 		memcpy(block, buf + len - left, left);
872d4086a48Svisa 
873d4086a48Svisa 		if (roundup(left + 1, hmac->countlen) >
874d4086a48Svisa 		    (hmac->blocklen - hmac->countlen)) {
875d4086a48Svisa 			hmac->transform(block, hmac->blocklen);
876d4086a48Svisa 			memset(block, 0, hmac->blocklen);
877d4086a48Svisa 		}
878d4086a48Svisa 	}
879d4086a48Svisa 
880d4086a48Svisa 	switch (crda->crd_alg) {
881d4086a48Svisa 	case CRYPTO_MD5_HMAC:
882d4086a48Svisa 		block[7] = htole64((64 + len) * 8);
883d4086a48Svisa 		break;
884d4086a48Svisa 	case CRYPTO_SHA1_HMAC:
885d4086a48Svisa 	case CRYPTO_SHA2_256_HMAC:
886d4086a48Svisa 		block[7] = htobe64((64 + len) * 8);
887d4086a48Svisa 		break;
888d4086a48Svisa 	case CRYPTO_SHA2_384_HMAC:
889d4086a48Svisa 	case CRYPTO_SHA2_512_HMAC:
890d4086a48Svisa 		block[15] = htobe64((128 + len) * 8);
891d4086a48Svisa 		break;
892d4086a48Svisa 	}
893d4086a48Svisa 
894d4086a48Svisa 	hmac->transform(block, hmac->blocklen);
895d4086a48Svisa 
896d4086a48Svisa 	/*
897d4086a48Svisa 	 * Compute the outer hash.
898d4086a48Svisa 	 */
899d4086a48Svisa 
900d4086a48Svisa 	memset(block, 0, hmac->blocklen);
901d4086a48Svisa 	hmac->get_iv(block);
902d4086a48Svisa 	hmac->set_iv(ses->ses_oiv);
903d4086a48Svisa 
904d4086a48Svisa 	switch (crda->crd_alg) {
905d4086a48Svisa 	case CRYPTO_MD5_HMAC:
906d4086a48Svisa 		block[2] = htobe64(1ULL << 63);
907d4086a48Svisa 		block[7] = htole64((64 + 16) * 8);
908d4086a48Svisa 		break;
909d4086a48Svisa 	case CRYPTO_SHA1_HMAC:
910d4086a48Svisa 		block[2] |= htobe64(1ULL << 31);
911d4086a48Svisa 		block[7] = htobe64((64 + 20) * 8);
912d4086a48Svisa 		break;
913d4086a48Svisa 	case CRYPTO_SHA2_256_HMAC:
914d4086a48Svisa 		block[4] = htobe64(1ULL << 63);
915d4086a48Svisa 		block[7] = htobe64((64 + 32) * 8);
916d4086a48Svisa 		break;
917d4086a48Svisa 	case CRYPTO_SHA2_384_HMAC:
918d4086a48Svisa 		/*
919d4086a48Svisa 		 * The computed digest is 512 bits long.
920d4086a48Svisa 		 * It has to be truncated to 384 bits.
921d4086a48Svisa 		 */
922d4086a48Svisa 		block[6] = htobe64(1ULL << 63);
923d4086a48Svisa 		block[7] = 0;	/* truncation */
924d4086a48Svisa 		block[15] = htobe64((128 + 48) * 8);
925d4086a48Svisa 		break;
926d4086a48Svisa 	case CRYPTO_SHA2_512_HMAC:
927d4086a48Svisa 		block[8] = htobe64(1ULL << 63);
928d4086a48Svisa 		block[15] = htobe64((128 + 64) * 8);
929d4086a48Svisa 		break;
930d4086a48Svisa 	}
931d4086a48Svisa 
932d4086a48Svisa 	hmac->transform(block, hmac->blocklen);
933d4086a48Svisa 	hmac->get_iv(res);
934d4086a48Svisa 	hmac->clear();
935d4086a48Svisa 
936d4086a48Svisa 	cop2_disable();
937d4086a48Svisa 
938d4086a48Svisa 	explicit_bzero(block, sizeof(block));
939d4086a48Svisa }
940d4086a48Svisa 
941d4086a48Svisa int
octcrypto_authenc_hmac(struct cryptop * crp,struct cryptodesc * crde,struct cryptodesc * crda,struct octcrypto_session * ses)942d4086a48Svisa octcrypto_authenc_hmac(struct cryptop *crp, struct cryptodesc *crde,
943d4086a48Svisa     struct cryptodesc *crda, struct octcrypto_session *ses)
944d4086a48Svisa {
945d4086a48Svisa 	uint64_t icb[ndwords(AESCTR_BLOCKSIZE)];
946d4086a48Svisa 	uint64_t iv[ndwords(EALG_MAX_BLOCK_LEN)];
947d4086a48Svisa 	uint64_t tag[ndwords(AALG_MAX_RESULT_LEN)];
948d4086a48Svisa 	struct octcrypto_cpu *pcpu = &ses->ses_sc->sc_cpu[cpu_number()];
949d4086a48Svisa 	uint8_t *buf, *authbuf, *encbuf;
950d4086a48Svisa 	size_t authlen;
951d4086a48Svisa 	size_t buflen;
952d4086a48Svisa 	size_t len;
953d4086a48Svisa 	size_t skip;
954d4086a48Svisa 	off_t authskip = 0;
955d4086a48Svisa 	off_t encskip = 0;
956d4086a48Svisa 	int error = 0;
957d4086a48Svisa 	int ivlen;
958d4086a48Svisa 
959d4086a48Svisa 	if (crde != NULL && crda != NULL) {
960d4086a48Svisa 		skip = MIN(crde->crd_skip, crda->crd_skip);
961d4086a48Svisa 		len = MAX(crde->crd_skip + crde->crd_len,
962d4086a48Svisa 		    crda->crd_skip + crda->crd_len) - skip;
963d4086a48Svisa 
964d4086a48Svisa 		if (crda->crd_skip < crde->crd_skip)
965d4086a48Svisa 			encskip = crde->crd_skip - crda->crd_skip;
966d4086a48Svisa 		else
967d4086a48Svisa 			authskip = crda->crd_skip - crde->crd_skip;
968d4086a48Svisa 	} else if (crde != NULL) {
969d4086a48Svisa 		skip = crde->crd_skip;
970d4086a48Svisa 		len = crde->crd_len;
971d4086a48Svisa 	} else {
972d4086a48Svisa 		KASSERT(crda != NULL);
973d4086a48Svisa 
974d4086a48Svisa 		skip = crda->crd_skip;
975d4086a48Svisa 		len = crda->crd_len;
976d4086a48Svisa 	}
977d4086a48Svisa 
978d4086a48Svisa 	buflen = len;
979d4086a48Svisa 
980d4086a48Svisa 	/* Reserve space for ESN. */
981d4086a48Svisa 	if (crda != NULL && (crda->crd_flags & CRD_F_ESN) != 0)
982d4086a48Svisa 		buflen += 4;
983d4086a48Svisa 
984d4086a48Svisa 	buflen = roundup(buflen, EALG_MAX_BLOCK_LEN);
985d4086a48Svisa 	if (buflen > pcpu->pcpu_buflen) {
986d4086a48Svisa 		if (pcpu->pcpu_buf != NULL) {
987d4086a48Svisa 			explicit_bzero(pcpu->pcpu_buf, pcpu->pcpu_buflen);
988d4086a48Svisa 			free(pcpu->pcpu_buf, M_DEVBUF, pcpu->pcpu_buflen);
989d4086a48Svisa 		}
990d4086a48Svisa 		pcpu->pcpu_buflen = 0;
991d4086a48Svisa 		pcpu->pcpu_buf = malloc(buflen, M_DEVBUF, M_NOWAIT | M_ZERO);
992d4086a48Svisa 		if (pcpu->pcpu_buf == NULL)
993d4086a48Svisa 			return ENOMEM;
994d4086a48Svisa 		pcpu->pcpu_buflen = buflen;
995d4086a48Svisa 	}
996d4086a48Svisa 	buf = pcpu->pcpu_buf;
997d4086a48Svisa 
998d4086a48Svisa 	authbuf = buf + authskip;
999d4086a48Svisa 	encbuf = buf + encskip;
1000d4086a48Svisa 
1001d4086a48Svisa 	/* Prepare the IV. */
1002d4086a48Svisa 	if (crde != NULL) {
1003d4086a48Svisa 		/* CBC uses 16 bytes, CTR 8 bytes. */
1004d4086a48Svisa 		ivlen = (crde->crd_alg == CRYPTO_AES_CBC) ? 16 : 8;
1005d4086a48Svisa 
1006d4086a48Svisa 		if (crde->crd_flags & CRD_F_ENCRYPT) {
1007d4086a48Svisa 			if (crde->crd_flags & CRD_F_IV_EXPLICIT)
1008d4086a48Svisa 				memcpy(iv, crde->crd_iv, ivlen);
1009d4086a48Svisa 			else
1010d4086a48Svisa 				arc4random_buf(iv, ivlen);
1011d4086a48Svisa 
1012d4086a48Svisa 			if ((crde->crd_flags & CRD_F_IV_PRESENT) == 0) {
1013d4086a48Svisa 				if (crp->crp_flags & CRYPTO_F_IMBUF) {
1014d4086a48Svisa 					if (m_copyback(
1015d4086a48Svisa 					    (struct mbuf *)crp->crp_buf,
1016d4086a48Svisa 					    crde->crd_inject, ivlen, iv,
1017d4086a48Svisa 					    M_NOWAIT)) {
1018d4086a48Svisa 						error = ENOMEM;
1019d4086a48Svisa 						goto out;
1020d4086a48Svisa 					}
1021d4086a48Svisa 				} else {
1022d4086a48Svisa 					cuio_copyback(
1023d4086a48Svisa 					    (struct uio *)crp->crp_buf,
1024d4086a48Svisa 					    crde->crd_inject, ivlen, iv);
1025d4086a48Svisa 				}
1026d4086a48Svisa 			}
1027d4086a48Svisa 		} else {
1028d4086a48Svisa 			if (crde->crd_flags & CRD_F_IV_EXPLICIT) {
1029d4086a48Svisa 				memcpy(iv, crde->crd_iv, ivlen);
1030d4086a48Svisa 			} else {
1031d4086a48Svisa 				if (crp->crp_flags & CRYPTO_F_IMBUF)
10325c7fed39Sdlg 					m_copydata((struct mbuf *)crp->crp_buf,
10335c7fed39Sdlg 					    crde->crd_inject, ivlen, iv);
1034d4086a48Svisa 				else
1035d4086a48Svisa 					cuio_copydata(
1036d4086a48Svisa 					    (struct uio *)crp->crp_buf,
1037d4086a48Svisa 					    crde->crd_inject, ivlen,
1038d4086a48Svisa 					    (uint8_t *)iv);
1039d4086a48Svisa 			}
1040d4086a48Svisa 		}
1041d4086a48Svisa 	}
1042d4086a48Svisa 
1043d4086a48Svisa 	/* Copy input to the working buffer. */
1044d4086a48Svisa 	if (crp->crp_flags & CRYPTO_F_IMBUF)
1045d4086a48Svisa 		m_copydata((struct mbuf *)crp->crp_buf, skip, len, buf);
1046d4086a48Svisa 	else
1047d4086a48Svisa 		cuio_copydata((struct uio *)crp->crp_buf, skip, len, buf);
1048d4086a48Svisa 
1049d4086a48Svisa 	/* If ESN is used, append it to the buffer. */
1050d4086a48Svisa 	if (crda != NULL) {
1051d4086a48Svisa 		authlen = crda->crd_len;
1052d4086a48Svisa 		if (crda->crd_flags & CRD_F_ESN) {
1053d4086a48Svisa 			memcpy(buf + len, crda->crd_esn, 4);
1054d4086a48Svisa 			authlen += 4;
1055d4086a48Svisa 		}
1056d4086a48Svisa 	}
1057d4086a48Svisa 
1058d4086a48Svisa 	if (crde != NULL) {
1059d4086a48Svisa 		/* Compute authentication tag before decryption. */
1060d4086a48Svisa 		if (crda != NULL && (crde->crd_flags & CRD_F_ENCRYPT) == 0)
1061d4086a48Svisa 			octcrypto_hmac(crda, authbuf, authlen, ses, tag);
1062d4086a48Svisa 
1063d4086a48Svisa 		/* Apply the cipher. */
1064d4086a48Svisa 		switch (crde->crd_alg) {
1065d4086a48Svisa 		case CRYPTO_AES_CBC:
1066d4086a48Svisa 			cop2_enable();
1067d4086a48Svisa 			octcrypto_aes_set_key(ses->ses_key, ses->ses_klen);
1068d4086a48Svisa 			if (crde->crd_flags & CRD_F_ENCRYPT)
1069d4086a48Svisa 				octcrypto_aes_cbc_enc(encbuf, crde->crd_len,
1070d4086a48Svisa 				    iv);
1071d4086a48Svisa 			else
1072d4086a48Svisa 				octcrypto_aes_cbc_dec(encbuf, crde->crd_len,
1073d4086a48Svisa 				    iv);
1074d4086a48Svisa 			octcrypto_aes_clear();
1075d4086a48Svisa 			cop2_disable();
1076d4086a48Svisa 			break;
1077d4086a48Svisa 
1078d4086a48Svisa 		case CRYPTO_AES_CTR:
1079d4086a48Svisa 			memset(icb, 0, sizeof(icb));
1080d4086a48Svisa 			memcpy(icb, ses->ses_nonce, AESCTR_NONCESIZE);
1081d4086a48Svisa 			memcpy((uint8_t *)icb + AESCTR_NONCESIZE, iv,
1082d4086a48Svisa 			    AESCTR_IVSIZE);
1083d4086a48Svisa 			cop2_enable();
1084d4086a48Svisa 			octcrypto_aes_set_key(ses->ses_key, ses->ses_klen);
1085d4086a48Svisa 			octcrypto_aes_ctr_enc(encbuf, crde->crd_len, icb);
1086d4086a48Svisa 			octcrypto_aes_clear();
1087d4086a48Svisa 			cop2_disable();
1088d4086a48Svisa 			explicit_bzero(icb, sizeof(icb));
1089d4086a48Svisa 			break;
1090d4086a48Svisa 		}
1091d4086a48Svisa 
1092d4086a48Svisa 		/* Copy back the output. */
1093d4086a48Svisa 		if (crp->crp_flags & CRYPTO_F_IMBUF) {
1094d4086a48Svisa 			if (m_copyback((struct mbuf *)crp->crp_buf,
1095d4086a48Svisa 			    crde->crd_skip, crde->crd_len, encbuf, M_NOWAIT)) {
1096d4086a48Svisa 				error = ENOMEM;
1097d4086a48Svisa 				goto out;
1098d4086a48Svisa 			}
1099d4086a48Svisa 		} else {
1100d4086a48Svisa 			cuio_copyback((struct uio *)crp->crp_buf,
1101d4086a48Svisa 			    crde->crd_skip, crde->crd_len, encbuf);
1102d4086a48Svisa 		}
1103d4086a48Svisa 	}
1104d4086a48Svisa 
1105d4086a48Svisa 	if (crda != NULL) {
1106d4086a48Svisa 		/*
1107d4086a48Svisa 		 * Compute authentication tag after encryption.
1108d4086a48Svisa 		 * This also handles the authentication only case.
1109d4086a48Svisa 		 */
1110d4086a48Svisa 		if (crde == NULL || (crde->crd_flags & CRD_F_ENCRYPT) != 0)
1111d4086a48Svisa 			octcrypto_hmac(crda, authbuf, authlen, ses, tag);
1112d4086a48Svisa 
1113d4086a48Svisa 		/* Copy back the authentication tag. */
1114d4086a48Svisa 		if (crp->crp_flags & CRYPTO_F_IMBUF) {
1115d4086a48Svisa 			if (m_copyback((struct mbuf *)crp->crp_buf,
1116d4086a48Svisa 			    crda->crd_inject, ses->ses_hmac->taglen, tag,
1117d4086a48Svisa 			    M_NOWAIT)) {
1118d4086a48Svisa 				error = ENOMEM;
1119d4086a48Svisa 				goto out;
1120d4086a48Svisa 			}
1121d4086a48Svisa 		} else {
1122d4086a48Svisa 			memcpy(crp->crp_mac, tag, ses->ses_hmac->taglen);
1123d4086a48Svisa 		}
1124d4086a48Svisa 
1125d4086a48Svisa 		explicit_bzero(tag, sizeof(tag));
1126d4086a48Svisa 	}
1127d4086a48Svisa 
1128d4086a48Svisa out:
1129d4086a48Svisa 	explicit_bzero(buf, len);
1130d4086a48Svisa 	return error;
1131d4086a48Svisa }
1132d4086a48Svisa 
1133d4086a48Svisa void
octcrypto_ghash_update_md(GHASH_CTX * ghash,uint8_t * src,size_t len)1134d4086a48Svisa octcrypto_ghash_update_md(GHASH_CTX *ghash, uint8_t *src, size_t len)
1135d4086a48Svisa {
1136d4086a48Svisa 	CTASSERT(offsetof(GHASH_CTX, H) % 8 == 0);
1137d4086a48Svisa 	CTASSERT(offsetof(GHASH_CTX, S) % 8 == 0);
1138d4086a48Svisa 
1139d4086a48Svisa 	cop2_enable();
1140d4086a48Svisa 	octcrypto_ghash_init((uint64_t *)ghash->H, (uint64_t *)ghash->S);
1141d4086a48Svisa 	octcrypto_ghash_update(src, len);
1142d4086a48Svisa 	octcrypto_ghash_finish((uint64_t *)ghash->S);
1143d4086a48Svisa 	cop2_disable();
1144d4086a48Svisa }
1145