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 #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 455 /* The fast path for SW providers. */ 456 if (CHECK_FASTPATH(cr, pd)) { 457 error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext, 458 ciphertext, NULL); 459 KCF_PROV_INCRSTATS(pd, error); 460 } else { 461 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 462 ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL); 463 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 464 } 465 466 return (error); 467 } 468 469 /* 470 * crypto_encrypt_final() 471 * 472 * Arguments: 473 * context: A crypto_context_t initialized by encrypt_init(). 474 * ciphertext: Storage for the last part of encrypted message 475 * cr: crypto_call_req_t calling conditions and call back info. 476 * 477 * Description: 478 * Asynchronously submits a request for, or synchronously performs the 479 * final part of an encryption operation. 480 * 481 * Context: 482 * Process or interrupt, according to the semantics dictated by the 'cr'. 483 * 484 * Returns: 485 * See comment in the beginning of the file. 486 */ 487 int 488 crypto_encrypt_final(crypto_context_t context, crypto_data_t *ciphertext, 489 crypto_call_req_t *cr) 490 { 491 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 492 kcf_context_t *kcf_ctx; 493 kcf_provider_desc_t *pd; 494 int error; 495 kcf_req_params_t params; 496 497 if ((ctx == NULL) || 498 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 499 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 500 return (CRYPTO_INVALID_CONTEXT); 501 } 502 503 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 504 505 /* The fast path for SW providers. */ 506 if (CHECK_FASTPATH(cr, pd)) { 507 error = KCF_PROV_ENCRYPT_FINAL(pd, ctx, ciphertext, NULL); 508 KCF_PROV_INCRSTATS(pd, error); 509 } else { 510 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL, 511 ctx->cc_session, NULL, NULL, NULL, ciphertext, NULL); 512 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 513 } 514 515 /* Release the hold done in kcf_new_ctx() during init step. */ 516 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 517 return (error); 518 } 519 520 /* 521 * crypto_decrypt_prov() 522 * 523 * Arguments: 524 * pd: provider descriptor 525 * sid: session id 526 * mech: crypto_mechanism_t pointer. 527 * mech_type is a valid value previously returned by 528 * crypto_mech2id(); 529 * When the mech's parameter is not NULL, its definition depends 530 * on the standard definition of the mechanism. 531 * key: pointer to a crypto_key_t structure. 532 * ciphertext: The message to be encrypted 533 * plaintext: Storage for the encrypted message. The length needed 534 * depends on the mechanism, and the plaintext's size. 535 * tmpl: a crypto_ctx_template_t, opaque template of a context of an 536 * encryption with the 'mech' using 'key'. 'tmpl' is created by 537 * a previous call to crypto_create_ctx_template(). 538 * cr: crypto_call_req_t calling conditions and call back info. 539 * 540 * Description: 541 * Asynchronously submits a request for, or synchronously performs a 542 * single-part decryption of 'ciphertext' with the mechanism 'mech', using 543 * the key 'key'. 544 * When complete and successful, 'plaintext' will contain the decrypted 545 * message. 546 * 547 * Context: 548 * Process or interrupt, according to the semantics dictated by the 'cr'. 549 * 550 * Returns: 551 * See comment in the beginning of the file. 552 */ 553 int 554 crypto_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid, 555 crypto_mechanism_t *mech, crypto_data_t *ciphertext, crypto_key_t *key, 556 crypto_ctx_template_t tmpl, crypto_data_t *plaintext, 557 crypto_call_req_t *crq) 558 { 559 kcf_req_params_t params; 560 kcf_provider_desc_t *pd = provider; 561 kcf_provider_desc_t *real_provider = pd; 562 int rv; 563 564 ASSERT(KCF_PROV_REFHELD(pd)); 565 566 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 567 rv = kcf_get_hardware_provider(mech->cm_type, 568 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 569 &real_provider, CRYPTO_FG_DECRYPT_ATOMIC); 570 571 if (rv != CRYPTO_SUCCESS) 572 return (rv); 573 } 574 575 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, sid, mech, key, 576 ciphertext, plaintext, tmpl); 577 578 rv = kcf_submit_request(real_provider, NULL, crq, ¶ms, B_FALSE); 579 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 580 KCF_PROV_REFRELE(real_provider); 581 582 return (rv); 583 } 584 585 /* 586 * Same as crypto_decrypt_prov(), but relies on the KCF scheduler to 587 * choose a provider. See crypto_decrypt_prov() comments for more 588 * information. 589 */ 590 int 591 crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext, 592 crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext, 593 crypto_call_req_t *crq) 594 { 595 int error; 596 kcf_mech_entry_t *me; 597 kcf_req_params_t params; 598 kcf_provider_desc_t *pd; 599 kcf_ctx_template_t *ctx_tmpl; 600 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 601 kcf_prov_tried_t *list = NULL; 602 603 retry: 604 /* pd is returned held */ 605 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 606 list, CRYPTO_FG_DECRYPT_ATOMIC, CHECK_RESTRICT(crq), 607 ciphertext->cd_length)) == NULL) { 608 if (list != NULL) 609 kcf_free_triedlist(list); 610 return (error); 611 } 612 613 /* 614 * For SW providers, check the validity of the context template 615 * It is very rare that the generation number mis-matches, so 616 * is acceptable to fail here, and let the consumer recover by 617 * freeing this tmpl and create a new one for the key and new SW 618 * provider 619 */ 620 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) && 621 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) { 622 if (ctx_tmpl->ct_generation != me->me_gen_swprov) { 623 if (list != NULL) 624 kcf_free_triedlist(list); 625 KCF_PROV_REFRELE(pd); 626 return (CRYPTO_OLD_CTX_TEMPLATE); 627 } else { 628 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 629 } 630 } 631 632 /* The fast path for SW providers. */ 633 if (CHECK_FASTPATH(crq, pd)) { 634 crypto_mechanism_t lmech; 635 636 lmech = *mech; 637 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 638 639 error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key, 640 ciphertext, plaintext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq)); 641 KCF_PROV_INCRSTATS(pd, error); 642 } else { 643 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, pd->pd_sid, 644 mech, key, ciphertext, plaintext, spi_ctx_tmpl); 645 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE); 646 } 647 648 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 649 IS_RECOVERABLE(error)) { 650 /* Add pd to the linked list of providers tried. */ 651 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 652 goto retry; 653 } 654 655 if (list != NULL) 656 kcf_free_triedlist(list); 657 658 KCF_PROV_REFRELE(pd); 659 return (error); 660 } 661 662 /* 663 * crypto_decrypt_init_prov() 664 * 665 * Calls crypto_cipher_init_prov() to initialize a decryption operation 666 */ 667 int 668 crypto_decrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid, 669 crypto_mechanism_t *mech, crypto_key_t *key, 670 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 671 crypto_call_req_t *crq) 672 { 673 return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq, 674 CRYPTO_FG_DECRYPT)); 675 } 676 677 /* 678 * crypto_decrypt_init() 679 * 680 * Calls crypto_cipher_init() to initialize a decryption operation 681 */ 682 int 683 crypto_decrypt_init(crypto_mechanism_t *mech, crypto_key_t *key, 684 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 685 crypto_call_req_t *crq) 686 { 687 return (crypto_cipher_init(mech, key, tmpl, ctxp, crq, 688 CRYPTO_FG_DECRYPT)); 689 } 690 691 /* 692 * crypto_decrypt_update() 693 * 694 * Arguments: 695 * context: A crypto_context_t initialized by decrypt_init(). 696 * ciphertext: The message part to be decrypted 697 * plaintext: Storage for the decrypted message part. 698 * cr: crypto_call_req_t calling conditions and call back info. 699 * 700 * Description: 701 * Asynchronously submits a request for, or synchronously performs a 702 * part of an decryption operation. 703 * 704 * Context: 705 * Process or interrupt, according to the semantics dictated by the 'cr'. 706 * 707 * Returns: 708 * See comment in the beginning of the file. 709 */ 710 int 711 crypto_decrypt_update(crypto_context_t context, crypto_data_t *ciphertext, 712 crypto_data_t *plaintext, crypto_call_req_t *cr) 713 { 714 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 715 kcf_context_t *kcf_ctx; 716 kcf_provider_desc_t *pd; 717 int error; 718 kcf_req_params_t params; 719 720 if ((ctx == NULL) || 721 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 722 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 723 return (CRYPTO_INVALID_CONTEXT); 724 } 725 726 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 727 728 /* The fast path for SW providers. */ 729 if (CHECK_FASTPATH(cr, pd)) { 730 error = KCF_PROV_DECRYPT_UPDATE(pd, ctx, ciphertext, 731 plaintext, NULL); 732 KCF_PROV_INCRSTATS(pd, error); 733 } else { 734 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 735 ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL); 736 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 737 } 738 739 return (error); 740 } 741 742 /* 743 * crypto_decrypt_final() 744 * 745 * Arguments: 746 * context: A crypto_context_t initialized by decrypt_init(). 747 * plaintext: Storage for the last part of the decrypted message 748 * cr: crypto_call_req_t calling conditions and call back info. 749 * 750 * Description: 751 * Asynchronously submits a request for, or synchronously performs the 752 * final part of a decryption operation. 753 * 754 * Context: 755 * Process or interrupt, according to the semantics dictated by the 'cr'. 756 * 757 * Returns: 758 * See comment in the beginning of the file. 759 */ 760 int 761 crypto_decrypt_final(crypto_context_t context, crypto_data_t *plaintext, 762 crypto_call_req_t *cr) 763 { 764 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 765 kcf_context_t *kcf_ctx; 766 kcf_provider_desc_t *pd; 767 int error; 768 kcf_req_params_t params; 769 770 if ((ctx == NULL) || 771 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 772 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 773 return (CRYPTO_INVALID_CONTEXT); 774 } 775 776 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 777 778 /* The fast path for SW providers. */ 779 if (CHECK_FASTPATH(cr, pd)) { 780 error = KCF_PROV_DECRYPT_FINAL(pd, ctx, plaintext, 781 NULL); 782 KCF_PROV_INCRSTATS(pd, error); 783 } else { 784 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL, 785 ctx->cc_session, NULL, NULL, NULL, plaintext, NULL); 786 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 787 } 788 789 /* Release the hold done in kcf_new_ctx() during init step. */ 790 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 791 return (error); 792 } 793 794 /* 795 * See comments for crypto_encrypt_update(). 796 */ 797 int 798 crypto_encrypt_single(crypto_context_t context, crypto_data_t *plaintext, 799 crypto_data_t *ciphertext, crypto_call_req_t *cr) 800 { 801 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 802 kcf_context_t *kcf_ctx; 803 kcf_provider_desc_t *pd; 804 int error; 805 kcf_req_params_t params; 806 807 if ((ctx == NULL) || 808 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 809 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 810 return (CRYPTO_INVALID_CONTEXT); 811 } 812 813 814 /* The fast path for SW providers. */ 815 if (CHECK_FASTPATH(cr, pd)) { 816 error = KCF_PROV_ENCRYPT(pd, ctx, plaintext, 817 ciphertext, NULL); 818 KCF_PROV_INCRSTATS(pd, error); 819 } else { 820 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_SINGLE, pd->pd_sid, 821 NULL, NULL, plaintext, ciphertext, NULL); 822 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 823 } 824 825 /* Release the hold done in kcf_new_ctx() during init step. */ 826 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 827 return (error); 828 } 829 830 /* 831 * See comments for crypto_decrypt_update(). 832 */ 833 int 834 crypto_decrypt_single(crypto_context_t context, crypto_data_t *ciphertext, 835 crypto_data_t *plaintext, crypto_call_req_t *cr) 836 { 837 crypto_ctx_t *ctx = (crypto_ctx_t *)context; 838 kcf_context_t *kcf_ctx; 839 kcf_provider_desc_t *pd; 840 int error; 841 kcf_req_params_t params; 842 843 if ((ctx == NULL) || 844 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 845 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 846 return (CRYPTO_INVALID_CONTEXT); 847 } 848 849 850 /* The fast path for SW providers. */ 851 if (CHECK_FASTPATH(cr, pd)) { 852 error = KCF_PROV_DECRYPT(pd, ctx, ciphertext, 853 plaintext, NULL); 854 KCF_PROV_INCRSTATS(pd, error); 855 } else { 856 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_SINGLE, pd->pd_sid, 857 NULL, NULL, ciphertext, plaintext, NULL); 858 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 859 } 860 861 /* Release the hold done in kcf_new_ctx() during init step. */ 862 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 863 return (error); 864 } 865