This source file includes following definitions.
- crypto_newsession
- crypto_freesession
- crypto_get_driverid
- crypto_kregister
- crypto_register
- crypto_unregister
- crypto_dispatch
- crypto_kdispatch
- crypto_kinvoke
- crypto_invoke
- crypto_freereq
- crypto_getreq
- crypto_thread
- crypto_done
- crypto_kdone
- crypto_getfeat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/malloc.h>
26 #include <sys/proc.h>
27 #include <sys/pool.h>
28 #include <crypto/cryptodev.h>
29
30 struct cryptocap *crypto_drivers = NULL;
31 int crypto_drivers_num = 0;
32
33 struct pool cryptop_pool;
34 struct pool cryptodesc_pool;
35 int crypto_pool_initialized = 0;
36
37 struct cryptop *crp_req_queue = NULL;
38 struct cryptop **crp_req_queue_tail = NULL;
39
40 struct cryptkop *krp_req_queue = NULL;
41 struct cryptkop **krp_req_queue_tail = NULL;
42
43
44
45
46 int
47 crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
48 {
49 u_int32_t hid, lid, hid2 = -1;
50 struct cryptocap *cpc;
51 struct cryptoini *cr;
52 int err, s, turn = 0;
53
54 if (crypto_drivers == NULL)
55 return EINVAL;
56
57 s = splvm();
58
59
60
61
62
63
64
65
66
67
68
69 do {
70 for (hid = 0; hid < crypto_drivers_num; hid++) {
71 cpc = &crypto_drivers[hid];
72
73
74
75
76
77 if (cpc->cc_newsession == NULL ||
78 (cpc->cc_flags & CRYPTOCAP_F_CLEANUP))
79 continue;
80
81 if (cpc->cc_flags & CRYPTOCAP_F_SOFTWARE) {
82
83
84
85
86 if (turn == 0)
87 continue;
88 } else {
89
90 if (turn == 1)
91 continue;
92 }
93
94
95 for (cr = cri; cr; cr = cr->cri_next) {
96 if (cpc->cc_alg[cr->cri_alg] == 0)
97 break;
98 }
99
100
101
102
103
104 if (cr != NULL)
105 continue;
106
107
108
109
110
111
112 if (hid2 != -1) {
113
114
115
116
117
118
119 if (crypto_drivers[hid].cc_sessions <=
120 crypto_drivers[hid2].cc_sessions)
121 hid2 = hid;
122 } else {
123
124
125
126
127 hid2 = hid;
128 }
129 }
130
131
132
133
134
135
136 if (hid2 != -1)
137 break;
138
139 turn++;
140
141
142 } while (turn <= 2 && hard == 0);
143
144 hid = hid2;
145
146
147
148
149
150
151
152
153 if (hid == -1) {
154 splx(s);
155 return EINVAL;
156 }
157
158
159 lid = hid;
160 err = crypto_drivers[hid].cc_newsession(&lid, cri);
161 if (err == 0) {
162 (*sid) = hid;
163 (*sid) <<= 32;
164 (*sid) |= (lid & 0xffffffff);
165 crypto_drivers[hid].cc_sessions++;
166 }
167
168 splx(s);
169 return err;
170 }
171
172
173
174
175
176 int
177 crypto_freesession(u_int64_t sid)
178 {
179 int err = 0, s;
180 u_int32_t hid;
181
182 if (crypto_drivers == NULL)
183 return EINVAL;
184
185
186 hid = (sid >> 32) & 0xffffffff;
187
188 if (hid >= crypto_drivers_num)
189 return ENOENT;
190
191 s = splvm();
192
193 if (crypto_drivers[hid].cc_sessions)
194 crypto_drivers[hid].cc_sessions--;
195
196
197 if (crypto_drivers[hid].cc_freesession)
198 err = crypto_drivers[hid].cc_freesession(sid);
199
200
201
202
203
204 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) &&
205 crypto_drivers[hid].cc_sessions == 0)
206 bzero(&crypto_drivers[hid], sizeof(struct cryptocap));
207
208 splx(s);
209 return err;
210 }
211
212
213
214
215 int32_t
216 crypto_get_driverid(u_int8_t flags)
217 {
218 struct cryptocap *newdrv;
219 int i, s;
220
221 s = splvm();
222
223 if (crypto_drivers_num == 0) {
224 crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
225 crypto_drivers = malloc(crypto_drivers_num *
226 sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT);
227 if (crypto_drivers == NULL) {
228 crypto_drivers_num = 0;
229 splx(s);
230 return -1;
231 }
232
233 bzero(crypto_drivers, crypto_drivers_num *
234 sizeof(struct cryptocap));
235 }
236
237 for (i = 0; i < crypto_drivers_num; i++) {
238 if (crypto_drivers[i].cc_process == NULL &&
239 !(crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) &&
240 crypto_drivers[i].cc_sessions == 0) {
241 crypto_drivers[i].cc_sessions = 1;
242 crypto_drivers[i].cc_flags = flags;
243 splx(s);
244 return i;
245 }
246 }
247
248
249 if (i == crypto_drivers_num) {
250
251 if (2 * crypto_drivers_num <= crypto_drivers_num) {
252 splx(s);
253 return -1;
254 }
255
256 newdrv = malloc(2 * crypto_drivers_num *
257 sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT);
258 if (newdrv == NULL) {
259 splx(s);
260 return -1;
261 }
262
263 bcopy(crypto_drivers, newdrv,
264 crypto_drivers_num * sizeof(struct cryptocap));
265 bzero(&newdrv[crypto_drivers_num],
266 crypto_drivers_num * sizeof(struct cryptocap));
267
268 newdrv[i].cc_sessions = 1;
269 newdrv[i].cc_flags = flags;
270 crypto_drivers_num *= 2;
271
272 free(crypto_drivers, M_CRYPTO_DATA);
273 crypto_drivers = newdrv;
274 splx(s);
275 return i;
276 }
277
278
279 splx(s);
280 return -1;
281 }
282
283
284
285
286
287 int
288 crypto_kregister(u_int32_t driverid, int *kalg,
289 int (*kprocess)(struct cryptkop *))
290 {
291 int s, i;
292
293 if (driverid >= crypto_drivers_num || kalg == NULL ||
294 crypto_drivers == NULL)
295 return EINVAL;
296
297 s = splvm();
298
299 for (i = 0; i < CRK_ALGORITHM_MAX; i++) {
300
301
302
303
304
305
306 crypto_drivers[driverid].cc_kalg[i] = kalg[i];
307 }
308
309 crypto_drivers[driverid].cc_kprocess = kprocess;
310
311 splx(s);
312 return 0;
313 }
314
315
316 int
317 crypto_register(u_int32_t driverid, int *alg,
318 int (*newses)(u_int32_t *, struct cryptoini *),
319 int (*freeses)(u_int64_t), int (*process)(struct cryptop *))
320 {
321 int s, i;
322
323
324 if (driverid >= crypto_drivers_num || alg == NULL ||
325 crypto_drivers == NULL)
326 return EINVAL;
327
328 s = splvm();
329
330 for (i = 0; i < CRYPTO_ALGORITHM_ALL; i++) {
331
332
333
334
335
336
337 crypto_drivers[driverid].cc_alg[i] = alg[i];
338 }
339
340
341 crypto_drivers[driverid].cc_newsession = newses;
342 crypto_drivers[driverid].cc_process = process;
343 crypto_drivers[driverid].cc_freesession = freeses;
344 crypto_drivers[driverid].cc_sessions = 0;
345
346 splx(s);
347
348 return 0;
349 }
350
351
352
353
354
355
356
357 int
358 crypto_unregister(u_int32_t driverid, int alg)
359 {
360 int i = CRYPTO_ALGORITHM_MAX + 1, s;
361 u_int32_t ses;
362
363 s = splvm();
364
365
366 if (driverid >= crypto_drivers_num || crypto_drivers == NULL ||
367 ((alg <= 0 || alg > CRYPTO_ALGORITHM_MAX) &&
368 alg != CRYPTO_ALGORITHM_ALL) ||
369 crypto_drivers[driverid].cc_alg[alg] == 0) {
370 splx(s);
371 return EINVAL;
372 }
373
374 if (alg != CRYPTO_ALGORITHM_ALL) {
375 crypto_drivers[driverid].cc_alg[alg] = 0;
376
377
378 for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
379 if (crypto_drivers[driverid].cc_alg[i] != 0)
380 break;
381 }
382
383
384
385
386
387 if (i == CRYPTO_ALGORITHM_MAX + 1 || alg == CRYPTO_ALGORITHM_ALL) {
388 ses = crypto_drivers[driverid].cc_sessions;
389 bzero(&crypto_drivers[driverid], sizeof(struct cryptocap));
390 if (ses != 0) {
391
392
393
394 crypto_drivers[driverid].cc_flags |= CRYPTOCAP_F_CLEANUP;
395 crypto_drivers[driverid].cc_sessions = ses;
396 }
397 }
398 splx(s);
399 return 0;
400 }
401
402
403
404
405 int
406 crypto_dispatch(struct cryptop *crp)
407 {
408 int s;
409 u_int32_t hid;
410
411 s = splvm();
412
413
414
415
416
417 hid = (crp->crp_sid >> 32) & 0xffffffff;
418 if (hid < crypto_drivers_num)
419 crypto_drivers[hid].cc_queued++;
420
421 crp->crp_next = NULL;
422 if (crp_req_queue == NULL) {
423 crp_req_queue = crp;
424 crp_req_queue_tail = &(crp->crp_next);
425 splx(s);
426 wakeup(&crp_req_queue);
427 } else {
428 *crp_req_queue_tail = crp;
429 crp_req_queue_tail = &(crp->crp_next);
430 splx(s);
431 }
432 return 0;
433 }
434
435 int
436 crypto_kdispatch(struct cryptkop *krp)
437 {
438 int s;
439
440 s = splvm();
441
442 krp->krp_next = NULL;
443 if (krp_req_queue == NULL) {
444 krp_req_queue = krp;
445 krp_req_queue_tail = &(krp->krp_next);
446 splx(s);
447 wakeup(&crp_req_queue);
448 } else {
449 *krp_req_queue_tail = krp;
450 krp_req_queue_tail = &(krp->krp_next);
451 splx(s);
452 }
453 return 0;
454 }
455
456
457
458
459 int
460 crypto_kinvoke(struct cryptkop *krp)
461 {
462 extern int cryptodevallowsoft;
463 u_int32_t hid;
464 int error;
465
466
467 if (krp == NULL || krp->krp_callback == NULL)
468 return (EINVAL);
469
470 for (hid = 0; hid < crypto_drivers_num; hid++) {
471 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
472 cryptodevallowsoft == 0)
473 continue;
474 if (crypto_drivers[hid].cc_kprocess == NULL)
475 continue;
476 if ((crypto_drivers[hid].cc_kalg[krp->krp_op] &
477 CRYPTO_ALG_FLAG_SUPPORTED) == 0)
478 continue;
479 break;
480 }
481
482 if (hid == crypto_drivers_num) {
483 krp->krp_status = ENODEV;
484 crypto_kdone(krp);
485 return (0);
486 }
487
488 krp->krp_hid = hid;
489
490 crypto_drivers[hid].cc_koperations++;
491
492 error = crypto_drivers[hid].cc_kprocess(krp);
493 if (error) {
494 krp->krp_status = error;
495 crypto_kdone(krp);
496 }
497 return (0);
498 }
499
500
501
502
503 int
504 crypto_invoke(struct cryptop *crp)
505 {
506 struct cryptodesc *crd;
507 u_int64_t nid;
508 u_int32_t hid;
509 int error;
510
511
512 if (crp == NULL || crp->crp_callback == NULL)
513 return EINVAL;
514
515 if (crp->crp_desc == NULL || crypto_drivers == NULL) {
516 crp->crp_etype = EINVAL;
517 crypto_done(crp);
518 return 0;
519 }
520
521 hid = (crp->crp_sid >> 32) & 0xffffffff;
522 if (hid >= crypto_drivers_num)
523 goto migrate;
524
525 crypto_drivers[hid].cc_queued--;
526
527 if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) {
528 crypto_freesession(crp->crp_sid);
529 goto migrate;
530 }
531
532 if (crypto_drivers[hid].cc_process == NULL)
533 goto migrate;
534
535 crypto_drivers[hid].cc_operations++;
536 crypto_drivers[hid].cc_bytes += crp->crp_ilen;
537
538 error = crypto_drivers[hid].cc_process(crp);
539 if (error) {
540 if (error == ERESTART) {
541
542 crypto_unregister(hid, CRYPTO_ALGORITHM_ALL);
543 goto migrate;
544 } else {
545 crp->crp_etype = error;
546 crypto_done(crp);
547 }
548 }
549
550 return 0;
551
552 migrate:
553
554 for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
555 crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
556
557 if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
558 crp->crp_sid = nid;
559
560 crp->crp_etype = EAGAIN;
561 crypto_done(crp);
562 return 0;
563 }
564
565
566
567
568 void
569 crypto_freereq(struct cryptop *crp)
570 {
571 struct cryptodesc *crd;
572 int s;
573
574 if (crp == NULL)
575 return;
576
577 s = splvm();
578
579 while ((crd = crp->crp_desc) != NULL) {
580 crp->crp_desc = crd->crd_next;
581 pool_put(&cryptodesc_pool, crd);
582 }
583
584 pool_put(&cryptop_pool, crp);
585 splx(s);
586 }
587
588
589
590
591 struct cryptop *
592 crypto_getreq(int num)
593 {
594 struct cryptodesc *crd;
595 struct cryptop *crp;
596 int s;
597
598 s = splvm();
599
600 if (crypto_pool_initialized == 0) {
601 pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,
602 0, "cryptop", NULL);
603 pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0,
604 0, "cryptodesc", NULL);
605 crypto_pool_initialized = 1;
606 }
607
608 crp = pool_get(&cryptop_pool, PR_NOWAIT);
609 if (crp == NULL) {
610 splx(s);
611 return NULL;
612 }
613 bzero(crp, sizeof(struct cryptop));
614
615 while (num--) {
616 crd = pool_get(&cryptodesc_pool, PR_NOWAIT);
617 if (crd == NULL) {
618 splx(s);
619 crypto_freereq(crp);
620 return NULL;
621 }
622
623 bzero(crd, sizeof(struct cryptodesc));
624 crd->crd_next = crp->crp_desc;
625 crp->crp_desc = crd;
626 }
627
628 splx(s);
629 return crp;
630 }
631
632
633
634
635 void
636 crypto_thread(void)
637 {
638 struct cryptop *crp;
639 struct cryptkop *krp;
640 int s;
641
642 s = splvm();
643
644 for (;;) {
645 crp = crp_req_queue;
646 krp = krp_req_queue;
647 if (crp == NULL && krp == NULL) {
648 (void)tsleep(&crp_req_queue, PLOCK, "crypto_wait", 0);
649 continue;
650 }
651
652 if (crp) {
653
654 crp_req_queue = crp->crp_next;
655 crypto_invoke(crp);
656 }
657 if (krp) {
658
659 krp_req_queue = krp->krp_next;
660 crypto_kinvoke(krp);
661 }
662 }
663 }
664
665
666
667
668 void
669 crypto_done(struct cryptop *crp)
670 {
671 crp->crp_flags |= CRYPTO_F_DONE;
672 crp->crp_callback(crp);
673 }
674
675
676
677
678 void
679 crypto_kdone(struct cryptkop *krp)
680 {
681 krp->krp_callback(krp);
682 }
683
684 int
685 crypto_getfeat(int *featp)
686 {
687 extern int cryptodevallowsoft, userasymcrypto;
688 int hid, kalg, feat = 0;
689
690 if (userasymcrypto == 0)
691 goto out;
692 for (hid = 0; hid < crypto_drivers_num; hid++) {
693 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
694 cryptodevallowsoft == 0) {
695 continue;
696 }
697 if (crypto_drivers[hid].cc_kprocess == NULL)
698 continue;
699 for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
700 if ((crypto_drivers[hid].cc_kalg[kalg] &
701 CRYPTO_ALG_FLAG_SUPPORTED) != 0)
702 feat |= 1 << kalg;
703 }
704 out:
705 *featp = feat;
706 return (0);
707 }