| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: crypto.c,v 1.87 2017/06/14 07:32:19 knakahara Exp $ */ | | 1 | /* $NetBSD: crypto.c,v 1.88 2017/06/14 07:36:24 knakahara Exp $ */ |
2 | /* $FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.5 2003/02/26 00:14:05 sam 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 $ */ | | 3 | /* $OpenBSD: crypto.c,v 1.41 2002/07/17 23:52:38 art Exp $ */ |
4 | | | 4 | |
5 | /*- | | 5 | /*- |
6 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 6 | * Copyright (c) 2008 The NetBSD Foundation, Inc. |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * This code is derived from software contributed to The NetBSD Foundation | | 9 | * This code is derived from software contributed to The NetBSD Foundation |
10 | * by Coyote Point Systems, Inc. | | 10 | * by Coyote Point Systems, Inc. |
11 | * | | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | | 14 | * are met: |
| @@ -43,27 +43,27 @@ | | | @@ -43,27 +43,27 @@ |
43 | * Permission to use, copy, and modify this software with or without fee | | 43 | * Permission to use, copy, and modify this software with or without fee |
44 | * is hereby granted, provided that this entire notice is included in | | 44 | * is hereby granted, provided that this entire notice is included in |
45 | * all source code copies of any software which is or includes a copy or | | 45 | * all source code copies of any software which is or includes a copy or |
46 | * modification of this software. | | 46 | * modification of this software. |
47 | * | | 47 | * |
48 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR | | 48 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR |
49 | * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY | | 49 | * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY |
50 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE | | 50 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE |
51 | * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR | | 51 | * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR |
52 | * PURPOSE. | | 52 | * PURPOSE. |
53 | */ | | 53 | */ |
54 | | | 54 | |
55 | #include <sys/cdefs.h> | | 55 | #include <sys/cdefs.h> |
56 | __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.87 2017/06/14 07:32:19 knakahara Exp $"); | | 56 | __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.88 2017/06/14 07:36:24 knakahara Exp $"); |
57 | | | 57 | |
58 | #include <sys/param.h> | | 58 | #include <sys/param.h> |
59 | #include <sys/reboot.h> | | 59 | #include <sys/reboot.h> |
60 | #include <sys/systm.h> | | 60 | #include <sys/systm.h> |
61 | #include <sys/malloc.h> | | 61 | #include <sys/malloc.h> |
62 | #include <sys/proc.h> | | 62 | #include <sys/proc.h> |
63 | #include <sys/pool.h> | | 63 | #include <sys/pool.h> |
64 | #include <sys/kthread.h> | | 64 | #include <sys/kthread.h> |
65 | #include <sys/once.h> | | 65 | #include <sys/once.h> |
66 | #include <sys/sysctl.h> | | 66 | #include <sys/sysctl.h> |
67 | #include <sys/intr.h> | | 67 | #include <sys/intr.h> |
68 | #include <sys/errno.h> | | 68 | #include <sys/errno.h> |
69 | #include <sys/module.h> | | 69 | #include <sys/module.h> |
| @@ -491,49 +491,54 @@ crypto_destroy(bool exit_kthread) | | | @@ -491,49 +491,54 @@ crypto_destroy(bool exit_kthread) |
491 | pool_destroy(&cryptop_pool); | | 491 | pool_destroy(&cryptop_pool); |
492 | pool_destroy(&cryptodesc_pool); | | 492 | pool_destroy(&cryptodesc_pool); |
493 | pool_destroy(&cryptkop_pool); | | 493 | pool_destroy(&cryptkop_pool); |
494 | | | 494 | |
495 | cv_destroy(&cryptoret_cv); | | 495 | cv_destroy(&cryptoret_cv); |
496 | | | 496 | |
497 | mutex_destroy(&crypto_ret_q_mtx); | | 497 | mutex_destroy(&crypto_ret_q_mtx); |
498 | mutex_destroy(&crypto_q_mtx); | | 498 | mutex_destroy(&crypto_q_mtx); |
499 | mutex_destroy(&crypto_drv_mtx); | | 499 | mutex_destroy(&crypto_drv_mtx); |
500 | | | 500 | |
501 | return 0; | | 501 | return 0; |
502 | } | | 502 | } |
503 | | | 503 | |
504 | /* | | 504 | static bool |
505 | * Create a new session. | | 505 | crypto_driver_suitable(struct cryptocap *cap, struct cryptoini *cri) |
506 | */ | | | |
507 | int | | | |
508 | crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard) | | | |
509 | { | | 506 | { |
510 | struct cryptoini *cr; | | 507 | struct cryptoini *cr; |
511 | struct cryptocap *cap; | | | |
512 | u_int32_t hid, lid; | | | |
513 | int err = EINVAL; | | | |
514 | | | 508 | |
515 | mutex_enter(&crypto_drv_mtx); | | 509 | for (cr = cri; cr; cr = cr->cri_next) |
| | | 510 | if (cap->cc_alg[cr->cri_alg] == 0) { |
| | | 511 | DPRINTF("alg %d not supported\n", cr->cri_alg); |
| | | 512 | return false; |
| | | 513 | } |
516 | | | 514 | |
517 | /* | | 515 | return true; |
518 | * The algorithm we use here is pretty stupid; just use the | | 516 | } |
519 | * first driver that supports all the algorithms we need. | | 517 | |
520 | * | | 518 | /* |
521 | * XXX We need more smarts here (in real life too, but that's | | 519 | * The algorithm we use here is pretty stupid; just use the |
522 | * XXX another story altogether). | | 520 | * first driver that supports all the algorithms we need. |
523 | */ | | 521 | * |
| | | 522 | * XXX We need more smarts here (in real life too, but that's |
| | | 523 | * XXX another story altogether). |
| | | 524 | */ |
| | | 525 | static struct cryptocap * |
| | | 526 | crypto_select_driver_lock(struct cryptoini *cri, int hard) |
| | | 527 | { |
| | | 528 | u_int32_t hid; |
524 | | | 529 | |
525 | for (hid = 0; hid < crypto_drivers_num; hid++) { | | 530 | for (hid = 0; hid < crypto_drivers_num; hid++) { |
526 | cap = crypto_checkdriver(hid); | | 531 | struct cryptocap *cap = crypto_checkdriver(hid); |
527 | if (cap == NULL) | | 532 | if (cap == NULL) |
528 | continue; | | 533 | continue; |
529 | | | 534 | |
530 | crypto_driver_lock(cap); | | 535 | crypto_driver_lock(cap); |
531 | | | 536 | |
532 | /* | | 537 | /* |
533 | * If it's not initialized or has remaining sessions | | 538 | * If it's not initialized or has remaining sessions |
534 | * referencing it, skip. | | 539 | * referencing it, skip. |
535 | */ | | 540 | */ |
536 | if (cap->cc_newsession == NULL || | | 541 | if (cap->cc_newsession == NULL || |
537 | (cap->cc_flags & CRYPTOCAP_F_CLEANUP)) { | | 542 | (cap->cc_flags & CRYPTOCAP_F_CLEANUP)) { |
538 | crypto_driver_unlock(cap); | | 543 | crypto_driver_unlock(cap); |
539 | continue; | | 544 | continue; |
| @@ -541,65 +546,79 @@ crypto_newsession(u_int64_t *sid, struct | | | @@ -541,65 +546,79 @@ crypto_newsession(u_int64_t *sid, struct |
541 | | | 546 | |
542 | /* Hardware required -- ignore software drivers. */ | | 547 | /* Hardware required -- ignore software drivers. */ |
543 | if (hard > 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE)) { | | 548 | if (hard > 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE)) { |
544 | crypto_driver_unlock(cap); | | 549 | crypto_driver_unlock(cap); |
545 | continue; | | 550 | continue; |
546 | } | | 551 | } |
547 | /* Software required -- ignore hardware drivers. */ | | 552 | /* Software required -- ignore hardware drivers. */ |
548 | if (hard < 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0) { | | 553 | if (hard < 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0) { |
549 | crypto_driver_unlock(cap); | | 554 | crypto_driver_unlock(cap); |
550 | continue; | | 555 | continue; |
551 | } | | 556 | } |
552 | | | 557 | |
553 | /* See if all the algorithms are supported. */ | | 558 | /* See if all the algorithms are supported. */ |
554 | for (cr = cri; cr; cr = cr->cri_next) | | 559 | if (crypto_driver_suitable(cap, cri)) { |
555 | if (cap->cc_alg[cr->cri_alg] == 0) { | | 560 | /* keep holding crypto_driver_lock(cap) */ |
556 | DPRINTF("alg %d not supported\n", cr->cri_alg); | | 561 | return cap; |
557 | break; | | 562 | } |
558 | } | | | |
559 | | | 563 | |
560 | if (cr == NULL) { | | 564 | crypto_driver_unlock(cap); |
561 | /* Ok, all algorithms are supported. */ | | 565 | } |
562 | | | 566 | |
563 | /* | | 567 | return NULL; |
564 | * Can't do everything in one session. | | 568 | } |
565 | * | | | |
566 | * XXX Fix this. We need to inject a "virtual" session layer right | | | |
567 | * XXX about here. | | | |
568 | */ | | | |
569 | | | 569 | |
570 | /* Call the driver initialization routine. */ | | 570 | /* |
571 | lid = hid; /* Pass the driver ID. */ | | 571 | * Create a new session. |
572 | crypto_driver_unlock(cap); | | 572 | */ |
573 | err = cap->cc_newsession(cap->cc_arg, &lid, cri); | | 573 | int |
574 | crypto_driver_lock(cap); | | 574 | crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard) |
575 | if (err == 0) { | | 575 | { |
576 | (*sid) = hid; | | 576 | struct cryptocap *cap; |
577 | (*sid) <<= 32; | | 577 | int err = EINVAL; |
578 | (*sid) |= (lid & 0xffffffff); | | | |
579 | (cap->cc_sessions)++; | | | |
580 | } else { | | | |
581 | DPRINTF("crypto_drivers[%d].cc_newsession() failed. error=%d\n", | | | |
582 | hid, err); | | | |
583 | } | | | |
584 | crypto_driver_unlock(cap); | | | |
585 | goto done; | | | |
586 | /*break;*/ | | | |
587 | } | | | |
588 | | | 578 | |
| | | 579 | mutex_enter(&crypto_drv_mtx); |
| | | 580 | |
| | | 581 | cap = crypto_select_driver_lock(cri, hard); |
| | | 582 | if (cap != NULL) { |
| | | 583 | u_int32_t hid, lid; |
| | | 584 | |
| | | 585 | hid = cap - crypto_drivers; |
| | | 586 | /* |
| | | 587 | * Can't do everything in one session. |
| | | 588 | * |
| | | 589 | * XXX Fix this. We need to inject a "virtual" session layer right |
| | | 590 | * XXX about here. |
| | | 591 | */ |
| | | 592 | |
| | | 593 | /* Call the driver initialization routine. */ |
| | | 594 | lid = hid; /* Pass the driver ID. */ |
| | | 595 | crypto_driver_unlock(cap); |
| | | 596 | err = cap->cc_newsession(cap->cc_arg, &lid, cri); |
| | | 597 | crypto_driver_lock(cap); |
| | | 598 | if (err == 0) { |
| | | 599 | (*sid) = hid; |
| | | 600 | (*sid) <<= 32; |
| | | 601 | (*sid) |= (lid & 0xffffffff); |
| | | 602 | (cap->cc_sessions)++; |
| | | 603 | } else { |
| | | 604 | DPRINTF("crypto_drivers[%d].cc_newsession() failed. error=%d\n", |
| | | 605 | hid, err); |
| | | 606 | } |
589 | crypto_driver_unlock(cap); | | 607 | crypto_driver_unlock(cap); |
590 | } | | 608 | } |
591 | done: | | 609 | |
592 | mutex_exit(&crypto_drv_mtx); | | 610 | mutex_exit(&crypto_drv_mtx); |
| | | 611 | |
593 | return err; | | 612 | return err; |
594 | } | | 613 | } |
595 | | | 614 | |
596 | /* | | 615 | /* |
597 | * Delete an existing session (or a reserved session on an unregistered | | 616 | * Delete an existing session (or a reserved session on an unregistered |
598 | * driver). | | 617 | * driver). |
599 | */ | | 618 | */ |
600 | int | | 619 | int |
601 | crypto_freesession(u_int64_t sid) | | 620 | crypto_freesession(u_int64_t sid) |
602 | { | | 621 | { |
603 | struct cryptocap *cap; | | 622 | struct cryptocap *cap; |
604 | int err = 0; | | 623 | int err = 0; |
605 | | | 624 | |