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