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