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