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