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