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]
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>
37 #include <sys/cmn_err.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.
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
*),
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.
74 kcf_policy_add_entry(kcf_policy_desc_t
*policy_desc
)
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
)
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
);
96 return (CRYPTO_SUCCESS
);
100 * Remove policy descriptor for the specified software module.
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
;
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
,
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
;
133 if (i
== KCF_MAX_POLICY
) {
138 mutex_exit(&policy_tab_mutex
);
142 * Remove policy descriptor for the specified device.
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
;
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
;
172 if (i
== KCF_MAX_POLICY
) {
177 mutex_exit(&policy_tab_mutex
);
181 * Returns policy descriptor for the specified software module.
184 kcf_policy_lookup_by_name(char *module_name
)
186 kcf_policy_desc_t
*policy_desc
;
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
,
197 KCF_POLICY_REFHOLD(policy_desc
);
198 mutex_exit(&policy_tab_mutex
);
199 return (policy_desc
);
204 mutex_exit(&policy_tab_mutex
);
209 * Returns policy descriptor for the specified device.
212 kcf_policy_lookup_by_dev(char *name
, uint_t instance
)
214 kcf_policy_desc_t
*policy_desc
;
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
);
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
;
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
,
268 policy_desc
= policy_tab
[i
];
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
);
280 policy_desc
= new_desc
;
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
;
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
];
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
);
342 policy_desc
= new_desc
;
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
)
370 mutex_init(&desc
->pd_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
376 * Free a policy descriptor.
379 kcf_policy_free_desc(kcf_policy_desc_t
*desc
)
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
));