Home | History | Annotate | Line # | Download | only in opencrypto
crypto.c revision 1.20.10.1
      1  1.20.10.1      yamt /*	$NetBSD: crypto.c,v 1.20.10.1 2007/10/14 11:49:04 yamt Exp $ */
      2        1.1  jonathan /*	$FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.5 2003/02/26 00:14:05 sam Exp $	*/
      3        1.1  jonathan /*	$OpenBSD: crypto.c,v 1.41 2002/07/17 23:52:38 art 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.20.10.1      yamt __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.20.10.1 2007/10/14 11:49:04 yamt Exp $");
     28        1.1  jonathan 
     29        1.1  jonathan /* XXX FIXME: should be defopt'ed */
     30        1.1  jonathan #define CRYPTO_TIMING			/* enable cryptop timing stuff */
     31        1.1  jonathan 
     32        1.1  jonathan #include <sys/param.h>
     33        1.1  jonathan #include <sys/reboot.h>
     34        1.1  jonathan #include <sys/systm.h>
     35        1.1  jonathan #include <sys/malloc.h>
     36        1.1  jonathan #include <sys/proc.h>
     37        1.1  jonathan #include <sys/pool.h>
     38        1.1  jonathan #include <sys/kthread.h>
     39       1.11   thorpej #include <sys/once.h>
     40       1.13  christos #include <sys/sysctl.h>
     41  1.20.10.1      yamt #include <sys/intr.h>
     42        1.1  jonathan 
     43  1.20.10.1      yamt #include <opencrypto/cryptodev.h>
     44        1.1  jonathan #include <opencrypto/xform.h>			/* XXX for M_XDATA */
     45        1.1  jonathan 
     46        1.1  jonathan #ifdef __NetBSD__
     47        1.1  jonathan   #define splcrypto splnet
     48        1.1  jonathan   /* below is kludges to check whats still missing */
     49        1.1  jonathan   #define SWI_CRYPTO 17
     50        1.1  jonathan   #define register_swi(lvl, fn)  \
     51  1.20.10.1      yamt   softint_establish(SOFTINT_NET, (void (*)(void*))fn, NULL)
     52  1.20.10.1      yamt   #define unregister_swi(lvl, fn)  softint_disestablish(softintr_cookie)
     53  1.20.10.1      yamt   #define setsoftcrypto(x) softint_schedule(x)
     54        1.1  jonathan #endif
     55        1.1  jonathan 
     56        1.1  jonathan #define	SESID2HID(sid)	(((sid) >> 32) & 0xffffffff)
     57        1.1  jonathan 
     58        1.1  jonathan /*
     59        1.1  jonathan  * Crypto drivers register themselves by allocating a slot in the
     60        1.1  jonathan  * crypto_drivers table with crypto_get_driverid() and then registering
     61        1.1  jonathan  * each algorithm they support with crypto_register() and crypto_kregister().
     62        1.1  jonathan  */
     63       1.11   thorpej static	struct cryptocap *crypto_drivers;
     64       1.11   thorpej static	int crypto_drivers_num;
     65        1.1  jonathan static	void* softintr_cookie;
     66        1.1  jonathan 
     67        1.1  jonathan /*
     68        1.1  jonathan  * There are two queues for crypto requests; one for symmetric (e.g.
     69        1.1  jonathan  * cipher) operations and one for asymmetric (e.g. MOD) operations.
     70        1.1  jonathan  * See below for how synchronization is handled.
     71        1.1  jonathan  */
     72       1.11   thorpej static	TAILQ_HEAD(,cryptop) crp_q =		/* request queues */
     73       1.11   thorpej 		TAILQ_HEAD_INITIALIZER(crp_q);
     74       1.11   thorpej static	TAILQ_HEAD(,cryptkop) crp_kq =
     75       1.11   thorpej 		TAILQ_HEAD_INITIALIZER(crp_kq);
     76        1.1  jonathan 
     77        1.1  jonathan /*
     78        1.1  jonathan  * There are two queues for processing completed crypto requests; one
     79        1.1  jonathan  * for the symmetric and one for the asymmetric ops.  We only need one
     80        1.1  jonathan  * but have two to avoid type futzing (cryptop vs. cryptkop).  See below
     81        1.1  jonathan  * for how synchronization is handled.
     82        1.1  jonathan  */
     83       1.11   thorpej static	TAILQ_HEAD(,cryptop) crp_ret_q =	/* callback queues */
     84       1.11   thorpej 		TAILQ_HEAD_INITIALIZER(crp_ret_q);
     85       1.11   thorpej static	TAILQ_HEAD(,cryptkop) crp_ret_kq =
     86       1.11   thorpej 		TAILQ_HEAD_INITIALIZER(crp_ret_kq);
     87        1.1  jonathan 
     88        1.1  jonathan /*
     89        1.1  jonathan  * Crypto op and desciptor data structures are allocated
     90        1.1  jonathan  * from separate private zones(FreeBSD)/pools(netBSD/OpenBSD) .
     91        1.1  jonathan  */
     92        1.1  jonathan struct pool cryptop_pool;
     93        1.1  jonathan struct pool cryptodesc_pool;
     94        1.1  jonathan int crypto_pool_initialized = 0;
     95        1.1  jonathan 
     96        1.1  jonathan int	crypto_usercrypto = 1;		/* userland may open /dev/crypto */
     97        1.1  jonathan int	crypto_userasymcrypto = 1;	/* userland may do asym crypto reqs */
     98       1.10     perry /*
     99        1.6  jonathan  * cryptodevallowsoft is (intended to be) sysctl'able, controlling
    100        1.6  jonathan  * access to hardware versus software transforms as below:
    101        1.6  jonathan  *
    102        1.6  jonathan  * crypto_devallowsoft < 0:  Force userlevel requests to use software
    103        1.6  jonathan  *                              transforms, always
    104        1.6  jonathan  * crypto_devallowsoft = 0:  Use hardware if present, grant userlevel
    105        1.6  jonathan  *                              requests for non-accelerated transforms
    106        1.6  jonathan  *                              (handling the latter in software)
    107        1.6  jonathan  * crypto_devallowsoft > 0:  Allow user requests only for transforms which
    108        1.6  jonathan  *                               are hardware-accelerated.
    109        1.6  jonathan  */
    110        1.9  jonathan int	crypto_devallowsoft = 1;	/* only use hardware crypto */
    111        1.6  jonathan 
    112        1.1  jonathan #ifdef __FreeBSD__
    113        1.1  jonathan SYSCTL_INT(_kern, OID_AUTO, usercrypto, CTLFLAG_RW,
    114        1.1  jonathan 	   &crypto_usercrypto, 0,
    115        1.1  jonathan 	   "Enable/disable user-mode access to crypto support");
    116        1.1  jonathan SYSCTL_INT(_kern, OID_AUTO, userasymcrypto, CTLFLAG_RW,
    117        1.1  jonathan 	   &crypto_userasymcrypto, 0,
    118        1.1  jonathan 	   "Enable/disable user-mode access to asymmetric crypto support");
    119        1.1  jonathan SYSCTL_INT(_kern, OID_AUTO, cryptodevallowsoft, CTLFLAG_RW,
    120        1.1  jonathan 	   &crypto_devallowsoft, 0,
    121        1.1  jonathan 	   "Enable/disable use of software asym crypto support");
    122        1.1  jonathan #endif
    123       1.13  christos #ifdef __NetBSD__
    124       1.13  christos SYSCTL_SETUP(sysctl_opencrypto_setup, "sysctl opencrypto subtree setup")
    125       1.13  christos {
    126       1.13  christos 	sysctl_createv(clog, 0, NULL, NULL,
    127       1.13  christos 		       CTLFLAG_PERMANENT,
    128       1.13  christos 		       CTLTYPE_NODE, "kern", NULL,
    129       1.13  christos 		       NULL, 0, NULL, 0,
    130       1.13  christos 		       CTL_KERN, CTL_EOL);
    131       1.13  christos 	sysctl_createv(clog, 0, NULL, NULL,
    132       1.13  christos 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
    133       1.13  christos 		       CTLTYPE_INT, "usercrypto",
    134       1.13  christos 		       SYSCTL_DESCR("Enable/disable user-mode access to "
    135       1.13  christos 			   "crypto support"),
    136       1.13  christos 		       NULL, 0, &crypto_usercrypto, 0,
    137       1.13  christos 		       CTL_KERN, CTL_CREATE, CTL_EOL);
    138       1.13  christos 	sysctl_createv(clog, 0, NULL, NULL,
    139       1.13  christos 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
    140       1.13  christos 		       CTLTYPE_INT, "userasymcrypto",
    141       1.13  christos 		       SYSCTL_DESCR("Enable/disable user-mode access to "
    142       1.13  christos 			   "asymmetric crypto support"),
    143       1.13  christos 		       NULL, 0, &crypto_userasymcrypto, 0,
    144       1.13  christos 		       CTL_KERN, CTL_CREATE, CTL_EOL);
    145       1.13  christos 	sysctl_createv(clog, 0, NULL, NULL,
    146       1.13  christos 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
    147       1.13  christos 		       CTLTYPE_INT, "cryptodevallowsoft",
    148       1.13  christos 		       SYSCTL_DESCR("Enable/disable use of software "
    149       1.13  christos 			   "asymmetric crypto support"),
    150       1.13  christos 		       NULL, 0, &crypto_devallowsoft, 0,
    151       1.13  christos 		       CTL_KERN, CTL_CREATE, CTL_EOL);
    152       1.13  christos }
    153       1.13  christos #endif
    154        1.1  jonathan 
    155        1.1  jonathan MALLOC_DEFINE(M_CRYPTO_DATA, "crypto", "crypto session records");
    156        1.1  jonathan 
    157        1.1  jonathan /*
    158        1.1  jonathan  * Synchronization: read carefully, this is non-trivial.
    159        1.1  jonathan  *
    160        1.1  jonathan  * Crypto requests are submitted via crypto_dispatch.  Typically
    161        1.1  jonathan  * these come in from network protocols at spl0 (output path) or
    162        1.1  jonathan  * spl[,soft]net (input path).
    163        1.1  jonathan  *
    164        1.1  jonathan  * Requests are typically passed on the driver directly, but they
    165        1.1  jonathan  * may also be queued for processing by a software interrupt thread,
    166       1.10     perry  * cryptointr, that runs at splsoftcrypto.  This thread dispatches
    167        1.1  jonathan  * the requests to crypto drivers (h/w or s/w) who call crypto_done
    168        1.1  jonathan  * when a request is complete.  Hardware crypto drivers are assumed
    169        1.1  jonathan  * to register their IRQ's as network devices so their interrupt handlers
    170        1.1  jonathan  * and subsequent "done callbacks" happen at spl[imp,net].
    171        1.1  jonathan  *
    172        1.1  jonathan  * Completed crypto ops are queued for a separate kernel thread that
    173        1.1  jonathan  * handles the callbacks at spl0.  This decoupling insures the crypto
    174        1.1  jonathan  * driver interrupt service routine is not delayed while the callback
    175        1.1  jonathan  * takes place and that callbacks are delivered after a context switch
    176        1.1  jonathan  * (as opposed to a software interrupt that clients must block).
    177        1.1  jonathan  *
    178        1.1  jonathan  * This scheme is not intended for SMP machines.
    179       1.10     perry  */
    180        1.1  jonathan static	void cryptointr(void);		/* swi thread to dispatch ops */
    181        1.1  jonathan static	void cryptoret(void);		/* kernel thread for callbacks*/
    182       1.20        ad static	struct lwp *cryptothread;
    183        1.1  jonathan static	void crypto_destroy(void);
    184        1.1  jonathan static	int crypto_invoke(struct cryptop *crp, int hint);
    185        1.1  jonathan static	int crypto_kinvoke(struct cryptkop *krp, int hint);
    186        1.1  jonathan 
    187        1.1  jonathan static struct cryptostats cryptostats;
    188        1.1  jonathan static	int crypto_timing = 0;
    189        1.1  jonathan 
    190        1.1  jonathan #ifdef __FreeBSD__
    191        1.1  jonathan SYSCTL_STRUCT(_kern, OID_AUTO, crypto_stats, CTLFLAG_RW, &cryptostats,
    192        1.1  jonathan 	    cryptostats, "Crypto system statistics");
    193        1.1  jonathan 
    194        1.1  jonathan SYSCTL_INT(_debug, OID_AUTO, crypto_timing, CTLFLAG_RW,
    195        1.1  jonathan 	   &crypto_timing, 0, "Enable/disable crypto timing support");
    196        1.1  jonathan SYSCTL_STRUCT(_kern, OID_AUTO, crypto_stats, CTLFLAG_RW, &cryptostats,
    197        1.1  jonathan 	    cryptostats, "Crypto system statistics");
    198        1.4       lha #endif /* __FreeBSD__ */
    199        1.1  jonathan 
    200       1.12      yamt static int
    201       1.11   thorpej crypto_init0(void)
    202        1.1  jonathan {
    203        1.1  jonathan 	int error;
    204        1.1  jonathan 
    205       1.20        ad #ifdef __FreeBSD__
    206        1.1  jonathan 	cryptop_zone = zinit("cryptop", sizeof (struct cryptop), 0, 0, 1);
    207        1.1  jonathan 	cryptodesc_zone = zinit("cryptodesc", sizeof (struct cryptodesc),
    208        1.1  jonathan 				0, 0, 1);
    209        1.1  jonathan 	if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
    210        1.1  jonathan 		printf("crypto_init: cannot setup crypto zones\n");
    211       1.11   thorpej 		return;
    212        1.1  jonathan 	}
    213        1.1  jonathan #endif
    214        1.1  jonathan 
    215       1.11   thorpej 	crypto_drivers = malloc(CRYPTO_DRIVERS_INITIAL *
    216        1.1  jonathan 	    sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
    217        1.1  jonathan 	if (crypto_drivers == NULL) {
    218        1.1  jonathan 		printf("crypto_init: cannot malloc driver table\n");
    219       1.12      yamt 		return 0;
    220        1.1  jonathan 	}
    221       1.11   thorpej 	crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
    222        1.1  jonathan 
    223        1.1  jonathan 	softintr_cookie = register_swi(SWI_CRYPTO, cryptointr);
    224        1.1  jonathan #ifdef __FreeBSD__
    225        1.1  jonathan 	error = kthread_create((void (*)(void *)) cryptoret, NULL,
    226       1.20        ad 		    &cryptothread, "cryptoret");
    227       1.20        ad #else
    228       1.20        ad 	error = kthread_create(PRI_NONE, 0, NULL, (void (*)(void*))cryptoret,
    229       1.20        ad 	    NULL, &cryptothread, "cryptoret");
    230       1.20        ad #endif
    231        1.1  jonathan 	if (error) {
    232        1.1  jonathan 		printf("crypto_init: cannot start cryptoret thread; error %d",
    233        1.1  jonathan 			error);
    234        1.1  jonathan 		crypto_destroy();
    235        1.1  jonathan 	}
    236       1.20        ad 
    237       1.12      yamt 	return 0;
    238       1.11   thorpej }
    239       1.11   thorpej 
    240       1.11   thorpej void
    241       1.11   thorpej crypto_init(void)
    242       1.11   thorpej {
    243       1.18    daniel 	static ONCE_DECL(crypto_init_once);
    244       1.11   thorpej 
    245       1.11   thorpej 	RUN_ONCE(&crypto_init_once, crypto_init0);
    246        1.1  jonathan }
    247        1.1  jonathan 
    248        1.1  jonathan static void
    249        1.1  jonathan crypto_destroy(void)
    250        1.1  jonathan {
    251        1.1  jonathan 	/* XXX no wait to reclaim zones */
    252        1.1  jonathan 	if (crypto_drivers != NULL)
    253        1.1  jonathan 		free(crypto_drivers, M_CRYPTO_DATA);
    254        1.1  jonathan 	unregister_swi(SWI_CRYPTO, cryptointr);
    255        1.1  jonathan }
    256        1.1  jonathan 
    257        1.1  jonathan /*
    258        1.1  jonathan  * Create a new session.
    259        1.1  jonathan  */
    260        1.1  jonathan int
    261        1.1  jonathan crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
    262        1.1  jonathan {
    263        1.1  jonathan 	struct cryptoini *cr;
    264        1.1  jonathan 	u_int32_t hid, lid;
    265        1.1  jonathan 	int err = EINVAL;
    266        1.1  jonathan 	int s;
    267        1.1  jonathan 
    268        1.1  jonathan 	s = splcrypto();
    269        1.1  jonathan 
    270        1.1  jonathan 	if (crypto_drivers == NULL)
    271        1.1  jonathan 		goto done;
    272        1.1  jonathan 
    273        1.1  jonathan 	/*
    274        1.1  jonathan 	 * The algorithm we use here is pretty stupid; just use the
    275        1.1  jonathan 	 * first driver that supports all the algorithms we need.
    276        1.1  jonathan 	 *
    277        1.1  jonathan 	 * XXX We need more smarts here (in real life too, but that's
    278        1.1  jonathan 	 * XXX another story altogether).
    279        1.1  jonathan 	 */
    280        1.1  jonathan 
    281        1.1  jonathan 	for (hid = 0; hid < crypto_drivers_num; hid++) {
    282        1.1  jonathan 		/*
    283        1.1  jonathan 		 * If it's not initialized or has remaining sessions
    284        1.1  jonathan 		 * referencing it, skip.
    285        1.1  jonathan 		 */
    286        1.1  jonathan 		if (crypto_drivers[hid].cc_newsession == NULL ||
    287        1.1  jonathan 		    (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP))
    288        1.1  jonathan 			continue;
    289        1.1  jonathan 
    290        1.1  jonathan 		/* Hardware required -- ignore software drivers. */
    291        1.1  jonathan 		if (hard > 0 &&
    292        1.1  jonathan 		    (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE))
    293        1.1  jonathan 			continue;
    294        1.1  jonathan 		/* Software required -- ignore hardware drivers. */
    295        1.1  jonathan 		if (hard < 0 &&
    296        1.1  jonathan 		    (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) == 0)
    297        1.1  jonathan 			continue;
    298        1.1  jonathan 
    299        1.1  jonathan 		/* See if all the algorithms are supported. */
    300        1.1  jonathan 		for (cr = cri; cr; cr = cr->cri_next)
    301        1.1  jonathan 			if (crypto_drivers[hid].cc_alg[cr->cri_alg] == 0)
    302        1.1  jonathan 				break;
    303        1.1  jonathan 
    304        1.1  jonathan 		if (cr == NULL) {
    305        1.1  jonathan 			/* Ok, all algorithms are supported. */
    306        1.1  jonathan 
    307        1.1  jonathan 			/*
    308        1.1  jonathan 			 * Can't do everything in one session.
    309        1.1  jonathan 			 *
    310        1.1  jonathan 			 * XXX Fix this. We need to inject a "virtual" session layer right
    311        1.1  jonathan 			 * XXX about here.
    312        1.1  jonathan 			 */
    313        1.1  jonathan 
    314        1.1  jonathan 			/* Call the driver initialization routine. */
    315        1.1  jonathan 			lid = hid;		/* Pass the driver ID. */
    316        1.1  jonathan 			err = crypto_drivers[hid].cc_newsession(
    317        1.1  jonathan 					crypto_drivers[hid].cc_arg, &lid, cri);
    318        1.1  jonathan 			if (err == 0) {
    319        1.1  jonathan 				(*sid) = hid;
    320        1.1  jonathan 				(*sid) <<= 32;
    321        1.1  jonathan 				(*sid) |= (lid & 0xffffffff);
    322        1.1  jonathan 				crypto_drivers[hid].cc_sessions++;
    323        1.1  jonathan 			}
    324        1.1  jonathan 			goto done;
    325        1.1  jonathan 			/*break;*/
    326        1.1  jonathan 		}
    327        1.1  jonathan 	}
    328        1.1  jonathan done:
    329        1.1  jonathan 	splx(s);
    330        1.1  jonathan 	return err;
    331        1.1  jonathan }
    332        1.1  jonathan 
    333        1.1  jonathan /*
    334        1.1  jonathan  * Delete an existing session (or a reserved session on an unregistered
    335        1.1  jonathan  * driver).
    336        1.1  jonathan  */
    337        1.1  jonathan int
    338        1.1  jonathan crypto_freesession(u_int64_t sid)
    339        1.1  jonathan {
    340        1.1  jonathan 	u_int32_t hid;
    341        1.1  jonathan 	int err = 0;
    342        1.1  jonathan 	int s;
    343        1.1  jonathan 
    344        1.1  jonathan 	s = splcrypto();
    345        1.1  jonathan 
    346        1.1  jonathan 	if (crypto_drivers == NULL) {
    347        1.1  jonathan 		err = EINVAL;
    348        1.1  jonathan 		goto done;
    349        1.1  jonathan 	}
    350        1.1  jonathan 
    351        1.1  jonathan 	/* Determine two IDs. */
    352        1.1  jonathan 	hid = SESID2HID(sid);
    353        1.1  jonathan 
    354        1.1  jonathan 	if (hid >= crypto_drivers_num) {
    355        1.1  jonathan 		err = ENOENT;
    356        1.1  jonathan 		goto done;
    357        1.1  jonathan 	}
    358        1.1  jonathan 
    359        1.1  jonathan 	if (crypto_drivers[hid].cc_sessions)
    360        1.1  jonathan 		crypto_drivers[hid].cc_sessions--;
    361        1.1  jonathan 
    362        1.1  jonathan 	/* Call the driver cleanup routine, if available. */
    363        1.1  jonathan 	if (crypto_drivers[hid].cc_freesession)
    364        1.1  jonathan 		err = crypto_drivers[hid].cc_freesession(
    365        1.1  jonathan 				crypto_drivers[hid].cc_arg, sid);
    366        1.1  jonathan 	else
    367        1.1  jonathan 		err = 0;
    368        1.1  jonathan 
    369        1.1  jonathan 	/*
    370        1.1  jonathan 	 * If this was the last session of a driver marked as invalid,
    371        1.1  jonathan 	 * make the entry available for reuse.
    372        1.1  jonathan 	 */
    373        1.1  jonathan 	if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) &&
    374        1.1  jonathan 	    crypto_drivers[hid].cc_sessions == 0)
    375        1.1  jonathan 		bzero(&crypto_drivers[hid], sizeof(struct cryptocap));
    376        1.1  jonathan 
    377        1.1  jonathan done:
    378        1.1  jonathan 	splx(s);
    379        1.1  jonathan 	return err;
    380        1.1  jonathan }
    381        1.1  jonathan 
    382        1.1  jonathan /*
    383        1.1  jonathan  * Return an unused driver id.  Used by drivers prior to registering
    384        1.1  jonathan  * support for the algorithms they handle.
    385        1.1  jonathan  */
    386        1.1  jonathan int32_t
    387        1.1  jonathan crypto_get_driverid(u_int32_t flags)
    388        1.1  jonathan {
    389        1.1  jonathan 	struct cryptocap *newdrv;
    390        1.1  jonathan 	int i, s;
    391        1.1  jonathan 
    392       1.11   thorpej 	crypto_init();
    393       1.11   thorpej 
    394        1.1  jonathan 	s = splcrypto();
    395        1.1  jonathan 	for (i = 0; i < crypto_drivers_num; i++)
    396        1.1  jonathan 		if (crypto_drivers[i].cc_process == NULL &&
    397        1.1  jonathan 		    (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0 &&
    398        1.1  jonathan 		    crypto_drivers[i].cc_sessions == 0)
    399        1.1  jonathan 			break;
    400        1.1  jonathan 
    401        1.1  jonathan 	/* Out of entries, allocate some more. */
    402        1.1  jonathan 	if (i == crypto_drivers_num) {
    403        1.1  jonathan 		/* Be careful about wrap-around. */
    404        1.1  jonathan 		if (2 * crypto_drivers_num <= crypto_drivers_num) {
    405        1.1  jonathan 			splx(s);
    406        1.1  jonathan 			printf("crypto: driver count wraparound!\n");
    407        1.1  jonathan 			return -1;
    408        1.1  jonathan 		}
    409        1.1  jonathan 
    410        1.1  jonathan 		newdrv = malloc(2 * crypto_drivers_num *
    411        1.1  jonathan 		    sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
    412        1.1  jonathan 		if (newdrv == NULL) {
    413        1.1  jonathan 			splx(s);
    414        1.1  jonathan 			printf("crypto: no space to expand driver table!\n");
    415        1.1  jonathan 			return -1;
    416        1.1  jonathan 		}
    417        1.1  jonathan 
    418        1.1  jonathan 		bcopy(crypto_drivers, newdrv,
    419        1.1  jonathan 		    crypto_drivers_num * sizeof(struct cryptocap));
    420        1.1  jonathan 
    421        1.1  jonathan 		crypto_drivers_num *= 2;
    422        1.1  jonathan 
    423        1.1  jonathan 		free(crypto_drivers, M_CRYPTO_DATA);
    424        1.1  jonathan 		crypto_drivers = newdrv;
    425        1.1  jonathan 	}
    426        1.1  jonathan 
    427        1.1  jonathan 	/* NB: state is zero'd on free */
    428        1.1  jonathan 	crypto_drivers[i].cc_sessions = 1;	/* Mark */
    429        1.1  jonathan 	crypto_drivers[i].cc_flags = flags;
    430        1.1  jonathan 
    431        1.1  jonathan 	if (bootverbose)
    432        1.1  jonathan 		printf("crypto: assign driver %u, flags %u\n", i, flags);
    433        1.1  jonathan 
    434        1.1  jonathan 	splx(s);
    435        1.1  jonathan 
    436        1.1  jonathan 	return i;
    437        1.1  jonathan }
    438        1.1  jonathan 
    439        1.1  jonathan static struct cryptocap *
    440        1.1  jonathan crypto_checkdriver(u_int32_t hid)
    441        1.1  jonathan {
    442        1.1  jonathan 	if (crypto_drivers == NULL)
    443        1.1  jonathan 		return NULL;
    444        1.1  jonathan 	return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
    445        1.1  jonathan }
    446        1.1  jonathan 
    447        1.1  jonathan /*
    448        1.1  jonathan  * Register support for a key-related algorithm.  This routine
    449        1.1  jonathan  * is called once for each algorithm supported a driver.
    450        1.1  jonathan  */
    451        1.1  jonathan int
    452        1.1  jonathan crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags,
    453        1.1  jonathan     int (*kprocess)(void*, struct cryptkop *, int),
    454        1.1  jonathan     void *karg)
    455        1.1  jonathan {
    456        1.1  jonathan 	int s;
    457        1.1  jonathan 	struct cryptocap *cap;
    458        1.1  jonathan 	int err;
    459        1.1  jonathan 
    460        1.1  jonathan 	s = splcrypto();
    461        1.1  jonathan 
    462        1.1  jonathan 	cap = crypto_checkdriver(driverid);
    463        1.1  jonathan 	if (cap != NULL &&
    464        1.1  jonathan 	    (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
    465        1.1  jonathan 		/*
    466        1.1  jonathan 		 * XXX Do some performance testing to determine placing.
    467        1.1  jonathan 		 * XXX We probably need an auxiliary data structure that
    468        1.1  jonathan 		 * XXX describes relative performances.
    469        1.1  jonathan 		 */
    470        1.1  jonathan 
    471        1.1  jonathan 		cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
    472        1.1  jonathan 		if (bootverbose)
    473        1.1  jonathan 			printf("crypto: driver %u registers key alg %u flags %u\n"
    474        1.1  jonathan 				, driverid
    475        1.1  jonathan 				, kalg
    476        1.1  jonathan 				, flags
    477        1.1  jonathan 			);
    478        1.1  jonathan 
    479        1.1  jonathan 		if (cap->cc_kprocess == NULL) {
    480        1.1  jonathan 			cap->cc_karg = karg;
    481        1.1  jonathan 			cap->cc_kprocess = kprocess;
    482        1.1  jonathan 		}
    483        1.1  jonathan 		err = 0;
    484        1.1  jonathan 	} else
    485        1.1  jonathan 		err = EINVAL;
    486        1.1  jonathan 
    487        1.1  jonathan 	splx(s);
    488        1.1  jonathan 	return err;
    489        1.1  jonathan }
    490        1.1  jonathan 
    491        1.1  jonathan /*
    492        1.1  jonathan  * Register support for a non-key-related algorithm.  This routine
    493        1.1  jonathan  * is called once for each such algorithm supported by a driver.
    494        1.1  jonathan  */
    495        1.1  jonathan int
    496        1.1  jonathan crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
    497        1.1  jonathan     u_int32_t flags,
    498        1.1  jonathan     int (*newses)(void*, u_int32_t*, struct cryptoini*),
    499        1.1  jonathan     int (*freeses)(void*, u_int64_t),
    500        1.1  jonathan     int (*process)(void*, struct cryptop *, int),
    501        1.1  jonathan     void *arg)
    502        1.1  jonathan {
    503        1.1  jonathan 	struct cryptocap *cap;
    504        1.1  jonathan 	int s, err;
    505        1.1  jonathan 
    506        1.1  jonathan 	s = splcrypto();
    507        1.1  jonathan 
    508        1.1  jonathan 	cap = crypto_checkdriver(driverid);
    509        1.1  jonathan 	/* NB: algorithms are in the range [1..max] */
    510        1.1  jonathan 	if (cap != NULL &&
    511        1.1  jonathan 	    (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
    512        1.1  jonathan 		/*
    513        1.1  jonathan 		 * XXX Do some performance testing to determine placing.
    514        1.1  jonathan 		 * XXX We probably need an auxiliary data structure that
    515        1.1  jonathan 		 * XXX describes relative performances.
    516        1.1  jonathan 		 */
    517        1.1  jonathan 
    518        1.1  jonathan 		cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
    519        1.1  jonathan 		cap->cc_max_op_len[alg] = maxoplen;
    520        1.1  jonathan 		if (bootverbose)
    521        1.1  jonathan 			printf("crypto: driver %u registers alg %u flags %u maxoplen %u\n"
    522        1.1  jonathan 				, driverid
    523        1.1  jonathan 				, alg
    524        1.1  jonathan 				, flags
    525        1.1  jonathan 				, maxoplen
    526        1.1  jonathan 			);
    527        1.1  jonathan 
    528        1.1  jonathan 		if (cap->cc_process == NULL) {
    529        1.1  jonathan 			cap->cc_arg = arg;
    530        1.1  jonathan 			cap->cc_newsession = newses;
    531        1.1  jonathan 			cap->cc_process = process;
    532        1.1  jonathan 			cap->cc_freesession = freeses;
    533        1.1  jonathan 			cap->cc_sessions = 0;		/* Unmark */
    534        1.1  jonathan 		}
    535        1.1  jonathan 		err = 0;
    536        1.1  jonathan 	} else
    537        1.1  jonathan 		err = EINVAL;
    538        1.1  jonathan 
    539        1.1  jonathan 	splx(s);
    540        1.1  jonathan 	return err;
    541        1.1  jonathan }
    542        1.1  jonathan 
    543        1.1  jonathan /*
    544        1.1  jonathan  * Unregister a crypto driver. If there are pending sessions using it,
    545        1.1  jonathan  * leave enough information around so that subsequent calls using those
    546        1.1  jonathan  * sessions will correctly detect the driver has been unregistered and
    547        1.1  jonathan  * reroute requests.
    548        1.1  jonathan  */
    549        1.1  jonathan int
    550        1.1  jonathan crypto_unregister(u_int32_t driverid, int alg)
    551        1.1  jonathan {
    552        1.1  jonathan 	int i, err, s;
    553        1.1  jonathan 	u_int32_t ses;
    554        1.1  jonathan 	struct cryptocap *cap;
    555        1.1  jonathan 
    556        1.1  jonathan 	s = splcrypto();
    557        1.1  jonathan 
    558        1.1  jonathan 	cap = crypto_checkdriver(driverid);
    559        1.1  jonathan 	if (cap != NULL &&
    560        1.1  jonathan 	    (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
    561        1.1  jonathan 	    cap->cc_alg[alg] != 0) {
    562        1.1  jonathan 		cap->cc_alg[alg] = 0;
    563        1.1  jonathan 		cap->cc_max_op_len[alg] = 0;
    564        1.1  jonathan 
    565        1.1  jonathan 		/* Was this the last algorithm ? */
    566        1.1  jonathan 		for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
    567        1.1  jonathan 			if (cap->cc_alg[i] != 0)
    568        1.1  jonathan 				break;
    569        1.1  jonathan 
    570        1.1  jonathan 		if (i == CRYPTO_ALGORITHM_MAX + 1) {
    571        1.1  jonathan 			ses = cap->cc_sessions;
    572        1.1  jonathan 			bzero(cap, sizeof(struct cryptocap));
    573        1.1  jonathan 			if (ses != 0) {
    574        1.1  jonathan 				/*
    575        1.1  jonathan 				 * If there are pending sessions, just mark as invalid.
    576        1.1  jonathan 				 */
    577        1.1  jonathan 				cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
    578        1.1  jonathan 				cap->cc_sessions = ses;
    579        1.1  jonathan 			}
    580        1.1  jonathan 		}
    581        1.1  jonathan 		err = 0;
    582        1.1  jonathan 	} else
    583        1.1  jonathan 		err = EINVAL;
    584        1.1  jonathan 
    585        1.1  jonathan 	splx(s);
    586        1.1  jonathan 	return err;
    587        1.1  jonathan }
    588        1.1  jonathan 
    589        1.1  jonathan /*
    590        1.1  jonathan  * Unregister all algorithms associated with a crypto driver.
    591        1.1  jonathan  * If there are pending sessions using it, leave enough information
    592        1.1  jonathan  * around so that subsequent calls using those sessions will
    593        1.1  jonathan  * correctly detect the driver has been unregistered and reroute
    594        1.1  jonathan  * requests.
    595        1.1  jonathan  */
    596        1.1  jonathan int
    597        1.1  jonathan crypto_unregister_all(u_int32_t driverid)
    598        1.1  jonathan {
    599        1.1  jonathan 	int i, err, s = splcrypto();
    600        1.1  jonathan 	u_int32_t ses;
    601        1.1  jonathan 	struct cryptocap *cap;
    602        1.1  jonathan 
    603        1.1  jonathan 	cap = crypto_checkdriver(driverid);
    604        1.1  jonathan 	if (cap != NULL) {
    605        1.1  jonathan 		for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; i++) {
    606        1.1  jonathan 			cap->cc_alg[i] = 0;
    607        1.1  jonathan 			cap->cc_max_op_len[i] = 0;
    608        1.1  jonathan 		}
    609        1.1  jonathan 		ses = cap->cc_sessions;
    610        1.1  jonathan 		bzero(cap, sizeof(struct cryptocap));
    611        1.1  jonathan 		if (ses != 0) {
    612        1.1  jonathan 			/*
    613        1.1  jonathan 			 * If there are pending sessions, just mark as invalid.
    614        1.1  jonathan 			 */
    615        1.1  jonathan 			cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
    616        1.1  jonathan 			cap->cc_sessions = ses;
    617        1.1  jonathan 		}
    618        1.1  jonathan 		err = 0;
    619        1.1  jonathan 	} else
    620        1.1  jonathan 		err = EINVAL;
    621        1.1  jonathan 
    622        1.1  jonathan 	splx(s);
    623        1.1  jonathan 	return err;
    624        1.1  jonathan }
    625        1.1  jonathan 
    626        1.1  jonathan /*
    627        1.1  jonathan  * Clear blockage on a driver.  The what parameter indicates whether
    628        1.1  jonathan  * the driver is now ready for cryptop's and/or cryptokop's.
    629        1.1  jonathan  */
    630        1.1  jonathan int
    631        1.1  jonathan crypto_unblock(u_int32_t driverid, int what)
    632        1.1  jonathan {
    633        1.1  jonathan 	struct cryptocap *cap;
    634        1.1  jonathan 	int needwakeup, err, s;
    635        1.1  jonathan 
    636        1.1  jonathan 	s = splcrypto();
    637        1.1  jonathan 	cap = crypto_checkdriver(driverid);
    638        1.1  jonathan 	if (cap != NULL) {
    639        1.1  jonathan 		needwakeup = 0;
    640        1.1  jonathan 		if (what & CRYPTO_SYMQ) {
    641        1.1  jonathan 			needwakeup |= cap->cc_qblocked;
    642        1.1  jonathan 			cap->cc_qblocked = 0;
    643        1.1  jonathan 		}
    644        1.1  jonathan 		if (what & CRYPTO_ASYMQ) {
    645        1.1  jonathan 			needwakeup |= cap->cc_kqblocked;
    646        1.1  jonathan 			cap->cc_kqblocked = 0;
    647        1.1  jonathan 		}
    648        1.1  jonathan 		if (needwakeup) {
    649        1.1  jonathan 			setsoftcrypto(softintr_cookie);
    650        1.1  jonathan 		}
    651        1.1  jonathan 		err = 0;
    652        1.1  jonathan 	} else
    653        1.1  jonathan 		err = EINVAL;
    654        1.1  jonathan 	splx(s);
    655        1.1  jonathan 
    656        1.1  jonathan 	return err;
    657        1.1  jonathan }
    658        1.1  jonathan 
    659        1.1  jonathan /*
    660        1.1  jonathan  * Dispatch a crypto request to a driver or queue
    661        1.1  jonathan  * it, to be processed by the kernel thread.
    662        1.1  jonathan  */
    663        1.1  jonathan int
    664        1.1  jonathan crypto_dispatch(struct cryptop *crp)
    665        1.1  jonathan {
    666        1.1  jonathan 	u_int32_t hid = SESID2HID(crp->crp_sid);
    667        1.1  jonathan 	int s, result;
    668        1.1  jonathan 
    669        1.1  jonathan 	s = splcrypto();
    670        1.1  jonathan 
    671        1.1  jonathan 	cryptostats.cs_ops++;
    672        1.1  jonathan 
    673        1.1  jonathan #ifdef CRYPTO_TIMING
    674        1.1  jonathan 	if (crypto_timing)
    675        1.1  jonathan 		nanouptime(&crp->crp_tstamp);
    676        1.1  jonathan #endif
    677        1.1  jonathan 	if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
    678        1.1  jonathan 		struct cryptocap *cap;
    679        1.1  jonathan 		/*
    680        1.1  jonathan 		 * Caller marked the request to be processed
    681        1.1  jonathan 		 * immediately; dispatch it directly to the
    682        1.1  jonathan 		 * driver unless the driver is currently blocked.
    683        1.1  jonathan 		 */
    684        1.1  jonathan 		cap = crypto_checkdriver(hid);
    685        1.1  jonathan 		if (cap && !cap->cc_qblocked) {
    686        1.1  jonathan 			result = crypto_invoke(crp, 0);
    687        1.1  jonathan 			if (result == ERESTART) {
    688        1.1  jonathan 				/*
    689        1.1  jonathan 				 * The driver ran out of resources, mark the
    690        1.1  jonathan 				 * driver ``blocked'' for cryptop's and put
    691        1.1  jonathan 				 * the op on the queue.
    692        1.1  jonathan 				 */
    693        1.1  jonathan 				crypto_drivers[hid].cc_qblocked = 1;
    694        1.1  jonathan 				TAILQ_INSERT_HEAD(&crp_q, crp, crp_next);
    695        1.1  jonathan 				cryptostats.cs_blocks++;
    696        1.1  jonathan 			}
    697        1.1  jonathan 		} else {
    698        1.1  jonathan 			/*
    699        1.1  jonathan 			 * The driver is blocked, just queue the op until
    700        1.1  jonathan 			 * it unblocks and the swi thread gets kicked.
    701        1.1  jonathan 			 */
    702        1.1  jonathan 			TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
    703        1.1  jonathan 			result = 0;
    704        1.1  jonathan 		}
    705        1.1  jonathan 	} else {
    706        1.1  jonathan 		int wasempty = TAILQ_EMPTY(&crp_q);
    707        1.1  jonathan 		/*
    708        1.1  jonathan 		 * Caller marked the request as ``ok to delay'';
    709        1.1  jonathan 		 * queue it for the swi thread.  This is desirable
    710        1.1  jonathan 		 * when the operation is low priority and/or suitable
    711        1.1  jonathan 		 * for batching.
    712        1.1  jonathan 		 */
    713        1.1  jonathan 		TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
    714        1.1  jonathan 		if (wasempty) {
    715        1.1  jonathan 			setsoftcrypto(softintr_cookie);
    716        1.1  jonathan 		}
    717        1.1  jonathan 
    718        1.1  jonathan 		result = 0;
    719        1.1  jonathan 	}
    720        1.1  jonathan 	splx(s);
    721        1.1  jonathan 
    722        1.1  jonathan 	return result;
    723        1.1  jonathan }
    724        1.1  jonathan 
    725        1.1  jonathan /*
    726        1.1  jonathan  * Add an asymetric crypto request to a queue,
    727        1.1  jonathan  * to be processed by the kernel thread.
    728        1.1  jonathan  */
    729        1.1  jonathan int
    730        1.1  jonathan crypto_kdispatch(struct cryptkop *krp)
    731        1.1  jonathan {
    732        1.1  jonathan 	struct cryptocap *cap;
    733        1.1  jonathan 	int s, result;
    734        1.1  jonathan 
    735        1.1  jonathan 	s = splcrypto();
    736        1.1  jonathan 	cryptostats.cs_kops++;
    737        1.1  jonathan 
    738        1.1  jonathan 	cap = crypto_checkdriver(krp->krp_hid);
    739        1.1  jonathan 	if (cap && !cap->cc_kqblocked) {
    740        1.1  jonathan 		result = crypto_kinvoke(krp, 0);
    741        1.1  jonathan 		if (result == ERESTART) {
    742        1.1  jonathan 			/*
    743        1.1  jonathan 			 * The driver ran out of resources, mark the
    744        1.1  jonathan 			 * driver ``blocked'' for cryptop's and put
    745        1.1  jonathan 			 * the op on the queue.
    746        1.1  jonathan 			 */
    747        1.1  jonathan 			crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
    748        1.1  jonathan 			TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
    749        1.1  jonathan 			cryptostats.cs_kblocks++;
    750        1.1  jonathan 		}
    751        1.1  jonathan 	} else {
    752        1.1  jonathan 		/*
    753        1.1  jonathan 		 * The driver is blocked, just queue the op until
    754        1.1  jonathan 		 * it unblocks and the swi thread gets kicked.
    755        1.1  jonathan 		 */
    756        1.1  jonathan 		TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
    757        1.1  jonathan 		result = 0;
    758        1.1  jonathan 	}
    759        1.1  jonathan 	splx(s);
    760        1.1  jonathan 
    761        1.1  jonathan 	return result;
    762        1.1  jonathan }
    763        1.1  jonathan 
    764        1.1  jonathan /*
    765        1.1  jonathan  * Dispatch an assymetric crypto request to the appropriate crypto devices.
    766        1.1  jonathan  */
    767        1.1  jonathan static int
    768        1.1  jonathan crypto_kinvoke(struct cryptkop *krp, int hint)
    769        1.1  jonathan {
    770        1.1  jonathan 	u_int32_t hid;
    771        1.1  jonathan 	int error;
    772        1.1  jonathan 
    773        1.1  jonathan 	/* Sanity checks. */
    774        1.1  jonathan 	if (krp == NULL)
    775        1.1  jonathan 		return EINVAL;
    776        1.1  jonathan 	if (krp->krp_callback == NULL) {
    777        1.1  jonathan 		free(krp, M_XDATA);		/* XXX allocated in cryptodev */
    778        1.1  jonathan 		return EINVAL;
    779        1.1  jonathan 	}
    780        1.1  jonathan 
    781        1.1  jonathan 	for (hid = 0; hid < crypto_drivers_num; hid++) {
    782        1.1  jonathan 		if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
    783        1.1  jonathan 		    crypto_devallowsoft == 0)
    784        1.1  jonathan 			continue;
    785        1.1  jonathan 		if (crypto_drivers[hid].cc_kprocess == NULL)
    786        1.1  jonathan 			continue;
    787        1.1  jonathan 		if ((crypto_drivers[hid].cc_kalg[krp->krp_op] &
    788        1.1  jonathan 		    CRYPTO_ALG_FLAG_SUPPORTED) == 0)
    789        1.1  jonathan 			continue;
    790        1.1  jonathan 		break;
    791        1.1  jonathan 	}
    792        1.1  jonathan 	if (hid < crypto_drivers_num) {
    793        1.1  jonathan 		krp->krp_hid = hid;
    794        1.1  jonathan 		error = crypto_drivers[hid].cc_kprocess(
    795        1.1  jonathan 				crypto_drivers[hid].cc_karg, krp, hint);
    796        1.1  jonathan 	} else {
    797        1.1  jonathan 		error = ENODEV;
    798        1.1  jonathan 	}
    799        1.1  jonathan 
    800        1.1  jonathan 	if (error) {
    801        1.1  jonathan 		krp->krp_status = error;
    802        1.1  jonathan 		crypto_kdone(krp);
    803        1.1  jonathan 	}
    804        1.1  jonathan 	return 0;
    805        1.1  jonathan }
    806        1.1  jonathan 
    807        1.1  jonathan #ifdef CRYPTO_TIMING
    808        1.1  jonathan static void
    809        1.1  jonathan crypto_tstat(struct cryptotstat *ts, struct timespec *tv)
    810        1.1  jonathan {
    811        1.1  jonathan 	struct timespec now, t;
    812        1.1  jonathan 
    813        1.1  jonathan 	nanouptime(&now);
    814        1.1  jonathan 	t.tv_sec = now.tv_sec - tv->tv_sec;
    815        1.1  jonathan 	t.tv_nsec = now.tv_nsec - tv->tv_nsec;
    816        1.1  jonathan 	if (t.tv_nsec < 0) {
    817        1.1  jonathan 		t.tv_sec--;
    818        1.1  jonathan 		t.tv_nsec += 1000000000;
    819        1.1  jonathan 	}
    820        1.1  jonathan 	timespecadd(&ts->acc, &t, &t);
    821        1.1  jonathan 	if (timespeccmp(&t, &ts->min, <))
    822        1.1  jonathan 		ts->min = t;
    823        1.1  jonathan 	if (timespeccmp(&t, &ts->max, >))
    824        1.1  jonathan 		ts->max = t;
    825        1.1  jonathan 	ts->count++;
    826        1.1  jonathan 
    827        1.1  jonathan 	*tv = now;
    828        1.1  jonathan }
    829        1.1  jonathan #endif
    830        1.1  jonathan 
    831        1.1  jonathan /*
    832        1.1  jonathan  * Dispatch a crypto request to the appropriate crypto devices.
    833        1.1  jonathan  */
    834        1.1  jonathan static int
    835        1.1  jonathan crypto_invoke(struct cryptop *crp, int hint)
    836        1.1  jonathan {
    837        1.1  jonathan 	u_int32_t hid;
    838        1.1  jonathan 	int (*process)(void*, struct cryptop *, int);
    839        1.1  jonathan 
    840        1.1  jonathan #ifdef CRYPTO_TIMING
    841        1.1  jonathan 	if (crypto_timing)
    842        1.1  jonathan 		crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
    843        1.1  jonathan #endif
    844        1.1  jonathan 	/* Sanity checks. */
    845        1.1  jonathan 	if (crp == NULL)
    846        1.1  jonathan 		return EINVAL;
    847        1.1  jonathan 	if (crp->crp_callback == NULL) {
    848        1.1  jonathan 		crypto_freereq(crp);
    849        1.1  jonathan 		return EINVAL;
    850        1.1  jonathan 	}
    851        1.1  jonathan 	if (crp->crp_desc == NULL) {
    852        1.1  jonathan 		crp->crp_etype = EINVAL;
    853        1.1  jonathan 		crypto_done(crp);
    854        1.1  jonathan 		return 0;
    855        1.1  jonathan 	}
    856        1.1  jonathan 
    857        1.1  jonathan 	hid = SESID2HID(crp->crp_sid);
    858        1.1  jonathan 	if (hid < crypto_drivers_num) {
    859        1.1  jonathan 		if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP)
    860        1.1  jonathan 			crypto_freesession(crp->crp_sid);
    861        1.1  jonathan 		process = crypto_drivers[hid].cc_process;
    862        1.1  jonathan 	} else {
    863        1.1  jonathan 		process = NULL;
    864        1.1  jonathan 	}
    865        1.1  jonathan 
    866        1.1  jonathan 	if (process == NULL) {
    867        1.1  jonathan 		struct cryptodesc *crd;
    868       1.16       mrg 		u_int64_t nid = 0;
    869        1.1  jonathan 
    870        1.1  jonathan 		/*
    871        1.1  jonathan 		 * Driver has unregistered; migrate the session and return
    872        1.1  jonathan 		 * an error to the caller so they'll resubmit the op.
    873        1.1  jonathan 		 */
    874        1.1  jonathan 		for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
    875        1.1  jonathan 			crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
    876        1.1  jonathan 
    877        1.1  jonathan 		if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
    878        1.1  jonathan 			crp->crp_sid = nid;
    879        1.1  jonathan 
    880        1.1  jonathan 		crp->crp_etype = EAGAIN;
    881        1.1  jonathan 		crypto_done(crp);
    882        1.1  jonathan 		return 0;
    883        1.1  jonathan 	} else {
    884        1.1  jonathan 		/*
    885        1.1  jonathan 		 * Invoke the driver to process the request.
    886        1.1  jonathan 		 */
    887        1.1  jonathan 		return (*process)(crypto_drivers[hid].cc_arg, crp, hint);
    888        1.1  jonathan 	}
    889        1.1  jonathan }
    890        1.1  jonathan 
    891        1.1  jonathan /*
    892        1.1  jonathan  * Release a set of crypto descriptors.
    893        1.1  jonathan  */
    894        1.1  jonathan void
    895        1.1  jonathan crypto_freereq(struct cryptop *crp)
    896        1.1  jonathan {
    897        1.1  jonathan 	struct cryptodesc *crd;
    898        1.1  jonathan 	int s;
    899        1.1  jonathan 
    900        1.1  jonathan 	if (crp == NULL)
    901        1.1  jonathan 		return;
    902        1.1  jonathan 
    903        1.1  jonathan 	s = splcrypto();
    904        1.1  jonathan 
    905        1.1  jonathan 	while ((crd = crp->crp_desc) != NULL) {
    906        1.1  jonathan 		crp->crp_desc = crd->crd_next;
    907        1.1  jonathan 		pool_put(&cryptodesc_pool, crd);
    908        1.1  jonathan 	}
    909        1.1  jonathan 
    910        1.1  jonathan 	pool_put(&cryptop_pool, crp);
    911        1.1  jonathan 	splx(s);
    912        1.1  jonathan }
    913        1.1  jonathan 
    914        1.1  jonathan /*
    915        1.1  jonathan  * Acquire a set of crypto descriptors.
    916        1.1  jonathan  */
    917        1.1  jonathan struct cryptop *
    918        1.1  jonathan crypto_getreq(int num)
    919        1.1  jonathan {
    920        1.1  jonathan 	struct cryptodesc *crd;
    921        1.1  jonathan 	struct cryptop *crp;
    922        1.1  jonathan 	int s;
    923        1.1  jonathan 
    924        1.1  jonathan 	s = splcrypto();
    925        1.1  jonathan 
    926        1.1  jonathan 	if (crypto_pool_initialized == 0) {
    927        1.1  jonathan 		pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,
    928       1.19        ad 		    0, "cryptop", NULL, IPL_NET);
    929        1.1  jonathan 		pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0,
    930       1.19        ad 		    0, "cryptodesc", NULL, IPL_NET);
    931        1.1  jonathan 		crypto_pool_initialized = 1;
    932        1.1  jonathan 	}
    933        1.1  jonathan 
    934        1.1  jonathan 	crp = pool_get(&cryptop_pool, 0);
    935        1.1  jonathan 	if (crp == NULL) {
    936        1.1  jonathan 		splx(s);
    937        1.1  jonathan 		return NULL;
    938        1.1  jonathan 	}
    939        1.1  jonathan 	bzero(crp, sizeof(struct cryptop));
    940        1.1  jonathan 
    941        1.1  jonathan 	while (num--) {
    942        1.1  jonathan 		crd = pool_get(&cryptodesc_pool, 0);
    943        1.1  jonathan 		if (crd == NULL) {
    944        1.1  jonathan 			splx(s);
    945        1.1  jonathan 			crypto_freereq(crp);
    946        1.1  jonathan 			return NULL;
    947        1.1  jonathan 		}
    948        1.1  jonathan 
    949        1.1  jonathan 		bzero(crd, sizeof(struct cryptodesc));
    950        1.1  jonathan 		crd->crd_next = crp->crp_desc;
    951        1.1  jonathan 		crp->crp_desc = crd;
    952        1.1  jonathan 	}
    953        1.1  jonathan 
    954        1.1  jonathan 	splx(s);
    955        1.1  jonathan 	return crp;
    956        1.1  jonathan }
    957        1.1  jonathan 
    958        1.1  jonathan /*
    959        1.1  jonathan  * Invoke the callback on behalf of the driver.
    960        1.1  jonathan  */
    961        1.1  jonathan void
    962        1.1  jonathan crypto_done(struct cryptop *crp)
    963        1.1  jonathan {
    964        1.1  jonathan 	if (crp->crp_etype != 0)
    965        1.1  jonathan 		cryptostats.cs_errs++;
    966        1.1  jonathan #ifdef CRYPTO_TIMING
    967        1.1  jonathan 	if (crypto_timing)
    968        1.1  jonathan 		crypto_tstat(&cryptostats.cs_done, &crp->crp_tstamp);
    969        1.1  jonathan #endif
    970        1.1  jonathan 	/*
    971        1.1  jonathan 	 * On netbsd 1.6O, CBIMM does its wake_one() before the requestor
    972        1.1  jonathan 	 * has done its tsleep().
    973        1.1  jonathan 	 */
    974        1.1  jonathan #ifndef __NetBSD__
    975        1.1  jonathan 	if (crp->crp_flags & CRYPTO_F_CBIMM) {
    976        1.1  jonathan 		/*
    977        1.1  jonathan 		 * Do the callback directly.  This is ok when the
    978        1.1  jonathan 		 * callback routine does very little (e.g. the
    979        1.1  jonathan 		 * /dev/crypto callback method just does a wakeup).
    980        1.1  jonathan 		 */
    981        1.1  jonathan #ifdef CRYPTO_TIMING
    982        1.1  jonathan 		if (crypto_timing) {
    983        1.1  jonathan 			/*
    984        1.1  jonathan 			 * NB: We must copy the timestamp before
    985        1.1  jonathan 			 * doing the callback as the cryptop is
    986        1.1  jonathan 			 * likely to be reclaimed.
    987        1.1  jonathan 			 */
    988        1.1  jonathan 			struct timespec t = crp->crp_tstamp;
    989        1.1  jonathan 			crypto_tstat(&cryptostats.cs_cb, &t);
    990        1.1  jonathan 			crp->crp_callback(crp);
    991        1.1  jonathan 			crypto_tstat(&cryptostats.cs_finis, &t);
    992        1.1  jonathan 		} else
    993        1.1  jonathan #endif
    994        1.1  jonathan 			crp->crp_callback(crp);
    995        1.1  jonathan 	} else
    996        1.1  jonathan #endif /* __NetBSD__ */
    997        1.1  jonathan 	{
    998        1.1  jonathan 		int s, wasempty;
    999        1.1  jonathan 		/*
   1000        1.1  jonathan 		 * Normal case; queue the callback for the thread.
   1001        1.1  jonathan 		 *
   1002        1.1  jonathan 		 * The return queue is manipulated by the swi thread
   1003        1.1  jonathan 		 * and, potentially, by crypto device drivers calling
   1004        1.1  jonathan 		 * back to mark operations completed.  Thus we need
   1005        1.1  jonathan 		 * to mask both while manipulating the return queue.
   1006        1.1  jonathan 		 */
   1007        1.1  jonathan 		s = splcrypto();
   1008        1.1  jonathan 		wasempty = TAILQ_EMPTY(&crp_ret_q);
   1009        1.1  jonathan 		TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
   1010        1.1  jonathan 		if (wasempty)
   1011        1.1  jonathan 			wakeup_one(&crp_ret_q);
   1012        1.1  jonathan 		splx(s);
   1013        1.1  jonathan 	}
   1014        1.1  jonathan }
   1015        1.1  jonathan 
   1016        1.1  jonathan /*
   1017        1.1  jonathan  * Invoke the callback on behalf of the driver.
   1018        1.1  jonathan  */
   1019        1.1  jonathan void
   1020        1.1  jonathan crypto_kdone(struct cryptkop *krp)
   1021        1.1  jonathan {
   1022        1.1  jonathan 	int s, wasempty;
   1023        1.1  jonathan 
   1024        1.1  jonathan 	if (krp->krp_status != 0)
   1025        1.1  jonathan 		cryptostats.cs_kerrs++;
   1026        1.1  jonathan 	/*
   1027        1.1  jonathan 	 * The return queue is manipulated by the swi thread
   1028        1.1  jonathan 	 * and, potentially, by crypto device drivers calling
   1029        1.1  jonathan 	 * back to mark operations completed.  Thus we need
   1030        1.1  jonathan 	 * to mask both while manipulating the return queue.
   1031        1.1  jonathan 	 */
   1032        1.1  jonathan 	s = splcrypto();
   1033        1.1  jonathan 	wasempty = TAILQ_EMPTY(&crp_ret_kq);
   1034        1.1  jonathan 	TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
   1035        1.1  jonathan 	if (wasempty)
   1036        1.1  jonathan 		wakeup_one(&crp_ret_q);
   1037        1.1  jonathan 	splx(s);
   1038        1.1  jonathan }
   1039        1.1  jonathan 
   1040        1.1  jonathan int
   1041        1.1  jonathan crypto_getfeat(int *featp)
   1042        1.1  jonathan {
   1043        1.1  jonathan 	int hid, kalg, feat = 0;
   1044        1.1  jonathan 	int s;
   1045        1.1  jonathan 
   1046        1.1  jonathan 	s = splcrypto();
   1047        1.1  jonathan 
   1048        1.1  jonathan 	if (crypto_userasymcrypto == 0)
   1049       1.10     perry 		goto out;
   1050        1.1  jonathan 
   1051        1.1  jonathan 	for (hid = 0; hid < crypto_drivers_num; hid++) {
   1052        1.1  jonathan 		if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
   1053        1.7  jonathan 		    crypto_devallowsoft == 0) {
   1054        1.1  jonathan 			continue;
   1055        1.1  jonathan 		}
   1056        1.1  jonathan 		if (crypto_drivers[hid].cc_kprocess == NULL)
   1057        1.1  jonathan 			continue;
   1058        1.1  jonathan 		for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
   1059        1.1  jonathan 			if ((crypto_drivers[hid].cc_kalg[kalg] &
   1060        1.1  jonathan 			    CRYPTO_ALG_FLAG_SUPPORTED) != 0)
   1061        1.1  jonathan 				feat |=  1 << kalg;
   1062        1.1  jonathan 	}
   1063        1.1  jonathan out:
   1064        1.1  jonathan 	splx(s);
   1065        1.1  jonathan 	*featp = feat;
   1066        1.1  jonathan 	return (0);
   1067        1.1  jonathan }
   1068        1.1  jonathan 
   1069        1.1  jonathan /*
   1070        1.1  jonathan  * Software interrupt thread to dispatch crypto requests.
   1071        1.1  jonathan  */
   1072        1.1  jonathan static void
   1073        1.1  jonathan cryptointr(void)
   1074        1.1  jonathan {
   1075        1.1  jonathan 	struct cryptop *crp, *submit;
   1076        1.1  jonathan 	struct cryptkop *krp;
   1077        1.1  jonathan 	struct cryptocap *cap;
   1078        1.1  jonathan 	int result, hint, s;
   1079        1.1  jonathan 
   1080        1.1  jonathan 	printf("crypto softint\n");
   1081        1.1  jonathan 	cryptostats.cs_intrs++;
   1082        1.1  jonathan 	s = splcrypto();
   1083        1.1  jonathan 	do {
   1084        1.1  jonathan 		/*
   1085        1.1  jonathan 		 * Find the first element in the queue that can be
   1086        1.1  jonathan 		 * processed and look-ahead to see if multiple ops
   1087        1.1  jonathan 		 * are ready for the same driver.
   1088        1.1  jonathan 		 */
   1089        1.1  jonathan 		submit = NULL;
   1090        1.1  jonathan 		hint = 0;
   1091        1.1  jonathan 		TAILQ_FOREACH(crp, &crp_q, crp_next) {
   1092        1.1  jonathan 			u_int32_t hid = SESID2HID(crp->crp_sid);
   1093        1.1  jonathan 			cap = crypto_checkdriver(hid);
   1094        1.1  jonathan 			if (cap == NULL || cap->cc_process == NULL) {
   1095        1.1  jonathan 				/* Op needs to be migrated, process it. */
   1096        1.1  jonathan 				if (submit == NULL)
   1097        1.1  jonathan 					submit = crp;
   1098        1.1  jonathan 				break;
   1099        1.1  jonathan 			}
   1100        1.1  jonathan 			if (!cap->cc_qblocked) {
   1101        1.1  jonathan 				if (submit != NULL) {
   1102        1.1  jonathan 					/*
   1103        1.1  jonathan 					 * We stop on finding another op,
   1104        1.1  jonathan 					 * regardless whether its for the same
   1105        1.1  jonathan 					 * driver or not.  We could keep
   1106        1.1  jonathan 					 * searching the queue but it might be
   1107        1.1  jonathan 					 * better to just use a per-driver
   1108        1.1  jonathan 					 * queue instead.
   1109        1.1  jonathan 					 */
   1110        1.1  jonathan 					if (SESID2HID(submit->crp_sid) == hid)
   1111        1.1  jonathan 						hint = CRYPTO_HINT_MORE;
   1112        1.1  jonathan 					break;
   1113        1.1  jonathan 				} else {
   1114        1.1  jonathan 					submit = crp;
   1115        1.1  jonathan 					if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
   1116        1.1  jonathan 						break;
   1117        1.1  jonathan 					/* keep scanning for more are q'd */
   1118        1.1  jonathan 				}
   1119        1.1  jonathan 			}
   1120        1.1  jonathan 		}
   1121        1.1  jonathan 		if (submit != NULL) {
   1122        1.1  jonathan 			TAILQ_REMOVE(&crp_q, submit, crp_next);
   1123        1.1  jonathan 			result = crypto_invoke(submit, hint);
   1124        1.1  jonathan 			if (result == ERESTART) {
   1125        1.1  jonathan 				/*
   1126        1.1  jonathan 				 * The driver ran out of resources, mark the
   1127        1.1  jonathan 				 * driver ``blocked'' for cryptop's and put
   1128        1.1  jonathan 				 * the request back in the queue.  It would
   1129        1.1  jonathan 				 * best to put the request back where we got
   1130        1.1  jonathan 				 * it but that's hard so for now we put it
   1131        1.1  jonathan 				 * at the front.  This should be ok; putting
   1132        1.1  jonathan 				 * it at the end does not work.
   1133        1.1  jonathan 				 */
   1134        1.1  jonathan 				/* XXX validate sid again? */
   1135        1.1  jonathan 				crypto_drivers[SESID2HID(submit->crp_sid)].cc_qblocked = 1;
   1136        1.1  jonathan 				TAILQ_INSERT_HEAD(&crp_q, submit, crp_next);
   1137        1.1  jonathan 				cryptostats.cs_blocks++;
   1138        1.1  jonathan 			}
   1139        1.1  jonathan 		}
   1140        1.1  jonathan 
   1141        1.1  jonathan 		/* As above, but for key ops */
   1142        1.1  jonathan 		TAILQ_FOREACH(krp, &crp_kq, krp_next) {
   1143        1.1  jonathan 			cap = crypto_checkdriver(krp->krp_hid);
   1144        1.1  jonathan 			if (cap == NULL || cap->cc_kprocess == NULL) {
   1145        1.1  jonathan 				/* Op needs to be migrated, process it. */
   1146        1.1  jonathan 				break;
   1147        1.1  jonathan 			}
   1148        1.1  jonathan 			if (!cap->cc_kqblocked)
   1149        1.1  jonathan 				break;
   1150        1.1  jonathan 		}
   1151        1.1  jonathan 		if (krp != NULL) {
   1152        1.1  jonathan 			TAILQ_REMOVE(&crp_kq, krp, krp_next);
   1153        1.1  jonathan 			result = crypto_kinvoke(krp, 0);
   1154        1.1  jonathan 			if (result == ERESTART) {
   1155        1.1  jonathan 				/*
   1156        1.1  jonathan 				 * The driver ran out of resources, mark the
   1157        1.1  jonathan 				 * driver ``blocked'' for cryptkop's and put
   1158        1.1  jonathan 				 * the request back in the queue.  It would
   1159        1.1  jonathan 				 * best to put the request back where we got
   1160        1.1  jonathan 				 * it but that's hard so for now we put it
   1161        1.1  jonathan 				 * at the front.  This should be ok; putting
   1162        1.1  jonathan 				 * it at the end does not work.
   1163        1.1  jonathan 				 */
   1164        1.1  jonathan 				/* XXX validate sid again? */
   1165        1.1  jonathan 				crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
   1166        1.1  jonathan 				TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
   1167        1.1  jonathan 				cryptostats.cs_kblocks++;
   1168        1.1  jonathan 			}
   1169        1.1  jonathan 		}
   1170        1.1  jonathan 	} while (submit != NULL || krp != NULL);
   1171        1.1  jonathan 	splx(s);
   1172        1.1  jonathan }
   1173        1.1  jonathan 
   1174        1.1  jonathan /*
   1175        1.1  jonathan  * Kernel thread to do callbacks.
   1176        1.1  jonathan  */
   1177        1.1  jonathan static void
   1178        1.1  jonathan cryptoret(void)
   1179        1.1  jonathan {
   1180        1.1  jonathan 	struct cryptop *crp;
   1181        1.1  jonathan 	struct cryptkop *krp;
   1182        1.1  jonathan 	int s;
   1183        1.1  jonathan 
   1184        1.1  jonathan 	s = splcrypto();
   1185        1.1  jonathan 	for (;;) {
   1186        1.1  jonathan 		crp = TAILQ_FIRST(&crp_ret_q);
   1187        1.1  jonathan 		if (crp != NULL)
   1188        1.1  jonathan 			TAILQ_REMOVE(&crp_ret_q, crp, crp_next);
   1189        1.1  jonathan 		krp = TAILQ_FIRST(&crp_ret_kq);
   1190        1.1  jonathan 		if (krp != NULL)
   1191        1.1  jonathan 			TAILQ_REMOVE(&crp_ret_kq, krp, krp_next);
   1192        1.1  jonathan 
   1193        1.1  jonathan 		if (crp != NULL || krp != NULL) {
   1194        1.1  jonathan 			splx(s);		/* lower ipl for callbacks */
   1195        1.1  jonathan 			if (crp != NULL) {
   1196        1.1  jonathan #ifdef CRYPTO_TIMING
   1197        1.1  jonathan 				if (crypto_timing) {
   1198        1.1  jonathan 					/*
   1199        1.1  jonathan 					 * NB: We must copy the timestamp before
   1200        1.1  jonathan 					 * doing the callback as the cryptop is
   1201        1.1  jonathan 					 * likely to be reclaimed.
   1202        1.1  jonathan 					 */
   1203        1.1  jonathan 					struct timespec t = crp->crp_tstamp;
   1204        1.1  jonathan 					crypto_tstat(&cryptostats.cs_cb, &t);
   1205        1.1  jonathan 					crp->crp_callback(crp);
   1206        1.1  jonathan 					crypto_tstat(&cryptostats.cs_finis, &t);
   1207        1.1  jonathan 				} else
   1208        1.1  jonathan #endif
   1209        1.1  jonathan 					crp->crp_callback(crp);
   1210        1.1  jonathan 			}
   1211        1.1  jonathan 			if (krp != NULL)
   1212        1.1  jonathan 				krp->krp_callback(krp);
   1213        1.1  jonathan 			s  = splcrypto();
   1214        1.1  jonathan 		} else {
   1215        1.1  jonathan 			(void) tsleep(&crp_ret_q, PLOCK, "crypto_wait", 0);
   1216        1.1  jonathan 			cryptostats.cs_rets++;
   1217        1.1  jonathan 		}
   1218        1.1  jonathan 	}
   1219        1.1  jonathan }
   1220        1.1  jonathan 
   1221        1.1  jonathan 
   1223        1.1  jonathan #ifdef __FreeBSD__
   1224        1.1  jonathan /*
   1225        1.1  jonathan  * Initialization code, both for static and dynamic loading.
   1226        1.1  jonathan  */
   1227        1.1  jonathan static int
   1228        1.1  jonathan crypto_modevent(module_t mod, int type, void *unused)
   1229        1.1  jonathan {
   1230        1.1  jonathan 	int error = EINVAL;
   1231        1.1  jonathan 
   1232        1.1  jonathan 	switch (type) {
   1233        1.1  jonathan 	case MOD_LOAD:
   1234        1.1  jonathan 		error = crypto_init();
   1235        1.1  jonathan 		if (error == 0 && bootverbose)
   1236        1.1  jonathan 			printf("crypto: <crypto core>\n");
   1237        1.1  jonathan 		break;
   1238        1.1  jonathan 	case MOD_UNLOAD:
   1239        1.1  jonathan 		/*XXX disallow if active sessions */
   1240        1.1  jonathan 		error = 0;
   1241        1.1  jonathan 		crypto_destroy();
   1242        1.1  jonathan 		break;
   1243        1.1  jonathan 	}
   1244        1.1  jonathan 	return error;
   1245        1.1  jonathan }
   1246        1.1  jonathan static moduledata_t crypto_mod = {
   1247        1.1  jonathan 	"crypto",
   1248        1.1  jonathan 	crypto_modevent,
   1249        1.1  jonathan 	0
   1250        1.1  jonathan };
   1251        1.1  jonathan 
   1252        1.1  jonathan MODULE_VERSION(crypto, 1);
   1253        1.4       lha DECLARE_MODULE(crypto, crypto_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
   1254        1.1  jonathan #endif /* __FreeBSD__ */
   1255        1.1  jonathan 
   1256                      
   1257