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