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