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