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