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