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