Wed Jun 14 07:36:24 2017 UTC ()
refactor crypto_newsession() like FreeBSD.


(knakahara)
diff -r1.87 -r1.88 src/sys/opencrypto/crypto.c

cvs diff -r1.87 -r1.88 src/sys/opencrypto/crypto.c (expand / switch to unified diff)

--- src/sys/opencrypto/crypto.c 2017/06/14 07:32:19 1.87
+++ src/sys/opencrypto/crypto.c 2017/06/14 07:36:24 1.88
@@ -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/* 504static bool
505 * Create a new session. 505crypto_driver_suitable(struct cryptocap *cap, struct cryptoini *cri)
506 */ 
507int 
508crypto_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 */
 525static struct cryptocap *
 526crypto_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); 573int
574 crypto_driver_lock(cap); 574crypto_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 }
591done: 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 */
600int 619int
601crypto_freesession(u_int64_t sid) 620crypto_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