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