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 2007 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/impl.h> 29 #include <sys/crypto/api.h> 30 #include <sys/crypto/spi.h> 31 #include <sys/crypto/sched_impl.h> 32 33 /* 34 * Encryption and decryption routines. 35 */ 36 37 /* 38 * The following are the possible returned values common to all the routines 39 * below. The applicability of some of these return values depends on the 40 * presence of the arguments. 41 * 42 * CRYPTO_SUCCESS: The operation completed successfully. 43 * CRYPTO_QUEUED: A request was submitted successfully. The callback 44 * routine will be called when the operation is done. 45 * CRYPTO_INVALID_MECH_NUMBER, CRYPTO_INVALID_MECH_PARAM, or 46 * CRYPTO_INVALID_MECH for problems with the 'mech'. 47 * CRYPTO_INVALID_DATA for bogus 'data' 48 * CRYPTO_HOST_MEMORY for failure to allocate memory to handle this work. 49 * CRYPTO_INVALID_CONTEXT: Not a valid context. 50 * CRYPTO_BUSY: Cannot process the request now. Schedule a 51 * crypto_bufcall(), or try later. 52 * CRYPTO_NOT_SUPPORTED and CRYPTO_MECH_NOT_SUPPORTED: No provider is 53 * capable of a function or a mechanism. 54 * CRYPTO_INVALID_KEY: bogus 'key' argument. 55 * CRYPTO_INVALID_PLAINTEXT: bogus 'plaintext' argument. 56 * CRYPTO_INVALID_CIPHERTEXT: bogus 'ciphertext' argument. 57 */ 58 59 /* 60 * crypto_cipher_init_prov() 61 * 62 * Arguments: 63 * 64 * pd: provider descriptor 65 * sid: session id 66 * mech: crypto_mechanism_t pointer. 67 * mech_type is a valid value previously returned by 68 * crypto_mech2id(); 69 * When the mech's parameter is not NULL, its definition depends 70 * on the standard definition of the mechanism. 71 * key: pointer to a crypto_key_t structure. 72 * tmpl: a crypto_ctx_template_t, opaque template of a context of an 73 * encryption or decryption with the 'mech' using 'key'. 74 * 'tmpl' is created by a previous call to 75 * crypto_create_ctx_template(). 76 * ctxp: Pointer to a crypto_context_t. 77 * func: CRYPTO_FG_ENCRYPT or CRYPTO_FG_DECRYPT. 78 * cr: crypto_call_req_t calling conditions and call back info. 79 * 80 * Description: 81 * This is a common function invoked internally by both 82 * crypto_encrypt_init() and crypto_decrypt_init(). 83 * Asynchronously submits a request for, or synchronously performs the 84 * initialization of an encryption or a decryption operation. 85 * When possible and applicable, will internally use the pre-expanded key 86 * schedule from the context template, tmpl. 87 * When complete and successful, 'ctxp' will contain a crypto_context_t 88 * valid for later calls to encrypt_update() and encrypt_final(), or 89 * decrypt_update() and decrypt_final(). 90 * The caller should hold a reference on the specified provider 91 * descriptor before calling this function. 92 * 93 * Context: 94 * Process or interrupt, according to the semantics dictated by the 'cr'. 95 * 96 * Returns: 97 * See comment in the beginning of the file. 98 */ 99 static int 100 crypto_cipher_init_prov(crypto_provider_t provider, crypto_session_id_t sid, 101 crypto_mechanism_t *mech, crypto_key_t *key, 102 crypto_spi_ctx_template_t tmpl, crypto_context_t *ctxp, 103 crypto_call_req_t *crq, crypto_func_group_t func) 104 { 105 int error; 106 crypto_ctx_t *ctx; 107 kcf_req_params_t params; 108 kcf_provider_desc_t *pd = provider; 109 kcf_provider_desc_t *real_provider = pd; 110 111 ASSERT(KCF_PROV_REFHELD(pd)); 112 113 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 114 if (func == CRYPTO_FG_ENCRYPT) { 115 error = kcf_get_hardware_provider(mech->cm_type, 116 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 117 &real_provider, CRYPTO_FG_ENCRYPT); 118 } else { 119 error = kcf_get_hardware_provider(mech->cm_type, 120 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 121 &real_provider, CRYPTO_FG_DECRYPT); 122 } 123 124 if (error != CRYPTO_SUCCESS) 125 return (error); 126 } 127 128 /* Allocate and initialize the canonical context */ 129 if ((ctx = kcf_new_ctx(crq, real_provider, sid)) == NULL) { 130 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 131 KCF_PROV_REFRELE(real_provider); 132 return (CRYPTO_HOST_MEMORY); 133 } 134 135 /* The fast path for SW providers. */ 136 if (CHECK_FASTPATH(crq, pd)) { 137 crypto_mechanism_t lmech; 138 139 lmech = *mech; 140 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech); 141 142 if (func == CRYPTO_FG_ENCRYPT) 143 error = KCF_PROV_ENCRYPT_INIT(real_provider, ctx, 144 &lmech, key, tmpl, KCF_SWFP_RHNDL(crq)); 145 else { 146 ASSERT(func == CRYPTO_FG_DECRYPT); 147 148 error = KCF_PROV_DECRYPT_INIT(real_provider, ctx, 149 &lmech, key, tmpl, KCF_SWFP_RHNDL(crq)); 150 } 151 KCF_PROV_INCRSTATS(pd, error); 152 153 goto done; 154 } 155 156 /* Check if context sharing is possible */ 157 if (pd->pd_prov_type == CRYPTO_HW_PROVIDER && 158 key->ck_format == CRYPTO_KEY_RAW && 159 KCF_CAN_SHARE_OPSTATE(pd, mech->cm_type)) { 160 kcf_context_t *tctxp = (kcf_context_t *)ctx; 161 kcf_provider_desc_t *tpd = NULL; 162 crypto_mech_info_t *sinfo; 163 164 if ((kcf_get_sw_prov(mech->cm_type, &tpd, &tctxp->kc_mech, 165 B_FALSE) == CRYPTO_SUCCESS)) { 166 int tlen; 167 168 sinfo = &(KCF_TO_PROV_MECHINFO(tpd, mech->cm_type)); 169 /* 170 * key->ck_length from the consumer is always in bits. 171 * We convert it to be in the same unit registered by 172 * the provider in order to do a comparison. 173 */ 174 if (sinfo->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES) 175 tlen = key->ck_length >> 3; 176 else 177 tlen = key->ck_length; 178 /* 179 * Check if the software provider can support context 180 * sharing and support this key length. 181 */ 182 if ((sinfo->cm_mech_flags & CRYPTO_CAN_SHARE_OPSTATE) && 183 (tlen >= sinfo->cm_min_key_length) && 184 (tlen <= sinfo->cm_max_key_length)) { 185 ctx->cc_flags = CRYPTO_INIT_OPSTATE; 186 tctxp->kc_sw_prov_desc = tpd; 187 } else 188 KCF_PROV_REFRELE(tpd); 189 } 190 } 191 192 if (func == CRYPTO_FG_ENCRYPT) { 193 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid, 194 mech, key, NULL, NULL, tmpl); 195 } else { 196 ASSERT(func == CRYPTO_FG_DECRYPT); 197 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid, 198 mech, key, NULL, NULL, tmpl); 199 } 200 201 error = kcf_submit_request(real_provider, ctx, crq, ¶ms, 202 B_FALSE); 203 204 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 205 KCF_PROV_REFRELE(real_provider); 206 207 done: 208 if ((error == CRYPTO_SUCCESS) || (error == CRYPTO_QUEUED)) 209 *ctxp = (crypto_context_t)ctx; 210 else { 211 /* Release the hold done in kcf_new_ctx(). */ 212 KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private); 213 } 214 215 return (error); 216 } 217 218 /* 219 * Same as crypto_cipher_init_prov(), but relies on the scheduler to pick 220 * an appropriate provider. See crypto_cipher_init_prov() comments for more 221 * details. 222 */ 223 static int 224 crypto_cipher_init(crypto_mechanism_t *mech, crypto_key_t *key, 225 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 226 crypto_call_req_t *crq, crypto_func_group_t func) 227 { 228 int error; 229 kcf_mech_entry_t *me; 230 kcf_provider_desc_t *pd; 231 kcf_ctx_template_t *ctx_tmpl; 232 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 233 kcf_prov_tried_t *list = NULL; 234 235 retry: 236 /* pd is returned held */ 237 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 238 list, func, CHECK_RESTRICT(crq), 0)) == NULL) { 239 if (list != NULL) 240 kcf_free_triedlist(list); 241 return (error); 242 } 243 244 /* 245 * For SW providers, check the validity of the context template 246 * It is very rare that the generation number mis-matches, so 247 * is acceptable to fail here, and let the consumer recover by 248 * freeing this tmpl and create a new one for the key and new SW 249 * provider 250 */ 251 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) && 252 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) { 253 if (ctx_tmpl->ct_generation != me->me_gen_swprov) { 254 if (list != NULL) 255 kcf_free_triedlist(list); 256 KCF_PROV_REFRELE(pd); 257 return (CRYPTO_OLD_CTX_TEMPLATE); 258 } else { 259 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 260 } 261 } 262 263 error = crypto_cipher_init_prov(pd, pd->pd_sid, mech, key, 264 spi_ctx_tmpl, ctxp, crq, func); 265 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 266 IS_RECOVERABLE(error)) { 267 /* Add pd to the linked list of providers tried. */ 268 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 269 goto retry; 270 } 271 272 if (list != NULL) 273 kcf_free_triedlist(list); 274 275 KCF_PROV_REFRELE(pd); 276 return (error); 277 } 278 279 /* 280 * crypto_encrypt_prov() 281 * 282 * Arguments: 283 * pd: provider descriptor 284 * sid: session id 285 * mech: crypto_mechanism_t pointer. 286 * mech_type is a valid value previously returned by 287 * crypto_mech2id(); 288 * When the mech's parameter is not NULL, its definition depends 289 * on the standard definition of the mechanism. 290 * key: pointer to a crypto_key_t structure. 291 * plaintext: The message to be encrypted 292 * ciphertext: Storage for the encrypted message. The length needed 293 * depends on the mechanism, and the plaintext's size. 294 * tmpl: a crypto_ctx_template_t, opaque template of a context of an 295 * encryption with the 'mech' using 'key'. 'tmpl' is created by 296 * a previous call to crypto_create_ctx_template(). 297 * cr: crypto_call_req_t calling conditions and call back info. 298 * 299 * Description: 300 * Asynchronously submits a request for, or synchronously performs a 301 * single-part encryption of 'plaintext' with the mechanism 'mech', using 302 * the key 'key'. 303 * When complete and successful, 'ciphertext' will contain the encrypted 304 * message. 305 * 306 * Context: 307 * Process or interrupt, according to the semantics dictated by the 'cr'. 308 * 309 * Returns: 310 * See comment in the beginning of the file. 311 */ 312 int 313 crypto_encrypt_prov(crypto_provider_t provider, crypto_session_id_t sid, 314 crypto_mechanism_t *mech, crypto_data_t *plaintext, crypto_key_t *key, 315 crypto_ctx_template_t tmpl, crypto_data_t *ciphertext, 316 crypto_call_req_t *crq) 317 { 318 kcf_req_params_t params; 319 kcf_provider_desc_t *pd = provider; 320 kcf_provider_desc_t *real_provider = pd; 321 int error; 322 323 ASSERT(KCF_PROV_REFHELD(pd)); 324 325 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 326 error = kcf_get_hardware_provider(mech->cm_type, 327 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 328 &real_provider, CRYPTO_FG_ENCRYPT_ATOMIC); 329 330 if (error != CRYPTO_SUCCESS) 331 return (error); 332 } 333 334 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, sid, mech, key, 335 plaintext, ciphertext, tmpl); 336 337 error = kcf_submit_request(real_provider, NULL, crq, ¶ms, B_FALSE); 338 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 339 KCF_PROV_REFRELE(real_provider); 340 341 return (error); 342 } 343 344 /* 345 * Same as crypto_encrypt_prov(), but relies on the scheduler to pick 346 * a provider. See crypto_encrypt_prov() for more details. 347 */ 348 int 349 crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext, 350 crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *ciphertext, 351 crypto_call_req_t *crq) 352 { 353 int error; 354 kcf_mech_entry_t *me; 355 kcf_req_params_t params; 356 kcf_provider_desc_t *pd; 357 kcf_ctx_template_t *ctx_tmpl; 358 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 359 kcf_prov_tried_t *list = NULL; 360 361 retry: 362 /* pd is returned held */ 363 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 364 list, CRYPTO_FG_ENCRYPT_ATOMIC, CHECK_RESTRICT(crq), 365 plaintext->cd_length)) == NULL) { 366 if (list != NULL) 367 kcf_free_triedlist(list); 368 return (error); 369 } 370 371 /* 372 * For SW providers, check the validity of the context template 373 * It is very rare that the generation number mis-matches, so 374 * is acceptable to fail here, and let the consumer recover by 375 * freeing this tmpl and create a new one for the key and new SW 376 * provider 377 */ 378 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) && 379 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) { 380 if (ctx_tmpl->ct_generation != me->me_gen_swprov) { 381 if (list != NULL) 382 kcf_free_triedlist(list); 383 KCF_PROV_REFRELE(pd); 384 return (CRYPTO_OLD_CTX_TEMPLATE); 385 } else { 386 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 387 } 388 } 389 390 /* The fast path for SW providers. */ 391 if (CHECK_FASTPATH(crq, pd)) { 392 crypto_mechanism_t lmech; 393 394 lmech = *mech; 395 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 396 397 error = KCF_PROV_ENCRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key, 398 plaintext, ciphertext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq)); 399 KCF_PROV_INCRSTATS(pd, error); 400 } else { 401 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, pd->pd_sid, 402 mech, key, plaintext, ciphertext, spi_ctx_tmpl); 403 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE); 404 } 405 406 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 407 IS_RECOVERABLE(error)) { 408 /* Add pd to the linked list of providers tried. */ 409 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 410 goto retry; 411 } 412 413 if (list != NULL) 414 kcf_free_triedlist(list); 415 416 KCF_PROV_REFRELE(pd); 417 return (error); 418 } 419 420 /* 421 * crypto_encrypt_init_prov() 422 * 423 * Calls crypto_cipher_init_prov() to initialize an encryption operation. 424 */ 425 int 426 crypto_encrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid, 427 crypto_mechanism_t *mech, crypto_key_t *key, 428 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 429 crypto_call_req_t *crq) 430 { 431 return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq, 432 CRYPTO_FG_ENCRYPT)); 433 } 434 435 /* 436 * crypto_encrypt_init() 437 * 438 * Calls crypto_cipher_init() to initialize an encryption operation 439 */ 440 int 441 crypto_encrypt_init(crypto_mechanism_t *mech, crypto_key_t *key, 442 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 443 crypto_call_req_t *crq) 444 { 445 return (crypto_cipher_init(mech, key, tmpl, ctxp, crq, 446 CRYPTO_FG_ENCRYPT)); 447 } 448 449 /* 450 * crypto_encrypt_update() 451 * 452 * Arguments: 453 * context: A crypto_context_t initialized by encrypt_init(). 454 * plaintext: The message part to be encrypted 455 * ciphertext: Storage for the encrypted message part. 456 * cr: crypto_call_req_t calling conditions and call back info. 457 * 458 * Description: 459 * Asynchronously submits a request for, or synchronously performs a 460 * part of an encryption operation. 461 * 462 * Context: 463 * Process or interrupt, according to the semantics dictated by the 'cr'. 464 * 465 * Returns: 466 * See comment in the beginning of the file. 467 */ 468 int 469 crypto_encrypt_update(crypto_context_t context, crypto_data_t *plaintext, 470 crypto_data_t *ciphertext, crypto_call_req_t *cr) 471 { 472 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 473 kcf_context_t *kcf_ctx; 474 kcf_provider_desc_t *pd; 475 int error; 476 kcf_req_params_t params; 477 478 if ((ctx == NULL) || 479 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 480 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 481 return (CRYPTO_INVALID_CONTEXT); 482 } 483 484 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 485 486 /* The fast path for SW providers. */ 487 if (CHECK_FASTPATH(cr, pd)) { 488 error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext, 489 ciphertext, NULL); 490 KCF_PROV_INCRSTATS(pd, error); 491 return (error); 492 } 493 494 /* Check if we should use a software provider for small jobs */ 495 if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) { 496 if (plaintext->cd_length < kcf_ctx->kc_mech->me_threshold && 497 kcf_ctx->kc_sw_prov_desc != NULL && 498 KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) { 499 pd = kcf_ctx->kc_sw_prov_desc; 500 } 501 } 502 503 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 504 ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL); 505 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 506 507 return (error); 508 } 509 510 /* 511 * crypto_encrypt_final() 512 * 513 * Arguments: 514 * context: A crypto_context_t initialized by encrypt_init(). 515 * ciphertext: Storage for the last part of encrypted message 516 * cr: crypto_call_req_t calling conditions and call back info. 517 * 518 * Description: 519 * Asynchronously submits a request for, or synchronously performs the 520 * final part of an encryption operation. 521 * 522 * Context: 523 * Process or interrupt, according to the semantics dictated by the 'cr'. 524 * 525 * Returns: 526 * See comment in the beginning of the file. 527 */ 528 int 529 crypto_encrypt_final(crypto_context_t context, crypto_data_t *ciphertext, 530 crypto_call_req_t *cr) 531 { 532 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 533 kcf_context_t *kcf_ctx; 534 kcf_provider_desc_t *pd; 535 int error; 536 kcf_req_params_t params; 537 538 if ((ctx == NULL) || 539 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 540 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 541 return (CRYPTO_INVALID_CONTEXT); 542 } 543 544 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 545 546 /* The fast path for SW providers. */ 547 if (CHECK_FASTPATH(cr, pd)) { 548 error = KCF_PROV_ENCRYPT_FINAL(pd, ctx, ciphertext, NULL); 549 KCF_PROV_INCRSTATS(pd, error); 550 } else { 551 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL, 552 ctx->cc_session, NULL, NULL, NULL, ciphertext, NULL); 553 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 554 } 555 556 /* Release the hold done in kcf_new_ctx() during init step. */ 557 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 558 return (error); 559 } 560 561 /* 562 * crypto_decrypt_prov() 563 * 564 * Arguments: 565 * pd: provider descriptor 566 * sid: session id 567 * mech: crypto_mechanism_t pointer. 568 * mech_type is a valid value previously returned by 569 * crypto_mech2id(); 570 * When the mech's parameter is not NULL, its definition depends 571 * on the standard definition of the mechanism. 572 * key: pointer to a crypto_key_t structure. 573 * ciphertext: The message to be encrypted 574 * plaintext: Storage for the encrypted message. The length needed 575 * depends on the mechanism, and the plaintext's size. 576 * tmpl: a crypto_ctx_template_t, opaque template of a context of an 577 * encryption with the 'mech' using 'key'. 'tmpl' is created by 578 * a previous call to crypto_create_ctx_template(). 579 * cr: crypto_call_req_t calling conditions and call back info. 580 * 581 * Description: 582 * Asynchronously submits a request for, or synchronously performs a 583 * single-part decryption of 'ciphertext' with the mechanism 'mech', using 584 * the key 'key'. 585 * When complete and successful, 'plaintext' will contain the decrypted 586 * message. 587 * 588 * Context: 589 * Process or interrupt, according to the semantics dictated by the 'cr'. 590 * 591 * Returns: 592 * See comment in the beginning of the file. 593 */ 594 int 595 crypto_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid, 596 crypto_mechanism_t *mech, crypto_data_t *ciphertext, crypto_key_t *key, 597 crypto_ctx_template_t tmpl, crypto_data_t *plaintext, 598 crypto_call_req_t *crq) 599 { 600 kcf_req_params_t params; 601 kcf_provider_desc_t *pd = provider; 602 kcf_provider_desc_t *real_provider = pd; 603 int rv; 604 605 ASSERT(KCF_PROV_REFHELD(pd)); 606 607 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 608 rv = kcf_get_hardware_provider(mech->cm_type, 609 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 610 &real_provider, CRYPTO_FG_DECRYPT_ATOMIC); 611 612 if (rv != CRYPTO_SUCCESS) 613 return (rv); 614 } 615 616 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, sid, mech, key, 617 ciphertext, plaintext, tmpl); 618 619 rv = kcf_submit_request(real_provider, NULL, crq, ¶ms, B_FALSE); 620 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 621 KCF_PROV_REFRELE(real_provider); 622 623 return (rv); 624 } 625 626 /* 627 * Same as crypto_decrypt_prov(), but relies on the KCF scheduler to 628 * choose a provider. See crypto_decrypt_prov() comments for more 629 * information. 630 */ 631 int 632 crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext, 633 crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext, 634 crypto_call_req_t *crq) 635 { 636 int error; 637 kcf_mech_entry_t *me; 638 kcf_req_params_t params; 639 kcf_provider_desc_t *pd; 640 kcf_ctx_template_t *ctx_tmpl; 641 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 642 kcf_prov_tried_t *list = NULL; 643 644 retry: 645 /* pd is returned held */ 646 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 647 list, CRYPTO_FG_DECRYPT_ATOMIC, CHECK_RESTRICT(crq), 648 ciphertext->cd_length)) == NULL) { 649 if (list != NULL) 650 kcf_free_triedlist(list); 651 return (error); 652 } 653 654 /* 655 * For SW providers, check the validity of the context template 656 * It is very rare that the generation number mis-matches, so 657 * is acceptable to fail here, and let the consumer recover by 658 * freeing this tmpl and create a new one for the key and new SW 659 * provider 660 */ 661 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) && 662 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) { 663 if (ctx_tmpl->ct_generation != me->me_gen_swprov) { 664 if (list != NULL) 665 kcf_free_triedlist(list); 666 KCF_PROV_REFRELE(pd); 667 return (CRYPTO_OLD_CTX_TEMPLATE); 668 } else { 669 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 670 } 671 } 672 673 /* The fast path for SW providers. */ 674 if (CHECK_FASTPATH(crq, pd)) { 675 crypto_mechanism_t lmech; 676 677 lmech = *mech; 678 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 679 680 error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key, 681 ciphertext, plaintext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq)); 682 KCF_PROV_INCRSTATS(pd, error); 683 } else { 684 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, pd->pd_sid, 685 mech, key, ciphertext, plaintext, spi_ctx_tmpl); 686 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE); 687 } 688 689 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 690 IS_RECOVERABLE(error)) { 691 /* Add pd to the linked list of providers tried. */ 692 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 693 goto retry; 694 } 695 696 if (list != NULL) 697 kcf_free_triedlist(list); 698 699 KCF_PROV_REFRELE(pd); 700 return (error); 701 } 702 703 /* 704 * crypto_decrypt_init_prov() 705 * 706 * Calls crypto_cipher_init_prov() to initialize a decryption operation 707 */ 708 int 709 crypto_decrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid, 710 crypto_mechanism_t *mech, crypto_key_t *key, 711 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 712 crypto_call_req_t *crq) 713 { 714 return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq, 715 CRYPTO_FG_DECRYPT)); 716 } 717 718 /* 719 * crypto_decrypt_init() 720 * 721 * Calls crypto_cipher_init() to initialize a decryption operation 722 */ 723 int 724 crypto_decrypt_init(crypto_mechanism_t *mech, crypto_key_t *key, 725 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 726 crypto_call_req_t *crq) 727 { 728 return (crypto_cipher_init(mech, key, tmpl, ctxp, crq, 729 CRYPTO_FG_DECRYPT)); 730 } 731 732 /* 733 * crypto_decrypt_update() 734 * 735 * Arguments: 736 * context: A crypto_context_t initialized by decrypt_init(). 737 * ciphertext: The message part to be decrypted 738 * plaintext: Storage for the decrypted message part. 739 * cr: crypto_call_req_t calling conditions and call back info. 740 * 741 * Description: 742 * Asynchronously submits a request for, or synchronously performs a 743 * part of an decryption operation. 744 * 745 * Context: 746 * Process or interrupt, according to the semantics dictated by the 'cr'. 747 * 748 * Returns: 749 * See comment in the beginning of the file. 750 */ 751 int 752 crypto_decrypt_update(crypto_context_t context, crypto_data_t *ciphertext, 753 crypto_data_t *plaintext, crypto_call_req_t *cr) 754 { 755 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 756 kcf_context_t *kcf_ctx; 757 kcf_provider_desc_t *pd; 758 int error; 759 kcf_req_params_t params; 760 761 if ((ctx == NULL) || 762 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 763 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 764 return (CRYPTO_INVALID_CONTEXT); 765 } 766 767 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 768 769 /* The fast path for SW providers. */ 770 if (CHECK_FASTPATH(cr, pd)) { 771 error = KCF_PROV_DECRYPT_UPDATE(pd, ctx, ciphertext, 772 plaintext, NULL); 773 KCF_PROV_INCRSTATS(pd, error); 774 return (error); 775 } 776 777 /* Check if we should use a software provider for small jobs */ 778 if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) { 779 if (ciphertext->cd_length < kcf_ctx->kc_mech->me_threshold && 780 kcf_ctx->kc_sw_prov_desc != NULL && 781 KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) { 782 pd = kcf_ctx->kc_sw_prov_desc; 783 } 784 } 785 786 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 787 ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL); 788 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 789 790 return (error); 791 } 792 793 /* 794 * crypto_decrypt_final() 795 * 796 * Arguments: 797 * context: A crypto_context_t initialized by decrypt_init(). 798 * plaintext: Storage for the last part of the decrypted message 799 * cr: crypto_call_req_t calling conditions and call back info. 800 * 801 * Description: 802 * Asynchronously submits a request for, or synchronously performs the 803 * final part of a decryption operation. 804 * 805 * Context: 806 * Process or interrupt, according to the semantics dictated by the 'cr'. 807 * 808 * Returns: 809 * See comment in the beginning of the file. 810 */ 811 int 812 crypto_decrypt_final(crypto_context_t context, crypto_data_t *plaintext, 813 crypto_call_req_t *cr) 814 { 815 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 816 kcf_context_t *kcf_ctx; 817 kcf_provider_desc_t *pd; 818 int error; 819 kcf_req_params_t params; 820 821 if ((ctx == NULL) || 822 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 823 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 824 return (CRYPTO_INVALID_CONTEXT); 825 } 826 827 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 828 829 /* The fast path for SW providers. */ 830 if (CHECK_FASTPATH(cr, pd)) { 831 error = KCF_PROV_DECRYPT_FINAL(pd, ctx, plaintext, 832 NULL); 833 KCF_PROV_INCRSTATS(pd, error); 834 } else { 835 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL, 836 ctx->cc_session, NULL, NULL, NULL, plaintext, NULL); 837 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 838 } 839 840 /* Release the hold done in kcf_new_ctx() during init step. */ 841 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 842 return (error); 843 } 844 845 /* 846 * See comments for crypto_encrypt_update(). 847 */ 848 int 849 crypto_encrypt_single(crypto_context_t context, crypto_data_t *plaintext, 850 crypto_data_t *ciphertext, crypto_call_req_t *cr) 851 { 852 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 853 kcf_context_t *kcf_ctx; 854 kcf_provider_desc_t *pd; 855 int error; 856 kcf_req_params_t params; 857 858 if ((ctx == NULL) || 859 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 860 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 861 return (CRYPTO_INVALID_CONTEXT); 862 } 863 864 /* The fast path for SW providers. */ 865 if (CHECK_FASTPATH(cr, pd)) { 866 error = KCF_PROV_ENCRYPT(pd, ctx, plaintext, 867 ciphertext, NULL); 868 KCF_PROV_INCRSTATS(pd, error); 869 } else { 870 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_SINGLE, pd->pd_sid, 871 NULL, NULL, plaintext, ciphertext, NULL); 872 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 873 } 874 875 /* Release the hold done in kcf_new_ctx() during init step. */ 876 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 877 return (error); 878 } 879 880 /* 881 * See comments for crypto_decrypt_update(). 882 */ 883 int 884 crypto_decrypt_single(crypto_context_t context, crypto_data_t *ciphertext, 885 crypto_data_t *plaintext, crypto_call_req_t *cr) 886 { 887 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 888 kcf_context_t *kcf_ctx; 889 kcf_provider_desc_t *pd; 890 int error; 891 kcf_req_params_t params; 892 893 if ((ctx == NULL) || 894 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 895 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 896 return (CRYPTO_INVALID_CONTEXT); 897 } 898 899 /* The fast path for SW providers. */ 900 if (CHECK_FASTPATH(cr, pd)) { 901 error = KCF_PROV_DECRYPT(pd, ctx, ciphertext, 902 plaintext, NULL); 903 KCF_PROV_INCRSTATS(pd, error); 904 } else { 905 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_SINGLE, pd->pd_sid, 906 NULL, NULL, ciphertext, plaintext, NULL); 907 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 908 } 909 910 /* Release the hold done in kcf_new_ctx() during init step. */ 911 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 912 return (error); 913 } 914 915 #if defined(_KERNEL) 916 EXPORT_SYMBOL(crypto_encrypt_prov); 917 EXPORT_SYMBOL(crypto_encrypt); 918 EXPORT_SYMBOL(crypto_encrypt_init_prov); 919 EXPORT_SYMBOL(crypto_encrypt_init); 920 EXPORT_SYMBOL(crypto_encrypt_update); 921 EXPORT_SYMBOL(crypto_encrypt_final); 922 EXPORT_SYMBOL(crypto_decrypt_prov); 923 EXPORT_SYMBOL(crypto_decrypt); 924 EXPORT_SYMBOL(crypto_decrypt_init_prov); 925 EXPORT_SYMBOL(crypto_decrypt_init); 926 EXPORT_SYMBOL(crypto_decrypt_update); 927 EXPORT_SYMBOL(crypto_decrypt_final); 928 EXPORT_SYMBOL(crypto_encrypt_single); 929 EXPORT_SYMBOL(crypto_decrypt_single); 930 #endif 931