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 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * This file is part of the core Kernel Cryptographic Framework.
30 * It implements the management of tables of Providers. Entries to
31 * added and removed when cryptographic providers register with
32 * and unregister from the framework, respectively. The KCF scheduler
33 * and ioctl pseudo driver call this function to obtain the list
34 * of available providers.
35 *
36 * The provider table is indexed by crypto_provider_id_t. Each
37 * element of the table contains a pointer to a provider descriptor,
38 * or NULL if the entry is free.
39 *
40 * This file also implements helper functions to allocate and free
41 * provider descriptors.
42 */
43
44 #include <sys/types.h>
45 #include <sys/kmem.h>
46 #include <sys/cmn_err.h>
47 #include <sys/ddi.h>
48 #include <sys/sunddi.h>
49 #include <sys/ksynch.h>
50 #include <sys/crypto/common.h>
51 #include <sys/crypto/impl.h>
52 #include <sys/crypto/sched_impl.h>
53 #include <sys/crypto/spi.h>
54
55 #define KCF_MAX_PROVIDERS 512 /* max number of providers */
56
57 static kmutex_t prov_tab_mutex; /* ensure exclusive access to the table */
58 static kcf_provider_desc_t **prov_tab = NULL;
59 static uint_t prov_tab_num = 0; /* number of providers in table */
60 static uint_t prov_tab_max = KCF_MAX_PROVIDERS;
61
62 #if DEBUG
63 extern int kcf_frmwrk_debug;
64 static void kcf_prov_tab_dump(void);
65 #endif /* DEBUG */
66
67 /*
68 * Initialize the providers table. The providers table is dynamically
69 * allocated with prov_tab_max entries.
70 */
71 void
72 kcf_prov_tab_init(void)
73 {
74 mutex_init(&prov_tab_mutex, NULL, MUTEX_DRIVER, NULL);
75
76 prov_tab = kmem_zalloc(prov_tab_max * sizeof (kcf_provider_desc_t *),
77 KM_SLEEP);
78 }
79
80 /*
81 * Add a provider to the provider table. If no free entry can be found
82 * for the new provider, returns CRYPTO_HOST_MEMORY. Otherwise, add
83 * the provider to the table, initialize the pd_prov_id field
84 * of the specified provider descriptor to the index in that table,
85 * and return CRYPTO_SUCCESS. Note that a REFHOLD is done on the
86 * provider when pointed to by a table entry.
87 */
88 int
89 kcf_prov_tab_add_provider(kcf_provider_desc_t *prov_desc)
107 /* initialize entry */
108 prov_tab[i] = prov_desc;
109 KCF_PROV_REFHOLD(prov_desc);
110 KCF_PROV_IREFHOLD(prov_desc);
111 prov_tab_num++;
112
113 mutex_exit(&prov_tab_mutex);
114
115 /* update provider descriptor */
116 prov_desc->pd_prov_id = i;
117
118 /*
119 * The KCF-private provider handle is defined as the internal
120 * provider id.
121 */
122 prov_desc->pd_kcf_prov_handle =
123 (crypto_kcf_provider_handle_t)prov_desc->pd_prov_id;
124
125 #if DEBUG
126 if (kcf_frmwrk_debug >= 1)
127 kcf_prov_tab_dump();
128 #endif /* DEBUG */
129
130 return (CRYPTO_SUCCESS);
131 }
132
133 /*
134 * Remove the provider specified by its id. A REFRELE is done on the
135 * corresponding provider descriptor before this function returns.
136 * Returns CRYPTO_UNKNOWN_PROVIDER if the provider id is not valid.
137 */
138 int
139 kcf_prov_tab_rem_provider(crypto_provider_id_t prov_id)
140 {
141 kcf_provider_desc_t *prov_desc;
142
143 ASSERT(prov_tab != NULL);
144 ASSERT(prov_tab_num >= 0);
145
146 /*
147 * Validate provider id, since it can be specified by a 3rd-party
153 ((prov_desc = prov_tab[prov_id]) == NULL)) {
154 mutex_exit(&prov_tab_mutex);
155 return (CRYPTO_INVALID_PROVIDER_ID);
156 }
157 mutex_exit(&prov_tab_mutex);
158
159 /*
160 * The provider id must remain valid until the associated provider
161 * descriptor is freed. For this reason, we simply release our
162 * reference to the descriptor here. When the reference count
163 * reaches zero, kcf_free_provider_desc() will be invoked and
164 * the associated entry in the providers table will be released
165 * at that time.
166 */
167
168 KCF_PROV_REFRELE(prov_desc);
169 KCF_PROV_IREFRELE(prov_desc);
170
171 #if DEBUG
172 if (kcf_frmwrk_debug >= 1)
173 kcf_prov_tab_dump();
174 #endif /* DEBUG */
175
176 return (CRYPTO_SUCCESS);
177 }
178
179 /*
180 * Returns the provider descriptor corresponding to the specified
181 * provider id. A REFHOLD is done on the descriptor before it is
182 * returned to the caller. It is the responsibility of the caller
183 * to do a REFRELE once it is done with the provider descriptor.
184 */
185 kcf_provider_desc_t *
186 kcf_prov_tab_lookup(crypto_provider_id_t prov_id)
187 {
188 kcf_provider_desc_t *prov_desc;
189
190 mutex_enter(&prov_tab_mutex);
191
192 prov_desc = prov_tab[prov_id];
193
800 if (me->me_sw_prov == NULL ||
801 (*pd = me->me_sw_prov->pm_prov_desc) == NULL) {
802 /* no SW provider for this mechanism */
803 if (log_warn)
804 cmn_err(CE_WARN, "no SW provider for \"%s\"\n",
805 me->me_name);
806 mutex_exit(&me->me_mutex);
807 return (CRYPTO_MECH_NOT_SUPPORTED);
808 }
809
810 KCF_PROV_REFHOLD(*pd);
811 mutex_exit(&me->me_mutex);
812
813 if (mep != NULL)
814 *mep = me;
815
816 return (CRYPTO_SUCCESS);
817 }
818
819 #if DEBUG
820
821 static void
822 kcf_prov_tab_dump(void)
823 {
824 uint_t i;
825
826 mutex_enter(&prov_tab_mutex);
827
828 printf("Providers table:\n");
829 for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
830 if (prov_tab[i] != NULL) {
831 printf("[%d]: (%s) %s\n",
832 i, (prov_tab[i]->pd_prov_type ==
833 CRYPTO_HW_PROVIDER) ? "HW" : "SW",
834 prov_tab[i]->pd_description);
835 }
836 }
837 printf("(end of providers table)\n");
838
839 mutex_exit(&prov_tab_mutex);
840 }
841
842 #endif /* DEBUG */
843
844 /*
845 * This function goes through the provider table and verifies
846 * any unverified providers.
847 *
848 * This is called when kcfd is up and the door handle is ready.
849 */
850 void
851 verify_unverified_providers()
852 {
853 int i;
854 kcf_provider_desc_t *pd;
855 boolean_t need_verify;
856
|
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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * This file is part of the core Kernel Cryptographic Framework.
28 * It implements the management of tables of Providers. Entries to
29 * added and removed when cryptographic providers register with
30 * and unregister from the framework, respectively. The KCF scheduler
31 * and ioctl pseudo driver call this function to obtain the list
32 * of available providers.
33 *
34 * The provider table is indexed by crypto_provider_id_t. Each
35 * element of the table contains a pointer to a provider descriptor,
36 * or NULL if the entry is free.
37 *
38 * This file also implements helper functions to allocate and free
39 * provider descriptors.
40 */
41
42 #include <sys/types.h>
43 #include <sys/kmem.h>
44 #include <sys/cmn_err.h>
45 #include <sys/ddi.h>
46 #include <sys/sunddi.h>
47 #include <sys/ksynch.h>
48 #include <sys/crypto/common.h>
49 #include <sys/crypto/impl.h>
50 #include <sys/crypto/sched_impl.h>
51 #include <sys/crypto/spi.h>
52
53 #define KCF_MAX_PROVIDERS 512 /* max number of providers */
54
55 /*
56 * Prov_tab is an array of providers which is updated when
57 * a crypto provider registers with kcf. The provider calls the
58 * SPI routine, crypto_register_provider(), which in turn calls
59 * kcf_prov_tab_add_provider().
60 *
61 * A provider unregisters by calling crypto_unregister_provider()
62 * which triggers the removal of the prov_tab entry.
63 * It also calls kcf_remove_mech_provider().
64 *
65 * prov_tab entries are not updated from kcf.conf or by cryptoadm(1M).
66 */
67 static kcf_provider_desc_t **prov_tab = NULL;
68 static kmutex_t prov_tab_mutex; /* ensure exclusive access to the table */
69 static uint_t prov_tab_num = 0; /* number of providers in table */
70 static uint_t prov_tab_max = KCF_MAX_PROVIDERS;
71
72 #if DEBUG
73 extern int kcf_frmwrk_debug;
74 static void kcf_prov_tab_dump(char *message);
75 #endif /* DEBUG */
76
77
78 /*
79 * Initialize a mutex and the KCF providers table, prov_tab.
80 * The providers table is dynamically allocated with prov_tab_max entries.
81 * Called from kcf module _init().
82 */
83 void
84 kcf_prov_tab_init(void)
85 {
86 mutex_init(&prov_tab_mutex, NULL, MUTEX_DRIVER, NULL);
87
88 prov_tab = kmem_zalloc(prov_tab_max * sizeof (kcf_provider_desc_t *),
89 KM_SLEEP);
90 }
91
92 /*
93 * Add a provider to the provider table. If no free entry can be found
94 * for the new provider, returns CRYPTO_HOST_MEMORY. Otherwise, add
95 * the provider to the table, initialize the pd_prov_id field
96 * of the specified provider descriptor to the index in that table,
97 * and return CRYPTO_SUCCESS. Note that a REFHOLD is done on the
98 * provider when pointed to by a table entry.
99 */
100 int
101 kcf_prov_tab_add_provider(kcf_provider_desc_t *prov_desc)
119 /* initialize entry */
120 prov_tab[i] = prov_desc;
121 KCF_PROV_REFHOLD(prov_desc);
122 KCF_PROV_IREFHOLD(prov_desc);
123 prov_tab_num++;
124
125 mutex_exit(&prov_tab_mutex);
126
127 /* update provider descriptor */
128 prov_desc->pd_prov_id = i;
129
130 /*
131 * The KCF-private provider handle is defined as the internal
132 * provider id.
133 */
134 prov_desc->pd_kcf_prov_handle =
135 (crypto_kcf_provider_handle_t)prov_desc->pd_prov_id;
136
137 #if DEBUG
138 if (kcf_frmwrk_debug >= 1)
139 kcf_prov_tab_dump("kcf_prov_tab_add_provider");
140 #endif /* DEBUG */
141
142 return (CRYPTO_SUCCESS);
143 }
144
145 /*
146 * Remove the provider specified by its id. A REFRELE is done on the
147 * corresponding provider descriptor before this function returns.
148 * Returns CRYPTO_UNKNOWN_PROVIDER if the provider id is not valid.
149 */
150 int
151 kcf_prov_tab_rem_provider(crypto_provider_id_t prov_id)
152 {
153 kcf_provider_desc_t *prov_desc;
154
155 ASSERT(prov_tab != NULL);
156 ASSERT(prov_tab_num >= 0);
157
158 /*
159 * Validate provider id, since it can be specified by a 3rd-party
165 ((prov_desc = prov_tab[prov_id]) == NULL)) {
166 mutex_exit(&prov_tab_mutex);
167 return (CRYPTO_INVALID_PROVIDER_ID);
168 }
169 mutex_exit(&prov_tab_mutex);
170
171 /*
172 * The provider id must remain valid until the associated provider
173 * descriptor is freed. For this reason, we simply release our
174 * reference to the descriptor here. When the reference count
175 * reaches zero, kcf_free_provider_desc() will be invoked and
176 * the associated entry in the providers table will be released
177 * at that time.
178 */
179
180 KCF_PROV_REFRELE(prov_desc);
181 KCF_PROV_IREFRELE(prov_desc);
182
183 #if DEBUG
184 if (kcf_frmwrk_debug >= 1)
185 kcf_prov_tab_dump("kcf_prov_tab_rem_provider");
186 #endif /* DEBUG */
187
188 return (CRYPTO_SUCCESS);
189 }
190
191 /*
192 * Returns the provider descriptor corresponding to the specified
193 * provider id. A REFHOLD is done on the descriptor before it is
194 * returned to the caller. It is the responsibility of the caller
195 * to do a REFRELE once it is done with the provider descriptor.
196 */
197 kcf_provider_desc_t *
198 kcf_prov_tab_lookup(crypto_provider_id_t prov_id)
199 {
200 kcf_provider_desc_t *prov_desc;
201
202 mutex_enter(&prov_tab_mutex);
203
204 prov_desc = prov_tab[prov_id];
205
812 if (me->me_sw_prov == NULL ||
813 (*pd = me->me_sw_prov->pm_prov_desc) == NULL) {
814 /* no SW provider for this mechanism */
815 if (log_warn)
816 cmn_err(CE_WARN, "no SW provider for \"%s\"\n",
817 me->me_name);
818 mutex_exit(&me->me_mutex);
819 return (CRYPTO_MECH_NOT_SUPPORTED);
820 }
821
822 KCF_PROV_REFHOLD(*pd);
823 mutex_exit(&me->me_mutex);
824
825 if (mep != NULL)
826 *mep = me;
827
828 return (CRYPTO_SUCCESS);
829 }
830
831 #if DEBUG
832 /*
833 * Dump the Kernel crypto providers table, prov_tab.
834 * If kcf_frmwrk_debug is >=2, also dump the mechanism lists.
835 */
836 static void
837 kcf_prov_tab_dump(char *message)
838 {
839 uint_t i, j;
840
841 mutex_enter(&prov_tab_mutex);
842 printf("Providers table prov_tab at %s:\n",
843 message != NULL ? message : "");
844
845 for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
846 kcf_provider_desc_t *p = prov_tab[i];
847 if (p != NULL) {
848 printf("[%d]: (%s) %d mechanisms, %s\n", i,
849 (p->pd_prov_type == CRYPTO_HW_PROVIDER) ?
850 "HW" : "SW",
851 p->pd_mech_list_count, p->pd_description);
852 if (kcf_frmwrk_debug >= 2) {
853 printf("\tpd_mechanisms: ");
854 for (j = 0; j < p->pd_mech_list_count; ++j) {
855 printf("%s \n",
856 p->pd_mechanisms[j].cm_mech_name);
857 }
858 printf("\n");
859 }
860 }
861 }
862 printf("(end of providers table)\n");
863
864 mutex_exit(&prov_tab_mutex);
865 }
866
867 #endif /* DEBUG */
868
869 /*
870 * This function goes through the provider table and verifies
871 * any unverified providers.
872 *
873 * This is called when kcfd is up and the door handle is ready.
874 */
875 void
876 verify_unverified_providers()
877 {
878 int i;
879 kcf_provider_desc_t *pd;
880 boolean_t need_verify;
881
|