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