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