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