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