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