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