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