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 #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 memcpy(&prov_mech->pm_mech_info, mech_info, 254 sizeof (crypto_mech_info_t)); 255 prov_mech->pm_prov_desc = prov_desc; 256 prov_desc->pd_mech_indx[KCF_MECH2CLASS(kcf_mech_type)] 257 [KCF_MECH2INDEX(kcf_mech_type)] = mech_indx; 258 259 KCF_PROV_REFHOLD(prov_desc); 260 KCF_PROV_IREFHOLD(prov_desc); 261 262 /* 263 * Add new kcf_prov_mech_desc at the front of HW providers 264 * chain. 265 */ 266 if (mech_entry->me_sw_prov != NULL) { 267 /* 268 * There is already a provider for this mechanism. 269 * Since we allow only one provider per mechanism, 270 * report this condition. 271 */ 272 cmn_err(CE_WARN, "The cryptographic provider " 273 "\"%s\" will not be used for %s. The provider " 274 "\"%s\" will be used for this mechanism " 275 "instead.", prov_desc->pd_description, 276 mech_info->cm_mech_name, 277 mech_entry->me_sw_prov->pm_prov_desc-> 278 pd_description); 279 KCF_PROV_REFRELE(prov_desc); 280 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t)); 281 prov_mech = NULL; 282 } else { 283 /* 284 * Set the provider as the provider for 285 * this mechanism. 286 */ 287 mech_entry->me_sw_prov = prov_mech; 288 } 289 290 *pmdpp = prov_mech; 291 292 return (KCF_SUCCESS); 293 } 294 295 /* 296 * kcf_remove_mech_provider() 297 * 298 * Arguments: 299 * . mech_name: the name of the mechanism. 300 * . prov_desc: The provider descriptor 301 * 302 * Description: 303 * Removes a provider from chain of provider descriptors. 304 * The provider is made unavailable to kernel consumers for the specified 305 * mechanism. 306 * 307 * Context: 308 * User context only. 309 */ 310 void 311 kcf_remove_mech_provider(const char *mech_name, kcf_provider_desc_t *prov_desc) 312 { 313 crypto_mech_type_t mech_type; 314 kcf_prov_mech_desc_t *prov_mech = NULL; 315 kcf_mech_entry_t *mech_entry; 316 317 /* get the KCF mech type that was assigned to the mechanism */ 318 if ((mech_type = crypto_mech2id(mech_name)) == 319 CRYPTO_MECH_INVALID) { 320 /* 321 * Provider was not allowed for this mech due to policy or 322 * configuration. 323 */ 324 return; 325 } 326 327 /* get a ptr to the mech_entry that was created */ 328 if (kcf_get_mech_entry(mech_type, &mech_entry) != KCF_SUCCESS) { 329 /* 330 * Provider was not allowed for this mech due to policy or 331 * configuration. 332 */ 333 return; 334 } 335 336 if (mech_entry->me_sw_prov == NULL || 337 mech_entry->me_sw_prov->pm_prov_desc != prov_desc) { 338 /* not the provider for this mechanism */ 339 return; 340 } 341 prov_mech = mech_entry->me_sw_prov; 342 mech_entry->me_sw_prov = NULL; 343 344 /* free entry */ 345 KCF_PROV_IREFRELE(prov_mech->pm_prov_desc); 346 KCF_PROV_REFRELE(prov_mech->pm_prov_desc); 347 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t)); 348 } 349 350 /* 351 * kcf_get_mech_entry() 352 * 353 * Arguments: 354 * . The framework mechanism type 355 * . Storage for the mechanism entry 356 * 357 * Description: 358 * Retrieves the mechanism entry for the mech. 359 * 360 * Context: 361 * User and interrupt contexts. 362 * 363 * Returns: 364 * KCF_MECHANISM_XXX appropriate error code. 365 * KCF_SUCCESS otherwise. 366 */ 367 int 368 kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep) 369 { 370 kcf_ops_class_t class; 371 int index; 372 const kcf_mech_entry_tab_t *me_tab; 373 374 ASSERT(mep != NULL); 375 376 class = KCF_MECH2CLASS(mech_type); 377 378 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) { 379 /* the caller won't need to know it's an invalid class */ 380 return (KCF_INVALID_MECH_NUMBER); 381 } 382 383 me_tab = &kcf_mech_tabs_tab[class]; 384 index = KCF_MECH2INDEX(mech_type); 385 386 if ((index < 0) || (index >= me_tab->met_size)) { 387 return (KCF_INVALID_MECH_NUMBER); 388 } 389 390 *mep = &((me_tab->met_tab)[index]); 391 392 return (KCF_SUCCESS); 393 } 394 395 /* 396 * crypto_mech2id() 397 * 398 * Arguments: 399 * . mechname: A null-terminated string identifying the mechanism name. 400 * 401 * Description: 402 * Walks the mechanisms tables, looking for an entry that matches the 403 * mechname. Once it find it, it builds the 64-bit mech_type and returns 404 * it. 405 * 406 * Context: 407 * Process and interruption. 408 * 409 * Returns: 410 * The unique mechanism identified by 'mechname', if found. 411 * CRYPTO_MECH_INVALID otherwise. 412 */ 413 /* 414 * Lookup the hash table for an entry that matches the mechname. 415 * If there are no providers for the mechanism, 416 * but there is an unloaded provider, this routine will attempt 417 * to load it. 418 */ 419 crypto_mech_type_t 420 crypto_mech2id(const char *mechname) 421 { 422 kcf_mech_entry_t tmptab, *found; 423 strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME); 424 425 if ((found = avl_find(&kcf_mech_hash, &tmptab, NULL))) { 426 ASSERT(found->me_mechid != CRYPTO_MECH_INVALID); 427 return (found->me_mechid); 428 } 429 430 return (CRYPTO_MECH_INVALID); 431 } 432 433 #if defined(_KERNEL) 434 EXPORT_SYMBOL(crypto_mech2id); 435 #endif 436