xref: /freebsd/sys/opencrypto/cryptosoft.c (revision 9608d7e2cd58c1a7fff6562810f2ce519e6ec50a)
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  * Apply a symmetric encryption/decryption algorithm.
92  */
93 static int
94 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
95     int outtype)
96 {
97 	unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
98 	unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
99 	struct enc_xform *exf;
100 	int i, k, j, blks;
101 
102 	exf = sw->sw_exf;
103 	blks = exf->blocksize;
104 
105 	/* Check for non-padded data */
106 	if (crd->crd_len % blks)
107 		return EINVAL;
108 
109 	/* Initialize the IV */
110 	if (crd->crd_flags & CRD_F_ENCRYPT) {
111 		/* IV explicitly provided ? */
112 		if (crd->crd_flags & CRD_F_IV_EXPLICIT)
113 			bcopy(crd->crd_iv, iv, blks);
114 		else {
115 			/* Get random IV */
116 			for (i = 0;
117 			    i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN;
118 			    i += sizeof (u_int32_t)) {
119 				u_int32_t temp = arc4random();
120 
121 				bcopy(&temp, iv + i, sizeof(u_int32_t));
122 			}
123 			/*
124 			 * What if the block size is not a multiple
125 			 * of sizeof (u_int32_t), which is the size of
126 			 * what arc4random() returns ?
127 			 */
128 			if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) {
129 				u_int32_t temp = arc4random();
130 
131 				bcopy (&temp, iv + i,
132 				    EALG_MAX_BLOCK_LEN - i);
133 			}
134 		}
135 
136 		/* Do we need to write the IV */
137 		if (!(crd->crd_flags & CRD_F_IV_PRESENT)) {
138 			COPYBACK(outtype, buf, crd->crd_inject, blks, iv);
139 		}
140 
141 	} else {	/* Decryption */
142 			/* IV explicitly provided ? */
143 		if (crd->crd_flags & CRD_F_IV_EXPLICIT)
144 			bcopy(crd->crd_iv, iv, blks);
145 		else {
146 			/* Get IV off buf */
147 			COPYDATA(outtype, buf, crd->crd_inject, blks, iv);
148 		}
149 	}
150 
151 	ivp = iv;
152 
153 	if (outtype == CRYPTO_BUF_CONTIG) {
154 		if (crd->crd_flags & CRD_F_ENCRYPT) {
155 			for (i = crd->crd_skip;
156 			    i < crd->crd_skip + crd->crd_len; i += blks) {
157 				/* XOR with the IV/previous block, as appropriate. */
158 				if (i == crd->crd_skip)
159 					for (k = 0; k < blks; k++)
160 						buf[i + k] ^= ivp[k];
161 				else
162 					for (k = 0; k < blks; k++)
163 						buf[i + k] ^= buf[i + k - blks];
164 				exf->encrypt(sw->sw_kschedule, buf + i);
165 			}
166 		} else {		/* Decrypt */
167 			/*
168 			 * Start at the end, so we don't need to keep the encrypted
169 			 * block as the IV for the next block.
170 			 */
171 			for (i = crd->crd_skip + crd->crd_len - blks;
172 			    i >= crd->crd_skip; i -= blks) {
173 				exf->decrypt(sw->sw_kschedule, buf + i);
174 
175 				/* XOR with the IV/previous block, as appropriate */
176 				if (i == crd->crd_skip)
177 					for (k = 0; k < blks; k++)
178 						buf[i + k] ^= ivp[k];
179 				else
180 					for (k = 0; k < blks; k++)
181 						buf[i + k] ^= buf[i + k - blks];
182 			}
183 		}
184 
185 		return 0;
186 	} else if (outtype == CRYPTO_BUF_MBUF) {
187 		struct mbuf *m = (struct mbuf *) buf;
188 
189 		/* Find beginning of data */
190 		m = m_getptr(m, crd->crd_skip, &k);
191 		if (m == NULL)
192 			return EINVAL;
193 
194 		i = crd->crd_len;
195 
196 		while (i > 0) {
197 			/*
198 			 * If there's insufficient data at the end of
199 			 * an mbuf, we have to do some copying.
200 			 */
201 			if (m->m_len < k + blks && m->m_len != k) {
202 				m_copydata(m, k, blks, blk);
203 
204 				/* Actual encryption/decryption */
205 				if (crd->crd_flags & CRD_F_ENCRYPT) {
206 					/* XOR with previous block */
207 					for (j = 0; j < blks; j++)
208 						blk[j] ^= ivp[j];
209 
210 					exf->encrypt(sw->sw_kschedule, blk);
211 
212 					/*
213 					 * Keep encrypted block for XOR'ing
214 					 * with next block
215 					 */
216 					bcopy(blk, iv, blks);
217 					ivp = iv;
218 				} else {	/* decrypt */
219 					/*
220 					 * Keep encrypted block for XOR'ing
221 					 * with next block
222 					 */
223 					if (ivp == iv)
224 						bcopy(blk, piv, blks);
225 					else
226 						bcopy(blk, iv, blks);
227 
228 					exf->decrypt(sw->sw_kschedule, blk);
229 
230 					/* XOR with previous block */
231 					for (j = 0; j < blks; j++)
232 						blk[j] ^= ivp[j];
233 
234 					if (ivp == iv)
235 						bcopy(piv, iv, blks);
236 					else
237 						ivp = iv;
238 				}
239 
240 				/* Copy back decrypted block */
241 				m_copyback(m, k, blks, blk);
242 
243 				/* Advance pointer */
244 				m = m_getptr(m, k + blks, &k);
245 				if (m == NULL)
246 					return EINVAL;
247 
248 				i -= blks;
249 
250 				/* Could be done... */
251 				if (i == 0)
252 					break;
253 			}
254 
255 			/* Skip possibly empty mbufs */
256 			if (k == m->m_len) {
257 				for (m = m->m_next; m && m->m_len == 0;
258 				    m = m->m_next)
259 					;
260 				k = 0;
261 			}
262 
263 			/* Sanity check */
264 			if (m == NULL)
265 				return EINVAL;
266 
267 			/*
268 			 * Warning: idat may point to garbage here, but
269 			 * we only use it in the while() loop, only if
270 			 * there are indeed enough data.
271 			 */
272 			idat = mtod(m, unsigned char *) + k;
273 
274 	   		while (m->m_len >= k + blks && i > 0) {
275 				if (crd->crd_flags & CRD_F_ENCRYPT) {
276 					/* XOR with previous block/IV */
277 					for (j = 0; j < blks; j++)
278 						idat[j] ^= ivp[j];
279 
280 					exf->encrypt(sw->sw_kschedule, idat);
281 					ivp = idat;
282 				} else {	/* decrypt */
283 					/*
284 					 * Keep encrypted block to be used
285 					 * in next block's processing.
286 					 */
287 					if (ivp == iv)
288 						bcopy(idat, piv, blks);
289 					else
290 						bcopy(idat, iv, blks);
291 
292 					exf->decrypt(sw->sw_kschedule, idat);
293 
294 					/* XOR with previous block/IV */
295 					for (j = 0; j < blks; j++)
296 						idat[j] ^= ivp[j];
297 
298 					if (ivp == iv)
299 						bcopy(piv, iv, blks);
300 					else
301 						ivp = iv;
302 				}
303 
304 				idat += blks;
305 				k += blks;
306 				i -= blks;
307 			}
308 		}
309 
310 		return 0; /* Done with mbuf encryption/decryption */
311 	} else if (outtype == CRYPTO_BUF_IOV) {
312 		struct uio *uio = (struct uio *) buf;
313 		struct iovec *iov;
314 
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 	}
426 
427 	/* Unreachable */
428 	return EINVAL;
429 }
430 
431 /*
432  * Compute keyed-hash authenticator.
433  */
434 static int
435 swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
436     struct swcr_data *sw, caddr_t buf, int outtype)
437 {
438 	unsigned char aalg[AALG_MAX_RESULT_LEN];
439 	struct auth_hash *axf;
440 	union authctx ctx;
441 	int err;
442 
443 	if (sw->sw_ictx == 0)
444 		return EINVAL;
445 
446 	axf = sw->sw_axf;
447 
448 	bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
449 
450 	switch (outtype) {
451 	case CRYPTO_BUF_CONTIG:
452 		axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len);
453 		break;
454 	case CRYPTO_BUF_MBUF:
455 		err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
456 		    (int (*)(void *, void *, unsigned int)) axf->Update,
457 		    (caddr_t) &ctx);
458 		if (err)
459 			return err;
460 		break;
461 	case CRYPTO_BUF_IOV:
462 	default:
463 		return EINVAL;
464 	}
465 
466 	switch (sw->sw_alg) {
467 	case CRYPTO_MD5_HMAC:
468 	case CRYPTO_SHA1_HMAC:
469 	case CRYPTO_SHA2_HMAC:
470 	case CRYPTO_RIPEMD160_HMAC:
471 		if (sw->sw_octx == NULL)
472 			return EINVAL;
473 
474 		axf->Final(aalg, &ctx);
475 		bcopy(sw->sw_octx, &ctx, axf->ctxsize);
476 		axf->Update(&ctx, aalg, axf->hashsize);
477 		axf->Final(aalg, &ctx);
478 		break;
479 
480 	case CRYPTO_MD5_KPDK:
481 	case CRYPTO_SHA1_KPDK:
482 		if (sw->sw_octx == NULL)
483 			return EINVAL;
484 
485 		axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
486 		axf->Final(aalg, &ctx);
487 		break;
488 
489 	case CRYPTO_NULL_HMAC:
490 		axf->Final(aalg, &ctx);
491 		break;
492 	}
493 
494 	/* Inject the authentication data */
495 	if (outtype == CRYPTO_BUF_CONTIG)
496 		bcopy(aalg, buf + crd->crd_inject, axf->authsize);
497 	else
498 		m_copyback((struct mbuf *) buf, crd->crd_inject,
499 		    axf->authsize, aalg);
500 	return 0;
501 }
502 
503 /*
504  * Apply a compression/decompression algorithm
505  */
506 static int
507 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
508     caddr_t buf, int outtype)
509 {
510 	u_int8_t *data, *out;
511 	struct comp_algo *cxf;
512 	int adj;
513 	u_int32_t result;
514 
515 	cxf = sw->sw_cxf;
516 
517 	/* We must handle the whole buffer of data in one time
518 	 * then if there is not all the data in the mbuf, we must
519 	 * copy in a buffer.
520 	 */
521 
522 	MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA,  M_NOWAIT);
523 	if (data == NULL)
524 		return (EINVAL);
525 	COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
526 
527 	if (crd->crd_flags & CRD_F_COMP)
528 		result = cxf->compress(data, crd->crd_len, &out);
529 	else
530 		result = cxf->decompress(data, crd->crd_len, &out);
531 
532 	FREE(data, M_CRYPTO_DATA);
533 	if (result == 0)
534 		return EINVAL;
535 
536 	/* Copy back the (de)compressed data. m_copyback is
537 	 * extending the mbuf as necessary.
538 	 */
539 	sw->sw_size = result;
540 	/* Check the compressed size when doing compression */
541 	if (crd->crd_flags & CRD_F_COMP) {
542 		if (result > crd->crd_len) {
543 			/* Compression was useless, we lost time */
544 			FREE(out, M_CRYPTO_DATA);
545 			return 0;
546 		}
547 	}
548 
549 	COPYBACK(outtype, buf, crd->crd_skip, result, out);
550 	if (result < crd->crd_len) {
551 		adj = result - crd->crd_len;
552 		if (outtype == CRYPTO_BUF_MBUF) {
553 			adj = result - crd->crd_len;
554 			m_adj((struct mbuf *)buf, adj);
555 		} else {
556 			struct uio *uio = (struct uio *)buf;
557 			int ind;
558 
559 			adj = crd->crd_len - result;
560 			ind = uio->uio_iovcnt - 1;
561 
562 			while (adj > 0 && ind >= 0) {
563 				if (adj < uio->uio_iov[ind].iov_len) {
564 					uio->uio_iov[ind].iov_len -= adj;
565 					break;
566 				}
567 
568 				adj -= uio->uio_iov[ind].iov_len;
569 				uio->uio_iov[ind].iov_len = 0;
570 				ind--;
571 				uio->uio_iovcnt--;
572 			}
573 		}
574 	}
575 	FREE(out, M_CRYPTO_DATA);
576 	return 0;
577 }
578 
579 /*
580  * Generate a new software session.
581  */
582 static int
583 swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
584 {
585 	struct swcr_data **swd;
586 	struct auth_hash *axf;
587 	struct enc_xform *txf;
588 	struct comp_algo *cxf;
589 	u_int32_t i;
590 	int k, error;
591 
592 	if (sid == NULL || cri == NULL)
593 		return EINVAL;
594 
595 	if (swcr_sessions) {
596 		for (i = 1; i < swcr_sesnum; i++)
597 			if (swcr_sessions[i] == NULL)
598 				break;
599 	} else
600 		i = 1;		/* NB: to silence compiler warning */
601 
602 	if (swcr_sessions == NULL || i == swcr_sesnum) {
603 		if (swcr_sessions == NULL) {
604 			i = 1; /* We leave swcr_sessions[0] empty */
605 			swcr_sesnum = CRYPTO_SW_SESSIONS;
606 		} else
607 			swcr_sesnum *= 2;
608 
609 		swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
610 		    M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
611 		if (swd == NULL) {
612 			/* Reset session number */
613 			if (swcr_sesnum == CRYPTO_SW_SESSIONS)
614 				swcr_sesnum = 0;
615 			else
616 				swcr_sesnum /= 2;
617 			return ENOBUFS;
618 		}
619 
620 		/* Copy existing sessions */
621 		if (swcr_sessions) {
622 			bcopy(swcr_sessions, swd,
623 			    (swcr_sesnum / 2) * sizeof(struct swcr_data *));
624 			free(swcr_sessions, M_CRYPTO_DATA);
625 		}
626 
627 		swcr_sessions = swd;
628 	}
629 
630 	swd = &swcr_sessions[i];
631 	*sid = i;
632 
633 	while (cri) {
634 		MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
635 		    M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
636 		if (*swd == NULL) {
637 			swcr_freesession(NULL, i);
638 			return ENOBUFS;
639 		}
640 
641 		switch (cri->cri_alg) {
642 		case CRYPTO_DES_CBC:
643 			txf = &enc_xform_des;
644 			goto enccommon;
645 		case CRYPTO_3DES_CBC:
646 			txf = &enc_xform_3des;
647 			goto enccommon;
648 		case CRYPTO_BLF_CBC:
649 			txf = &enc_xform_blf;
650 			goto enccommon;
651 		case CRYPTO_CAST_CBC:
652 			txf = &enc_xform_cast5;
653 			goto enccommon;
654 		case CRYPTO_SKIPJACK_CBC:
655 			txf = &enc_xform_skipjack;
656 			goto enccommon;
657 		case CRYPTO_RIJNDAEL128_CBC:
658 			txf = &enc_xform_rijndael128;
659 			goto enccommon;
660 		case CRYPTO_NULL_CBC:
661 			txf = &enc_xform_null;
662 			goto enccommon;
663 		enccommon:
664 			error = txf->setkey(&((*swd)->sw_kschedule),
665 					cri->cri_key, cri->cri_klen / 8);
666 			if (error) {
667 				swcr_freesession(NULL, i);
668 				return error;
669 			}
670 			(*swd)->sw_exf = txf;
671 			break;
672 
673 		case CRYPTO_MD5_HMAC:
674 			axf = &auth_hash_hmac_md5_96;
675 			goto authcommon;
676 		case CRYPTO_SHA1_HMAC:
677 			axf = &auth_hash_hmac_sha1_96;
678 			goto authcommon;
679 		case CRYPTO_SHA2_HMAC:
680 			if (cri->cri_klen == 256)
681 				axf = &auth_hash_hmac_sha2_256;
682 			else if (cri->cri_klen == 384)
683 				axf = &auth_hash_hmac_sha2_384;
684 			else if (cri->cri_klen == 512)
685 				axf = &auth_hash_hmac_sha2_512;
686 			else {
687 				swcr_freesession(NULL, i);
688 				return EINVAL;
689 			}
690 			goto authcommon;
691 		case CRYPTO_NULL_HMAC:
692 			axf = &auth_hash_null;
693 			goto authcommon;
694 		case CRYPTO_RIPEMD160_HMAC:
695 			axf = &auth_hash_hmac_ripemd_160_96;
696 		authcommon:
697 			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
698 			    M_NOWAIT);
699 			if ((*swd)->sw_ictx == NULL) {
700 				swcr_freesession(NULL, i);
701 				return ENOBUFS;
702 			}
703 
704 			(*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
705 			    M_NOWAIT);
706 			if ((*swd)->sw_octx == NULL) {
707 				swcr_freesession(NULL, i);
708 				return ENOBUFS;
709 			}
710 
711 			for (k = 0; k < cri->cri_klen / 8; k++)
712 				cri->cri_key[k] ^= HMAC_IPAD_VAL;
713 
714 			axf->Init((*swd)->sw_ictx);
715 			axf->Update((*swd)->sw_ictx, cri->cri_key,
716 			    cri->cri_klen / 8);
717 			axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
718 			    HMAC_BLOCK_LEN - (cri->cri_klen / 8));
719 
720 			for (k = 0; k < cri->cri_klen / 8; k++)
721 				cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
722 
723 			axf->Init((*swd)->sw_octx);
724 			axf->Update((*swd)->sw_octx, cri->cri_key,
725 			    cri->cri_klen / 8);
726 			axf->Update((*swd)->sw_octx, hmac_opad_buffer,
727 			    HMAC_BLOCK_LEN - (cri->cri_klen / 8));
728 
729 			for (k = 0; k < cri->cri_klen / 8; k++)
730 				cri->cri_key[k] ^= HMAC_OPAD_VAL;
731 			(*swd)->sw_axf = axf;
732 			break;
733 
734 		case CRYPTO_MD5_KPDK:
735 			axf = &auth_hash_key_md5;
736 			goto auth2common;
737 
738 		case CRYPTO_SHA1_KPDK:
739 			axf = &auth_hash_key_sha1;
740 		auth2common:
741 			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
742 			    M_NOWAIT);
743 			if ((*swd)->sw_ictx == NULL) {
744 				swcr_freesession(NULL, i);
745 				return ENOBUFS;
746 			}
747 
748 			/* Store the key so we can "append" it to the payload */
749 			(*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
750 			    M_NOWAIT);
751 			if ((*swd)->sw_octx == NULL) {
752 				swcr_freesession(NULL, i);
753 				return ENOBUFS;
754 			}
755 
756 			(*swd)->sw_klen = cri->cri_klen / 8;
757 			bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
758 			axf->Init((*swd)->sw_ictx);
759 			axf->Update((*swd)->sw_ictx, cri->cri_key,
760 			    cri->cri_klen / 8);
761 			axf->Final(NULL, (*swd)->sw_ictx);
762 			(*swd)->sw_axf = axf;
763 			break;
764 #ifdef notdef
765 		case CRYPTO_MD5:
766 			axf = &auth_hash_md5;
767 			goto auth3common;
768 
769 		case CRYPTO_SHA1:
770 			axf = &auth_hash_sha1;
771 		auth3common:
772 			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
773 			    M_NOWAIT);
774 			if ((*swd)->sw_ictx == NULL) {
775 				swcr_freesession(NULL, i);
776 				return ENOBUFS;
777 			}
778 
779 			axf->Init((*swd)->sw_ictx);
780 			(*swd)->sw_axf = axf;
781 			break;
782 #endif
783 		case CRYPTO_DEFLATE_COMP:
784 			cxf = &comp_algo_deflate;
785 			(*swd)->sw_cxf = cxf;
786 			break;
787 		default:
788 			swcr_freesession(NULL, i);
789 			return EINVAL;
790 		}
791 
792 		(*swd)->sw_alg = cri->cri_alg;
793 		cri = cri->cri_next;
794 		swd = &((*swd)->sw_next);
795 	}
796 	return 0;
797 }
798 
799 /*
800  * Free a session.
801  */
802 static int
803 swcr_freesession(void *arg, u_int64_t tid)
804 {
805 	struct swcr_data *swd;
806 	struct enc_xform *txf;
807 	struct auth_hash *axf;
808 	struct comp_algo *cxf;
809 	u_int32_t sid = CRYPTO_SESID2LID(tid);
810 
811 	if (sid > swcr_sesnum || swcr_sessions == NULL ||
812 	    swcr_sessions[sid] == NULL)
813 		return EINVAL;
814 
815 	/* Silently accept and return */
816 	if (sid == 0)
817 		return 0;
818 
819 	while ((swd = swcr_sessions[sid]) != NULL) {
820 		swcr_sessions[sid] = swd->sw_next;
821 
822 		switch (swd->sw_alg) {
823 		case CRYPTO_DES_CBC:
824 		case CRYPTO_3DES_CBC:
825 		case CRYPTO_BLF_CBC:
826 		case CRYPTO_CAST_CBC:
827 		case CRYPTO_SKIPJACK_CBC:
828 		case CRYPTO_RIJNDAEL128_CBC:
829 		case CRYPTO_NULL_CBC:
830 			txf = swd->sw_exf;
831 
832 			if (swd->sw_kschedule)
833 				txf->zerokey(&(swd->sw_kschedule));
834 			break;
835 
836 		case CRYPTO_MD5_HMAC:
837 		case CRYPTO_SHA1_HMAC:
838 		case CRYPTO_SHA2_HMAC:
839 		case CRYPTO_RIPEMD160_HMAC:
840 		case CRYPTO_NULL_HMAC:
841 			axf = swd->sw_axf;
842 
843 			if (swd->sw_ictx) {
844 				bzero(swd->sw_ictx, axf->ctxsize);
845 				free(swd->sw_ictx, M_CRYPTO_DATA);
846 			}
847 			if (swd->sw_octx) {
848 				bzero(swd->sw_octx, axf->ctxsize);
849 				free(swd->sw_octx, M_CRYPTO_DATA);
850 			}
851 			break;
852 
853 		case CRYPTO_MD5_KPDK:
854 		case CRYPTO_SHA1_KPDK:
855 			axf = swd->sw_axf;
856 
857 			if (swd->sw_ictx) {
858 				bzero(swd->sw_ictx, axf->ctxsize);
859 				free(swd->sw_ictx, M_CRYPTO_DATA);
860 			}
861 			if (swd->sw_octx) {
862 				bzero(swd->sw_octx, swd->sw_klen);
863 				free(swd->sw_octx, M_CRYPTO_DATA);
864 			}
865 			break;
866 
867 		case CRYPTO_MD5:
868 		case CRYPTO_SHA1:
869 			axf = swd->sw_axf;
870 
871 			if (swd->sw_ictx)
872 				free(swd->sw_ictx, M_CRYPTO_DATA);
873 			break;
874 
875 		case CRYPTO_DEFLATE_COMP:
876 			cxf = swd->sw_cxf;
877 			break;
878 		}
879 
880 		FREE(swd, M_CRYPTO_DATA);
881 	}
882 	return 0;
883 }
884 
885 /*
886  * Process a software request.
887  */
888 static int
889 swcr_process(void *arg, struct cryptop *crp, int hint)
890 {
891 	struct cryptodesc *crd;
892 	struct swcr_data *sw;
893 	u_int32_t lid;
894 	int type;
895 
896 	/* Sanity check */
897 	if (crp == NULL)
898 		return EINVAL;
899 
900 	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
901 		crp->crp_etype = EINVAL;
902 		goto done;
903 	}
904 
905 	lid = crp->crp_sid & 0xffffffff;
906 	if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
907 		crp->crp_etype = ENOENT;
908 		goto done;
909 	}
910 
911 	if (crp->crp_flags & CRYPTO_F_IMBUF) {
912 		type = CRYPTO_BUF_MBUF;
913 	} else if (crp->crp_flags & CRYPTO_F_IOV) {
914 		type = CRYPTO_BUF_IOV;
915 	} else {
916 		type = CRYPTO_BUF_CONTIG;
917 	}
918 
919 	/* Go through crypto descriptors, processing as we go */
920 	for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
921 		/*
922 		 * Find the crypto context.
923 		 *
924 		 * XXX Note that the logic here prevents us from having
925 		 * XXX the same algorithm multiple times in a session
926 		 * XXX (or rather, we can but it won't give us the right
927 		 * XXX results). To do that, we'd need some way of differentiating
928 		 * XXX between the various instances of an algorithm (so we can
929 		 * XXX locate the correct crypto context).
930 		 */
931 		for (sw = swcr_sessions[lid];
932 		    sw && sw->sw_alg != crd->crd_alg;
933 		    sw = sw->sw_next)
934 			;
935 
936 		/* No such context ? */
937 		if (sw == NULL) {
938 			crp->crp_etype = EINVAL;
939 			goto done;
940 		}
941 		switch (sw->sw_alg) {
942 		case CRYPTO_DES_CBC:
943 		case CRYPTO_3DES_CBC:
944 		case CRYPTO_BLF_CBC:
945 		case CRYPTO_CAST_CBC:
946 		case CRYPTO_SKIPJACK_CBC:
947 		case CRYPTO_RIJNDAEL128_CBC:
948 			if ((crp->crp_etype = swcr_encdec(crd, sw,
949 			    crp->crp_buf, type)) != 0)
950 				goto done;
951 			break;
952 		case CRYPTO_NULL_CBC:
953 			crp->crp_etype = 0;
954 			break;
955 		case CRYPTO_MD5_HMAC:
956 		case CRYPTO_SHA1_HMAC:
957 		case CRYPTO_SHA2_HMAC:
958 		case CRYPTO_RIPEMD160_HMAC:
959 		case CRYPTO_NULL_HMAC:
960 		case CRYPTO_MD5_KPDK:
961 		case CRYPTO_SHA1_KPDK:
962 		case CRYPTO_MD5:
963 		case CRYPTO_SHA1:
964 			if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
965 			    crp->crp_buf, type)) != 0)
966 				goto done;
967 			break;
968 
969 		case CRYPTO_DEFLATE_COMP:
970 			if ((crp->crp_etype = swcr_compdec(crd, sw,
971 			    crp->crp_buf, type)) != 0)
972 				goto done;
973 			else
974 				crp->crp_olen = (int)sw->sw_size;
975 			break;
976 
977 		default:
978 			/* Unknown/unsupported algorithm */
979 			crp->crp_etype = EINVAL;
980 			goto done;
981 		}
982 	}
983 
984 done:
985 	crypto_done(crp);
986 	return 0;
987 }
988 
989 /*
990  * Initialize the driver, called from the kernel main().
991  */
992 static void
993 swcr_init(void)
994 {
995 	swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
996 	if (swcr_id < 0)
997 		panic("Software crypto device cannot initialize!");
998 	crypto_register(swcr_id, CRYPTO_DES_CBC,
999 	    0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL);
1000 #define	REGISTER(alg) \
1001 	crypto_register(swcr_id, alg, 0,0,NULL,NULL,NULL,NULL)
1002 	REGISTER(CRYPTO_3DES_CBC);
1003 	REGISTER(CRYPTO_BLF_CBC);
1004 	REGISTER(CRYPTO_CAST_CBC);
1005 	REGISTER(CRYPTO_SKIPJACK_CBC);
1006 	REGISTER(CRYPTO_NULL_CBC);
1007 	REGISTER(CRYPTO_MD5_HMAC);
1008 	REGISTER(CRYPTO_SHA1_HMAC);
1009 	REGISTER(CRYPTO_SHA2_HMAC);
1010 	REGISTER(CRYPTO_RIPEMD160_HMAC);
1011 	REGISTER(CRYPTO_NULL_HMAC);
1012 	REGISTER(CRYPTO_MD5_KPDK);
1013 	REGISTER(CRYPTO_SHA1_KPDK);
1014 	REGISTER(CRYPTO_MD5);
1015 	REGISTER(CRYPTO_SHA1);
1016 	REGISTER(CRYPTO_RIJNDAEL128_CBC);
1017 	REGISTER(CRYPTO_DEFLATE_COMP);
1018 #undef REGISTER
1019 }
1020 SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
1021