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