Home | History | Annotate | Line # | Download | only in opencrypto
cryptosoft.c revision 1.6
      1 /*	$NetBSD: cryptosoft.c,v 1.6 2003/08/25 04:09:57 thorpej Exp $ */
      2 /*	$FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $	*/
      3 /*	$OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $	*/
      4 
      5 /*
      6  * The author of this code is Angelos D. Keromytis (angelos (at) cis.upenn.edu)
      7  *
      8  * This code was written by Angelos D. Keromytis in Athens, Greece, in
      9  * February 2000. Network Security Technologies Inc. (NSTI) kindly
     10  * supported the development of this code.
     11  *
     12  * Copyright (c) 2000, 2001 Angelos D. Keromytis
     13  *
     14  * Permission to use, copy, and modify this software with or without fee
     15  * is hereby granted, provided that this entire notice is included in
     16  * all source code copies of any software which is or includes a copy or
     17  * modification of this software.
     18  *
     19  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
     20  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
     21  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
     22  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
     23  * PURPOSE.
     24  */
     25 
     26 #include <sys/cdefs.h>
     27 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.6 2003/08/25 04:09:57 thorpej Exp $");
     28 
     29 #include <sys/param.h>
     30 #include <sys/systm.h>
     31 #include <sys/malloc.h>
     32 #include <sys/mbuf.h>
     33 #include <sys/sysctl.h>
     34 #include <sys/errno.h>
     35 #include <sys/md5.h>
     36 #include <sys/sha1.h>
     37 
     38 #include <crypto/ripemd160/rmd160.h>
     39 
     40 #include <opencrypto/cast.h>
     41 #include <opencrypto/skipjack.h>
     42 #include <opencrypto/blf.h>
     43 #include <opencrypto/cryptodev.h>
     44 #include <opencrypto/cryptosoft.h>
     45 #include <opencrypto/xform.h>
     46 
     47 u_int8_t hmac_ipad_buffer[64] = {
     48 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
     49 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
     50 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
     51 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
     52 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
     53 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
     54 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
     55 	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
     56 };
     57 
     58 u_int8_t hmac_opad_buffer[64] = {
     59 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
     60 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
     61 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
     62 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
     63 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
     64 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
     65 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
     66 	0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
     67 };
     68 
     69 
     70 struct swcr_data **swcr_sessions = NULL;
     71 u_int32_t swcr_sesnum = 0;
     72 int32_t swcr_id = -1;
     73 
     74 #define COPYBACK(x, a, b, c, d) \
     75 	(x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \
     76 	: cuio_copyback((struct uio *)a,b,c,d)
     77 #define COPYDATA(x, a, b, c, d) \
     78 	(x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \
     79 	: cuio_copydata((struct uio *)a,b,c,d)
     80 
     81 static	int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
     82 static	int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
     83 			     struct swcr_data *sw, caddr_t buf, int outtype);
     84 static	int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
     85 static	int swcr_process(void *, struct cryptop *, int);
     86 static	int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
     87 static	int swcr_freesession(void *, u_int64_t);
     88 
     89 /*
     90  * Apply a symmetric encryption/decryption algorithm.
     91  */
     92 static int
     93 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
     94     int outtype)
     95 {
     96 	unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
     97 	unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
     98 	struct enc_xform *exf;
     99 	int i, k, j, blks;
    100 	int count, ind;
    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 
    314 #ifdef __FreeBSD__
    315 		struct iovec *iov;
    316 		/* Find beginning of data */
    317 		iov = cuio_getptr(uio, crd->crd_skip, &k);
    318 		if (iov == NULL)
    319 			return EINVAL;
    320 
    321 		i = crd->crd_len;
    322 
    323 		while (i > 0) {
    324 			/*
    325 			 * If there's insufficient data at the end of
    326 			 * an iovec, we have to do some copying.
    327 			 */
    328 			if (iov->iov_len < k + blks && iov->iov_len != k) {
    329 				cuio_copydata(uio, k, blks, blk);
    330 
    331 				/* Actual encryption/decryption */
    332 				if (crd->crd_flags & CRD_F_ENCRYPT) {
    333 					/* XOR with previous block */
    334 					for (j = 0; j < blks; j++)
    335 						blk[j] ^= ivp[j];
    336 
    337 					exf->encrypt(sw->sw_kschedule, blk);
    338 
    339 					/*
    340 					 * Keep encrypted block for XOR'ing
    341 					 * with next block
    342 					 */
    343 					bcopy(blk, iv, blks);
    344 					ivp = iv;
    345 				} else {	/* decrypt */
    346 					/*
    347 					 * Keep encrypted block for XOR'ing
    348 					 * with next block
    349 					 */
    350 					if (ivp == iv)
    351 						bcopy(blk, piv, blks);
    352 					else
    353 						bcopy(blk, iv, blks);
    354 
    355 					exf->decrypt(sw->sw_kschedule, blk);
    356 
    357 					/* XOR with previous block */
    358 					for (j = 0; j < blks; j++)
    359 						blk[j] ^= ivp[j];
    360 
    361 					if (ivp == iv)
    362 						bcopy(piv, iv, blks);
    363 					else
    364 						ivp = iv;
    365 				}
    366 
    367 				/* Copy back decrypted block */
    368 				cuio_copyback(uio, k, blks, blk);
    369 
    370 				/* Advance pointer */
    371 				iov = cuio_getptr(uio, k + blks, &k);
    372 				if (iov == NULL)
    373 					return EINVAL;
    374 
    375 				i -= blks;
    376 
    377 				/* Could be done... */
    378 				if (i == 0)
    379 					break;
    380 			}
    381 
    382 			/*
    383 			 * Warning: idat may point to garbage here, but
    384 			 * we only use it in the while() loop, only if
    385 			 * there are indeed enough data.
    386 			 */
    387 			idat = (char *)iov->iov_base + k;
    388 
    389 	   		while (iov->iov_len >= k + blks && i > 0) {
    390 				if (crd->crd_flags & CRD_F_ENCRYPT) {
    391 					/* XOR with previous block/IV */
    392 					for (j = 0; j < blks; j++)
    393 						idat[j] ^= ivp[j];
    394 
    395 					exf->encrypt(sw->sw_kschedule, idat);
    396 					ivp = idat;
    397 				} else {	/* decrypt */
    398 					/*
    399 					 * Keep encrypted block to be used
    400 					 * in next block's processing.
    401 					 */
    402 					if (ivp == iv)
    403 						bcopy(idat, piv, blks);
    404 					else
    405 						bcopy(idat, iv, blks);
    406 
    407 					exf->decrypt(sw->sw_kschedule, idat);
    408 
    409 					/* XOR with previous block/IV */
    410 					for (j = 0; j < blks; j++)
    411 						idat[j] ^= ivp[j];
    412 
    413 					if (ivp == iv)
    414 						bcopy(piv, iv, blks);
    415 					else
    416 						ivp = iv;
    417 				}
    418 
    419 				idat += blks;
    420 				k += blks;
    421 				i -= blks;
    422 			}
    423 		}
    424 
    425 		return 0; /* Done with mbuf encryption/decryption */
    426 #else  /* !freebsd iov */
    427 		/* Find beginning of data */
    428 		count = crd->crd_skip;
    429 		ind = cuio_getptr(uio, count, &k);
    430 		if (ind == -1)
    431 			return EINVAL;
    432 
    433 		i = crd->crd_len;
    434 
    435 		while (i > 0) {
    436 			/*
    437 			 * If there's insufficient data at the end,
    438 			 * we have to do some copying.
    439 			 */
    440 			if (uio->uio_iov[ind].iov_len < k + blks &&
    441 			    uio->uio_iov[ind].iov_len != k) {
    442 				cuio_copydata(uio, k, blks, blk);
    443 
    444 				/* Actual encryption/decryption */
    445 				if (crd->crd_flags & CRD_F_ENCRYPT) {
    446 					/* XOR with previous block */
    447 					for (j = 0; j < blks; j++)
    448 						blk[j] ^= ivp[j];
    449 
    450 					exf->encrypt(sw->sw_kschedule, blk);
    451 
    452 					/*
    453 					 * Keep encrypted block for XOR'ing
    454 					 * with next block
    455 					 */
    456 					bcopy(blk, iv, blks);
    457 					ivp = iv;
    458 				} else {	/* decrypt */
    459 					/*
    460 					 * Keep encrypted block for XOR'ing
    461 					 * with next block
    462 					 */
    463 					if (ivp == iv)
    464 						bcopy(blk, piv, blks);
    465 					else
    466 						bcopy(blk, iv, blks);
    467 
    468 					exf->decrypt(sw->sw_kschedule, blk);
    469 
    470 					/* XOR with previous block */
    471 					for (j = 0; j < blks; j++)
    472 						blk[j] ^= ivp[j];
    473 
    474 					if (ivp == iv)
    475 						bcopy(piv, iv, blks);
    476 					else
    477 						ivp = iv;
    478 				}
    479 
    480 				/* Copy back decrypted block */
    481 				cuio_copyback(uio, k, blks, blk);
    482 
    483 				count += blks;
    484 
    485 				/* Advance pointer */
    486 				ind = cuio_getptr(uio, count, &k);
    487 				if (ind == -1)
    488 					return (EINVAL);
    489 
    490 				i -= blks;
    491 
    492 				/* Could be done... */
    493 				if (i == 0)
    494 					break;
    495 			}
    496 
    497 			/*
    498 			 * Warning: idat may point to garbage here, but
    499 			 * we only use it in the while() loop, only if
    500 			 * there are indeed enough data.
    501 			 */
    502 			idat = ((caddr_t)uio->uio_iov[ind].iov_base) + k;
    503 
    504 			while (uio->uio_iov[ind].iov_len >= k + blks &&
    505 			    i > 0) {
    506 				if (crd->crd_flags & CRD_F_ENCRYPT) {
    507 					/* XOR with previous block/IV */
    508 					for (j = 0; j < blks; j++)
    509 						idat[j] ^= ivp[j];
    510 
    511 					exf->encrypt(sw->sw_kschedule, idat);
    512 					ivp = idat;
    513 				} else {	/* decrypt */
    514 					/*
    515 					 * Keep encrypted block to be used
    516 					 * in next block's processing.
    517 					 */
    518 					if (ivp == iv)
    519 						bcopy(idat, piv, blks);
    520 					else
    521 						bcopy(idat, iv, blks);
    522 
    523 					exf->decrypt(sw->sw_kschedule, idat);
    524 
    525 					/* XOR with previous block/IV */
    526 					for (j = 0; j < blks; j++)
    527 						idat[j] ^= ivp[j];
    528 
    529 					if (ivp == iv)
    530 						bcopy(piv, iv, blks);
    531 					else
    532 						ivp = iv;
    533 				}
    534 
    535 				idat += blks;
    536 				count += blks;
    537 				k += blks;
    538 				i -= blks;
    539 			}
    540 		}
    541 #endif
    542 		return 0; /* Done with mbuf encryption/decryption */
    543 	}
    544 
    545 	/* Unreachable */
    546 	return EINVAL;
    547 }
    548 
    549 /*
    550  * Compute keyed-hash authenticator.
    551  */
    552 static int
    553 swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
    554     struct swcr_data *sw, caddr_t buf, int outtype)
    555 {
    556 	unsigned char aalg[AALG_MAX_RESULT_LEN];
    557 	struct auth_hash *axf;
    558 	union authctx ctx;
    559 	int err;
    560 
    561 	if (sw->sw_ictx == 0)
    562 		return EINVAL;
    563 
    564 	axf = sw->sw_axf;
    565 
    566 	bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
    567 
    568 	switch (outtype) {
    569 	case CRYPTO_BUF_CONTIG:
    570 		axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len);
    571 		break;
    572 	case CRYPTO_BUF_MBUF:
    573 		err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
    574 		    (int (*)(void*, caddr_t, unsigned int)) axf->Update,
    575 		    (caddr_t) &ctx);
    576 		if (err)
    577 			return err;
    578 		break;
    579 	case CRYPTO_BUF_IOV:
    580 #ifdef __FreeBSD__
    581 		/*XXX FIXME: handle iov case*/
    582 		return EINVAL;
    583 #else
    584 		err = cuio_apply((struct uio *) buf, crd->crd_skip,
    585 		    crd->crd_len,
    586 		    (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
    587 		    (caddr_t) &ctx);
    588 		if (err) {
    589 			return err;
    590 		}
    591 #endif
    592 		break;
    593 	default:
    594 		return EINVAL;
    595 	}
    596 
    597 	switch (sw->sw_alg) {
    598 	case CRYPTO_MD5_HMAC:
    599 	case CRYPTO_SHA1_HMAC:
    600 	case CRYPTO_SHA2_HMAC:
    601 	case CRYPTO_RIPEMD160_HMAC:
    602 		if (sw->sw_octx == NULL)
    603 			return EINVAL;
    604 
    605 		axf->Final(aalg, &ctx);
    606 		bcopy(sw->sw_octx, &ctx, axf->ctxsize);
    607 		axf->Update(&ctx, aalg, axf->hashsize);
    608 		axf->Final(aalg, &ctx);
    609 		break;
    610 
    611 	case CRYPTO_MD5_KPDK:
    612 	case CRYPTO_SHA1_KPDK:
    613 		if (sw->sw_octx == NULL)
    614 			return EINVAL;
    615 
    616 		axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
    617 		axf->Final(aalg, &ctx);
    618 		break;
    619 
    620 	case CRYPTO_NULL_HMAC:
    621 	case CRYPTO_MD5:
    622 	case CRYPTO_SHA1:
    623 		axf->Final(aalg, &ctx);
    624 		break;
    625 	}
    626 
    627 	/* Inject the authentication data */
    628 	switch (outtype) {
    629 	case CRYPTO_BUF_CONTIG:
    630 		bcopy(aalg, buf + crd->crd_inject, axf->authsize);
    631 		break;
    632 	case CRYPTO_BUF_MBUF:
    633 		m_copyback((struct mbuf *) buf, crd->crd_inject,
    634 		    axf->authsize, aalg);
    635 		break;
    636 	case CRYPTO_BUF_IOV:
    637 		bcopy(aalg, crp->crp_mac, axf->authsize);
    638 		break;
    639 	default:
    640 		return EINVAL;
    641 	}
    642 	return 0;
    643 }
    644 
    645 /*
    646  * Apply a compression/decompression algorithm
    647  */
    648 static int
    649 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
    650     caddr_t buf, int outtype)
    651 {
    652 	u_int8_t *data, *out;
    653 	struct comp_algo *cxf;
    654 	int adj;
    655 	u_int32_t result;
    656 
    657 	cxf = sw->sw_cxf;
    658 
    659 	/* We must handle the whole buffer of data in one time
    660 	 * then if there is not all the data in the mbuf, we must
    661 	 * copy in a buffer.
    662 	 */
    663 
    664 	MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA,  M_NOWAIT);
    665 	if (data == NULL)
    666 		return (EINVAL);
    667 	COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
    668 
    669 	if (crd->crd_flags & CRD_F_COMP)
    670 		result = cxf->compress(data, crd->crd_len, &out);
    671 	else
    672 		result = cxf->decompress(data, crd->crd_len, &out);
    673 
    674 	FREE(data, M_CRYPTO_DATA);
    675 	if (result == 0)
    676 		return EINVAL;
    677 
    678 	/* Copy back the (de)compressed data. m_copyback is
    679 	 * extending the mbuf as necessary.
    680 	 */
    681 	sw->sw_size = result;
    682 	/* Check the compressed size when doing compression */
    683 	if (crd->crd_flags & CRD_F_COMP) {
    684 		if (result > crd->crd_len) {
    685 			/* Compression was useless, we lost time */
    686 			FREE(out, M_CRYPTO_DATA);
    687 			return 0;
    688 		}
    689 	}
    690 
    691 	COPYBACK(outtype, buf, crd->crd_skip, result, out);
    692 	if (result < crd->crd_len) {
    693 		adj = result - crd->crd_len;
    694 		if (outtype == CRYPTO_BUF_MBUF) {
    695 			adj = result - crd->crd_len;
    696 			m_adj((struct mbuf *)buf, adj);
    697 		} else {
    698 			struct uio *uio = (struct uio *)buf;
    699 			int ind;
    700 
    701 			adj = crd->crd_len - result;
    702 			ind = uio->uio_iovcnt - 1;
    703 
    704 			while (adj > 0 && ind >= 0) {
    705 				if (adj < uio->uio_iov[ind].iov_len) {
    706 					uio->uio_iov[ind].iov_len -= adj;
    707 					break;
    708 				}
    709 
    710 				adj -= uio->uio_iov[ind].iov_len;
    711 				uio->uio_iov[ind].iov_len = 0;
    712 				ind--;
    713 				uio->uio_iovcnt--;
    714 			}
    715 		}
    716 	}
    717 	FREE(out, M_CRYPTO_DATA);
    718 	return 0;
    719 }
    720 
    721 /*
    722  * Generate a new software session.
    723  */
    724 static int
    725 swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
    726 {
    727 	struct swcr_data **swd;
    728 	struct auth_hash *axf;
    729 	struct enc_xform *txf;
    730 	struct comp_algo *cxf;
    731 	u_int32_t i;
    732 	int k, error;
    733 
    734 	if (sid == NULL || cri == NULL)
    735 		return EINVAL;
    736 
    737 	if (swcr_sessions) {
    738 		for (i = 1; i < swcr_sesnum; i++)
    739 			if (swcr_sessions[i] == NULL)
    740 				break;
    741 	} else
    742 		i = 1;		/* NB: to silence compiler warning */
    743 
    744 	if (swcr_sessions == NULL || i == swcr_sesnum) {
    745 		if (swcr_sessions == NULL) {
    746 			i = 1; /* We leave swcr_sessions[0] empty */
    747 			swcr_sesnum = CRYPTO_SW_SESSIONS;
    748 		} else
    749 			swcr_sesnum *= 2;
    750 
    751 		swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
    752 		    M_CRYPTO_DATA, M_NOWAIT);
    753 		if (swd == NULL) {
    754 			/* Reset session number */
    755 			if (swcr_sesnum == CRYPTO_SW_SESSIONS)
    756 				swcr_sesnum = 0;
    757 			else
    758 				swcr_sesnum /= 2;
    759 			return ENOBUFS;
    760 		}
    761 
    762 		bzero(swd, swcr_sesnum * sizeof(struct swcr_data *));
    763 
    764 		/* Copy existing sessions */
    765 		if (swcr_sessions) {
    766 			bcopy(swcr_sessions, swd,
    767 			    (swcr_sesnum / 2) * sizeof(struct swcr_data *));
    768 			free(swcr_sessions, M_CRYPTO_DATA);
    769 		}
    770 
    771 		swcr_sessions = swd;
    772 	}
    773 
    774 	swd = &swcr_sessions[i];
    775 	*sid = i;
    776 
    777 	while (cri) {
    778 		MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
    779 		    M_CRYPTO_DATA, M_NOWAIT);
    780 		if (*swd == NULL) {
    781 			swcr_freesession(NULL, i);
    782 			return ENOBUFS;
    783 		}
    784 		bzero(*swd, sizeof(struct swcr_data));
    785 
    786 		switch (cri->cri_alg) {
    787 		case CRYPTO_DES_CBC:
    788 			txf = &enc_xform_des;
    789 			goto enccommon;
    790 		case CRYPTO_3DES_CBC:
    791 			txf = &enc_xform_3des;
    792 			goto enccommon;
    793 		case CRYPTO_BLF_CBC:
    794 			txf = &enc_xform_blf;
    795 			goto enccommon;
    796 		case CRYPTO_CAST_CBC:
    797 			txf = &enc_xform_cast5;
    798 			goto enccommon;
    799 		case CRYPTO_SKIPJACK_CBC:
    800 			txf = &enc_xform_skipjack;
    801 			goto enccommon;
    802 		case CRYPTO_RIJNDAEL128_CBC:
    803 			txf = &enc_xform_rijndael128;
    804 			goto enccommon;
    805 		case CRYPTO_NULL_CBC:
    806 			txf = &enc_xform_null;
    807 			goto enccommon;
    808 		enccommon:
    809 			error = txf->setkey(&((*swd)->sw_kschedule),
    810 					cri->cri_key, cri->cri_klen / 8);
    811 			if (error) {
    812 				swcr_freesession(NULL, i);
    813 				return error;
    814 			}
    815 			(*swd)->sw_exf = txf;
    816 			break;
    817 
    818 		case CRYPTO_MD5_HMAC:
    819 			axf = &auth_hash_hmac_md5_96;
    820 			goto authcommon;
    821 		case CRYPTO_SHA1_HMAC:
    822 			axf = &auth_hash_hmac_sha1_96;
    823 			goto authcommon;
    824 		case CRYPTO_SHA2_HMAC:
    825 			if (cri->cri_klen == 256)
    826 				axf = &auth_hash_hmac_sha2_256;
    827 			else if (cri->cri_klen == 384)
    828 				axf = &auth_hash_hmac_sha2_384;
    829 			else if (cri->cri_klen == 512)
    830 				axf = &auth_hash_hmac_sha2_512;
    831 			else {
    832 				swcr_freesession(NULL, i);
    833 				return EINVAL;
    834 			}
    835 			goto authcommon;
    836 		case CRYPTO_NULL_HMAC:
    837 			axf = &auth_hash_null;
    838 			goto authcommon;
    839 		case CRYPTO_RIPEMD160_HMAC:
    840 			axf = &auth_hash_hmac_ripemd_160_96;
    841 		authcommon:
    842 			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
    843 			    M_NOWAIT);
    844 			if ((*swd)->sw_ictx == NULL) {
    845 				swcr_freesession(NULL, i);
    846 				return ENOBUFS;
    847 			}
    848 
    849 			(*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
    850 			    M_NOWAIT);
    851 			if ((*swd)->sw_octx == NULL) {
    852 				swcr_freesession(NULL, i);
    853 				return ENOBUFS;
    854 			}
    855 
    856 			for (k = 0; k < cri->cri_klen / 8; k++)
    857 				cri->cri_key[k] ^= HMAC_IPAD_VAL;
    858 
    859 			axf->Init((*swd)->sw_ictx);
    860 			axf->Update((*swd)->sw_ictx, cri->cri_key,
    861 			    cri->cri_klen / 8);
    862 			axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
    863 			    HMAC_BLOCK_LEN - (cri->cri_klen / 8));
    864 
    865 			for (k = 0; k < cri->cri_klen / 8; k++)
    866 				cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
    867 
    868 			axf->Init((*swd)->sw_octx);
    869 			axf->Update((*swd)->sw_octx, cri->cri_key,
    870 			    cri->cri_klen / 8);
    871 			axf->Update((*swd)->sw_octx, hmac_opad_buffer,
    872 			    HMAC_BLOCK_LEN - (cri->cri_klen / 8));
    873 
    874 			for (k = 0; k < cri->cri_klen / 8; k++)
    875 				cri->cri_key[k] ^= HMAC_OPAD_VAL;
    876 			(*swd)->sw_axf = axf;
    877 			break;
    878 
    879 		case CRYPTO_MD5_KPDK:
    880 			axf = &auth_hash_key_md5;
    881 			goto auth2common;
    882 
    883 		case CRYPTO_SHA1_KPDK:
    884 			axf = &auth_hash_key_sha1;
    885 		auth2common:
    886 			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
    887 			    M_NOWAIT);
    888 			if ((*swd)->sw_ictx == NULL) {
    889 				swcr_freesession(NULL, i);
    890 				return ENOBUFS;
    891 			}
    892 
    893 			/* Store the key so we can "append" it to the payload */
    894 			(*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
    895 			    M_NOWAIT);
    896 			if ((*swd)->sw_octx == NULL) {
    897 				swcr_freesession(NULL, i);
    898 				return ENOBUFS;
    899 			}
    900 
    901 			(*swd)->sw_klen = cri->cri_klen / 8;
    902 			bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
    903 			axf->Init((*swd)->sw_ictx);
    904 			axf->Update((*swd)->sw_ictx, cri->cri_key,
    905 			    cri->cri_klen / 8);
    906 			axf->Final(NULL, (*swd)->sw_ictx);
    907 			(*swd)->sw_axf = axf;
    908 			break;
    909 
    910 		case CRYPTO_MD5:
    911 			axf = &auth_hash_md5;
    912 			goto auth3common;
    913 
    914 		case CRYPTO_SHA1:
    915 			axf = &auth_hash_sha1;
    916 		auth3common:
    917 			(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
    918 			    M_NOWAIT);
    919 			if ((*swd)->sw_ictx == NULL) {
    920 				swcr_freesession(NULL, i);
    921 				return ENOBUFS;
    922 			}
    923 
    924 			axf->Init((*swd)->sw_ictx);
    925 			(*swd)->sw_axf = axf;
    926 			break;
    927 
    928 		case CRYPTO_DEFLATE_COMP:
    929 			cxf = &comp_algo_deflate;
    930 			(*swd)->sw_cxf = cxf;
    931 			break;
    932 		default:
    933 			swcr_freesession(NULL, i);
    934 			return EINVAL;
    935 		}
    936 
    937 		(*swd)->sw_alg = cri->cri_alg;
    938 		cri = cri->cri_next;
    939 		swd = &((*swd)->sw_next);
    940 	}
    941 	return 0;
    942 }
    943 
    944 /*
    945  * Free a session.
    946  */
    947 static int
    948 swcr_freesession(void *arg, u_int64_t tid)
    949 {
    950 	struct swcr_data *swd;
    951 	struct enc_xform *txf;
    952 	struct auth_hash *axf;
    953 	struct comp_algo *cxf;
    954 	u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
    955 
    956 	if (sid > swcr_sesnum || swcr_sessions == NULL ||
    957 	    swcr_sessions[sid] == NULL)
    958 		return EINVAL;
    959 
    960 	/* Silently accept and return */
    961 	if (sid == 0)
    962 		return 0;
    963 
    964 	while ((swd = swcr_sessions[sid]) != NULL) {
    965 		swcr_sessions[sid] = swd->sw_next;
    966 
    967 		switch (swd->sw_alg) {
    968 		case CRYPTO_DES_CBC:
    969 		case CRYPTO_3DES_CBC:
    970 		case CRYPTO_BLF_CBC:
    971 		case CRYPTO_CAST_CBC:
    972 		case CRYPTO_SKIPJACK_CBC:
    973 		case CRYPTO_RIJNDAEL128_CBC:
    974 		case CRYPTO_NULL_CBC:
    975 			txf = swd->sw_exf;
    976 
    977 			if (swd->sw_kschedule)
    978 				txf->zerokey(&(swd->sw_kschedule));
    979 			break;
    980 
    981 		case CRYPTO_MD5_HMAC:
    982 		case CRYPTO_SHA1_HMAC:
    983 		case CRYPTO_SHA2_HMAC:
    984 		case CRYPTO_RIPEMD160_HMAC:
    985 		case CRYPTO_NULL_HMAC:
    986 			axf = swd->sw_axf;
    987 
    988 			if (swd->sw_ictx) {
    989 				bzero(swd->sw_ictx, axf->ctxsize);
    990 				free(swd->sw_ictx, M_CRYPTO_DATA);
    991 			}
    992 			if (swd->sw_octx) {
    993 				bzero(swd->sw_octx, axf->ctxsize);
    994 				free(swd->sw_octx, M_CRYPTO_DATA);
    995 			}
    996 			break;
    997 
    998 		case CRYPTO_MD5_KPDK:
    999 		case CRYPTO_SHA1_KPDK:
   1000 			axf = swd->sw_axf;
   1001 
   1002 			if (swd->sw_ictx) {
   1003 				bzero(swd->sw_ictx, axf->ctxsize);
   1004 				free(swd->sw_ictx, M_CRYPTO_DATA);
   1005 			}
   1006 			if (swd->sw_octx) {
   1007 				bzero(swd->sw_octx, swd->sw_klen);
   1008 				free(swd->sw_octx, M_CRYPTO_DATA);
   1009 			}
   1010 			break;
   1011 
   1012 		case CRYPTO_MD5:
   1013 		case CRYPTO_SHA1:
   1014 			axf = swd->sw_axf;
   1015 
   1016 			if (swd->sw_ictx)
   1017 				free(swd->sw_ictx, M_CRYPTO_DATA);
   1018 			break;
   1019 
   1020 		case CRYPTO_DEFLATE_COMP:
   1021 			cxf = swd->sw_cxf;
   1022 			break;
   1023 		}
   1024 
   1025 		FREE(swd, M_CRYPTO_DATA);
   1026 	}
   1027 	return 0;
   1028 }
   1029 
   1030 /*
   1031  * Process a software request.
   1032  */
   1033 static int
   1034 swcr_process(void *arg, struct cryptop *crp, int hint)
   1035 {
   1036 	struct cryptodesc *crd;
   1037 	struct swcr_data *sw;
   1038 	u_int32_t lid;
   1039 	int type;
   1040 
   1041 	/* Sanity check */
   1042 	if (crp == NULL)
   1043 		return EINVAL;
   1044 
   1045 	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
   1046 		crp->crp_etype = EINVAL;
   1047 		goto done;
   1048 	}
   1049 
   1050 	lid = crp->crp_sid & 0xffffffff;
   1051 	if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
   1052 		crp->crp_etype = ENOENT;
   1053 		goto done;
   1054 	}
   1055 
   1056 	if (crp->crp_flags & CRYPTO_F_IMBUF) {
   1057 		type = CRYPTO_BUF_MBUF;
   1058 	} else if (crp->crp_flags & CRYPTO_F_IOV) {
   1059 		type = CRYPTO_BUF_IOV;
   1060 	} else {
   1061 		type = CRYPTO_BUF_CONTIG;
   1062 	}
   1063 
   1064 	/* Go through crypto descriptors, processing as we go */
   1065 	for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
   1066 		/*
   1067 		 * Find the crypto context.
   1068 		 *
   1069 		 * XXX Note that the logic here prevents us from having
   1070 		 * XXX the same algorithm multiple times in a session
   1071 		 * XXX (or rather, we can but it won't give us the right
   1072 		 * XXX results). To do that, we'd need some way of differentiating
   1073 		 * XXX between the various instances of an algorithm (so we can
   1074 		 * XXX locate the correct crypto context).
   1075 		 */
   1076 		for (sw = swcr_sessions[lid];
   1077 		    sw && sw->sw_alg != crd->crd_alg;
   1078 		    sw = sw->sw_next)
   1079 			;
   1080 
   1081 		/* No such context ? */
   1082 		if (sw == NULL) {
   1083 			crp->crp_etype = EINVAL;
   1084 			goto done;
   1085 		}
   1086 
   1087 		switch (sw->sw_alg) {
   1088 		case CRYPTO_DES_CBC:
   1089 		case CRYPTO_3DES_CBC:
   1090 		case CRYPTO_BLF_CBC:
   1091 		case CRYPTO_CAST_CBC:
   1092 		case CRYPTO_SKIPJACK_CBC:
   1093 		case CRYPTO_RIJNDAEL128_CBC:
   1094 			if ((crp->crp_etype = swcr_encdec(crd, sw,
   1095 			    crp->crp_buf, type)) != 0)
   1096 				goto done;
   1097 			break;
   1098 		case CRYPTO_NULL_CBC:
   1099 			crp->crp_etype = 0;
   1100 			break;
   1101 		case CRYPTO_MD5_HMAC:
   1102 		case CRYPTO_SHA1_HMAC:
   1103 		case CRYPTO_SHA2_HMAC:
   1104 		case CRYPTO_RIPEMD160_HMAC:
   1105 		case CRYPTO_NULL_HMAC:
   1106 		case CRYPTO_MD5_KPDK:
   1107 		case CRYPTO_SHA1_KPDK:
   1108 		case CRYPTO_MD5:
   1109 		case CRYPTO_SHA1:
   1110 			if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
   1111 			    crp->crp_buf, type)) != 0)
   1112 				goto done;
   1113 			break;
   1114 
   1115 		case CRYPTO_DEFLATE_COMP:
   1116 			if ((crp->crp_etype = swcr_compdec(crd, sw,
   1117 			    crp->crp_buf, type)) != 0)
   1118 				goto done;
   1119 			else
   1120 				crp->crp_olen = (int)sw->sw_size;
   1121 			break;
   1122 
   1123 		default:
   1124 			/* Unknown/unsupported algorithm */
   1125 			crp->crp_etype = EINVAL;
   1126 			goto done;
   1127 		}
   1128 	}
   1129 
   1130 done:
   1131 	crypto_done(crp);
   1132 	return 0;
   1133 }
   1134 
   1135 /*
   1136  * Initialize the driver, called from the kernel main().
   1137  */
   1138 /*static*/
   1139 void
   1140 swcr_init(void)
   1141 {
   1142 	swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE);
   1143 	if (swcr_id < 0) {
   1144 		/* This should never happen */
   1145 		panic("Software crypto device cannot initialize!");
   1146 	}
   1147 
   1148 	crypto_register(swcr_id, CRYPTO_DES_CBC,
   1149 	    0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL);
   1150 #define	REGISTER(alg) \
   1151 	crypto_register(swcr_id, alg, 0, 0, NULL, NULL, NULL, NULL)
   1152 
   1153 	REGISTER(CRYPTO_3DES_CBC);
   1154 	REGISTER(CRYPTO_BLF_CBC);
   1155 	REGISTER(CRYPTO_CAST_CBC);
   1156 	REGISTER(CRYPTO_SKIPJACK_CBC);
   1157 	REGISTER(CRYPTO_NULL_CBC);
   1158 	REGISTER(CRYPTO_MD5_HMAC);
   1159 	REGISTER(CRYPTO_SHA1_HMAC);
   1160 	REGISTER(CRYPTO_SHA2_HMAC);
   1161 	REGISTER(CRYPTO_RIPEMD160_HMAC);
   1162 	REGISTER(CRYPTO_NULL_HMAC);
   1163 	REGISTER(CRYPTO_MD5_KPDK);
   1164 	REGISTER(CRYPTO_SHA1_KPDK);
   1165 	REGISTER(CRYPTO_MD5);
   1166 	REGISTER(CRYPTO_SHA1);
   1167 	REGISTER(CRYPTO_RIJNDAEL128_CBC);
   1168 	REGISTER(CRYPTO_DEFLATE_COMP);
   1169 #undef REGISTER
   1170 }
   1171 
   1172 #ifdef __FreeBSD__
   1173 SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
   1174 #endif
   1175