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 2006 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_MAC_OFFSET(f) offsetof(crypto_dual_cipher_mac_ops_t, f) 40 41 static int crypto_mac_decrypt_common(crypto_mechanism_t *, 42 crypto_mechanism_t *, crypto_dual_data_t *, crypto_key_t *, crypto_key_t *, 43 crypto_ctx_template_t, crypto_ctx_template_t, crypto_data_t *, 44 crypto_data_t *, crypto_call_req_t *, boolean_t); 45 46 static int crypto_mac_decrypt_common_prov(crypto_provider_t provider, 47 crypto_session_id_t sid, crypto_mechanism_t *, crypto_mechanism_t *, 48 crypto_dual_data_t *, crypto_key_t *, crypto_key_t *, 49 crypto_ctx_template_t, crypto_ctx_template_t, crypto_data_t *, 50 crypto_data_t *, crypto_call_req_t *, boolean_t); 51 52 int 53 crypto_encrypt_mac_prov(crypto_provider_t provider, crypto_session_id_t sid, 54 crypto_mechanism_t *encr_mech, crypto_mechanism_t *mac_mech, 55 crypto_data_t *pt, crypto_key_t *encr_key, crypto_key_t *mac_key, 56 crypto_ctx_template_t encr_tmpl, crypto_ctx_template_t mac_tmpl, 57 crypto_dual_data_t *ct, crypto_data_t *mac, crypto_call_req_t *crq) 58 { 59 /* 60 * First try to find a provider for the encryption mechanism, that 61 * is also capable of the MAC mechanism. 62 */ 63 int rv; 64 kcf_mech_entry_t *me; 65 kcf_provider_desc_t *pd = provider; 66 kcf_provider_desc_t *real_provider = pd; 67 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl; 68 kcf_req_params_t params; 69 kcf_encrypt_mac_ops_params_t *cmops; 70 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL; 71 72 ASSERT(KCF_PROV_REFHELD(pd)); 73 74 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 75 rv = kcf_get_hardware_provider(encr_mech->cm_type, 76 mac_mech->cm_type, CHECK_RESTRICT(crq), pd, 77 &real_provider, CRYPTO_FG_ENCRYPT_MAC_ATOMIC); 78 79 if (rv != CRYPTO_SUCCESS) 80 return (rv); 81 } 82 83 /* 84 * For SW providers, check the validity of the context template 85 * It is very rare that the generation number mis-matches, so 86 * is acceptable to fail here, and let the consumer recover by 87 * freeing this tmpl and create a new one for the key and new SW 88 * provider 89 * Warning! will need to change when multiple software providers 90 * per mechanism are supported. 91 */ 92 93 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) { 94 if (encr_tmpl != NULL) { 95 if (kcf_get_mech_entry(encr_mech->cm_type, &me) != 96 KCF_SUCCESS) { 97 rv = CRYPTO_MECHANISM_INVALID; 98 goto out; 99 } 100 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl; 101 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) { 102 rv = CRYPTO_OLD_CTX_TEMPLATE; 103 goto out; 104 } 105 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl; 106 } 107 108 if (mac_tmpl != NULL) { 109 if (kcf_get_mech_entry(mac_mech->cm_type, &me) != 110 KCF_SUCCESS) { 111 rv = CRYPTO_MECHANISM_INVALID; 112 goto out; 113 } 114 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 115 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 116 rv = CRYPTO_OLD_CTX_TEMPLATE; 117 goto out; 118 } 119 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 120 } 121 } 122 123 /* The fast path for SW providers. */ 124 if (CHECK_FASTPATH(crq, real_provider)) { 125 crypto_mechanism_t lencr_mech; 126 crypto_mechanism_t lmac_mech; 127 128 /* careful! structs assignments */ 129 lencr_mech = *encr_mech; 130 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider, 131 &lencr_mech); 132 133 lmac_mech = *mac_mech; 134 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 135 &lmac_mech); 136 137 rv = KCF_PROV_ENCRYPT_MAC_ATOMIC(real_provider, sid, 138 &lencr_mech, encr_key, &lmac_mech, mac_key, pt, ct, 139 mac, spi_encr_tmpl, spi_mac_tmpl, KCF_SWFP_RHNDL(crq)); 140 141 KCF_PROV_INCRSTATS(pd, rv); 142 } else { 143 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, 144 sid, encr_key, mac_key, pt, ct, mac, spi_encr_tmpl, 145 spi_mac_tmpl); 146 147 cmops = &(params.rp_u.encrypt_mac_params); 148 149 /* careful! structs assignments */ 150 cmops->em_encr_mech = *encr_mech; 151 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider, 152 &cmops->em_encr_mech); 153 cmops->em_framework_encr_mechtype = encr_mech->cm_type; 154 155 cmops->em_mac_mech = *mac_mech; 156 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 157 &cmops->em_mac_mech); 158 cmops->em_framework_mac_mechtype = mac_mech->cm_type; 159 160 rv = kcf_submit_request(real_provider, NULL, crq, ¶ms, 161 B_FALSE); 162 } 163 164 out: 165 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 166 KCF_PROV_REFRELE(real_provider); 167 return (rv); 168 } 169 170 /* 171 * Performs a dual encrypt/mac atomic operation. The provider and session 172 * to use are determined by the KCF dispatcher. 173 */ 174 int 175 crypto_encrypt_mac(crypto_mechanism_t *encr_mech, 176 crypto_mechanism_t *mac_mech, crypto_data_t *pt, 177 crypto_key_t *encr_key, crypto_key_t *mac_key, 178 crypto_ctx_template_t encr_tmpl, crypto_ctx_template_t mac_tmpl, 179 crypto_dual_data_t *ct, crypto_data_t *mac, crypto_call_req_t *crq) 180 { 181 /* 182 * First try to find a provider for the encryption mechanism, that 183 * is also capable of the MAC mechanism. 184 */ 185 int error; 186 kcf_mech_entry_t *me; 187 kcf_provider_desc_t *pd; 188 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl; 189 kcf_req_params_t params; 190 kcf_encrypt_mac_ops_params_t *cmops; 191 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL; 192 crypto_mech_type_t prov_encr_mechid, prov_mac_mechid; 193 kcf_prov_tried_t *list = NULL; 194 boolean_t encr_tmpl_checked = B_FALSE; 195 boolean_t mac_tmpl_checked = B_FALSE; 196 kcf_dual_req_t *next_req = NULL; 197 198 retry: 199 /* pd is returned held on success */ 200 pd = kcf_get_dual_provider(encr_mech, mac_mech, &me, &prov_encr_mechid, 201 &prov_mac_mechid, &error, list, 202 CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC, 203 CRYPTO_FG_MAC_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC, 204 CHECK_RESTRICT(crq), ct->dd_len1); 205 if (pd == NULL) { 206 if (list != NULL) 207 kcf_free_triedlist(list); 208 if (next_req != NULL) 209 kmem_free(next_req, sizeof (kcf_dual_req_t)); 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 * Warning! will need to change when multiple software providers 220 * per mechanism are supported. 221 */ 222 223 if ((!encr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 224 if (encr_tmpl != NULL) { 225 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl; 226 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) { 227 228 if (next_req != NULL) 229 kmem_free(next_req, 230 sizeof (kcf_dual_req_t)); 231 if (list != NULL) 232 kcf_free_triedlist(list); 233 234 KCF_PROV_REFRELE(pd); 235 /* Which one is the the old one ? */ 236 return (CRYPTO_OLD_CTX_TEMPLATE); 237 } 238 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl; 239 } 240 encr_tmpl_checked = B_TRUE; 241 } 242 243 if (prov_mac_mechid == CRYPTO_MECH_INVALID) { 244 crypto_call_req_t encr_req; 245 246 /* Need to emulate with 2 internal calls */ 247 /* Allocate and initialize the MAC req for the callback */ 248 249 if (crq != NULL) { 250 if (next_req == NULL) { 251 next_req = kcf_alloc_req(crq); 252 253 if (next_req == NULL) { 254 KCF_PROV_REFRELE(pd); 255 if (list != NULL) 256 kcf_free_triedlist(list); 257 return (CRYPTO_HOST_MEMORY); 258 } 259 /* 260 * Careful! we're wrapping-in mac_tmpl instead 261 * of an spi_mac_tmpl. The callback routine will 262 * have to validate mac_tmpl, and use the 263 * mac_ctx_tmpl, once it picks a MAC provider. 264 */ 265 KCF_WRAP_MAC_OPS_PARAMS(&(next_req->kr_params), 266 KCF_OP_ATOMIC, NULL, mac_mech, mac_key, 267 (crypto_data_t *)ct, mac, mac_tmpl); 268 } 269 270 encr_req.cr_flag = crq->cr_flag; 271 encr_req.cr_callback_func = kcf_next_req; 272 encr_req.cr_callback_arg = next_req; 273 } 274 275 if (pt == NULL) { 276 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, 277 pd->pd_sid, encr_mech, encr_key, 278 (crypto_data_t *)ct, NULL, spi_encr_tmpl); 279 } else { 280 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, 281 pd->pd_sid, encr_mech, encr_key, pt, 282 (crypto_data_t *)ct, spi_encr_tmpl); 283 } 284 285 error = kcf_submit_request(pd, NULL, (crq == NULL) ? NULL : 286 &encr_req, ¶ms, B_TRUE); 287 288 switch (error) { 289 case CRYPTO_SUCCESS: { 290 off_t saveoffset; 291 size_t savelen; 292 293 /* 294 * The encryption step is done. Reuse the encr_req 295 * for submitting the MAC step. 296 */ 297 if (next_req == NULL) { 298 saveoffset = ct->dd_offset1; 299 savelen = ct->dd_len1; 300 } else { 301 saveoffset = next_req->kr_saveoffset = 302 ct->dd_offset1; 303 savelen = next_req->kr_savelen = ct->dd_len1; 304 encr_req.cr_callback_func = kcf_last_req; 305 } 306 307 ct->dd_offset1 = ct->dd_offset2; 308 ct->dd_len1 = ct->dd_len2; 309 310 error = crypto_mac(mac_mech, (crypto_data_t *)ct, 311 mac_key, mac_tmpl, mac, (crq == NULL) ? NULL : 312 &encr_req); 313 314 if (error != CRYPTO_QUEUED) { 315 ct->dd_offset1 = saveoffset; 316 ct->dd_len1 = savelen; 317 } 318 break; 319 } 320 321 case CRYPTO_QUEUED: 322 if ((crq != NULL) && 323 !(crq->cr_flag & CRYPTO_SKIP_REQID)) 324 crq->cr_reqid = encr_req.cr_reqid; 325 break; 326 327 default: 328 329 /* Add pd to the linked list of providers tried. */ 330 if (IS_RECOVERABLE(error)) { 331 if (kcf_insert_triedlist(&list, pd, 332 KCF_KMFLAG(crq)) != NULL) 333 goto retry; 334 } 335 } 336 if (error != CRYPTO_QUEUED && next_req != NULL) 337 kmem_free(next_req, sizeof (kcf_dual_req_t)); 338 if (list != NULL) 339 kcf_free_triedlist(list); 340 KCF_PROV_REFRELE(pd); 341 return (error); 342 } 343 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 344 if ((mac_tmpl != NULL) && 345 (prov_mac_mechid != CRYPTO_MECH_INVALID)) { 346 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 347 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 348 349 if (next_req != NULL) 350 kmem_free(next_req, 351 sizeof (kcf_dual_req_t)); 352 if (list != NULL) 353 kcf_free_triedlist(list); 354 355 KCF_PROV_REFRELE(pd); 356 /* Which one is the the old one ? */ 357 return (CRYPTO_OLD_CTX_TEMPLATE); 358 } 359 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 360 } 361 mac_tmpl_checked = B_TRUE; 362 } 363 364 /* The fast path for SW providers. */ 365 if (CHECK_FASTPATH(crq, pd)) { 366 crypto_mechanism_t lencr_mech; 367 crypto_mechanism_t lmac_mech; 368 369 /* careful! structs assignments */ 370 lencr_mech = *encr_mech; 371 lencr_mech.cm_type = prov_encr_mechid; 372 lmac_mech = *mac_mech; 373 lmac_mech.cm_type = prov_mac_mechid; 374 375 error = KCF_PROV_ENCRYPT_MAC_ATOMIC(pd, pd->pd_sid, 376 &lencr_mech, encr_key, &lmac_mech, mac_key, pt, ct, 377 mac, spi_encr_tmpl, spi_mac_tmpl, KCF_SWFP_RHNDL(crq)); 378 379 KCF_PROV_INCRSTATS(pd, error); 380 } else { 381 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, 382 pd->pd_sid, encr_key, mac_key, pt, ct, mac, spi_encr_tmpl, 383 spi_mac_tmpl); 384 385 cmops = &(params.rp_u.encrypt_mac_params); 386 387 /* careful! structs assignments */ 388 cmops->em_encr_mech = *encr_mech; 389 cmops->em_encr_mech.cm_type = prov_encr_mechid; 390 cmops->em_framework_encr_mechtype = encr_mech->cm_type; 391 cmops->em_mac_mech = *mac_mech; 392 cmops->em_mac_mech.cm_type = prov_mac_mechid; 393 cmops->em_framework_mac_mechtype = mac_mech->cm_type; 394 395 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE); 396 } 397 398 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 399 IS_RECOVERABLE(error)) { 400 /* Add pd to the linked list of providers tried. */ 401 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 402 goto retry; 403 } 404 405 if (next_req != NULL) 406 kmem_free(next_req, sizeof (kcf_dual_req_t)); 407 408 if (list != NULL) 409 kcf_free_triedlist(list); 410 411 KCF_PROV_REFRELE(pd); 412 return (error); 413 } 414 415 int 416 crypto_encrypt_mac_init_prov(crypto_provider_t provider, 417 crypto_session_id_t sid, crypto_mechanism_t *encr_mech, 418 crypto_mechanism_t *mac_mech, crypto_key_t *encr_key, 419 crypto_key_t *mac_key, crypto_ctx_template_t encr_tmpl, 420 crypto_ctx_template_t mac_tmpl, crypto_context_t *ctxp, 421 crypto_call_req_t *cr) 422 { 423 /* 424 * First try to find a provider for the encryption mechanism, that 425 * is also capable of the MAC mechanism. 426 */ 427 int rv; 428 kcf_mech_entry_t *me; 429 kcf_provider_desc_t *pd = provider; 430 kcf_provider_desc_t *real_provider = pd; 431 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl; 432 kcf_req_params_t params; 433 kcf_encrypt_mac_ops_params_t *cmops; 434 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL; 435 crypto_ctx_t *ctx; 436 kcf_context_t *encr_kcf_context = NULL; 437 438 ASSERT(KCF_PROV_REFHELD(pd)); 439 440 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 441 rv = kcf_get_hardware_provider(encr_mech->cm_type, 442 mac_mech->cm_type, CHECK_RESTRICT(cr), pd, &real_provider, 443 CRYPTO_FG_ENCRYPT_MAC); 444 445 if (rv != CRYPTO_SUCCESS) 446 return (rv); 447 } 448 449 /* 450 * For SW providers, check the validity of the context template 451 * It is very rare that the generation number mis-matches, so 452 * is acceptable to fail here, and let the consumer recover by 453 * freeing this tmpl and create a new one for the key and new SW 454 * provider 455 * Warning! will need to change when multiple software providers 456 * per mechanism are supported. 457 */ 458 459 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) { 460 if (encr_tmpl != NULL) { 461 if (kcf_get_mech_entry(encr_mech->cm_type, &me) != 462 KCF_SUCCESS) { 463 rv = CRYPTO_MECHANISM_INVALID; 464 goto out; 465 } 466 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl; 467 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) { 468 rv = CRYPTO_OLD_CTX_TEMPLATE; 469 goto out; 470 } 471 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl; 472 } 473 474 if (mac_tmpl != NULL) { 475 if (kcf_get_mech_entry(mac_mech->cm_type, &me) != 476 KCF_SUCCESS) { 477 rv = CRYPTO_MECHANISM_INVALID; 478 goto out; 479 } 480 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 481 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 482 rv = CRYPTO_OLD_CTX_TEMPLATE; 483 goto out; 484 } 485 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 486 } 487 } 488 489 ctx = kcf_new_ctx(cr, real_provider, sid); 490 if (ctx == NULL) { 491 rv = CRYPTO_HOST_MEMORY; 492 goto out; 493 } 494 encr_kcf_context = (kcf_context_t *)ctx->cc_framework_private; 495 496 /* The fast path for SW providers. */ 497 if (CHECK_FASTPATH(cr, real_provider)) { 498 crypto_mechanism_t lencr_mech; 499 crypto_mechanism_t lmac_mech; 500 501 /* careful! structs assignments */ 502 lencr_mech = *encr_mech; 503 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider, 504 &lencr_mech); 505 506 lmac_mech = *mac_mech; 507 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 508 &lmac_mech); 509 510 rv = KCF_PROV_ENCRYPT_MAC_INIT(real_provider, ctx, &lencr_mech, 511 encr_key, &lmac_mech, mac_key, spi_encr_tmpl, spi_mac_tmpl, 512 KCF_SWFP_RHNDL(cr)); 513 514 KCF_PROV_INCRSTATS(pd, rv); 515 } else { 516 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_INIT, 517 sid, encr_key, mac_key, NULL, NULL, NULL, 518 spi_encr_tmpl, spi_mac_tmpl); 519 520 cmops = &(params.rp_u.encrypt_mac_params); 521 522 /* careful! structs assignments */ 523 cmops->em_encr_mech = *encr_mech; 524 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider, 525 &cmops->em_encr_mech); 526 cmops->em_framework_encr_mechtype = encr_mech->cm_type; 527 528 cmops->em_mac_mech = *mac_mech; 529 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 530 &cmops->em_mac_mech); 531 cmops->em_framework_mac_mechtype = mac_mech->cm_type; 532 533 rv = kcf_submit_request(real_provider, ctx, cr, ¶ms, 534 B_FALSE); 535 } 536 537 if (rv != CRYPTO_SUCCESS && rv != CRYPTO_QUEUED) { 538 KCF_CONTEXT_REFRELE(encr_kcf_context); 539 } else 540 *ctxp = (crypto_context_t)ctx; 541 542 out: 543 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 544 KCF_PROV_REFRELE(real_provider); 545 return (rv); 546 } 547 548 /* 549 * Starts a multi-part dual encrypt/mac operation. The provider and session 550 * to use are determined by the KCF dispatcher. 551 */ 552 /* ARGSUSED */ 553 int 554 crypto_encrypt_mac_init(crypto_mechanism_t *encr_mech, 555 crypto_mechanism_t *mac_mech, crypto_key_t *encr_key, 556 crypto_key_t *mac_key, crypto_ctx_template_t encr_tmpl, 557 crypto_ctx_template_t mac_tmpl, crypto_context_t *ctxp, 558 crypto_call_req_t *cr) 559 { 560 /* 561 * First try to find a provider for the encryption mechanism, that 562 * is also capable of the MAC mechanism. 563 */ 564 int error; 565 kcf_mech_entry_t *me; 566 kcf_provider_desc_t *pd; 567 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl; 568 kcf_req_params_t params; 569 kcf_encrypt_mac_ops_params_t *cmops; 570 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL; 571 crypto_mech_type_t prov_encr_mechid, prov_mac_mechid; 572 kcf_prov_tried_t *list = NULL; 573 boolean_t encr_tmpl_checked = B_FALSE; 574 boolean_t mac_tmpl_checked = B_FALSE; 575 crypto_ctx_t *ctx = NULL; 576 kcf_context_t *encr_kcf_context = NULL, *mac_kcf_context; 577 crypto_call_flag_t save_flag; 578 579 retry: 580 /* pd is returned held on success */ 581 pd = kcf_get_dual_provider(encr_mech, mac_mech, &me, &prov_encr_mechid, 582 &prov_mac_mechid, &error, list, 583 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_MAC, CRYPTO_FG_MAC, 584 CHECK_RESTRICT(cr), 0); 585 if (pd == NULL) { 586 if (list != NULL) 587 kcf_free_triedlist(list); 588 return (error); 589 } 590 591 /* 592 * For SW providers, check the validity of the context template 593 * It is very rare that the generation number mis-matches, so 594 * is acceptable to fail here, and let the consumer recover by 595 * freeing this tmpl and create a new one for the key and new SW 596 * provider 597 * Warning! will need to change when multiple software providers 598 * per mechanism are supported. 599 */ 600 601 if ((!encr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 602 if (encr_tmpl != NULL) { 603 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl; 604 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) { 605 606 if (list != NULL) 607 kcf_free_triedlist(list); 608 if (encr_kcf_context != NULL) 609 KCF_CONTEXT_REFRELE(encr_kcf_context); 610 611 KCF_PROV_REFRELE(pd); 612 /* Which one is the the old one ? */ 613 return (CRYPTO_OLD_CTX_TEMPLATE); 614 } 615 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl; 616 } 617 encr_tmpl_checked = B_TRUE; 618 } 619 620 if (prov_mac_mechid == CRYPTO_MECH_INVALID) { 621 /* Need to emulate with 2 internal calls */ 622 623 /* 624 * We avoid code complexity by limiting the pure async. 625 * case to be done using only a SW provider. 626 * XXX - Redo the emulation code below so that we can 627 * remove this limitation. 628 */ 629 if (cr != NULL && pd->pd_prov_type == CRYPTO_HW_PROVIDER) { 630 if ((kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr)) 631 != NULL)) 632 goto retry; 633 if (list != NULL) 634 kcf_free_triedlist(list); 635 if (encr_kcf_context != NULL) 636 KCF_CONTEXT_REFRELE(encr_kcf_context); 637 KCF_PROV_REFRELE(pd); 638 return (CRYPTO_HOST_MEMORY); 639 } 640 641 if (ctx == NULL && pd->pd_prov_type == CRYPTO_SW_PROVIDER) { 642 ctx = kcf_new_ctx(cr, pd, pd->pd_sid); 643 if (ctx == NULL) { 644 if (list != NULL) 645 kcf_free_triedlist(list); 646 if (encr_kcf_context != NULL) 647 KCF_CONTEXT_REFRELE(encr_kcf_context); 648 KCF_PROV_REFRELE(pd); 649 return (CRYPTO_HOST_MEMORY); 650 } 651 encr_kcf_context = (kcf_context_t *) 652 ctx->cc_framework_private; 653 } 654 /* 655 * Trade-off speed vs avoidance of code complexity and 656 * duplication: 657 * Could do all the combinations of fastpath / synch / asynch 658 * for the encryption and the mac steps. Early attempts 659 * showed the code grew wild and bug-prone, for little gain. 660 * Therefore, the adaptative asynch case is not implemented. 661 * It's either pure synchronous, or pure asynchronous. 662 * We still preserve a fastpath for the pure synchronous 663 * requests to SW providers. 664 */ 665 if (cr == NULL) { 666 crypto_context_t mac_context; 667 668 if (pd->pd_prov_type == CRYPTO_SW_PROVIDER) { 669 crypto_mechanism_t lmech = *encr_mech; 670 671 lmech.cm_type = prov_encr_mechid; 672 673 error = KCF_PROV_ENCRYPT_INIT(pd, ctx, &lmech, 674 encr_key, spi_encr_tmpl, 675 KCF_RHNDL(KM_SLEEP)); 676 } else { 677 /* 678 * If we did the 'goto retry' then ctx may not 679 * be NULL. In general, we can't reuse another 680 * provider's context, so we free it now so 681 * we don't leak it. 682 */ 683 if (ctx != NULL) { 684 KCF_CONTEXT_REFRELE((kcf_context_t *) 685 ctx->cc_framework_private); 686 encr_kcf_context = NULL; 687 } 688 error = crypto_encrypt_init_prov(pd, pd->pd_sid, 689 encr_mech, encr_key, &encr_tmpl, 690 (crypto_context_t *)&ctx, NULL); 691 692 if (error == CRYPTO_SUCCESS) { 693 encr_kcf_context = (kcf_context_t *) 694 ctx->cc_framework_private; 695 } 696 } 697 KCF_PROV_INCRSTATS(pd, error); 698 699 KCF_PROV_REFRELE(pd); 700 701 if (error != CRYPTO_SUCCESS) { 702 /* Can't be CRYPTO_QUEUED. return the failure */ 703 if (list != NULL) 704 kcf_free_triedlist(list); 705 if (encr_kcf_context != NULL) 706 KCF_CONTEXT_REFRELE(encr_kcf_context); 707 708 return (error); 709 } 710 error = crypto_mac_init(mac_mech, mac_key, mac_tmpl, 711 &mac_context, NULL); 712 713 if (list != NULL) 714 kcf_free_triedlist(list); 715 716 if (error != CRYPTO_SUCCESS) { 717 /* Should this be an ASSERT() ? */ 718 719 KCF_CONTEXT_REFRELE(encr_kcf_context); 720 } else { 721 encr_kcf_context = (kcf_context_t *) 722 ctx->cc_framework_private; 723 mac_kcf_context = (kcf_context_t *) 724 ((crypto_ctx_t *)mac_context)-> 725 cc_framework_private; 726 727 encr_kcf_context->kc_secondctx = 728 mac_kcf_context; 729 KCF_CONTEXT_REFHOLD(mac_kcf_context); 730 731 *ctxp = (crypto_context_t)ctx; 732 } 733 734 return (error); 735 } 736 737 /* submit a pure asynchronous request. */ 738 save_flag = cr->cr_flag; 739 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE; 740 741 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_INIT, 742 pd->pd_sid, encr_key, mac_key, NULL, NULL, NULL, 743 spi_encr_tmpl, spi_mac_tmpl); 744 745 cmops = &(params.rp_u.encrypt_mac_params); 746 747 /* careful! structs assignments */ 748 cmops->em_encr_mech = *encr_mech; 749 /* 750 * cmops->em_encr_mech.cm_type will be set when we get to 751 * kcf_emulate_dual() routine. 752 */ 753 cmops->em_framework_encr_mechtype = encr_mech->cm_type; 754 cmops->em_mac_mech = *mac_mech; 755 756 /* 757 * cmops->em_mac_mech.cm_type will be set when we know the 758 * MAC provider. 759 */ 760 cmops->em_framework_mac_mechtype = mac_mech->cm_type; 761 762 /* 763 * non-NULL ctx->kc_secondctx tells common_submit_request 764 * that this request uses separate cipher and MAC contexts. 765 * That function will set ctx->kc_secondctx to the new 766 * MAC context, once it gets one. 767 */ 768 encr_kcf_context->kc_secondctx = encr_kcf_context; 769 770 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 771 772 cr->cr_flag = save_flag; 773 774 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) { 775 KCF_CONTEXT_REFRELE(encr_kcf_context); 776 } 777 if (list != NULL) 778 kcf_free_triedlist(list); 779 *ctxp = (crypto_context_t)ctx; 780 KCF_PROV_REFRELE(pd); 781 return (error); 782 } 783 784 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 785 if ((mac_tmpl != NULL) && 786 (prov_mac_mechid != CRYPTO_MECH_INVALID)) { 787 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 788 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 789 790 if (list != NULL) 791 kcf_free_triedlist(list); 792 793 KCF_PROV_REFRELE(pd); 794 /* Which one is the the old one ? */ 795 return (CRYPTO_OLD_CTX_TEMPLATE); 796 } 797 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 798 } 799 mac_tmpl_checked = B_TRUE; 800 } 801 802 if (ctx == NULL) { 803 ctx = kcf_new_ctx(cr, pd, pd->pd_sid); 804 if (ctx == NULL) { 805 if (list != NULL) 806 kcf_free_triedlist(list); 807 808 KCF_PROV_REFRELE(pd); 809 return (CRYPTO_HOST_MEMORY); 810 } 811 encr_kcf_context = (kcf_context_t *)ctx->cc_framework_private; 812 } 813 814 /* The fast path for SW providers. */ 815 if (CHECK_FASTPATH(cr, pd)) { 816 crypto_mechanism_t lencr_mech; 817 crypto_mechanism_t lmac_mech; 818 819 /* careful! structs assignments */ 820 lencr_mech = *encr_mech; 821 lencr_mech.cm_type = prov_encr_mechid; 822 lmac_mech = *mac_mech; 823 lmac_mech.cm_type = prov_mac_mechid; 824 825 error = KCF_PROV_ENCRYPT_MAC_INIT(pd, ctx, &lencr_mech, 826 encr_key, &lmac_mech, mac_key, spi_encr_tmpl, spi_mac_tmpl, 827 KCF_SWFP_RHNDL(cr)); 828 829 KCF_PROV_INCRSTATS(pd, error); 830 } else { 831 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_INIT, 832 pd->pd_sid, encr_key, mac_key, NULL, NULL, NULL, 833 spi_encr_tmpl, spi_mac_tmpl); 834 835 cmops = &(params.rp_u.encrypt_mac_params); 836 837 /* careful! structs assignments */ 838 cmops->em_encr_mech = *encr_mech; 839 cmops->em_encr_mech.cm_type = prov_encr_mechid; 840 cmops->em_framework_encr_mechtype = encr_mech->cm_type; 841 cmops->em_mac_mech = *mac_mech; 842 cmops->em_mac_mech.cm_type = prov_mac_mechid; 843 cmops->em_framework_mac_mechtype = mac_mech->cm_type; 844 845 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 846 } 847 848 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) { 849 if ((IS_RECOVERABLE(error)) && 850 (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr)) != NULL)) 851 goto retry; 852 853 KCF_CONTEXT_REFRELE(encr_kcf_context); 854 } else 855 *ctxp = (crypto_context_t)ctx; 856 857 if (list != NULL) 858 kcf_free_triedlist(list); 859 860 KCF_PROV_REFRELE(pd); 861 return (error); 862 } 863 864 /* 865 * Continues a multi-part dual encrypt/mac operation. 866 */ 867 /* ARGSUSED */ 868 int 869 crypto_encrypt_mac_update(crypto_context_t context, 870 crypto_data_t *pt, crypto_dual_data_t *ct, crypto_call_req_t *cr) 871 { 872 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx; 873 kcf_context_t *kcf_ctx, *kcf_mac_ctx; 874 kcf_provider_desc_t *pd; 875 int error; 876 kcf_req_params_t params; 877 878 if ((ctx == NULL) || 879 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 880 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 881 return (CRYPTO_INVALID_CONTEXT); 882 } 883 884 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 885 KCF_PROV_REFHOLD(pd); 886 887 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) { 888 off_t save_offset; 889 size_t save_len; 890 crypto_call_flag_t save_flag; 891 892 if (kcf_mac_ctx->kc_prov_desc == NULL) { 893 error = CRYPTO_INVALID_CONTEXT; 894 goto out; 895 } 896 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx; 897 898 /* First we submit the encryption request */ 899 if (cr == NULL) { 900 /* 901 * 'ct' is always not NULL. 902 * A NULL 'pt' means in-place. 903 */ 904 if (pt == NULL) 905 error = crypto_encrypt_update(context, 906 (crypto_data_t *)ct, NULL, NULL); 907 else 908 error = crypto_encrypt_update(context, pt, 909 (crypto_data_t *)ct, NULL); 910 911 if (error != CRYPTO_SUCCESS) 912 goto out; 913 914 /* 915 * call mac_update when there is data to throw in 916 * the mix. Either an explicitly non-zero ct->dd_len2, 917 * or the last ciphertext portion. 918 */ 919 save_offset = ct->dd_offset1; 920 save_len = ct->dd_len1; 921 if (ct->dd_len2 == 0) { 922 /* 923 * The previous encrypt step was an 924 * accumulation only and didn't produce any 925 * partial output 926 */ 927 if (ct->dd_len1 == 0) 928 goto out; 929 } else { 930 ct->dd_offset1 = ct->dd_offset2; 931 ct->dd_len1 = ct->dd_len2; 932 } 933 error = crypto_mac_update((crypto_context_t)mac_ctx, 934 (crypto_data_t *)ct, NULL); 935 936 ct->dd_offset1 = save_offset; 937 ct->dd_len1 = save_len; 938 939 goto out; 940 } 941 /* submit a pure asynchronous request. */ 942 save_flag = cr->cr_flag; 943 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE; 944 945 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 946 pd->pd_sid, NULL, NULL, pt, ct, NULL, NULL, NULL) 947 948 949 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 950 951 cr->cr_flag = save_flag; 952 goto out; 953 } 954 955 /* The fast path for SW providers. */ 956 if (CHECK_FASTPATH(cr, pd)) { 957 error = KCF_PROV_ENCRYPT_MAC_UPDATE(pd, ctx, pt, ct, NULL); 958 KCF_PROV_INCRSTATS(pd, error); 959 } else { 960 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 961 ctx->cc_session, NULL, NULL, pt, ct, NULL, NULL, NULL); 962 963 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 964 } 965 out: 966 KCF_PROV_REFRELE(pd); 967 return (error); 968 } 969 970 /* 971 * Terminates a multi-part dual encrypt/mac operation. 972 */ 973 /* ARGSUSED */ 974 int crypto_encrypt_mac_final(crypto_context_t context, crypto_dual_data_t *ct, 975 crypto_data_t *mac, crypto_call_req_t *cr) 976 { 977 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx; 978 kcf_context_t *kcf_ctx, *kcf_mac_ctx; 979 kcf_provider_desc_t *pd; 980 int error; 981 kcf_req_params_t params; 982 983 if ((ctx == NULL) || 984 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 985 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 986 return (CRYPTO_INVALID_CONTEXT); 987 } 988 989 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 990 KCF_PROV_REFHOLD(pd); 991 992 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) { 993 off_t save_offset; 994 size_t save_len; 995 crypto_context_t mac_context; 996 crypto_call_flag_t save_flag; 997 998 if (kcf_mac_ctx->kc_prov_desc == NULL) { 999 KCF_PROV_REFRELE(pd); 1000 return (CRYPTO_INVALID_CONTEXT); 1001 } 1002 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx; 1003 mac_context = (crypto_context_t)mac_ctx; 1004 1005 if (cr == NULL) { 1006 /* Get the last chunk of ciphertext */ 1007 error = crypto_encrypt_final(context, 1008 (crypto_data_t *)ct, NULL); 1009 1010 KCF_PROV_REFRELE(pd); 1011 1012 if (error != CRYPTO_SUCCESS) { 1013 /* 1014 * Needed here, because the caller of 1015 * crypto_encrypt_mac_final() lost all 1016 * refs to the mac_ctx. 1017 */ 1018 crypto_cancel_ctx(mac_context); 1019 return (error); 1020 } 1021 if (ct->dd_len2 > 0) { 1022 save_offset = ct->dd_offset1; 1023 save_len = ct->dd_len1; 1024 ct->dd_offset1 = ct->dd_offset2; 1025 ct->dd_len1 = ct->dd_len2; 1026 1027 error = crypto_mac_update(mac_context, 1028 (crypto_data_t *)ct, NULL); 1029 1030 ct->dd_offset1 = save_offset; 1031 ct->dd_len1 = save_len; 1032 1033 if (error != CRYPTO_SUCCESS) { 1034 crypto_cancel_ctx(mac_context); 1035 return (error); 1036 } 1037 } 1038 1039 /* and finally, collect the MAC */ 1040 error = crypto_mac_final(mac_context, mac, NULL); 1041 1042 return (error); 1043 } 1044 /* submit a pure asynchronous request. */ 1045 save_flag = cr->cr_flag; 1046 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE; 1047 1048 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_FINAL, 1049 pd->pd_sid, NULL, NULL, NULL, ct, mac, NULL, NULL) 1050 1051 1052 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 1053 1054 cr->cr_flag = save_flag; 1055 KCF_PROV_REFRELE(pd); 1056 return (error); 1057 } 1058 /* The fast path for SW providers. */ 1059 if (CHECK_FASTPATH(cr, pd)) { 1060 error = KCF_PROV_ENCRYPT_MAC_FINAL(pd, ctx, ct, mac, NULL); 1061 KCF_PROV_INCRSTATS(pd, error); 1062 } else { 1063 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_FINAL, 1064 ctx->cc_session, NULL, NULL, NULL, ct, mac, NULL, NULL); 1065 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 1066 } 1067 out: 1068 KCF_PROV_REFRELE(pd); 1069 /* Release the hold done in kcf_new_ctx() during init step. */ 1070 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 1071 return (error); 1072 } 1073 1074 /* 1075 * Performs an atomic dual mac/decrypt operation. The provider to use 1076 * is determined by the KCF dispatcher. 1077 */ 1078 int 1079 crypto_mac_decrypt(crypto_mechanism_t *mac_mech, 1080 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct, 1081 crypto_key_t *mac_key, crypto_key_t *decr_key, 1082 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl, 1083 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq) 1084 { 1085 return (crypto_mac_decrypt_common(mac_mech, decr_mech, ct, mac_key, 1086 decr_key, mac_tmpl, decr_tmpl, mac, pt, crq, B_FALSE)); 1087 } 1088 1089 int 1090 crypto_mac_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid, 1091 crypto_mechanism_t *mac_mech, crypto_mechanism_t *decr_mech, 1092 crypto_dual_data_t *ct, crypto_key_t *mac_key, crypto_key_t *decr_key, 1093 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl, 1094 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq) 1095 { 1096 return (crypto_mac_decrypt_common_prov(provider, sid, mac_mech, 1097 decr_mech, ct, mac_key, decr_key, mac_tmpl, decr_tmpl, mac, pt, 1098 crq, B_FALSE)); 1099 } 1100 1101 /* 1102 * Performs an atomic dual mac/decrypt operation. The provider to use 1103 * is determined by the KCF dispatcher. 'mac' specifies the expected 1104 * value for the MAC. The decryption is not performed if the computed 1105 * MAC does not match the expected MAC. 1106 */ 1107 int 1108 crypto_mac_verify_decrypt(crypto_mechanism_t *mac_mech, 1109 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct, 1110 crypto_key_t *mac_key, crypto_key_t *decr_key, 1111 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl, 1112 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq) 1113 { 1114 return (crypto_mac_decrypt_common(mac_mech, decr_mech, ct, mac_key, 1115 decr_key, mac_tmpl, decr_tmpl, mac, pt, crq, B_TRUE)); 1116 } 1117 1118 int 1119 crypto_mac_verify_decrypt_prov(crypto_provider_t provider, 1120 crypto_session_id_t sid, crypto_mechanism_t *mac_mech, 1121 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct, 1122 crypto_key_t *mac_key, crypto_key_t *decr_key, 1123 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl, 1124 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq) 1125 { 1126 return (crypto_mac_decrypt_common_prov(provider, sid, mac_mech, 1127 decr_mech, ct, mac_key, decr_key, mac_tmpl, decr_tmpl, mac, pt, 1128 crq, B_TRUE)); 1129 } 1130 1131 /* 1132 * Called by both crypto_mac_decrypt() and crypto_mac_verify_decrypt(). 1133 * optionally verified if the MACs match before calling the decryption step. 1134 */ 1135 static int 1136 crypto_mac_decrypt_common(crypto_mechanism_t *mac_mech, 1137 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct, 1138 crypto_key_t *mac_key, crypto_key_t *decr_key, 1139 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl, 1140 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq, 1141 boolean_t do_verify) 1142 { 1143 /* 1144 * First try to find a provider for the decryption mechanism, that 1145 * is also capable of the MAC mechanism. 1146 * We still favor optimizing the costlier decryption. 1147 */ 1148 int error; 1149 kcf_mech_entry_t *me; 1150 kcf_provider_desc_t *pd; 1151 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl; 1152 kcf_req_params_t params; 1153 kcf_mac_decrypt_ops_params_t *cmops; 1154 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL; 1155 crypto_mech_type_t prov_decr_mechid, prov_mac_mechid; 1156 kcf_prov_tried_t *list = NULL; 1157 boolean_t decr_tmpl_checked = B_FALSE; 1158 boolean_t mac_tmpl_checked = B_FALSE; 1159 kcf_dual_req_t *next_req = NULL; 1160 crypto_call_req_t mac_req, *mac_reqp = NULL; 1161 1162 retry: 1163 /* pd is returned held on success */ 1164 pd = kcf_get_dual_provider(decr_mech, mac_mech, &me, &prov_decr_mechid, 1165 &prov_mac_mechid, &error, list, 1166 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 1167 CRYPTO_FG_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 1168 CHECK_RESTRICT(crq), ct->dd_len2); 1169 if (pd == NULL) { 1170 if (list != NULL) 1171 kcf_free_triedlist(list); 1172 if (next_req != NULL) 1173 kmem_free(next_req, sizeof (kcf_dual_req_t)); 1174 return (CRYPTO_MECH_NOT_SUPPORTED); 1175 } 1176 1177 /* 1178 * For SW providers, check the validity of the context template 1179 * It is very rare that the generation number mis-matches, so 1180 * is acceptable to fail here, and let the consumer recover by 1181 * freeing this tmpl and create a new one for the key and new SW 1182 * provider 1183 */ 1184 1185 if ((!decr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 1186 if (decr_tmpl != NULL) { 1187 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl; 1188 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) { 1189 if (next_req != NULL) 1190 kmem_free(next_req, 1191 sizeof (kcf_dual_req_t)); 1192 if (list != NULL) 1193 kcf_free_triedlist(list); 1194 KCF_PROV_REFRELE(pd); 1195 1196 /* Which one is the the old one ? */ 1197 return (CRYPTO_OLD_CTX_TEMPLATE); 1198 } 1199 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl; 1200 } 1201 decr_tmpl_checked = B_TRUE; 1202 } 1203 if (prov_mac_mechid == CRYPTO_MECH_INVALID) { 1204 /* Need to emulate with 2 internal calls */ 1205 1206 /* Prepare the call_req to be submitted for the MAC step */ 1207 1208 if (crq != NULL) { 1209 1210 if (next_req == NULL) { 1211 /* 1212 * allocate, initialize and prepare the 1213 * params for the next step only in the 1214 * first pass (not on every retry). 1215 */ 1216 next_req = kcf_alloc_req(crq); 1217 1218 if (next_req == NULL) { 1219 KCF_PROV_REFRELE(pd); 1220 if (list != NULL) 1221 kcf_free_triedlist(list); 1222 return (CRYPTO_HOST_MEMORY); 1223 } 1224 KCF_WRAP_DECRYPT_OPS_PARAMS( 1225 &(next_req->kr_params), KCF_OP_ATOMIC, 1226 NULL, decr_mech, decr_key, 1227 (crypto_data_t *)ct, pt, spi_decr_tmpl); 1228 } 1229 1230 mac_req.cr_flag = (crq != NULL) ? crq->cr_flag : 0; 1231 mac_req.cr_flag |= CRYPTO_SETDUAL; 1232 mac_req.cr_callback_func = kcf_next_req; 1233 mac_req.cr_callback_arg = next_req; 1234 mac_reqp = &mac_req; 1235 } 1236 1237 /* 'pd' is the decryption provider. */ 1238 1239 if (do_verify) 1240 error = crypto_mac_verify(mac_mech, (crypto_data_t *)ct, 1241 mac_key, mac_tmpl, mac, 1242 (crq == NULL) ? NULL : mac_reqp); 1243 else 1244 error = crypto_mac(mac_mech, (crypto_data_t *)ct, 1245 mac_key, mac_tmpl, mac, 1246 (crq == NULL) ? NULL : mac_reqp); 1247 1248 switch (error) { 1249 case CRYPTO_SUCCESS: { 1250 off_t saveoffset; 1251 size_t savelen; 1252 1253 if (next_req == NULL) { 1254 saveoffset = ct->dd_offset1; 1255 savelen = ct->dd_len1; 1256 } else { 1257 saveoffset = next_req->kr_saveoffset = 1258 ct->dd_offset1; 1259 savelen = next_req->kr_savelen = ct->dd_len1; 1260 1261 ASSERT(mac_reqp != NULL); 1262 mac_req.cr_flag &= ~CRYPTO_SETDUAL; 1263 mac_req.cr_callback_func = kcf_last_req; 1264 } 1265 ct->dd_offset1 = ct->dd_offset2; 1266 ct->dd_len1 = ct->dd_len2; 1267 1268 if (CHECK_FASTPATH(crq, pd)) { 1269 crypto_mechanism_t lmech; 1270 1271 lmech = *decr_mech; 1272 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, 1273 pd, &lmech); 1274 1275 error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid, 1276 &lmech, decr_key, (crypto_data_t *)ct, 1277 (crypto_data_t *)pt, spi_decr_tmpl, 1278 KCF_SWFP_RHNDL(mac_reqp)); 1279 1280 KCF_PROV_INCRSTATS(pd, error); 1281 } else { 1282 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, 1283 KCF_OP_ATOMIC, pd->pd_sid, decr_mech, 1284 decr_key, (crypto_data_t *)ct, pt, 1285 spi_decr_tmpl); 1286 1287 error = kcf_submit_request(pd, NULL, 1288 (crq == NULL) ? NULL : mac_reqp, 1289 ¶ms, B_FALSE); 1290 } 1291 if (error != CRYPTO_QUEUED) { 1292 KCF_PROV_INCRSTATS(pd, error); 1293 ct->dd_offset1 = saveoffset; 1294 ct->dd_len1 = savelen; 1295 } 1296 break; 1297 } 1298 1299 case CRYPTO_QUEUED: 1300 if ((crq != NULL) && (crq->cr_flag & CRYPTO_SKIP_REQID)) 1301 crq->cr_reqid = mac_req.cr_reqid; 1302 break; 1303 1304 default: 1305 if (IS_RECOVERABLE(error)) { 1306 if (kcf_insert_triedlist(&list, pd, 1307 KCF_KMFLAG(crq)) != NULL) 1308 goto retry; 1309 } 1310 } 1311 if (error != CRYPTO_QUEUED && next_req != NULL) 1312 kmem_free(next_req, sizeof (kcf_dual_req_t)); 1313 if (list != NULL) 1314 kcf_free_triedlist(list); 1315 KCF_PROV_REFRELE(pd); 1316 return (error); 1317 } 1318 1319 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 1320 if ((mac_tmpl != NULL) && 1321 (prov_mac_mechid != CRYPTO_MECH_INVALID)) { 1322 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 1323 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 1324 if (next_req != NULL) 1325 kmem_free(next_req, 1326 sizeof (kcf_dual_req_t)); 1327 if (list != NULL) 1328 kcf_free_triedlist(list); 1329 KCF_PROV_REFRELE(pd); 1330 1331 /* Which one is the the old one ? */ 1332 return (CRYPTO_OLD_CTX_TEMPLATE); 1333 } 1334 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 1335 } 1336 mac_tmpl_checked = B_TRUE; 1337 } 1338 1339 /* The fast path for SW providers. */ 1340 if (CHECK_FASTPATH(crq, pd)) { 1341 crypto_mechanism_t lmac_mech; 1342 crypto_mechanism_t ldecr_mech; 1343 1344 /* careful! structs assignments */ 1345 ldecr_mech = *decr_mech; 1346 ldecr_mech.cm_type = prov_decr_mechid; 1347 lmac_mech = *mac_mech; 1348 lmac_mech.cm_type = prov_mac_mechid; 1349 1350 if (do_verify) 1351 error = KCF_PROV_MAC_VERIFY_DECRYPT_ATOMIC(pd, 1352 pd->pd_sid, &lmac_mech, mac_key, &ldecr_mech, 1353 decr_key, ct, mac, pt, spi_mac_tmpl, spi_decr_tmpl, 1354 KCF_SWFP_RHNDL(crq)); 1355 else 1356 error = KCF_PROV_MAC_DECRYPT_ATOMIC(pd, pd->pd_sid, 1357 &lmac_mech, mac_key, &ldecr_mech, decr_key, 1358 ct, mac, pt, spi_mac_tmpl, spi_decr_tmpl, 1359 KCF_SWFP_RHNDL(crq)); 1360 1361 KCF_PROV_INCRSTATS(pd, error); 1362 } else { 1363 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, 1364 (do_verify) ? KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC : 1365 KCF_OP_ATOMIC, pd->pd_sid, mac_key, decr_key, ct, mac, pt, 1366 spi_mac_tmpl, spi_decr_tmpl); 1367 1368 cmops = &(params.rp_u.mac_decrypt_params); 1369 1370 /* careful! structs assignments */ 1371 cmops->md_decr_mech = *decr_mech; 1372 cmops->md_decr_mech.cm_type = prov_decr_mechid; 1373 cmops->md_framework_decr_mechtype = decr_mech->cm_type; 1374 cmops->md_mac_mech = *mac_mech; 1375 cmops->md_mac_mech.cm_type = prov_mac_mechid; 1376 cmops->md_framework_mac_mechtype = mac_mech->cm_type; 1377 1378 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE); 1379 } 1380 1381 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 1382 IS_RECOVERABLE(error)) { 1383 /* Add pd to the linked list of providers tried. */ 1384 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 1385 goto retry; 1386 } 1387 1388 if (list != NULL) 1389 kcf_free_triedlist(list); 1390 1391 if (next_req != NULL) 1392 kmem_free(next_req, sizeof (kcf_dual_req_t)); 1393 KCF_PROV_REFRELE(pd); 1394 return (error); 1395 } 1396 1397 static int 1398 crypto_mac_decrypt_common_prov(crypto_provider_t provider, 1399 crypto_session_id_t sid, crypto_mechanism_t *mac_mech, 1400 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct, 1401 crypto_key_t *mac_key, crypto_key_t *decr_key, 1402 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl, 1403 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq, 1404 boolean_t do_verify) 1405 { 1406 /* 1407 * First try to find a provider for the decryption mechanism, that 1408 * is also capable of the MAC mechanism. 1409 * We still favor optimizing the costlier decryption. 1410 */ 1411 int error; 1412 kcf_mech_entry_t *me; 1413 kcf_provider_desc_t *pd = provider; 1414 kcf_provider_desc_t *real_provider = pd; 1415 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl; 1416 kcf_req_params_t params; 1417 kcf_mac_decrypt_ops_params_t *cmops; 1418 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL; 1419 1420 ASSERT(KCF_PROV_REFHELD(pd)); 1421 1422 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 1423 error = kcf_get_hardware_provider(decr_mech->cm_type, 1424 mac_mech->cm_type, CHECK_RESTRICT(crq), pd, 1425 &real_provider, CRYPTO_FG_MAC_DECRYPT_ATOMIC); 1426 1427 if (error != CRYPTO_SUCCESS) 1428 return (error); 1429 } 1430 1431 /* 1432 * For SW providers, check the validity of the context template 1433 * It is very rare that the generation number mis-matches, so 1434 * is acceptable to fail here, and let the consumer recover by 1435 * freeing this tmpl and create a new one for the key and new SW 1436 * provider 1437 */ 1438 1439 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) { 1440 if (decr_tmpl != NULL) { 1441 if (kcf_get_mech_entry(decr_mech->cm_type, &me) != 1442 KCF_SUCCESS) { 1443 error = CRYPTO_MECHANISM_INVALID; 1444 goto out; 1445 } 1446 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl; 1447 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) { 1448 error = CRYPTO_OLD_CTX_TEMPLATE; 1449 goto out; 1450 } 1451 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl; 1452 } 1453 1454 if (mac_tmpl != NULL) { 1455 if (kcf_get_mech_entry(mac_mech->cm_type, &me) != 1456 KCF_SUCCESS) { 1457 error = CRYPTO_MECHANISM_INVALID; 1458 goto out; 1459 } 1460 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 1461 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 1462 error = CRYPTO_OLD_CTX_TEMPLATE; 1463 goto out; 1464 } 1465 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 1466 } 1467 } 1468 1469 /* The fast path for SW providers. */ 1470 if (CHECK_FASTPATH(crq, pd)) { 1471 crypto_mechanism_t lmac_mech; 1472 crypto_mechanism_t ldecr_mech; 1473 1474 /* careful! structs assignments */ 1475 ldecr_mech = *decr_mech; 1476 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider, 1477 &ldecr_mech); 1478 1479 lmac_mech = *mac_mech; 1480 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 1481 &lmac_mech); 1482 1483 if (do_verify) 1484 error = KCF_PROV_MAC_VERIFY_DECRYPT_ATOMIC( 1485 real_provider, sid, &lmac_mech, mac_key, 1486 &ldecr_mech, decr_key, ct, mac, pt, spi_mac_tmpl, 1487 spi_decr_tmpl, KCF_SWFP_RHNDL(crq)); 1488 else 1489 error = KCF_PROV_MAC_DECRYPT_ATOMIC(real_provider, sid, 1490 &lmac_mech, mac_key, &ldecr_mech, decr_key, 1491 ct, mac, pt, spi_mac_tmpl, spi_decr_tmpl, 1492 KCF_SWFP_RHNDL(crq)); 1493 1494 KCF_PROV_INCRSTATS(pd, error); 1495 } else { 1496 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, 1497 (do_verify) ? KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC : 1498 KCF_OP_ATOMIC, sid, mac_key, decr_key, ct, mac, pt, 1499 spi_mac_tmpl, spi_decr_tmpl); 1500 1501 cmops = &(params.rp_u.mac_decrypt_params); 1502 1503 /* careful! structs assignments */ 1504 cmops->md_decr_mech = *decr_mech; 1505 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider, 1506 &cmops->md_decr_mech); 1507 cmops->md_framework_decr_mechtype = decr_mech->cm_type; 1508 1509 cmops->md_mac_mech = *mac_mech; 1510 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 1511 &cmops->md_mac_mech); 1512 cmops->md_framework_mac_mechtype = mac_mech->cm_type; 1513 1514 error = kcf_submit_request(real_provider, NULL, crq, ¶ms, 1515 B_FALSE); 1516 } 1517 1518 out: 1519 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 1520 KCF_PROV_REFRELE(real_provider); 1521 return (error); 1522 } 1523 1524 /* 1525 * Starts a multi-part dual mac/decrypt operation. The provider to 1526 * use is determined by the KCF dispatcher. 1527 */ 1528 /* ARGSUSED */ 1529 int 1530 crypto_mac_decrypt_init(crypto_mechanism_t *mac_mech, 1531 crypto_mechanism_t *decr_mech, crypto_key_t *mac_key, 1532 crypto_key_t *decr_key, crypto_ctx_template_t mac_tmpl, 1533 crypto_ctx_template_t decr_tmpl, crypto_context_t *ctxp, 1534 crypto_call_req_t *cr) 1535 { 1536 /* 1537 * First try to find a provider for the decryption mechanism, that 1538 * is also capable of the MAC mechanism. 1539 * We still favor optimizing the costlier decryption. 1540 */ 1541 int error; 1542 kcf_mech_entry_t *me; 1543 kcf_provider_desc_t *pd; 1544 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl; 1545 kcf_req_params_t params; 1546 kcf_mac_decrypt_ops_params_t *mdops; 1547 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL; 1548 crypto_mech_type_t prov_decr_mechid, prov_mac_mechid; 1549 kcf_prov_tried_t *list = NULL; 1550 boolean_t decr_tmpl_checked = B_FALSE; 1551 boolean_t mac_tmpl_checked = B_FALSE; 1552 crypto_ctx_t *ctx = NULL; 1553 kcf_context_t *decr_kcf_context = NULL, *mac_kcf_context = NULL; 1554 crypto_call_flag_t save_flag; 1555 1556 retry: 1557 /* pd is returned held on success */ 1558 pd = kcf_get_dual_provider(decr_mech, mac_mech, &me, &prov_decr_mechid, 1559 &prov_mac_mechid, &error, list, 1560 CRYPTO_FG_DECRYPT | CRYPTO_FG_MAC_DECRYPT, CRYPTO_FG_MAC, 1561 CHECK_RESTRICT(cr), 0); 1562 if (pd == NULL) { 1563 if (list != NULL) 1564 kcf_free_triedlist(list); 1565 return (error); 1566 } 1567 1568 /* 1569 * For SW providers, check the validity of the context template 1570 * It is very rare that the generation number mis-matches, so 1571 * is acceptable to fail here, and let the consumer recover by 1572 * freeing this tmpl and create a new one for the key and new SW 1573 * provider 1574 * Warning! will need to change when multiple software providers 1575 * per mechanism are supported. 1576 */ 1577 1578 if ((!decr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 1579 if (decr_tmpl != NULL) { 1580 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl; 1581 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) { 1582 1583 if (list != NULL) 1584 kcf_free_triedlist(list); 1585 if (decr_kcf_context != NULL) 1586 KCF_CONTEXT_REFRELE(decr_kcf_context); 1587 1588 KCF_PROV_REFRELE(pd); 1589 /* Which one is the the old one ? */ 1590 return (CRYPTO_OLD_CTX_TEMPLATE); 1591 } 1592 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl; 1593 } 1594 decr_tmpl_checked = B_TRUE; 1595 } 1596 1597 if (prov_mac_mechid == CRYPTO_MECH_INVALID) { 1598 /* Need to emulate with 2 internal calls */ 1599 1600 /* 1601 * We avoid code complexity by limiting the pure async. 1602 * case to be done using only a SW provider. 1603 * XXX - Redo the emulation code below so that we can 1604 * remove this limitation. 1605 */ 1606 if (cr != NULL && pd->pd_prov_type == CRYPTO_HW_PROVIDER) { 1607 if ((kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr)) 1608 != NULL)) 1609 goto retry; 1610 if (list != NULL) 1611 kcf_free_triedlist(list); 1612 if (decr_kcf_context != NULL) 1613 KCF_CONTEXT_REFRELE(decr_kcf_context); 1614 KCF_PROV_REFRELE(pd); 1615 return (CRYPTO_HOST_MEMORY); 1616 } 1617 1618 if (ctx == NULL && pd->pd_prov_type == CRYPTO_SW_PROVIDER) { 1619 ctx = kcf_new_ctx(cr, pd, pd->pd_sid); 1620 if (ctx == NULL) { 1621 if (list != NULL) 1622 kcf_free_triedlist(list); 1623 if (decr_kcf_context != NULL) 1624 KCF_CONTEXT_REFRELE(decr_kcf_context); 1625 KCF_PROV_REFRELE(pd); 1626 return (CRYPTO_HOST_MEMORY); 1627 } 1628 decr_kcf_context = (kcf_context_t *) 1629 ctx->cc_framework_private; 1630 } 1631 /* 1632 * Trade-off speed vs avoidance of code complexity and 1633 * duplication: 1634 * Could do all the combinations of fastpath / synch / asynch 1635 * for the decryption and the mac steps. Early attempts 1636 * showed the code grew wild and bug-prone, for little gain. 1637 * Therefore, the adaptative asynch case is not implemented. 1638 * It's either pure synchronous, or pure asynchronous. 1639 * We still preserve a fastpath for the pure synchronous 1640 * requests to SW providers. 1641 */ 1642 if (cr == NULL) { 1643 crypto_context_t mac_context; 1644 1645 error = crypto_mac_init(mac_mech, mac_key, mac_tmpl, 1646 &mac_context, NULL); 1647 1648 if (error != CRYPTO_SUCCESS) { 1649 /* Can't be CRYPTO_QUEUED. return the failure */ 1650 if (list != NULL) 1651 kcf_free_triedlist(list); 1652 1653 if (decr_kcf_context != NULL) 1654 KCF_CONTEXT_REFRELE(decr_kcf_context); 1655 return (error); 1656 } 1657 if (pd->pd_prov_type == CRYPTO_SW_PROVIDER) { 1658 crypto_mechanism_t lmech = *decr_mech; 1659 1660 lmech.cm_type = prov_decr_mechid; 1661 1662 error = KCF_PROV_DECRYPT_INIT(pd, ctx, &lmech, 1663 decr_key, spi_decr_tmpl, 1664 KCF_RHNDL(KM_SLEEP)); 1665 } else { 1666 /* 1667 * If we did the 'goto retry' then ctx may not 1668 * be NULL. In general, we can't reuse another 1669 * provider's context, so we free it now so 1670 * we don't leak it. 1671 */ 1672 if (ctx != NULL) { 1673 KCF_CONTEXT_REFRELE((kcf_context_t *) 1674 ctx->cc_framework_private); 1675 decr_kcf_context = NULL; 1676 } 1677 error = crypto_decrypt_init_prov(pd, pd->pd_sid, 1678 decr_mech, decr_key, &decr_tmpl, 1679 (crypto_context_t *)&ctx, NULL); 1680 1681 if (error == CRYPTO_SUCCESS) { 1682 decr_kcf_context = (kcf_context_t *) 1683 ctx->cc_framework_private; 1684 } 1685 } 1686 1687 KCF_PROV_INCRSTATS(pd, error); 1688 1689 KCF_PROV_REFRELE(pd); 1690 1691 if (error != CRYPTO_SUCCESS) { 1692 /* Can't be CRYPTO_QUEUED. return the failure */ 1693 if (list != NULL) 1694 kcf_free_triedlist(list); 1695 if (mac_kcf_context != NULL) 1696 KCF_CONTEXT_REFRELE(mac_kcf_context); 1697 1698 return (error); 1699 } 1700 mac_kcf_context = (kcf_context_t *) 1701 ((crypto_ctx_t *)mac_context)-> 1702 cc_framework_private; 1703 1704 decr_kcf_context = (kcf_context_t *) 1705 ctx->cc_framework_private; 1706 1707 /* 1708 * Here also, the mac context is second. The callback 1709 * case can't overwrite the context returned to 1710 * the caller. 1711 */ 1712 decr_kcf_context->kc_secondctx = mac_kcf_context; 1713 KCF_CONTEXT_REFHOLD(mac_kcf_context); 1714 1715 *ctxp = (crypto_context_t)ctx; 1716 1717 return (error); 1718 } 1719 /* submit a pure asynchronous request. */ 1720 save_flag = cr->cr_flag; 1721 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE; 1722 1723 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, 1724 pd->pd_sid, mac_key, decr_key, NULL, NULL, NULL, 1725 spi_mac_tmpl, spi_decr_tmpl); 1726 1727 mdops = &(params.rp_u.mac_decrypt_params); 1728 1729 /* careful! structs assignments */ 1730 mdops->md_decr_mech = *decr_mech; 1731 /* 1732 * mdops->md_decr_mech.cm_type will be set when we get to 1733 * kcf_emulate_dual() routine. 1734 */ 1735 mdops->md_framework_decr_mechtype = decr_mech->cm_type; 1736 mdops->md_mac_mech = *mac_mech; 1737 1738 /* 1739 * mdops->md_mac_mech.cm_type will be set when we know the 1740 * MAC provider. 1741 */ 1742 mdops->md_framework_mac_mechtype = mac_mech->cm_type; 1743 1744 /* 1745 * non-NULL ctx->kc_secondctx tells common_submit_request 1746 * that this request uses separate cipher and MAC contexts. 1747 * That function will set the MAC context's kc_secondctx to 1748 * this decrypt context. 1749 */ 1750 decr_kcf_context->kc_secondctx = decr_kcf_context; 1751 1752 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 1753 1754 cr->cr_flag = save_flag; 1755 1756 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) { 1757 KCF_CONTEXT_REFRELE(decr_kcf_context); 1758 } 1759 if (list != NULL) 1760 kcf_free_triedlist(list); 1761 *ctxp = ctx; 1762 KCF_PROV_REFRELE(pd); 1763 return (error); 1764 } 1765 1766 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) { 1767 if ((mac_tmpl != NULL) && 1768 (prov_mac_mechid != CRYPTO_MECH_INVALID)) { 1769 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 1770 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 1771 1772 if (list != NULL) 1773 kcf_free_triedlist(list); 1774 1775 KCF_PROV_REFRELE(pd); 1776 /* Which one is the the old one ? */ 1777 return (CRYPTO_OLD_CTX_TEMPLATE); 1778 } 1779 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 1780 } 1781 mac_tmpl_checked = B_TRUE; 1782 } 1783 1784 if (ctx == NULL) { 1785 ctx = kcf_new_ctx(cr, pd, pd->pd_sid); 1786 if (ctx == NULL) { 1787 error = CRYPTO_HOST_MEMORY; 1788 if (list != NULL) 1789 kcf_free_triedlist(list); 1790 return (CRYPTO_HOST_MEMORY); 1791 } 1792 decr_kcf_context = (kcf_context_t *)ctx->cc_framework_private; 1793 } 1794 1795 /* The fast path for SW providers. */ 1796 if (CHECK_FASTPATH(cr, pd)) { 1797 crypto_mechanism_t ldecr_mech; 1798 crypto_mechanism_t lmac_mech; 1799 1800 /* careful! structs assignments */ 1801 ldecr_mech = *decr_mech; 1802 ldecr_mech.cm_type = prov_decr_mechid; 1803 lmac_mech = *mac_mech; 1804 lmac_mech.cm_type = prov_mac_mechid; 1805 1806 error = KCF_PROV_MAC_DECRYPT_INIT(pd, ctx, &lmac_mech, 1807 mac_key, &ldecr_mech, decr_key, spi_mac_tmpl, spi_decr_tmpl, 1808 KCF_SWFP_RHNDL(cr)); 1809 1810 KCF_PROV_INCRSTATS(pd, error); 1811 } else { 1812 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, 1813 pd->pd_sid, mac_key, decr_key, NULL, NULL, NULL, 1814 spi_mac_tmpl, spi_decr_tmpl); 1815 1816 mdops = &(params.rp_u.mac_decrypt_params); 1817 1818 /* careful! structs assignments */ 1819 mdops->md_decr_mech = *decr_mech; 1820 mdops->md_decr_mech.cm_type = prov_decr_mechid; 1821 mdops->md_framework_decr_mechtype = decr_mech->cm_type; 1822 mdops->md_mac_mech = *mac_mech; 1823 mdops->md_mac_mech.cm_type = prov_mac_mechid; 1824 mdops->md_framework_mac_mechtype = mac_mech->cm_type; 1825 1826 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 1827 } 1828 1829 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) { 1830 if ((IS_RECOVERABLE(error)) && 1831 (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr)) != NULL)) 1832 goto retry; 1833 1834 KCF_CONTEXT_REFRELE(decr_kcf_context); 1835 } else 1836 *ctxp = (crypto_context_t)ctx; 1837 1838 if (list != NULL) 1839 kcf_free_triedlist(list); 1840 1841 KCF_PROV_REFRELE(pd); 1842 return (error); 1843 } 1844 1845 int 1846 crypto_mac_decrypt_init_prov(crypto_provider_t provider, 1847 crypto_session_id_t sid, crypto_mechanism_t *mac_mech, 1848 crypto_mechanism_t *decr_mech, crypto_key_t *mac_key, 1849 crypto_key_t *decr_key, crypto_ctx_template_t mac_tmpl, 1850 crypto_ctx_template_t decr_tmpl, crypto_context_t *ctxp, 1851 crypto_call_req_t *cr) 1852 { 1853 /* 1854 * First try to find a provider for the decryption mechanism, that 1855 * is also capable of the MAC mechanism. 1856 * We still favor optimizing the costlier decryption. 1857 */ 1858 int rv; 1859 kcf_mech_entry_t *me; 1860 kcf_provider_desc_t *pd = provider; 1861 kcf_provider_desc_t *real_provider = pd; 1862 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl; 1863 kcf_req_params_t params; 1864 kcf_mac_decrypt_ops_params_t *mdops; 1865 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL; 1866 crypto_ctx_t *ctx; 1867 kcf_context_t *decr_kcf_context = NULL; 1868 1869 ASSERT(KCF_PROV_REFHELD(pd)); 1870 1871 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 1872 rv = kcf_get_hardware_provider(decr_mech->cm_type, 1873 mac_mech->cm_type, CHECK_RESTRICT(cr), pd, &real_provider, 1874 CRYPTO_FG_MAC_DECRYPT); 1875 1876 if (rv != CRYPTO_SUCCESS) 1877 return (rv); 1878 } 1879 1880 /* 1881 * For SW providers, check the validity of the context template 1882 * It is very rare that the generation number mis-matches, so 1883 * is acceptable to fail here, and let the consumer recover by 1884 * freeing this tmpl and create a new one for the key and new SW 1885 * provider 1886 * Warning! will need to change when multiple software providers 1887 * per mechanism are supported. 1888 */ 1889 1890 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) { 1891 if (decr_tmpl != NULL) { 1892 if (kcf_get_mech_entry(decr_mech->cm_type, &me) != 1893 KCF_SUCCESS) { 1894 rv = CRYPTO_MECHANISM_INVALID; 1895 goto out; 1896 } 1897 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl; 1898 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) { 1899 rv = CRYPTO_OLD_CTX_TEMPLATE; 1900 goto out; 1901 } 1902 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl; 1903 } 1904 1905 if (mac_tmpl != NULL) { 1906 if (kcf_get_mech_entry(mac_mech->cm_type, &me) != 1907 KCF_SUCCESS) { 1908 rv = CRYPTO_MECHANISM_INVALID; 1909 goto out; 1910 } 1911 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl; 1912 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) { 1913 rv = CRYPTO_OLD_CTX_TEMPLATE; 1914 goto out; 1915 } 1916 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl; 1917 } 1918 } 1919 1920 ctx = kcf_new_ctx(cr, real_provider, sid); 1921 if (ctx == NULL) { 1922 rv = CRYPTO_HOST_MEMORY; 1923 goto out; 1924 } 1925 decr_kcf_context = (kcf_context_t *)ctx->cc_framework_private; 1926 1927 /* The fast path for SW providers. */ 1928 if (CHECK_FASTPATH(cr, pd)) { 1929 crypto_mechanism_t ldecr_mech; 1930 crypto_mechanism_t lmac_mech; 1931 1932 /* careful! structs assignments */ 1933 ldecr_mech = *decr_mech; 1934 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider, 1935 &ldecr_mech); 1936 1937 lmac_mech = *mac_mech; 1938 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 1939 &lmac_mech); 1940 1941 rv = KCF_PROV_MAC_DECRYPT_INIT(real_provider, ctx, &lmac_mech, 1942 mac_key, &ldecr_mech, decr_key, spi_mac_tmpl, spi_decr_tmpl, 1943 KCF_SWFP_RHNDL(cr)); 1944 1945 KCF_PROV_INCRSTATS(pd, rv); 1946 } else { 1947 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, 1948 sid, mac_key, decr_key, NULL, NULL, NULL, 1949 spi_mac_tmpl, spi_decr_tmpl); 1950 1951 mdops = &(params.rp_u.mac_decrypt_params); 1952 1953 /* careful! structs assignments */ 1954 mdops->md_decr_mech = *decr_mech; 1955 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider, 1956 &mdops->md_decr_mech); 1957 mdops->md_framework_decr_mechtype = decr_mech->cm_type; 1958 1959 mdops->md_mac_mech = *mac_mech; 1960 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider, 1961 &mdops->md_mac_mech); 1962 mdops->md_framework_mac_mechtype = mac_mech->cm_type; 1963 1964 rv = kcf_submit_request(real_provider, ctx, cr, ¶ms, 1965 B_FALSE); 1966 } 1967 1968 if (rv != CRYPTO_SUCCESS && rv != CRYPTO_QUEUED) { 1969 KCF_CONTEXT_REFRELE(decr_kcf_context); 1970 } else 1971 *ctxp = (crypto_context_t)ctx; 1972 1973 out: 1974 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 1975 KCF_PROV_REFRELE(real_provider); 1976 return (rv); 1977 } 1978 /* 1979 * Continues a multi-part dual mac/decrypt operation. 1980 */ 1981 /* ARGSUSED */ 1982 int 1983 crypto_mac_decrypt_update(crypto_context_t context, 1984 crypto_dual_data_t *ct, crypto_data_t *pt, crypto_call_req_t *cr) 1985 { 1986 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx; 1987 kcf_context_t *kcf_ctx, *kcf_mac_ctx; 1988 kcf_provider_desc_t *pd; 1989 int error; 1990 kcf_req_params_t params; 1991 1992 if ((ctx == NULL) || 1993 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 1994 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 1995 return (CRYPTO_INVALID_CONTEXT); 1996 } 1997 1998 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 1999 KCF_PROV_REFHOLD(pd); 2000 2001 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) { 2002 off_t save_offset; 2003 size_t save_len; 2004 crypto_call_flag_t save_flag; 2005 2006 if (kcf_mac_ctx->kc_prov_desc == NULL) { 2007 error = CRYPTO_INVALID_CONTEXT; 2008 goto out; 2009 } 2010 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx; 2011 2012 /* First we submit the MAC request */ 2013 if (cr == NULL) { 2014 /* 2015 * 'ct' is always not NULL. 2016 */ 2017 error = crypto_mac_update((crypto_context_t)mac_ctx, 2018 (crypto_data_t *)ct, NULL); 2019 2020 if (error != CRYPTO_SUCCESS) 2021 goto out; 2022 2023 /* Decrypt a different length only when told so */ 2024 2025 save_offset = ct->dd_offset1; 2026 save_len = ct->dd_len1; 2027 2028 if (ct->dd_len2 > 0) { 2029 ct->dd_offset1 = ct->dd_offset2; 2030 ct->dd_len1 = ct->dd_len2; 2031 } 2032 2033 error = crypto_decrypt_update(context, 2034 (crypto_data_t *)ct, pt, NULL); 2035 2036 ct->dd_offset1 = save_offset; 2037 ct->dd_len1 = save_len; 2038 2039 goto out; 2040 } 2041 /* submit a pure asynchronous request. */ 2042 save_flag = cr->cr_flag; 2043 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE; 2044 2045 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 2046 pd->pd_sid, NULL, NULL, ct, NULL, pt, NULL, NULL) 2047 2048 2049 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 2050 2051 cr->cr_flag = save_flag; 2052 goto out; 2053 } 2054 2055 /* The fast path for SW providers. */ 2056 if (CHECK_FASTPATH(cr, pd)) { 2057 error = KCF_PROV_MAC_DECRYPT_UPDATE(pd, ctx, ct, pt, NULL); 2058 KCF_PROV_INCRSTATS(pd, error); 2059 } else { 2060 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 2061 ctx->cc_session, NULL, NULL, ct, NULL, pt, NULL, NULL); 2062 2063 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 2064 } 2065 out: 2066 KCF_PROV_REFRELE(pd); 2067 return (error); 2068 } 2069 2070 /* 2071 * Terminates a multi-part dual mac/decrypt operation. 2072 */ 2073 /* ARGSUSED */ 2074 int 2075 crypto_mac_decrypt_final(crypto_context_t context, crypto_data_t *mac, 2076 crypto_data_t *pt, crypto_call_req_t *cr) 2077 { 2078 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx; 2079 kcf_context_t *kcf_ctx, *kcf_mac_ctx; 2080 kcf_provider_desc_t *pd; 2081 int error; 2082 kcf_req_params_t params; 2083 2084 if ((ctx == NULL) || 2085 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 2086 ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 2087 return (CRYPTO_INVALID_CONTEXT); 2088 } 2089 2090 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 2091 KCF_PROV_REFHOLD(pd); 2092 2093 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) { 2094 crypto_call_flag_t save_flag; 2095 2096 if (kcf_mac_ctx->kc_prov_desc == NULL) { 2097 error = CRYPTO_INVALID_CONTEXT; 2098 goto out; 2099 } 2100 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx; 2101 2102 /* First we collect the MAC */ 2103 if (cr == NULL) { 2104 2105 error = crypto_mac_final((crypto_context_t)mac_ctx, 2106 mac, NULL); 2107 2108 if (error != CRYPTO_SUCCESS) { 2109 crypto_cancel_ctx(ctx); 2110 } else { 2111 /* Get the last chunk of plaintext */ 2112 error = crypto_decrypt_final(context, pt, NULL); 2113 } 2114 2115 KCF_PROV_REFRELE(pd); 2116 return (error); 2117 } 2118 /* submit a pure asynchronous request. */ 2119 save_flag = cr->cr_flag; 2120 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE; 2121 2122 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL, 2123 pd->pd_sid, NULL, NULL, NULL, mac, pt, NULL, NULL) 2124 2125 2126 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 2127 2128 cr->cr_flag = save_flag; 2129 2130 KCF_PROV_REFRELE(pd); 2131 return (error); 2132 } 2133 2134 /* The fast path for SW providers. */ 2135 if (CHECK_FASTPATH(cr, pd)) { 2136 error = KCF_PROV_MAC_DECRYPT_FINAL(pd, ctx, mac, pt, NULL); 2137 KCF_PROV_INCRSTATS(pd, error); 2138 } else { 2139 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL, 2140 ctx->cc_session, NULL, NULL, NULL, mac, pt, NULL, NULL); 2141 2142 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 2143 } 2144 out: 2145 KCF_PROV_REFRELE(pd); 2146 /* Release the hold done in kcf_new_ctx() during init step. */ 2147 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 2148 return (error); 2149 } 2150 2151 /* 2152 * Digest/Encrypt dual operation. Project-private entry point, not part of 2153 * the k-API. 2154 */ 2155 /* ARGSUSED */ 2156 int 2157 crypto_digest_encrypt_update(crypto_context_t digest_ctx, 2158 crypto_context_t encrypt_ctx, crypto_data_t *plaintext, 2159 crypto_data_t *ciphertext, crypto_call_req_t *crq) 2160 { 2161 /* 2162 * RFE 4688647: 2163 * core functions needed by ioctl interface missing from impl.h 2164 */ 2165 return (CRYPTO_NOT_SUPPORTED); 2166 } 2167 2168 /* 2169 * Decrypt/Digest dual operation. Project-private entry point, not part of 2170 * the k-API. 2171 */ 2172 /* ARGSUSED */ 2173 int 2174 crypto_decrypt_digest_update(crypto_context_t decryptctx, 2175 crypto_context_t encrypt_ctx, crypto_data_t *ciphertext, 2176 crypto_data_t *plaintext, crypto_call_req_t *crq) 2177 { 2178 /* 2179 * RFE 4688647: 2180 * core functions needed by ioctl interface missing from impl.h 2181 */ 2182 return (CRYPTO_NOT_SUPPORTED); 2183 } 2184 2185 /* 2186 * Sign/Encrypt dual operation. Project-private entry point, not part of 2187 * the k-API. 2188 */ 2189 /* ARGSUSED */ 2190 int 2191 crypto_sign_encrypt_update(crypto_context_t sign_ctx, 2192 crypto_context_t encrypt_ctx, crypto_data_t *plaintext, 2193 crypto_data_t *ciphertext, crypto_call_req_t *crq) 2194 { 2195 /* 2196 * RFE 4688647: 2197 * core functions needed by ioctl interface missing from impl.h 2198 */ 2199 return (CRYPTO_NOT_SUPPORTED); 2200 } 2201 2202 /* 2203 * Decrypt/Verify dual operation. Project-private entry point, not part of 2204 * the k-API. 2205 */ 2206 /* ARGSUSED */ 2207 int 2208 crypto_decrypt_verify_update(crypto_context_t decrypt_ctx, 2209 crypto_context_t verify_ctx, crypto_data_t *ciphertext, 2210 crypto_data_t *plaintext, crypto_call_req_t *crq) 2211 { 2212 /* 2213 * RFE 4688647: 2214 * core functions needed by ioctl interface missing from impl.h 2215 */ 2216 return (CRYPTO_NOT_SUPPORTED); 2217 } 2218