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