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