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