cryptosoft.c revision 116191
1/*	$OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $	*/
2
3/*
4 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
5 *
6 * This code was written by Angelos D. Keromytis in Athens, Greece, in
7 * February 2000. Network Security Technologies Inc. (NSTI) kindly
8 * supported the development of this code.
9 *
10 * Copyright (c) 2000, 2001 Angelos D. Keromytis
11 *
12 * Permission to use, copy, and modify this software with or without fee
13 * is hereby granted, provided that this entire notice is included in
14 * all source code copies of any software which is or includes a copy or
15 * modification of this software.
16 *
17 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
19 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
20 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
21 * PURPOSE.
22 */
23
24#include <sys/cdefs.h>
25__FBSDID("$FreeBSD: head/sys/opencrypto/cryptosoft.c 116191 2003-06-11 05:57:50Z obrien $");
26
27#include <sys/param.h>
28#include <sys/systm.h>
29#include <sys/malloc.h>
30#include <sys/mbuf.h>
31#include <sys/sysctl.h>
32#include <sys/errno.h>
33#include <sys/random.h>
34#include <sys/kernel.h>
35#include <sys/uio.h>
36
37#include <crypto/blowfish/blowfish.h>
38#include <crypto/cast128/cast128.h>
39#include <crypto/sha1.h>
40#include <opencrypto/rmd160.h>
41#include <opencrypto/skipjack.h>
42#include <sys/md5.h>
43
44#include <opencrypto/cryptodev.h>
45#include <opencrypto/cryptosoft.h>
46#include <opencrypto/xform.h>
47
48u_int8_t hmac_ipad_buffer[64] = {
49	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
50	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
51	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
52	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
53	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
54	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
55	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
56	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
57};
58
59u_int8_t hmac_opad_buffer[64] = {
60	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
61	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
62	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
63	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
64	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
65	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
66	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
67	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
68};
69
70
71struct swcr_data **swcr_sessions = NULL;
72u_int32_t swcr_sesnum = 0;
73int32_t swcr_id = -1;
74
75#define COPYBACK(x, a, b, c, d) \
76	(x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \
77	: cuio_copyback((struct uio *)a,b,c,d)
78#define COPYDATA(x, a, b, c, d) \
79	(x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \
80	: cuio_copydata((struct uio *)a,b,c,d)
81
82static	int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
83static	int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
84			     struct swcr_data *sw, caddr_t buf, int outtype);
85static	int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
86static	int swcr_process(void *, struct cryptop *, int);
87static	int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
88static	int swcr_freesession(void *, u_int64_t);
89
90/*
91 * NB: These came over from openbsd and are kept private
92 *     to the crypto code for now.
93 */
94extern	int m_apply(struct mbuf *m, int off, int len,
95		    int (*f)(caddr_t, caddr_t, unsigned int), caddr_t fstate);
96
97/*
98 * Apply a symmetric encryption/decryption algorithm.
99 */
100static int
101swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
102    int outtype)
103{
104	unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
105	unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
106	struct enc_xform *exf;
107	int i, k, j, blks;
108
109	exf = sw->sw_exf;
110	blks = exf->blocksize;
111
112	/* Check for non-padded data */
113	if (crd->crd_len % blks)
114		return EINVAL;
115
116	/* Initialize the IV */
117	if (crd->crd_flags & CRD_F_ENCRYPT) {
118		/* IV explicitly provided ? */
119		if (crd->crd_flags & CRD_F_IV_EXPLICIT)
120			bcopy(crd->crd_iv, iv, blks);
121		else {
122			/* Get random IV */
123			for (i = 0;
124			    i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN;
125			    i += sizeof (u_int32_t)) {
126				u_int32_t temp = arc4random();
127
128				bcopy(&temp, iv + i, sizeof(u_int32_t));
129			}
130			/*
131			 * What if the block size is not a multiple
132			 * of sizeof (u_int32_t), which is the size of
133			 * what arc4random() returns ?
134			 */
135			if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) {
136				u_int32_t temp = arc4random();
137
138				bcopy (&temp, iv + i,
139				    EALG_MAX_BLOCK_LEN - i);
140			}
141		}
142
143		/* Do we need to write the IV */
144		if (!(crd->crd_flags & CRD_F_IV_PRESENT)) {
145			COPYBACK(outtype, buf, crd->crd_inject, blks, iv);
146		}
147
148	} else {	/* Decryption */
149			/* IV explicitly provided ? */
150		if (crd->crd_flags & CRD_F_IV_EXPLICIT)
151			bcopy(crd->crd_iv, iv, blks);
152		else {
153			/* Get IV off buf */
154			COPYDATA(outtype, buf, crd->crd_inject, blks, iv);
155		}
156	}
157
158	ivp = iv;
159
160	if (outtype == CRYPTO_BUF_CONTIG) {
161		if (crd->crd_flags & CRD_F_ENCRYPT) {
162			for (i = crd->crd_skip;
163			    i < crd->crd_skip + crd->crd_len; i += blks) {
164				/* XOR with the IV/previous block, as appropriate. */
165				if (i == crd->crd_skip)
166					for (k = 0; k < blks; k++)
167						buf[i + k] ^= ivp[k];
168				else
169					for (k = 0; k < blks; k++)
170						buf[i + k] ^= buf[i + k - blks];
171				exf->encrypt(sw->sw_kschedule, buf + i);
172			}
173		} else {		/* Decrypt */
174			/*
175			 * Start at the end, so we don't need to keep the encrypted
176			 * block as the IV for the next block.
177			 */
178			for (i = crd->crd_skip + crd->crd_len - blks;
179			    i >= crd->crd_skip; i -= blks) {
180				exf->decrypt(sw->sw_kschedule, buf + i);
181
182				/* XOR with the IV/previous block, as appropriate */
183				if (i == crd->crd_skip)
184					for (k = 0; k < blks; k++)
185						buf[i + k] ^= ivp[k];
186				else
187					for (k = 0; k < blks; k++)
188						buf[i + k] ^= buf[i + k - blks];
189			}
190		}
191
192		return 0;
193	} else if (outtype == CRYPTO_BUF_MBUF) {
194		struct mbuf *m = (struct mbuf *) buf;
195
196		/* Find beginning of data */
197		m = m_getptr(m, crd->crd_skip, &k);
198		if (m == NULL)
199			return EINVAL;
200
201		i = crd->crd_len;
202
203		while (i > 0) {
204			/*
205			 * If there's insufficient data at the end of
206			 * an mbuf, we have to do some copying.
207			 */
208			if (m->m_len < k + blks && m->m_len != k) {
209				m_copydata(m, k, blks, blk);
210
211				/* Actual encryption/decryption */
212				if (crd->crd_flags & CRD_F_ENCRYPT) {
213					/* XOR with previous block */
214					for (j = 0; j < blks; j++)
215						blk[j] ^= ivp[j];
216
217					exf->encrypt(sw->sw_kschedule, blk);
218
219					/*
220					 * Keep encrypted block for XOR'ing
221					 * with next block
222					 */
223					bcopy(blk, iv, blks);
224					ivp = iv;
225				} else {	/* decrypt */
226					/*
227					 * Keep encrypted block for XOR'ing
228					 * with next block
229					 */
230					if (ivp == iv)
231						bcopy(blk, piv, blks);
232					else
233						bcopy(blk, iv, blks);
234
235					exf->decrypt(sw->sw_kschedule, blk);
236
237					/* XOR with previous block */
238					for (j = 0; j < blks; j++)
239						blk[j] ^= ivp[j];
240
241					if (ivp == iv)
242						bcopy(piv, iv, blks);
243					else
244						ivp = iv;
245				}
246
247				/* Copy back decrypted block */
248				m_copyback(m, k, blks, blk);
249
250				/* Advance pointer */
251				m = m_getptr(m, k + blks, &k);
252				if (m == NULL)
253					return EINVAL;
254
255				i -= blks;
256
257				/* Could be done... */
258				if (i == 0)
259					break;
260			}
261
262			/* Skip possibly empty mbufs */
263			if (k == m->m_len) {
264				for (m = m->m_next; m && m->m_len == 0;
265				    m = m->m_next)
266					;
267				k = 0;
268			}
269
270			/* Sanity check */
271			if (m == NULL)
272				return EINVAL;
273
274			/*
275			 * Warning: idat may point to garbage here, but
276			 * we only use it in the while() loop, only if
277			 * there are indeed enough data.
278			 */
279			idat = mtod(m, unsigned char *) + k;
280
281	   		while (m->m_len >= k + blks && i > 0) {
282				if (crd->crd_flags & CRD_F_ENCRYPT) {
283					/* XOR with previous block/IV */
284					for (j = 0; j < blks; j++)
285						idat[j] ^= ivp[j];
286
287					exf->encrypt(sw->sw_kschedule, idat);
288					ivp = idat;
289				} else {	/* decrypt */
290					/*
291					 * Keep encrypted block to be used
292					 * in next block's processing.
293					 */
294					if (ivp == iv)
295						bcopy(idat, piv, blks);
296					else
297						bcopy(idat, iv, blks);
298
299					exf->decrypt(sw->sw_kschedule, idat);
300
301					/* XOR with previous block/IV */
302					for (j = 0; j < blks; j++)
303						idat[j] ^= ivp[j];
304
305					if (ivp == iv)
306						bcopy(piv, iv, blks);
307					else
308						ivp = iv;
309				}
310
311				idat += blks;
312				k += blks;
313				i -= blks;
314			}
315		}
316
317		return 0; /* Done with mbuf encryption/decryption */
318	} else if (outtype == CRYPTO_BUF_IOV) {
319		struct uio *uio = (struct uio *) buf;
320		struct iovec *iov;
321
322		/* Find beginning of data */
323		iov = cuio_getptr(uio, crd->crd_skip, &k);
324		if (iov == NULL)
325			return EINVAL;
326
327		i = crd->crd_len;
328
329		while (i > 0) {
330			/*
331			 * If there's insufficient data at the end of
332			 * an iovec, we have to do some copying.
333			 */
334			if (iov->iov_len < k + blks && iov->iov_len != k) {
335				cuio_copydata(uio, k, blks, blk);
336
337				/* Actual encryption/decryption */
338				if (crd->crd_flags & CRD_F_ENCRYPT) {
339					/* XOR with previous block */
340					for (j = 0; j < blks; j++)
341						blk[j] ^= ivp[j];
342
343					exf->encrypt(sw->sw_kschedule, blk);
344
345					/*
346					 * Keep encrypted block for XOR'ing
347					 * with next block
348					 */
349					bcopy(blk, iv, blks);
350					ivp = iv;
351				} else {	/* decrypt */
352					/*
353					 * Keep encrypted block for XOR'ing
354					 * with next block
355					 */
356					if (ivp == iv)
357						bcopy(blk, piv, blks);
358					else
359						bcopy(blk, iv, blks);
360
361					exf->decrypt(sw->sw_kschedule, blk);
362
363					/* XOR with previous block */
364					for (j = 0; j < blks; j++)
365						blk[j] ^= ivp[j];
366
367					if (ivp == iv)
368						bcopy(piv, iv, blks);
369					else
370						ivp = iv;
371				}
372
373				/* Copy back decrypted block */
374				cuio_copyback(uio, k, blks, blk);
375
376				/* Advance pointer */
377				iov = cuio_getptr(uio, k + blks, &k);
378				if (iov == NULL)
379					return EINVAL;
380
381				i -= blks;
382
383				/* Could be done... */
384				if (i == 0)
385					break;
386			}
387
388			/*
389			 * Warning: idat may point to garbage here, but
390			 * we only use it in the while() loop, only if
391			 * there are indeed enough data.
392			 */
393			idat = (char *)iov->iov_base + k;
394
395	   		while (iov->iov_len >= k + blks && i > 0) {
396				if (crd->crd_flags & CRD_F_ENCRYPT) {
397					/* XOR with previous block/IV */
398					for (j = 0; j < blks; j++)
399						idat[j] ^= ivp[j];
400
401					exf->encrypt(sw->sw_kschedule, idat);
402					ivp = idat;
403				} else {	/* decrypt */
404					/*
405					 * Keep encrypted block to be used
406					 * in next block's processing.
407					 */
408					if (ivp == iv)
409						bcopy(idat, piv, blks);
410					else
411						bcopy(idat, iv, blks);
412
413					exf->decrypt(sw->sw_kschedule, idat);
414
415					/* XOR with previous block/IV */
416					for (j = 0; j < blks; j++)
417						idat[j] ^= ivp[j];
418
419					if (ivp == iv)
420						bcopy(piv, iv, blks);
421					else
422						ivp = iv;
423				}
424
425				idat += blks;
426				k += blks;
427				i -= blks;
428			}
429		}
430
431		return 0; /* Done with mbuf encryption/decryption */
432	}
433
434	/* Unreachable */
435	return EINVAL;
436}
437
438/*
439 * Compute keyed-hash authenticator.
440 */
441static int
442swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
443    struct swcr_data *sw, caddr_t buf, int outtype)
444{
445	unsigned char aalg[AALG_MAX_RESULT_LEN];
446	struct auth_hash *axf;
447	union authctx ctx;
448	int err;
449
450	if (sw->sw_ictx == 0)
451		return EINVAL;
452
453	axf = sw->sw_axf;
454
455	bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
456
457	switch (outtype) {
458	case CRYPTO_BUF_CONTIG:
459		axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len);
460		break;
461	case CRYPTO_BUF_MBUF:
462		err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
463		    (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
464		    (caddr_t) &ctx);
465		if (err)
466			return err;
467		break;
468	case CRYPTO_BUF_IOV:
469	default:
470		return EINVAL;
471	}
472
473	switch (sw->sw_alg) {
474	case CRYPTO_MD5_HMAC:
475	case CRYPTO_SHA1_HMAC:
476	case CRYPTO_SHA2_HMAC:
477	case CRYPTO_RIPEMD160_HMAC:
478		if (sw->sw_octx == NULL)
479			return EINVAL;
480
481		axf->Final(aalg, &ctx);
482		bcopy(sw->sw_octx, &ctx, axf->ctxsize);
483		axf->Update(&ctx, aalg, axf->hashsize);
484		axf->Final(aalg, &ctx);
485		break;
486
487	case CRYPTO_MD5_KPDK:
488	case CRYPTO_SHA1_KPDK:
489		if (sw->sw_octx == NULL)
490			return EINVAL;
491
492		axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
493		axf->Final(aalg, &ctx);
494		break;
495
496	case CRYPTO_NULL_HMAC:
497		axf->Final(aalg, &ctx);
498		break;
499	}
500
501	/* Inject the authentication data */
502	if (outtype == CRYPTO_BUF_CONTIG)
503		bcopy(aalg, buf + crd->crd_inject, axf->authsize);
504	else
505		m_copyback((struct mbuf *) buf, crd->crd_inject,
506		    axf->authsize, aalg);
507	return 0;
508}
509
510/*
511 * Apply a compression/decompression algorithm
512 */
513static int
514swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
515    caddr_t buf, int outtype)
516{
517	u_int8_t *data, *out;
518	struct comp_algo *cxf;
519	int adj;
520	u_int32_t result;
521
522	cxf = sw->sw_cxf;
523
524	/* We must handle the whole buffer of data in one time
525	 * then if there is not all the data in the mbuf, we must
526	 * copy in a buffer.
527	 */
528
529	MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA,  M_NOWAIT);
530	if (data == NULL)
531		return (EINVAL);
532	COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
533
534	if (crd->crd_flags & CRD_F_COMP)
535		result = cxf->compress(data, crd->crd_len, &out);
536	else
537		result = cxf->decompress(data, crd->crd_len, &out);
538
539	FREE(data, M_CRYPTO_DATA);
540	if (result == 0)
541		return EINVAL;
542
543	/* Copy back the (de)compressed data. m_copyback is
544	 * extending the mbuf as necessary.
545	 */
546	sw->sw_size = result;
547	/* Check the compressed size when doing compression */
548	if (crd->crd_flags & CRD_F_COMP) {
549		if (result > crd->crd_len) {
550			/* Compression was useless, we lost time */
551			FREE(out, M_CRYPTO_DATA);
552			return 0;
553		}
554	}
555
556	COPYBACK(outtype, buf, crd->crd_skip, result, out);
557	if (result < crd->crd_len) {
558		adj = result - crd->crd_len;
559		if (outtype == CRYPTO_BUF_MBUF) {
560			adj = result - crd->crd_len;
561			m_adj((struct mbuf *)buf, adj);
562		} else {
563			struct uio *uio = (struct uio *)buf;
564			int ind;
565
566			adj = crd->crd_len - result;
567			ind = uio->uio_iovcnt - 1;
568
569			while (adj > 0 && ind >= 0) {
570				if (adj < uio->uio_iov[ind].iov_len) {
571					uio->uio_iov[ind].iov_len -= adj;
572					break;
573				}
574
575				adj -= uio->uio_iov[ind].iov_len;
576				uio->uio_iov[ind].iov_len = 0;
577				ind--;
578				uio->uio_iovcnt--;
579			}
580		}
581	}
582	FREE(out, M_CRYPTO_DATA);
583	return 0;
584}
585
586/*
587 * Generate a new software session.
588 */
589static int
590swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
591{
592	struct swcr_data **swd;
593	struct auth_hash *axf;
594	struct enc_xform *txf;
595	struct comp_algo *cxf;
596	u_int32_t i;
597	int k, error;
598
599	if (sid == NULL || cri == NULL)
600		return EINVAL;
601
602	if (swcr_sessions) {
603		for (i = 1; i < swcr_sesnum; i++)
604			if (swcr_sessions[i] == NULL)
605				break;
606	} else
607		i = 1;		/* NB: to silence compiler warning */
608
609	if (swcr_sessions == NULL || i == swcr_sesnum) {
610		if (swcr_sessions == NULL) {
611			i = 1; /* We leave swcr_sessions[0] empty */
612			swcr_sesnum = CRYPTO_SW_SESSIONS;
613		} else
614			swcr_sesnum *= 2;
615
616		swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
617		    M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
618		if (swd == NULL) {
619			/* Reset session number */
620			if (swcr_sesnum == CRYPTO_SW_SESSIONS)
621				swcr_sesnum = 0;
622			else
623				swcr_sesnum /= 2;
624			return ENOBUFS;
625		}
626
627		/* Copy existing sessions */
628		if (swcr_sessions) {
629			bcopy(swcr_sessions, swd,
630			    (swcr_sesnum / 2) * sizeof(struct swcr_data *));
631			free(swcr_sessions, M_CRYPTO_DATA);
632		}
633
634		swcr_sessions = swd;
635	}
636
637	swd = &swcr_sessions[i];
638	*sid = i;
639
640	while (cri) {
641		MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
642		    M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
643		if (*swd == NULL) {
644			swcr_freesession(NULL, i);
645			return ENOBUFS;
646		}
647
648		switch (cri->cri_alg) {
649		case CRYPTO_DES_CBC:
650			txf = &enc_xform_des;
651			goto enccommon;
652		case CRYPTO_3DES_CBC:
653			txf = &enc_xform_3des;
654			goto enccommon;
655		case CRYPTO_BLF_CBC:
656			txf = &enc_xform_blf;
657			goto enccommon;
658		case CRYPTO_CAST_CBC:
659			txf = &enc_xform_cast5;
660			goto enccommon;
661		case CRYPTO_SKIPJACK_CBC:
662			txf = &enc_xform_skipjack;
663			goto enccommon;
664		case CRYPTO_RIJNDAEL128_CBC:
665			txf = &enc_xform_rijndael128;
666			goto enccommon;
667		case CRYPTO_NULL_CBC:
668			txf = &enc_xform_null;
669			goto enccommon;
670		enccommon:
671			error = txf->setkey(&((*swd)->sw_kschedule),
672					cri->cri_key, cri->cri_klen / 8);
673			if (error) {
674				swcr_freesession(NULL, i);
675				return error;
676			}
677			(*swd)->sw_exf = txf;
678			break;
679
680		case CRYPTO_MD5_HMAC:
681			axf = &auth_hash_hmac_md5_96;
682			goto authcommon;
683		case CRYPTO_SHA1_HMAC:
684			axf = &auth_hash_hmac_sha1_96;
685			goto authcommon;
686		case CRYPTO_SHA2_HMAC:
687			if (cri->cri_klen == 256)
688				axf = &auth_hash_hmac_sha2_256;
689			else if (cri->cri_klen == 384)
690				axf = &auth_hash_hmac_sha2_384;
691			else if (cri->cri_klen == 512)
692				axf = &auth_hash_hmac_sha2_512;
693			else {
694				swcr_freesession(NULL, i);
695				return EINVAL;
696			}
697			goto authcommon;
698		case CRYPTO_NULL_HMAC:
699			axf = &auth_hash_null;
700			goto authcommon;
701		case CRYPTO_RIPEMD160_HMAC:
702			axf = &auth_hash_hmac_ripemd_160_96;
703		authcommon:
704			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
705			    M_NOWAIT);
706			if ((*swd)->sw_ictx == NULL) {
707				swcr_freesession(NULL, i);
708				return ENOBUFS;
709			}
710
711			(*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
712			    M_NOWAIT);
713			if ((*swd)->sw_octx == NULL) {
714				swcr_freesession(NULL, i);
715				return ENOBUFS;
716			}
717
718			for (k = 0; k < cri->cri_klen / 8; k++)
719				cri->cri_key[k] ^= HMAC_IPAD_VAL;
720
721			axf->Init((*swd)->sw_ictx);
722			axf->Update((*swd)->sw_ictx, cri->cri_key,
723			    cri->cri_klen / 8);
724			axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
725			    HMAC_BLOCK_LEN - (cri->cri_klen / 8));
726
727			for (k = 0; k < cri->cri_klen / 8; k++)
728				cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
729
730			axf->Init((*swd)->sw_octx);
731			axf->Update((*swd)->sw_octx, cri->cri_key,
732			    cri->cri_klen / 8);
733			axf->Update((*swd)->sw_octx, hmac_opad_buffer,
734			    HMAC_BLOCK_LEN - (cri->cri_klen / 8));
735
736			for (k = 0; k < cri->cri_klen / 8; k++)
737				cri->cri_key[k] ^= HMAC_OPAD_VAL;
738			(*swd)->sw_axf = axf;
739			break;
740
741		case CRYPTO_MD5_KPDK:
742			axf = &auth_hash_key_md5;
743			goto auth2common;
744
745		case CRYPTO_SHA1_KPDK:
746			axf = &auth_hash_key_sha1;
747		auth2common:
748			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
749			    M_NOWAIT);
750			if ((*swd)->sw_ictx == NULL) {
751				swcr_freesession(NULL, i);
752				return ENOBUFS;
753			}
754
755			/* Store the key so we can "append" it to the payload */
756			(*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
757			    M_NOWAIT);
758			if ((*swd)->sw_octx == NULL) {
759				swcr_freesession(NULL, i);
760				return ENOBUFS;
761			}
762
763			(*swd)->sw_klen = cri->cri_klen / 8;
764			bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
765			axf->Init((*swd)->sw_ictx);
766			axf->Update((*swd)->sw_ictx, cri->cri_key,
767			    cri->cri_klen / 8);
768			axf->Final(NULL, (*swd)->sw_ictx);
769			(*swd)->sw_axf = axf;
770			break;
771#ifdef notdef
772		case CRYPTO_MD5:
773			axf = &auth_hash_md5;
774			goto auth3common;
775
776		case CRYPTO_SHA1:
777			axf = &auth_hash_sha1;
778		auth3common:
779			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
780			    M_NOWAIT);
781			if ((*swd)->sw_ictx == NULL) {
782				swcr_freesession(NULL, i);
783				return ENOBUFS;
784			}
785
786			axf->Init((*swd)->sw_ictx);
787			(*swd)->sw_axf = axf;
788			break;
789#endif
790		case CRYPTO_DEFLATE_COMP:
791			cxf = &comp_algo_deflate;
792			(*swd)->sw_cxf = cxf;
793			break;
794		default:
795			swcr_freesession(NULL, i);
796			return EINVAL;
797		}
798
799		(*swd)->sw_alg = cri->cri_alg;
800		cri = cri->cri_next;
801		swd = &((*swd)->sw_next);
802	}
803	return 0;
804}
805
806/*
807 * Free a session.
808 */
809static int
810swcr_freesession(void *arg, u_int64_t tid)
811{
812	struct swcr_data *swd;
813	struct enc_xform *txf;
814	struct auth_hash *axf;
815	struct comp_algo *cxf;
816	u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
817
818	if (sid > swcr_sesnum || swcr_sessions == NULL ||
819	    swcr_sessions[sid] == NULL)
820		return EINVAL;
821
822	/* Silently accept and return */
823	if (sid == 0)
824		return 0;
825
826	while ((swd = swcr_sessions[sid]) != NULL) {
827		swcr_sessions[sid] = swd->sw_next;
828
829		switch (swd->sw_alg) {
830		case CRYPTO_DES_CBC:
831		case CRYPTO_3DES_CBC:
832		case CRYPTO_BLF_CBC:
833		case CRYPTO_CAST_CBC:
834		case CRYPTO_SKIPJACK_CBC:
835		case CRYPTO_RIJNDAEL128_CBC:
836		case CRYPTO_NULL_CBC:
837			txf = swd->sw_exf;
838
839			if (swd->sw_kschedule)
840				txf->zerokey(&(swd->sw_kschedule));
841			break;
842
843		case CRYPTO_MD5_HMAC:
844		case CRYPTO_SHA1_HMAC:
845		case CRYPTO_SHA2_HMAC:
846		case CRYPTO_RIPEMD160_HMAC:
847		case CRYPTO_NULL_HMAC:
848			axf = swd->sw_axf;
849
850			if (swd->sw_ictx) {
851				bzero(swd->sw_ictx, axf->ctxsize);
852				free(swd->sw_ictx, M_CRYPTO_DATA);
853			}
854			if (swd->sw_octx) {
855				bzero(swd->sw_octx, axf->ctxsize);
856				free(swd->sw_octx, M_CRYPTO_DATA);
857			}
858			break;
859
860		case CRYPTO_MD5_KPDK:
861		case CRYPTO_SHA1_KPDK:
862			axf = swd->sw_axf;
863
864			if (swd->sw_ictx) {
865				bzero(swd->sw_ictx, axf->ctxsize);
866				free(swd->sw_ictx, M_CRYPTO_DATA);
867			}
868			if (swd->sw_octx) {
869				bzero(swd->sw_octx, swd->sw_klen);
870				free(swd->sw_octx, M_CRYPTO_DATA);
871			}
872			break;
873
874		case CRYPTO_MD5:
875		case CRYPTO_SHA1:
876			axf = swd->sw_axf;
877
878			if (swd->sw_ictx)
879				free(swd->sw_ictx, M_CRYPTO_DATA);
880			break;
881
882		case CRYPTO_DEFLATE_COMP:
883			cxf = swd->sw_cxf;
884			break;
885		}
886
887		FREE(swd, M_CRYPTO_DATA);
888	}
889	return 0;
890}
891
892/*
893 * Process a software request.
894 */
895static int
896swcr_process(void *arg, struct cryptop *crp, int hint)
897{
898	struct cryptodesc *crd;
899	struct swcr_data *sw;
900	u_int32_t lid;
901	int type;
902
903	/* Sanity check */
904	if (crp == NULL)
905		return EINVAL;
906
907	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
908		crp->crp_etype = EINVAL;
909		goto done;
910	}
911
912	lid = crp->crp_sid & 0xffffffff;
913	if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
914		crp->crp_etype = ENOENT;
915		goto done;
916	}
917
918	if (crp->crp_flags & CRYPTO_F_IMBUF) {
919		type = CRYPTO_BUF_MBUF;
920	} else if (crp->crp_flags & CRYPTO_F_IOV) {
921		type = CRYPTO_BUF_IOV;
922	} else {
923		type = CRYPTO_BUF_CONTIG;
924	}
925
926	/* Go through crypto descriptors, processing as we go */
927	for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
928		/*
929		 * Find the crypto context.
930		 *
931		 * XXX Note that the logic here prevents us from having
932		 * XXX the same algorithm multiple times in a session
933		 * XXX (or rather, we can but it won't give us the right
934		 * XXX results). To do that, we'd need some way of differentiating
935		 * XXX between the various instances of an algorithm (so we can
936		 * XXX locate the correct crypto context).
937		 */
938		for (sw = swcr_sessions[lid];
939		    sw && sw->sw_alg != crd->crd_alg;
940		    sw = sw->sw_next)
941			;
942
943		/* No such context ? */
944		if (sw == NULL) {
945			crp->crp_etype = EINVAL;
946			goto done;
947		}
948		switch (sw->sw_alg) {
949		case CRYPTO_DES_CBC:
950		case CRYPTO_3DES_CBC:
951		case CRYPTO_BLF_CBC:
952		case CRYPTO_CAST_CBC:
953		case CRYPTO_SKIPJACK_CBC:
954		case CRYPTO_RIJNDAEL128_CBC:
955			if ((crp->crp_etype = swcr_encdec(crd, sw,
956			    crp->crp_buf, type)) != 0)
957				goto done;
958			break;
959		case CRYPTO_NULL_CBC:
960			crp->crp_etype = 0;
961			break;
962		case CRYPTO_MD5_HMAC:
963		case CRYPTO_SHA1_HMAC:
964		case CRYPTO_SHA2_HMAC:
965		case CRYPTO_RIPEMD160_HMAC:
966		case CRYPTO_NULL_HMAC:
967		case CRYPTO_MD5_KPDK:
968		case CRYPTO_SHA1_KPDK:
969		case CRYPTO_MD5:
970		case CRYPTO_SHA1:
971			if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
972			    crp->crp_buf, type)) != 0)
973				goto done;
974			break;
975
976		case CRYPTO_DEFLATE_COMP:
977			if ((crp->crp_etype = swcr_compdec(crd, sw,
978			    crp->crp_buf, type)) != 0)
979				goto done;
980			else
981				crp->crp_olen = (int)sw->sw_size;
982			break;
983
984		default:
985			/* Unknown/unsupported algorithm */
986			crp->crp_etype = EINVAL;
987			goto done;
988		}
989	}
990
991done:
992	crypto_done(crp);
993	return 0;
994}
995
996/*
997 * Initialize the driver, called from the kernel main().
998 */
999static void
1000swcr_init(void)
1001{
1002	swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE);
1003	if (swcr_id < 0)
1004		panic("Software crypto device cannot initialize!");
1005	crypto_register(swcr_id, CRYPTO_DES_CBC,
1006	    0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL);
1007#define	REGISTER(alg) \
1008	crypto_register(swcr_id, alg, 0,0,NULL,NULL,NULL,NULL)
1009	REGISTER(CRYPTO_3DES_CBC);
1010	REGISTER(CRYPTO_BLF_CBC);
1011	REGISTER(CRYPTO_CAST_CBC);
1012	REGISTER(CRYPTO_SKIPJACK_CBC);
1013	REGISTER(CRYPTO_NULL_CBC);
1014	REGISTER(CRYPTO_MD5_HMAC);
1015	REGISTER(CRYPTO_SHA1_HMAC);
1016	REGISTER(CRYPTO_SHA2_HMAC);
1017	REGISTER(CRYPTO_RIPEMD160_HMAC);
1018	REGISTER(CRYPTO_NULL_HMAC);
1019	REGISTER(CRYPTO_MD5_KPDK);
1020	REGISTER(CRYPTO_SHA1_KPDK);
1021	REGISTER(CRYPTO_MD5);
1022	REGISTER(CRYPTO_SHA1);
1023	REGISTER(CRYPTO_RIJNDAEL128_CBC);
1024	REGISTER(CRYPTO_DEFLATE_COMP);
1025#undef REGISTER
1026}
1027SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
1028