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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/zfs_context.h> 27 #include <sys/crypto/common.h> 28 #include <sys/crypto/api.h> 29 #include <sys/crypto/impl.h> 30 31 /* Cryptographic mechanisms tables and their access functions */ 32 33 /* 34 * Internal numbers assigned to mechanisms are coded as follows: 35 * 36 * +----------------+----------------+ 37 * | mech. class | mech. index | 38 * <--- 32-bits --->+<--- 32-bits ---> 39 * 40 * the mech_class identifies the table the mechanism belongs to. 41 * mech_index is the index for that mechanism in the table. 42 * A mechanism belongs to exactly 1 table. 43 * The tables are: 44 * . digest_mechs_tab[] for the msg digest mechs. 45 * . cipher_mechs_tab[] for encrypt/decrypt and wrap/unwrap mechs. 46 * . mac_mechs_tab[] for MAC mechs. 47 * . sign_mechs_tab[] for sign & verify mechs. 48 * . keyops_mechs_tab[] for key/key pair generation, and key derivation. 49 * . misc_mechs_tab[] for mechs that don't belong to any of the above. 50 * 51 * There are no holes in the tables. 52 */ 53 54 /* 55 * Locking conventions: 56 * -------------------- 57 * A mutex is associated with every entry of the tables. 58 * The mutex is acquired whenever the entry is accessed for 59 * 1) retrieving the mech_id (comparing the mech name) 60 * 2) finding a provider for an xxx_init() or atomic operation. 61 * 3) altering the mechs entry to add or remove a provider. 62 * 63 * In 2), after a provider is chosen, its prov_desc is held and the 64 * entry's mutex must be dropped. The provider's working function (SPI) is 65 * called outside the mech_entry's mutex. 66 * 67 * The number of providers for a particular mechanism is not expected to be 68 * long enough to justify the cost of using rwlocks, so the per-mechanism 69 * entry mutex won't be very *hot*. 70 * 71 */ 72 73 /* Mechanisms tables */ 74 75 76 /* RFE 4687834 Will deal with the extensibility of these tables later */ 77 78 static kcf_mech_entry_t kcf_digest_mechs_tab[KCF_MAXDIGEST]; 79 static kcf_mech_entry_t kcf_cipher_mechs_tab[KCF_MAXCIPHER]; 80 static kcf_mech_entry_t kcf_mac_mechs_tab[KCF_MAXMAC]; 81 82 const kcf_mech_entry_tab_t kcf_mech_tabs_tab[KCF_LAST_OPSCLASS + 1] = { 83 {0, NULL}, /* No class zero */ 84 {KCF_MAXDIGEST, kcf_digest_mechs_tab}, 85 {KCF_MAXCIPHER, kcf_cipher_mechs_tab}, 86 {KCF_MAXMAC, kcf_mac_mechs_tab}, 87 }; 88 89 static avl_tree_t kcf_mech_hash; 90 91 static int 92 kcf_mech_hash_compar(const void *lhs, const void *rhs) 93 { 94 const kcf_mech_entry_t *l = lhs, *r = rhs; 95 int cmp = strncmp(l->me_name, r->me_name, CRYPTO_MAX_MECH_NAME); 96 return ((0 < cmp) - (cmp < 0)); 97 } 98 99 void 100 kcf_destroy_mech_tabs(void) 101 { 102 for (void *cookie = NULL; avl_destroy_nodes(&kcf_mech_hash, &cookie); ) 103 ; 104 avl_destroy(&kcf_mech_hash); 105 } 106 107 /* 108 * kcf_init_mech_tabs() 109 * 110 * Called by the misc/kcf's _init() routine to initialize the tables 111 * of mech_entry's. 112 */ 113 void 114 kcf_init_mech_tabs(void) 115 { 116 avl_create(&kcf_mech_hash, kcf_mech_hash_compar, 117 sizeof (kcf_mech_entry_t), offsetof(kcf_mech_entry_t, me_node)); 118 } 119 120 /* 121 * kcf_create_mech_entry() 122 * 123 * Arguments: 124 * . The class of mechanism. 125 * . the name of the new mechanism. 126 * 127 * Description: 128 * Creates a new mech_entry for a mechanism not yet known to the 129 * framework. 130 * This routine is called by kcf_add_mech_provider, which is 131 * in turn invoked for each mechanism supported by a provider. 132 * The'class' argument depends on the crypto_func_group_t bitmask 133 * in the registering provider's mech_info struct for this mechanism. 134 * When there is ambiguity in the mapping between the crypto_func_group_t 135 * and a class (dual ops, ...) the KCF_MISC_CLASS should be used. 136 * 137 * Context: 138 * User context only. 139 * 140 * Returns: 141 * KCF_INVALID_MECH_CLASS or KCF_INVALID_MECH_NAME if the class or 142 * the mechname is bogus. 143 * KCF_MECH_TAB_FULL when there is no room left in the mech. tabs. 144 * KCF_SUCCESS otherwise. 145 */ 146 static int 147 kcf_create_mech_entry(kcf_ops_class_t class, const char *mechname) 148 { 149 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) 150 return (KCF_INVALID_MECH_CLASS); 151 152 if ((mechname == NULL) || (mechname[0] == 0)) 153 return (KCF_INVALID_MECH_NAME); 154 /* 155 * First check if the mechanism is already in one of the tables. 156 * The mech_entry could be in another class. 157 */ 158 avl_index_t where = 0; 159 kcf_mech_entry_t tmptab; 160 strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME); 161 if (avl_find(&kcf_mech_hash, &tmptab, &where) != NULL) 162 return (KCF_SUCCESS); 163 /* Now take the next unused mech entry in the class's tab */ 164 kcf_mech_entry_t *me_tab = kcf_mech_tabs_tab[class].met_tab; 165 int size = kcf_mech_tabs_tab[class].met_size; 166 167 for (int i = 0; i < size; ++i) 168 if (me_tab[i].me_name[0] == 0) { 169 /* Found an empty spot */ 170 strlcpy(me_tab[i].me_name, mechname, 171 CRYPTO_MAX_MECH_NAME); 172 me_tab[i].me_mechid = KCF_MECHID(class, i); 173 174 /* Add the new mechanism to the hash table */ 175 avl_insert(&kcf_mech_hash, &me_tab[i], where); 176 return (KCF_SUCCESS); 177 } 178 179 return (KCF_MECH_TAB_FULL); 180 } 181 182 /* 183 * kcf_add_mech_provider() 184 * 185 * Arguments: 186 * . An index in to the provider mechanism array 187 * . A pointer to the provider descriptor 188 * . A storage for the kcf_prov_mech_desc_t the entry was added at. 189 * 190 * Description: 191 * Adds a new provider of a mechanism to the mechanism's mech_entry 192 * chain. 193 * 194 * Context: 195 * User context only. 196 * 197 * Returns 198 * KCF_SUCCESS on success 199 * KCF_MECH_TAB_FULL otherwise. 200 */ 201 int 202 kcf_add_mech_provider(short mech_indx, 203 kcf_provider_desc_t *prov_desc, kcf_prov_mech_desc_t **pmdpp) 204 { 205 int error; 206 kcf_mech_entry_t *mech_entry = NULL; 207 const crypto_mech_info_t *mech_info; 208 crypto_mech_type_t kcf_mech_type; 209 kcf_prov_mech_desc_t *prov_mech; 210 211 mech_info = &prov_desc->pd_mechanisms[mech_indx]; 212 213 /* 214 * A mechanism belongs to exactly one mechanism table. 215 * Find the class corresponding to the function group flag of 216 * the mechanism. 217 */ 218 kcf_mech_type = crypto_mech2id(mech_info->cm_mech_name); 219 if (kcf_mech_type == CRYPTO_MECH_INVALID) { 220 crypto_func_group_t fg = mech_info->cm_func_group_mask; 221 kcf_ops_class_t class; 222 223 if (fg & CRYPTO_FG_DIGEST || fg & CRYPTO_FG_DIGEST_ATOMIC) 224 class = KCF_DIGEST_CLASS; 225 else if (fg & CRYPTO_FG_ENCRYPT || fg & CRYPTO_FG_DECRYPT || 226 fg & CRYPTO_FG_ENCRYPT_ATOMIC || 227 fg & CRYPTO_FG_DECRYPT_ATOMIC) 228 class = KCF_CIPHER_CLASS; 229 else if (fg & CRYPTO_FG_MAC || fg & CRYPTO_FG_MAC_ATOMIC) 230 class = KCF_MAC_CLASS; 231 else 232 __builtin_unreachable(); 233 234 /* 235 * Attempt to create a new mech_entry for the specified 236 * mechanism. kcf_create_mech_entry() can handle the case 237 * where such an entry already exists. 238 */ 239 if ((error = kcf_create_mech_entry(class, 240 mech_info->cm_mech_name)) != KCF_SUCCESS) { 241 return (error); 242 } 243 /* get the KCF mech type that was assigned to the mechanism */ 244 kcf_mech_type = crypto_mech2id(mech_info->cm_mech_name); 245 ASSERT(kcf_mech_type != CRYPTO_MECH_INVALID); 246 } 247 248 error = kcf_get_mech_entry(kcf_mech_type, &mech_entry); 249 ASSERT(error == KCF_SUCCESS); 250 251 /* allocate and initialize new kcf_prov_mech_desc */ 252 prov_mech = kmem_zalloc(sizeof (kcf_prov_mech_desc_t), KM_SLEEP); 253 bcopy(mech_info, &prov_mech->pm_mech_info, sizeof (crypto_mech_info_t)); 254 prov_mech->pm_prov_desc = prov_desc; 255 prov_desc->pd_mech_indx[KCF_MECH2CLASS(kcf_mech_type)] 256 [KCF_MECH2INDEX(kcf_mech_type)] = mech_indx; 257 258 KCF_PROV_REFHOLD(prov_desc); 259 KCF_PROV_IREFHOLD(prov_desc); 260 261 /* 262 * Add new kcf_prov_mech_desc at the front of HW providers 263 * chain. 264 */ 265 if (mech_entry->me_sw_prov != NULL) { 266 /* 267 * There is already a provider for this mechanism. 268 * Since we allow only one provider per mechanism, 269 * report this condition. 270 */ 271 cmn_err(CE_WARN, "The cryptographic provider " 272 "\"%s\" will not be used for %s. The provider " 273 "\"%s\" will be used for this mechanism " 274 "instead.", prov_desc->pd_description, 275 mech_info->cm_mech_name, 276 mech_entry->me_sw_prov->pm_prov_desc-> 277 pd_description); 278 KCF_PROV_REFRELE(prov_desc); 279 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t)); 280 prov_mech = NULL; 281 } else { 282 /* 283 * Set the provider as the provider for 284 * this mechanism. 285 */ 286 mech_entry->me_sw_prov = prov_mech; 287 } 288 289 *pmdpp = prov_mech; 290 291 return (KCF_SUCCESS); 292 } 293 294 /* 295 * kcf_remove_mech_provider() 296 * 297 * Arguments: 298 * . mech_name: the name of the mechanism. 299 * . prov_desc: The provider descriptor 300 * 301 * Description: 302 * Removes a provider from chain of provider descriptors. 303 * The provider is made unavailable to kernel consumers for the specified 304 * mechanism. 305 * 306 * Context: 307 * User context only. 308 */ 309 void 310 kcf_remove_mech_provider(const char *mech_name, kcf_provider_desc_t *prov_desc) 311 { 312 crypto_mech_type_t mech_type; 313 kcf_prov_mech_desc_t *prov_mech = NULL; 314 kcf_mech_entry_t *mech_entry; 315 316 /* get the KCF mech type that was assigned to the mechanism */ 317 if ((mech_type = crypto_mech2id(mech_name)) == 318 CRYPTO_MECH_INVALID) { 319 /* 320 * Provider was not allowed for this mech due to policy or 321 * configuration. 322 */ 323 return; 324 } 325 326 /* get a ptr to the mech_entry that was created */ 327 if (kcf_get_mech_entry(mech_type, &mech_entry) != KCF_SUCCESS) { 328 /* 329 * Provider was not allowed for this mech due to policy or 330 * configuration. 331 */ 332 return; 333 } 334 335 if (mech_entry->me_sw_prov == NULL || 336 mech_entry->me_sw_prov->pm_prov_desc != prov_desc) { 337 /* not the provider for this mechanism */ 338 return; 339 } 340 prov_mech = mech_entry->me_sw_prov; 341 mech_entry->me_sw_prov = NULL; 342 343 /* free entry */ 344 KCF_PROV_REFRELE(prov_mech->pm_prov_desc); 345 KCF_PROV_IREFRELE(prov_mech->pm_prov_desc); 346 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t)); 347 } 348 349 /* 350 * kcf_get_mech_entry() 351 * 352 * Arguments: 353 * . The framework mechanism type 354 * . Storage for the mechanism entry 355 * 356 * Description: 357 * Retrieves the mechanism entry for the mech. 358 * 359 * Context: 360 * User and interrupt contexts. 361 * 362 * Returns: 363 * KCF_MECHANISM_XXX appropriate error code. 364 * KCF_SUCCESS otherwise. 365 */ 366 int 367 kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep) 368 { 369 kcf_ops_class_t class; 370 int index; 371 const kcf_mech_entry_tab_t *me_tab; 372 373 ASSERT(mep != NULL); 374 375 class = KCF_MECH2CLASS(mech_type); 376 377 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) { 378 /* the caller won't need to know it's an invalid class */ 379 return (KCF_INVALID_MECH_NUMBER); 380 } 381 382 me_tab = &kcf_mech_tabs_tab[class]; 383 index = KCF_MECH2INDEX(mech_type); 384 385 if ((index < 0) || (index >= me_tab->met_size)) { 386 return (KCF_INVALID_MECH_NUMBER); 387 } 388 389 *mep = &((me_tab->met_tab)[index]); 390 391 return (KCF_SUCCESS); 392 } 393 394 /* 395 * crypto_mech2id() 396 * 397 * Arguments: 398 * . mechname: A null-terminated string identifying the mechanism name. 399 * 400 * Description: 401 * Walks the mechanisms tables, looking for an entry that matches the 402 * mechname. Once it find it, it builds the 64-bit mech_type and returns 403 * it. 404 * 405 * Context: 406 * Process and interruption. 407 * 408 * Returns: 409 * The unique mechanism identified by 'mechname', if found. 410 * CRYPTO_MECH_INVALID otherwise. 411 */ 412 /* 413 * Lookup the hash table for an entry that matches the mechname. 414 * If there are no providers for the mechanism, 415 * but there is an unloaded provider, this routine will attempt 416 * to load it. 417 */ 418 crypto_mech_type_t 419 crypto_mech2id(const char *mechname) 420 { 421 kcf_mech_entry_t tmptab, *found; 422 strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME); 423 424 if ((found = avl_find(&kcf_mech_hash, &tmptab, NULL))) { 425 ASSERT(found->me_mechid != CRYPTO_MECH_INVALID); 426 return (found->me_mechid); 427 } 428 429 return (CRYPTO_MECH_INVALID); 430 } 431 432 #if defined(_KERNEL) 433 EXPORT_SYMBOL(crypto_mech2id); 434 #endif 435