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