Unleashed v1.4
[unleashed.git] / usr / src / uts / common / crypto / core / kcf_policy.c
blobaf43a84dc0c721b6b14cab541caaccecde65d644
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * This file is part of the core Kernel Cryptographic Framework.
28 * It implements the management of the policy table. Entries are
29 * added and removed by administrative ioctls.
31 * Each element of the policy table contains a pointer to a
32 * policy descriptor, or NULL if the entry is free.
35 #include <sys/types.h>
36 #include <sys/kmem.h>
37 #include <sys/cmn_err.h>
38 #include <sys/ddi.h>
39 #include <sys/sunddi.h>
40 #include <sys/ksynch.h>
41 #include <sys/crypto/common.h>
42 #include <sys/crypto/impl.h>
44 #define KCF_MAX_POLICY 512 /* max number of policy entries */
46 static kmutex_t policy_tab_mutex; /* ensure exclusive access to the table */
47 static kcf_policy_desc_t **policy_tab = NULL;
48 static uint_t policy_tab_num = 0; /* number of providers in table */
49 static uint_t policy_tab_max = KCF_MAX_POLICY;
51 static int kcf_policy_add_entry(kcf_policy_desc_t *);
52 static kcf_policy_desc_t *kcf_policy_alloc_desc(int);
55 * Initialize the policy table. The policy table is dynamically
56 * allocated with policy_tab_max entries.
58 void
59 kcf_policy_tab_init(void)
61 mutex_init(&policy_tab_mutex, NULL, MUTEX_DRIVER, NULL);
63 policy_tab = kmem_zalloc(policy_tab_max * sizeof (kcf_policy_desc_t *),
64 KM_SLEEP);
68 * Add entry to the policy table. If no free slot can be found
69 * return CRYPTO_HOST_MEMORY, otherwise CRYPTO_SUCCESS.
71 * policy_tab_mutex must already be held.
73 static int
74 kcf_policy_add_entry(kcf_policy_desc_t *policy_desc)
76 uint_t i = 0;
78 ASSERT(policy_tab != NULL);
79 ASSERT(MUTEX_HELD(&policy_tab_mutex));
81 /* find free slot in policy table */
82 while (i < KCF_MAX_POLICY && policy_tab[i] != NULL)
83 i++;
85 if (i == KCF_MAX_POLICY) {
86 /* ran out of policy entries */
87 cmn_err(CE_WARN, "out of policy entries");
88 return (CRYPTO_HOST_MEMORY);
91 /* initialize entry */
92 policy_tab[i] = policy_desc;
93 KCF_POLICY_REFHOLD(policy_desc);
94 policy_tab_num++;
96 return (CRYPTO_SUCCESS);
100 * Remove policy descriptor for the specified software module.
102 void
103 kcf_policy_remove_by_name(char *module_name, uint_t *count,
104 crypto_mech_name_t **array)
106 kcf_policy_desc_t *policy_desc;
107 int i;
109 ASSERT(policy_tab != NULL);
110 ASSERT(policy_tab_num != (uint_t)-1); /* underflow */
112 mutex_enter(&policy_tab_mutex);
114 for (i = 0; i < KCF_MAX_POLICY; i++) {
115 if ((policy_desc = policy_tab[i]) != NULL &&
116 policy_desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
117 ASSERT(policy_desc->pd_name != NULL);
118 if (strncmp(module_name, policy_desc->pd_name,
119 MAXNAMELEN) == 0) {
120 *count = policy_desc->pd_disabled_count;
121 *array = policy_desc->pd_disabled_mechs;
122 mutex_destroy(&policy_desc->pd_mutex);
123 kmem_free(policy_desc->pd_name,
124 strlen(policy_desc->pd_name) + 1);
125 kmem_free(policy_desc,
126 sizeof (kcf_policy_desc_t));
127 policy_tab[i] = NULL;
128 policy_tab_num--;
129 break;
133 if (i == KCF_MAX_POLICY) {
134 *count = 0;
135 *array = NULL;
138 mutex_exit(&policy_tab_mutex);
142 * Remove policy descriptor for the specified device.
144 void
145 kcf_policy_remove_by_dev(char *name, uint_t instance, uint_t *count,
146 crypto_mech_name_t **array)
148 kcf_policy_desc_t *policy_desc;
149 int i;
151 ASSERT(policy_tab != NULL);
152 ASSERT(policy_tab_num != (uint_t)-1); /* underflow */
154 mutex_enter(&policy_tab_mutex);
156 for (i = 0; i < KCF_MAX_POLICY; i++) {
157 if ((policy_desc = policy_tab[i]) != NULL &&
158 policy_desc->pd_prov_type == CRYPTO_HW_PROVIDER &&
159 strncmp(policy_desc->pd_name, name, MAXNAMELEN) == 0 &&
160 policy_desc->pd_instance == instance) {
161 *count = policy_desc->pd_disabled_count;
162 *array = policy_desc->pd_disabled_mechs;
163 mutex_destroy(&policy_desc->pd_mutex);
164 kmem_free(policy_desc->pd_name,
165 strlen(policy_desc->pd_name) + 1);
166 kmem_free(policy_desc, sizeof (kcf_policy_desc_t));
167 policy_tab[i] = NULL;
168 policy_tab_num--;
169 break;
172 if (i == KCF_MAX_POLICY) {
173 *count = 0;
174 *array = NULL;
177 mutex_exit(&policy_tab_mutex);
181 * Returns policy descriptor for the specified software module.
183 kcf_policy_desc_t *
184 kcf_policy_lookup_by_name(char *module_name)
186 kcf_policy_desc_t *policy_desc;
187 uint_t i;
189 mutex_enter(&policy_tab_mutex);
191 for (i = 0; i < KCF_MAX_POLICY; i++) {
192 if ((policy_desc = policy_tab[i]) != NULL &&
193 policy_desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
194 ASSERT(policy_desc->pd_name != NULL);
195 if (strncmp(module_name, policy_desc->pd_name,
196 MAXNAMELEN) == 0) {
197 KCF_POLICY_REFHOLD(policy_desc);
198 mutex_exit(&policy_tab_mutex);
199 return (policy_desc);
204 mutex_exit(&policy_tab_mutex);
205 return (NULL);
209 * Returns policy descriptor for the specified device.
211 kcf_policy_desc_t *
212 kcf_policy_lookup_by_dev(char *name, uint_t instance)
214 kcf_policy_desc_t *policy_desc;
215 uint_t i;
217 mutex_enter(&policy_tab_mutex);
219 for (i = 0; i < KCF_MAX_POLICY; i++) {
220 if ((policy_desc = policy_tab[i]) != NULL &&
221 policy_desc->pd_prov_type == CRYPTO_HW_PROVIDER &&
222 strncmp(policy_desc->pd_name, name, MAXNAMELEN) == 0 &&
223 policy_desc->pd_instance == instance) {
224 KCF_POLICY_REFHOLD(policy_desc);
225 mutex_exit(&policy_tab_mutex);
226 return (policy_desc);
230 mutex_exit(&policy_tab_mutex);
231 return (NULL);
235 * Loads disabled mechanism array for specified software provider, and
236 * creates a policy descriptor if one does not already exist.
237 * Important note: new_array is consumed.
240 kcf_policy_load_soft_disabled(char *module_name, uint_t new_count,
241 crypto_mech_name_t *new_array, uint_t *prev_count,
242 crypto_mech_name_t **prev_array)
244 kcf_policy_desc_t *new_desc, *policy_desc = NULL;
245 uint_t i;
246 int rv;
249 * Allocate storage for a new entry.
250 * Free new entry if a policy descriptor already exists.
252 new_desc = kcf_policy_alloc_desc(KM_SLEEP);
253 new_desc->pd_prov_type = CRYPTO_SW_PROVIDER;
254 new_desc->pd_name = kmem_alloc(strlen(module_name) + 1, KM_SLEEP);
255 (void) strcpy(new_desc->pd_name, module_name);
257 mutex_enter(&policy_tab_mutex);
260 * Search for an existing entry.
262 for (i = 0; i < KCF_MAX_POLICY; i++) {
263 if (policy_tab[i] != NULL &&
264 policy_tab[i]->pd_prov_type == CRYPTO_SW_PROVIDER) {
265 ASSERT(policy_tab[i]->pd_name != NULL);
266 if (strncmp(policy_tab[i]->pd_name, module_name,
267 MAXNAMELEN) == 0) {
268 policy_desc = policy_tab[i];
269 break;
273 if (policy_desc == NULL) {
274 rv = kcf_policy_add_entry(new_desc);
275 if (rv != CRYPTO_SUCCESS) {
276 mutex_exit(&policy_tab_mutex);
277 kcf_policy_free_desc(new_desc);
278 return (rv);
280 policy_desc = new_desc;
281 } else {
282 kcf_policy_free_desc(new_desc);
285 mutex_enter(&policy_desc->pd_mutex);
286 *prev_count = policy_desc->pd_disabled_count;
288 /* prev_array is freed by the caller */
289 *prev_array = policy_desc->pd_disabled_mechs;
290 policy_desc->pd_disabled_count = new_count;
291 policy_desc->pd_disabled_mechs = new_array;
292 mutex_exit(&policy_desc->pd_mutex);
293 mutex_exit(&policy_tab_mutex);
294 return (CRYPTO_SUCCESS);
298 * Loads disabled mechanism array for specified device, and
299 * creates a policy descriptor if one does not already exist.
300 * Important note: new_array is consumed.
303 kcf_policy_load_dev_disabled(char *name, uint_t instance, uint_t new_count,
304 crypto_mech_name_t *new_array, uint_t *prev_count,
305 crypto_mech_name_t **prev_array)
307 kcf_policy_desc_t *new_desc, *policy_desc = NULL;
308 uint_t i;
309 int rv;
312 * Allocate storage for a new entry.
313 * Free new entry if a policy descriptor already exists.
315 new_desc = kcf_policy_alloc_desc(KM_SLEEP);
316 new_desc->pd_prov_type = CRYPTO_HW_PROVIDER;
317 new_desc->pd_name = kmem_alloc(strlen(name) + 1, KM_SLEEP);
318 (void) strcpy(new_desc->pd_name, name);
319 new_desc->pd_instance = instance;
321 mutex_enter(&policy_tab_mutex);
324 * Search for an existing entry.
326 for (i = 0; i < KCF_MAX_POLICY; i++) {
327 if (policy_tab[i] != NULL &&
328 policy_tab[i]->pd_prov_type == CRYPTO_HW_PROVIDER &&
329 strncmp(policy_tab[i]->pd_name, name, MAXNAMELEN) == 0 &&
330 policy_tab[i]->pd_instance == instance) {
331 policy_desc = policy_tab[i];
332 break;
335 if (policy_desc == NULL) {
336 rv = kcf_policy_add_entry(new_desc);
337 if (rv != CRYPTO_SUCCESS) {
338 mutex_exit(&policy_tab_mutex);
339 kcf_policy_free_desc(new_desc);
340 return (rv);
342 policy_desc = new_desc;
343 } else {
344 kcf_policy_free_desc(new_desc);
347 mutex_enter(&policy_desc->pd_mutex);
348 *prev_count = policy_desc->pd_disabled_count;
350 /* prev_array is freed by the caller */
351 *prev_array = policy_desc->pd_disabled_mechs;
352 policy_desc->pd_disabled_count = new_count;
353 policy_desc->pd_disabled_mechs = new_array;
354 mutex_exit(&policy_desc->pd_mutex);
355 mutex_exit(&policy_tab_mutex);
356 return (CRYPTO_SUCCESS);
360 * Allocate a policy descriptor.
362 static kcf_policy_desc_t *
363 kcf_policy_alloc_desc(int km_flag)
365 kcf_policy_desc_t *desc;
367 if ((desc = kmem_zalloc(sizeof (kcf_policy_desc_t), km_flag)) == NULL)
368 return (NULL);
370 mutex_init(&desc->pd_mutex, NULL, MUTEX_DEFAULT, NULL);
372 return (desc);
376 * Free a policy descriptor.
378 void
379 kcf_policy_free_desc(kcf_policy_desc_t *desc)
381 if (desc == NULL)
382 return;
384 mutex_destroy(&desc->pd_mutex);
386 ASSERT(desc->pd_name != NULL);
387 kmem_free(desc->pd_name, strlen(desc->pd_name) + 1);
389 if (desc->pd_disabled_mechs != NULL)
390 kmem_free(desc->pd_disabled_mechs, sizeof (crypto_mech_name_t) *
391 desc->pd_disabled_count);
393 kmem_free(desc, sizeof (kcf_policy_desc_t));