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 https://opensource.org/licenses/CDDL-1.0. 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/zfs_context.h> 43 #include <sys/crypto/common.h> 44 #include <sys/crypto/impl.h> 45 #include <sys/crypto/sched_impl.h> 46 #include <sys/crypto/spi.h> 47 48 #define KCF_MAX_PROVIDERS 8 /* max number of providers */ 49 50 /* 51 * Prov_tab is an array of providers which is updated when 52 * a crypto provider registers with kcf. The provider calls the 53 * SPI routine, crypto_register_provider(), which in turn calls 54 * kcf_prov_tab_add_provider(). 55 * 56 * A provider unregisters by calling crypto_unregister_provider() 57 * which triggers the removal of the prov_tab entry. 58 * It also calls kcf_remove_mech_provider(). 59 * 60 * prov_tab entries are not updated from kcf.conf or by cryptoadm(1M). 61 */ 62 static kcf_provider_desc_t *prov_tab[KCF_MAX_PROVIDERS]; 63 static kmutex_t prov_tab_mutex; /* ensure exclusive access to the table */ 64 static uint_t prov_tab_num = 0; /* number of providers in table */ 65 66 void 67 kcf_prov_tab_destroy(void) 68 { 69 mutex_destroy(&prov_tab_mutex); 70 } 71 72 /* 73 * Initialize a mutex and the KCF providers table, prov_tab. 74 * The providers table is dynamically allocated with KCF_MAX_PROVIDERS entries. 75 * Called from kcf module _init(). 76 */ 77 void 78 kcf_prov_tab_init(void) 79 { 80 mutex_init(&prov_tab_mutex, NULL, MUTEX_DEFAULT, NULL); 81 } 82 83 /* 84 * Add a provider to the provider table. If no free entry can be found 85 * for the new provider, returns CRYPTO_HOST_MEMORY. Otherwise, add 86 * the provider to the table, initialize the pd_prov_id field 87 * of the specified provider descriptor to the index in that table, 88 * and return CRYPTO_SUCCESS. Note that a REFHOLD is done on the 89 * provider when pointed to by a table entry. 90 */ 91 int 92 kcf_prov_tab_add_provider(kcf_provider_desc_t *prov_desc) 93 { 94 uint_t i; 95 96 mutex_enter(&prov_tab_mutex); 97 98 /* find free slot in providers table */ 99 for (i = 1; i < KCF_MAX_PROVIDERS && prov_tab[i] != NULL; i++) 100 ; 101 if (i == KCF_MAX_PROVIDERS) { 102 /* ran out of providers entries */ 103 mutex_exit(&prov_tab_mutex); 104 cmn_err(CE_WARN, "out of providers entries"); 105 return (CRYPTO_HOST_MEMORY); 106 } 107 108 /* initialize entry */ 109 prov_tab[i] = prov_desc; 110 KCF_PROV_REFHOLD(prov_desc); 111 KCF_PROV_IREFHOLD(prov_desc); 112 prov_tab_num++; 113 114 mutex_exit(&prov_tab_mutex); 115 116 /* update provider descriptor */ 117 prov_desc->pd_prov_id = i; 118 119 /* 120 * The KCF-private provider handle is defined as the internal 121 * provider id. 122 */ 123 prov_desc->pd_kcf_prov_handle = 124 (crypto_kcf_provider_handle_t)prov_desc->pd_prov_id; 125 126 return (CRYPTO_SUCCESS); 127 } 128 129 /* 130 * Remove the provider specified by its id. A REFRELE is done on the 131 * corresponding provider descriptor before this function returns. 132 * Returns CRYPTO_UNKNOWN_PROVIDER if the provider id is not valid. 133 */ 134 int 135 kcf_prov_tab_rem_provider(crypto_provider_id_t prov_id) 136 { 137 kcf_provider_desc_t *prov_desc; 138 139 /* 140 * Validate provider id, since it can be specified by a 3rd-party 141 * provider. 142 */ 143 144 mutex_enter(&prov_tab_mutex); 145 if (prov_id >= KCF_MAX_PROVIDERS || 146 ((prov_desc = prov_tab[prov_id]) == NULL)) { 147 mutex_exit(&prov_tab_mutex); 148 return (CRYPTO_INVALID_PROVIDER_ID); 149 } 150 mutex_exit(&prov_tab_mutex); 151 152 /* 153 * The provider id must remain valid until the associated provider 154 * descriptor is freed. For this reason, we simply release our 155 * reference to the descriptor here. When the reference count 156 * reaches zero, kcf_free_provider_desc() will be invoked and 157 * the associated entry in the providers table will be released 158 * at that time. 159 */ 160 161 KCF_PROV_IREFRELE(prov_desc); 162 KCF_PROV_REFRELE(prov_desc); 163 164 return (CRYPTO_SUCCESS); 165 } 166 167 /* 168 * Returns the provider descriptor corresponding to the specified 169 * provider id. A REFHOLD is done on the descriptor before it is 170 * returned to the caller. It is the responsibility of the caller 171 * to do a REFRELE once it is done with the provider descriptor. 172 */ 173 kcf_provider_desc_t * 174 kcf_prov_tab_lookup(crypto_provider_id_t prov_id) 175 { 176 kcf_provider_desc_t *prov_desc; 177 178 mutex_enter(&prov_tab_mutex); 179 180 prov_desc = prov_tab[prov_id]; 181 182 if (prov_desc == NULL) { 183 mutex_exit(&prov_tab_mutex); 184 return (NULL); 185 } 186 187 KCF_PROV_REFHOLD(prov_desc); 188 189 mutex_exit(&prov_tab_mutex); 190 191 return (prov_desc); 192 } 193 194 /* 195 * Allocate a provider descriptor. mech_list_count specifies the 196 * number of mechanisms supported by the providers, and is used 197 * to allocate storage for the mechanism table. 198 * This function may sleep while allocating memory, which is OK 199 * since it is invoked from user context during provider registration. 200 */ 201 kcf_provider_desc_t * 202 kcf_alloc_provider_desc(void) 203 { 204 kcf_provider_desc_t *desc = 205 kmem_zalloc(sizeof (kcf_provider_desc_t), KM_SLEEP); 206 207 for (int i = 0; i < KCF_OPS_CLASSSIZE; i++) 208 for (int j = 0; j < KCF_MAXMECHTAB; j++) 209 desc->pd_mech_indx[i][j] = KCF_INVALID_INDX; 210 211 desc->pd_prov_id = KCF_PROVID_INVALID; 212 desc->pd_state = KCF_PROV_ALLOCATED; 213 214 mutex_init(&desc->pd_lock, NULL, MUTEX_DEFAULT, NULL); 215 cv_init(&desc->pd_remove_cv, NULL, CV_DEFAULT, NULL); 216 217 return (desc); 218 } 219 220 /* 221 * Called by KCF_PROV_REFRELE when a provider's reference count drops 222 * to zero. We free the descriptor when the last reference is released. 223 * However, for providers, we do not free it when there is an 224 * unregister thread waiting. We signal that thread in this case and 225 * that thread is responsible for freeing the descriptor. 226 */ 227 void 228 kcf_provider_zero_refcnt(kcf_provider_desc_t *desc) 229 { 230 mutex_enter(&desc->pd_lock); 231 if (desc->pd_state == KCF_PROV_REMOVED || 232 desc->pd_state == KCF_PROV_DISABLED) { 233 desc->pd_state = KCF_PROV_FREED; 234 cv_broadcast(&desc->pd_remove_cv); 235 mutex_exit(&desc->pd_lock); 236 return; 237 } 238 239 mutex_exit(&desc->pd_lock); 240 kcf_free_provider_desc(desc); 241 } 242 243 /* 244 * Free a provider descriptor. 245 */ 246 void 247 kcf_free_provider_desc(kcf_provider_desc_t *desc) 248 { 249 if (desc == NULL) 250 return; 251 252 mutex_enter(&prov_tab_mutex); 253 if (desc->pd_prov_id != KCF_PROVID_INVALID) { 254 /* release the associated providers table entry */ 255 ASSERT(prov_tab[desc->pd_prov_id] != NULL); 256 prov_tab[desc->pd_prov_id] = NULL; 257 prov_tab_num--; 258 } 259 mutex_exit(&prov_tab_mutex); 260 261 /* free the kernel memory associated with the provider descriptor */ 262 263 mutex_destroy(&desc->pd_lock); 264 cv_destroy(&desc->pd_remove_cv); 265 266 kmem_free(desc, sizeof (kcf_provider_desc_t)); 267 } 268 269 /* 270 * Returns in the location pointed to by pd a pointer to the descriptor 271 * for the provider for the specified mechanism. 272 * The provider descriptor is returned held and it is the caller's 273 * responsibility to release it when done. The mechanism entry 274 * is returned if the optional argument mep is non NULL. 275 * 276 * Returns one of the CRYPTO_ * error codes on failure, and 277 * CRYPTO_SUCCESS on success. 278 */ 279 int 280 kcf_get_sw_prov(crypto_mech_type_t mech_type, kcf_provider_desc_t **pd, 281 kcf_mech_entry_t **mep, boolean_t log_warn) 282 { 283 kcf_mech_entry_t *me; 284 285 /* get the mechanism entry for this mechanism */ 286 if (kcf_get_mech_entry(mech_type, &me) != KCF_SUCCESS) 287 return (CRYPTO_MECHANISM_INVALID); 288 289 /* Get the provider for this mechanism. */ 290 if (me->me_sw_prov == NULL || 291 (*pd = me->me_sw_prov->pm_prov_desc) == NULL) { 292 /* no provider for this mechanism */ 293 if (log_warn) 294 cmn_err(CE_WARN, "no provider for \"%s\"\n", 295 me->me_name); 296 return (CRYPTO_MECH_NOT_SUPPORTED); 297 } 298 299 KCF_PROV_REFHOLD(*pd); 300 301 if (mep != NULL) 302 *mep = me; 303 304 return (CRYPTO_SUCCESS); 305 } 306