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