1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*
  30  * Core KCF (Kernel Cryptographic Framework). This file implements
  31  * the loadable module entry points and module verification routines.
  32  */
  33 
  34 #include <sys/systm.h>
  35 #include <sys/cmn_err.h>
  36 #include <sys/ddi.h>
  37 #include <sys/sunddi.h>
  38 #include <sys/modctl.h>
  39 #include <sys/errno.h>
  40 #include <sys/rwlock.h>
  41 #include <sys/kmem.h>
  42 #include <sys/door.h>
  43 #include <sys/kobj.h>
  44 
  45 #include <sys/crypto/common.h>
  46 #include <sys/crypto/api.h>
  47 #include <sys/crypto/spi.h>
  48 #include <sys/crypto/impl.h>
  49 #include <sys/crypto/sched_impl.h>
  50 #include <sys/crypto/elfsign.h>
  51 #include <sys/crypto/ioctladmin.h>
  52 
  53 #ifdef DEBUG
  54 int kcf_frmwrk_debug = 0;
  55 
  56 #define KCF_FRMWRK_DEBUG(l, x)  if (kcf_frmwrk_debug >= l) printf x
  57 #else   /* DEBUG */
  58 #define KCF_FRMWRK_DEBUG(l, x)
  59 #endif  /* DEBUG */
  60 
  61 static struct modlmisc modlmisc = {
  62         &mod_miscops, "Kernel Crypto Framework"
  63 };
  64 
  65 static struct modlinkage modlinkage = {
  66         MODREV_1, { (void *)&modlmisc, NULL }
  67 };
  68 
  69 extern int sys_shutdown;
  70 
  71 int
  72 _init()
  73 {
  74         /* initialize the mechanisms tables supported out-of-the-box */
  75         kcf_init_mech_tabs();
  76 
  77         /* initialize the providers tables */
  78         kcf_prov_tab_init();
  79 
  80         /* initialize the policy table */
  81         kcf_policy_tab_init();
  82 
  83         /* initialize soft_config_list */
  84         kcf_soft_config_init();
  85 
  86         /*
  87          * Initialize scheduling structures. Note that this does NOT
  88          * start any threads since it might not be safe to do so.
  89          */
  90         kcf_sched_init();
  91 
  92         /* initialize the RNG support structures */
  93         kcf_rnd_init();
  94 
  95         return (mod_install(&modlinkage));
  96 }
  97 
  98 int
  99 _info(struct modinfo *modinfop)
 100 {
 101         return (mod_info(&modlinkage, modinfop));
 102 }
 103 
 104 /*
 105  * We do not allow kcf to unload.
 106  */
 107 int
 108 _fini(void)
 109 {
 110         return (EBUSY);
 111 }
 112 
 113 
 114 /*
 115  * Return a pointer to the modctl structure of the
 116  * provider's module.
 117  */
 118 struct modctl *
 119 kcf_get_modctl(crypto_provider_info_t *pinfo)
 120 {
 121         struct modctl *mctlp;
 122 
 123         /* Get the modctl struct for this module */
 124         if (pinfo->pi_provider_type == CRYPTO_SW_PROVIDER)
 125                 mctlp = mod_getctl(pinfo->pi_provider_dev.pd_sw);
 126         else {
 127                 major_t major;
 128                 char *drvmod;
 129 
 130                 if ((major = ddi_driver_major(pinfo->pi_provider_dev.pd_hw))
 131                     != DDI_MAJOR_T_NONE) {
 132                         drvmod = ddi_major_to_name(major);
 133                         mctlp = mod_find_by_filename("drv", drvmod);
 134                 } else
 135                         return (NULL);
 136         }
 137 
 138         return (mctlp);
 139 }