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 * Message authentication codes 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_MAC: bogus 'mac' argument. 56*eda14cbcSMatt Macy */ 57*eda14cbcSMatt Macy 58*eda14cbcSMatt Macy /* 59*eda14cbcSMatt Macy * crypto_mac_prov() 60*eda14cbcSMatt Macy * 61*eda14cbcSMatt Macy * Arguments: 62*eda14cbcSMatt Macy * mech: crypto_mechanism_t pointer. 63*eda14cbcSMatt Macy * mech_type is a valid value previously returned by 64*eda14cbcSMatt Macy * crypto_mech2id(); 65*eda14cbcSMatt Macy * When the mech's parameter is not NULL, its definition depends 66*eda14cbcSMatt Macy * on the standard definition of the mechanism. 67*eda14cbcSMatt Macy * key: pointer to a crypto_key_t structure. 68*eda14cbcSMatt Macy * data: The message to compute the MAC for. 69*eda14cbcSMatt Macy * mac: Storage for the MAC. The length needed depends on the mechanism. 70*eda14cbcSMatt Macy * tmpl: a crypto_ctx_template_t, opaque template of a context of a 71*eda14cbcSMatt Macy * MAC with the 'mech' using 'key'. 'tmpl' is created by 72*eda14cbcSMatt Macy * a previous call to crypto_create_ctx_template(). 73*eda14cbcSMatt Macy * cr: crypto_call_req_t calling conditions and call back info. 74*eda14cbcSMatt Macy * 75*eda14cbcSMatt Macy * Description: 76*eda14cbcSMatt Macy * Asynchronously submits a request for, or synchronously performs a 77*eda14cbcSMatt Macy * single-part message authentication of 'data' with the mechanism 78*eda14cbcSMatt Macy * 'mech', using * the key 'key', on the specified provider with 79*eda14cbcSMatt Macy * the specified session id. 80*eda14cbcSMatt Macy * When complete and successful, 'mac' will contain the message 81*eda14cbcSMatt Macy * authentication code. 82*eda14cbcSMatt Macy * 83*eda14cbcSMatt Macy * Context: 84*eda14cbcSMatt Macy * Process or interrupt, according to the semantics dictated by the 'crq'. 85*eda14cbcSMatt Macy * 86*eda14cbcSMatt Macy * Returns: 87*eda14cbcSMatt Macy * See comment in the beginning of the file. 88*eda14cbcSMatt Macy */ 89*eda14cbcSMatt Macy int 90*eda14cbcSMatt Macy crypto_mac_prov(crypto_provider_t provider, crypto_session_id_t sid, 91*eda14cbcSMatt Macy crypto_mechanism_t *mech, crypto_data_t *data, crypto_key_t *key, 92*eda14cbcSMatt Macy crypto_ctx_template_t tmpl, crypto_data_t *mac, crypto_call_req_t *crq) 93*eda14cbcSMatt Macy { 94*eda14cbcSMatt Macy kcf_req_params_t params; 95*eda14cbcSMatt Macy kcf_provider_desc_t *pd = provider; 96*eda14cbcSMatt Macy kcf_provider_desc_t *real_provider = pd; 97*eda14cbcSMatt Macy int rv; 98*eda14cbcSMatt Macy 99*eda14cbcSMatt Macy ASSERT(KCF_PROV_REFHELD(pd)); 100*eda14cbcSMatt Macy 101*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 102*eda14cbcSMatt Macy rv = kcf_get_hardware_provider(mech->cm_type, 103*eda14cbcSMatt Macy CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 104*eda14cbcSMatt Macy &real_provider, CRYPTO_FG_MAC_ATOMIC); 105*eda14cbcSMatt Macy 106*eda14cbcSMatt Macy if (rv != CRYPTO_SUCCESS) 107*eda14cbcSMatt Macy return (rv); 108*eda14cbcSMatt Macy } 109*eda14cbcSMatt Macy 110*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, sid, mech, key, 111*eda14cbcSMatt Macy data, mac, tmpl); 112*eda14cbcSMatt Macy rv = kcf_submit_request(real_provider, NULL, crq, ¶ms, B_FALSE); 113*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 114*eda14cbcSMatt Macy KCF_PROV_REFRELE(real_provider); 115*eda14cbcSMatt Macy 116*eda14cbcSMatt Macy return (rv); 117*eda14cbcSMatt Macy } 118*eda14cbcSMatt Macy 119*eda14cbcSMatt Macy /* 120*eda14cbcSMatt Macy * Same as crypto_mac_prov(), but relies on the KCF scheduler to choose 121*eda14cbcSMatt Macy * a provider. See crypto_mac() comments for more information. 122*eda14cbcSMatt Macy */ 123*eda14cbcSMatt Macy int 124*eda14cbcSMatt Macy crypto_mac(crypto_mechanism_t *mech, crypto_data_t *data, 125*eda14cbcSMatt Macy crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *mac, 126*eda14cbcSMatt Macy crypto_call_req_t *crq) 127*eda14cbcSMatt Macy { 128*eda14cbcSMatt Macy int error; 129*eda14cbcSMatt Macy kcf_mech_entry_t *me; 130*eda14cbcSMatt Macy kcf_req_params_t params; 131*eda14cbcSMatt Macy kcf_provider_desc_t *pd; 132*eda14cbcSMatt Macy kcf_ctx_template_t *ctx_tmpl; 133*eda14cbcSMatt Macy crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 134*eda14cbcSMatt Macy kcf_prov_tried_t *list = NULL; 135*eda14cbcSMatt Macy 136*eda14cbcSMatt Macy retry: 137*eda14cbcSMatt Macy /* The pd is returned held */ 138*eda14cbcSMatt Macy if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 139*eda14cbcSMatt Macy list, CRYPTO_FG_MAC_ATOMIC, CHECK_RESTRICT(crq), 140*eda14cbcSMatt Macy data->cd_length)) == NULL) { 141*eda14cbcSMatt Macy if (list != NULL) 142*eda14cbcSMatt Macy kcf_free_triedlist(list); 143*eda14cbcSMatt Macy return (error); 144*eda14cbcSMatt Macy } 145*eda14cbcSMatt Macy 146*eda14cbcSMatt Macy /* 147*eda14cbcSMatt Macy * For SW providers, check the validity of the context template 148*eda14cbcSMatt Macy * It is very rare that the generation number mis-matches, so 149*eda14cbcSMatt Macy * is acceptable to fail here, and let the consumer recover by 150*eda14cbcSMatt Macy * freeing this tmpl and create a new one for the key and new SW 151*eda14cbcSMatt Macy * provider 152*eda14cbcSMatt Macy */ 153*eda14cbcSMatt Macy if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) && 154*eda14cbcSMatt Macy ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) { 155*eda14cbcSMatt Macy if (ctx_tmpl->ct_generation != me->me_gen_swprov) { 156*eda14cbcSMatt Macy if (list != NULL) 157*eda14cbcSMatt Macy kcf_free_triedlist(list); 158*eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 159*eda14cbcSMatt Macy return (CRYPTO_OLD_CTX_TEMPLATE); 160*eda14cbcSMatt Macy } else { 161*eda14cbcSMatt Macy spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 162*eda14cbcSMatt Macy } 163*eda14cbcSMatt Macy } 164*eda14cbcSMatt Macy 165*eda14cbcSMatt Macy /* The fast path for SW providers. */ 166*eda14cbcSMatt Macy if (CHECK_FASTPATH(crq, pd)) { 167*eda14cbcSMatt Macy crypto_mechanism_t lmech; 168*eda14cbcSMatt Macy 169*eda14cbcSMatt Macy lmech = *mech; 170*eda14cbcSMatt Macy KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 171*eda14cbcSMatt Macy 172*eda14cbcSMatt Macy error = KCF_PROV_MAC_ATOMIC(pd, pd->pd_sid, &lmech, key, data, 173*eda14cbcSMatt Macy mac, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq)); 174*eda14cbcSMatt Macy KCF_PROV_INCRSTATS(pd, error); 175*eda14cbcSMatt Macy } else { 176*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_HW_PROVIDER && 177*eda14cbcSMatt Macy (pd->pd_flags & CRYPTO_HASH_NO_UPDATE) && 178*eda14cbcSMatt Macy (data->cd_length > pd->pd_hash_limit)) { 179*eda14cbcSMatt Macy /* 180*eda14cbcSMatt Macy * XXX - We need a check to see if this is indeed 181*eda14cbcSMatt Macy * a HMAC. So far, all kernel clients use 182*eda14cbcSMatt Macy * this interface only for HMAC. So, this is fine 183*eda14cbcSMatt Macy * for now. 184*eda14cbcSMatt Macy */ 185*eda14cbcSMatt Macy error = CRYPTO_BUFFER_TOO_BIG; 186*eda14cbcSMatt Macy } else { 187*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, 188*eda14cbcSMatt Macy pd->pd_sid, mech, key, data, mac, spi_ctx_tmpl); 189*eda14cbcSMatt Macy 190*eda14cbcSMatt Macy error = kcf_submit_request(pd, NULL, crq, ¶ms, 191*eda14cbcSMatt Macy KCF_ISDUALREQ(crq)); 192*eda14cbcSMatt Macy } 193*eda14cbcSMatt Macy } 194*eda14cbcSMatt Macy 195*eda14cbcSMatt Macy if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 196*eda14cbcSMatt Macy IS_RECOVERABLE(error)) { 197*eda14cbcSMatt Macy /* Add pd to the linked list of providers tried. */ 198*eda14cbcSMatt Macy if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 199*eda14cbcSMatt Macy goto retry; 200*eda14cbcSMatt Macy } 201*eda14cbcSMatt Macy 202*eda14cbcSMatt Macy if (list != NULL) 203*eda14cbcSMatt Macy kcf_free_triedlist(list); 204*eda14cbcSMatt Macy 205*eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 206*eda14cbcSMatt Macy return (error); 207*eda14cbcSMatt Macy } 208*eda14cbcSMatt Macy 209*eda14cbcSMatt Macy /* 210*eda14cbcSMatt Macy * Single part operation to compute the MAC corresponding to the specified 211*eda14cbcSMatt Macy * 'data' and to verify that it matches the MAC specified by 'mac'. 212*eda14cbcSMatt Macy * The other arguments are the same as the function crypto_mac_prov(). 213*eda14cbcSMatt Macy */ 214*eda14cbcSMatt Macy int 215*eda14cbcSMatt Macy crypto_mac_verify_prov(crypto_provider_t provider, crypto_session_id_t sid, 216*eda14cbcSMatt Macy crypto_mechanism_t *mech, crypto_data_t *data, crypto_key_t *key, 217*eda14cbcSMatt Macy crypto_ctx_template_t tmpl, crypto_data_t *mac, crypto_call_req_t *crq) 218*eda14cbcSMatt Macy { 219*eda14cbcSMatt Macy kcf_req_params_t params; 220*eda14cbcSMatt Macy kcf_provider_desc_t *pd = provider; 221*eda14cbcSMatt Macy kcf_provider_desc_t *real_provider = pd; 222*eda14cbcSMatt Macy int rv; 223*eda14cbcSMatt Macy 224*eda14cbcSMatt Macy ASSERT(KCF_PROV_REFHELD(pd)); 225*eda14cbcSMatt Macy 226*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 227*eda14cbcSMatt Macy rv = kcf_get_hardware_provider(mech->cm_type, 228*eda14cbcSMatt Macy CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 229*eda14cbcSMatt Macy &real_provider, CRYPTO_FG_MAC_ATOMIC); 230*eda14cbcSMatt Macy 231*eda14cbcSMatt Macy if (rv != CRYPTO_SUCCESS) 232*eda14cbcSMatt Macy return (rv); 233*eda14cbcSMatt Macy } 234*eda14cbcSMatt Macy 235*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, KCF_OP_MAC_VERIFY_ATOMIC, sid, mech, 236*eda14cbcSMatt Macy key, data, mac, tmpl); 237*eda14cbcSMatt Macy rv = kcf_submit_request(real_provider, NULL, crq, ¶ms, B_FALSE); 238*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 239*eda14cbcSMatt Macy KCF_PROV_REFRELE(real_provider); 240*eda14cbcSMatt Macy 241*eda14cbcSMatt Macy return (rv); 242*eda14cbcSMatt Macy } 243*eda14cbcSMatt Macy 244*eda14cbcSMatt Macy /* 245*eda14cbcSMatt Macy * Same as crypto_mac_verify_prov(), but relies on the KCF scheduler to choose 246*eda14cbcSMatt Macy * a provider. See crypto_mac_verify_prov() comments for more information. 247*eda14cbcSMatt Macy */ 248*eda14cbcSMatt Macy int 249*eda14cbcSMatt Macy crypto_mac_verify(crypto_mechanism_t *mech, crypto_data_t *data, 250*eda14cbcSMatt Macy crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *mac, 251*eda14cbcSMatt Macy crypto_call_req_t *crq) 252*eda14cbcSMatt Macy { 253*eda14cbcSMatt Macy int error; 254*eda14cbcSMatt Macy kcf_mech_entry_t *me; 255*eda14cbcSMatt Macy kcf_req_params_t params; 256*eda14cbcSMatt Macy kcf_provider_desc_t *pd; 257*eda14cbcSMatt Macy kcf_ctx_template_t *ctx_tmpl; 258*eda14cbcSMatt Macy crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 259*eda14cbcSMatt Macy kcf_prov_tried_t *list = NULL; 260*eda14cbcSMatt Macy 261*eda14cbcSMatt Macy retry: 262*eda14cbcSMatt Macy /* The pd is returned held */ 263*eda14cbcSMatt Macy if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 264*eda14cbcSMatt Macy list, CRYPTO_FG_MAC_ATOMIC, CHECK_RESTRICT(crq), 265*eda14cbcSMatt Macy data->cd_length)) == NULL) { 266*eda14cbcSMatt Macy if (list != NULL) 267*eda14cbcSMatt Macy kcf_free_triedlist(list); 268*eda14cbcSMatt Macy return (error); 269*eda14cbcSMatt Macy } 270*eda14cbcSMatt Macy 271*eda14cbcSMatt Macy /* 272*eda14cbcSMatt Macy * For SW providers, check the validity of the context template 273*eda14cbcSMatt Macy * It is very rare that the generation number mis-matches, so 274*eda14cbcSMatt Macy * is acceptable to fail here, and let the consumer recover by 275*eda14cbcSMatt Macy * freeing this tmpl and create a new one for the key and new SW 276*eda14cbcSMatt Macy * provider 277*eda14cbcSMatt Macy */ 278*eda14cbcSMatt Macy if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) && 279*eda14cbcSMatt Macy ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) { 280*eda14cbcSMatt Macy if (ctx_tmpl->ct_generation != me->me_gen_swprov) { 281*eda14cbcSMatt Macy if (list != NULL) 282*eda14cbcSMatt Macy kcf_free_triedlist(list); 283*eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 284*eda14cbcSMatt Macy return (CRYPTO_OLD_CTX_TEMPLATE); 285*eda14cbcSMatt Macy } else { 286*eda14cbcSMatt Macy spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 287*eda14cbcSMatt Macy } 288*eda14cbcSMatt Macy } 289*eda14cbcSMatt Macy 290*eda14cbcSMatt Macy /* The fast path for SW providers. */ 291*eda14cbcSMatt Macy if (CHECK_FASTPATH(crq, pd)) { 292*eda14cbcSMatt Macy crypto_mechanism_t lmech; 293*eda14cbcSMatt Macy 294*eda14cbcSMatt Macy lmech = *mech; 295*eda14cbcSMatt Macy KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 296*eda14cbcSMatt Macy 297*eda14cbcSMatt Macy error = KCF_PROV_MAC_VERIFY_ATOMIC(pd, pd->pd_sid, &lmech, key, 298*eda14cbcSMatt Macy data, mac, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq)); 299*eda14cbcSMatt Macy KCF_PROV_INCRSTATS(pd, error); 300*eda14cbcSMatt Macy } else { 301*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_HW_PROVIDER && 302*eda14cbcSMatt Macy (pd->pd_flags & CRYPTO_HASH_NO_UPDATE) && 303*eda14cbcSMatt Macy (data->cd_length > pd->pd_hash_limit)) { 304*eda14cbcSMatt Macy /* see comments in crypto_mac() */ 305*eda14cbcSMatt Macy error = CRYPTO_BUFFER_TOO_BIG; 306*eda14cbcSMatt Macy } else { 307*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, 308*eda14cbcSMatt Macy KCF_OP_MAC_VERIFY_ATOMIC, pd->pd_sid, mech, 309*eda14cbcSMatt Macy key, data, mac, spi_ctx_tmpl); 310*eda14cbcSMatt Macy 311*eda14cbcSMatt Macy error = kcf_submit_request(pd, NULL, crq, ¶ms, 312*eda14cbcSMatt Macy KCF_ISDUALREQ(crq)); 313*eda14cbcSMatt Macy } 314*eda14cbcSMatt Macy } 315*eda14cbcSMatt Macy 316*eda14cbcSMatt Macy if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 317*eda14cbcSMatt Macy IS_RECOVERABLE(error)) { 318*eda14cbcSMatt Macy /* Add pd to the linked list of providers tried. */ 319*eda14cbcSMatt Macy if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 320*eda14cbcSMatt Macy goto retry; 321*eda14cbcSMatt Macy } 322*eda14cbcSMatt Macy 323*eda14cbcSMatt Macy if (list != NULL) 324*eda14cbcSMatt Macy kcf_free_triedlist(list); 325*eda14cbcSMatt Macy 326*eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 327*eda14cbcSMatt Macy return (error); 328*eda14cbcSMatt Macy } 329*eda14cbcSMatt Macy 330*eda14cbcSMatt Macy /* 331*eda14cbcSMatt Macy * crypto_mac_init_prov() 332*eda14cbcSMatt Macy * 333*eda14cbcSMatt Macy * Arguments: 334*eda14cbcSMatt Macy * pd: pointer to the descriptor of the provider to use for this 335*eda14cbcSMatt Macy * operation. 336*eda14cbcSMatt Macy * sid: provider session id. 337*eda14cbcSMatt Macy * mech: crypto_mechanism_t pointer. 338*eda14cbcSMatt Macy * mech_type is a valid value previously returned by 339*eda14cbcSMatt Macy * crypto_mech2id(); 340*eda14cbcSMatt Macy * When the mech's parameter is not NULL, its definition depends 341*eda14cbcSMatt Macy * on the standard definition of the mechanism. 342*eda14cbcSMatt Macy * key: pointer to a crypto_key_t structure. 343*eda14cbcSMatt Macy * tmpl: a crypto_ctx_template_t, opaque template of a context of a 344*eda14cbcSMatt Macy * MAC with the 'mech' using 'key'. 'tmpl' is created by 345*eda14cbcSMatt Macy * a previous call to crypto_create_ctx_template(). 346*eda14cbcSMatt Macy * ctxp: Pointer to a crypto_context_t. 347*eda14cbcSMatt Macy * cr: crypto_call_req_t calling conditions and call back info. 348*eda14cbcSMatt Macy * 349*eda14cbcSMatt Macy * Description: 350*eda14cbcSMatt Macy * Asynchronously submits a request for, or synchronously performs the 351*eda14cbcSMatt Macy * initialization of a MAC operation on the specified provider with 352*eda14cbcSMatt Macy * the specified session. 353*eda14cbcSMatt Macy * When possible and applicable, will internally use the pre-computed MAC 354*eda14cbcSMatt Macy * context from the context template, tmpl. 355*eda14cbcSMatt Macy * When complete and successful, 'ctxp' will contain a crypto_context_t 356*eda14cbcSMatt Macy * valid for later calls to mac_update() and mac_final(). 357*eda14cbcSMatt Macy * The caller should hold a reference on the specified provider 358*eda14cbcSMatt Macy * descriptor before calling this function. 359*eda14cbcSMatt Macy * 360*eda14cbcSMatt Macy * Context: 361*eda14cbcSMatt Macy * Process or interrupt, according to the semantics dictated by the 'cr'. 362*eda14cbcSMatt Macy * 363*eda14cbcSMatt Macy * Returns: 364*eda14cbcSMatt Macy * See comment in the beginning of the file. 365*eda14cbcSMatt Macy */ 366*eda14cbcSMatt Macy int 367*eda14cbcSMatt Macy crypto_mac_init_prov(crypto_provider_t provider, crypto_session_id_t sid, 368*eda14cbcSMatt Macy crypto_mechanism_t *mech, crypto_key_t *key, crypto_spi_ctx_template_t tmpl, 369*eda14cbcSMatt Macy crypto_context_t *ctxp, crypto_call_req_t *crq) 370*eda14cbcSMatt Macy { 371*eda14cbcSMatt Macy int rv; 372*eda14cbcSMatt Macy crypto_ctx_t *ctx; 373*eda14cbcSMatt Macy kcf_req_params_t params; 374*eda14cbcSMatt Macy kcf_provider_desc_t *pd = provider; 375*eda14cbcSMatt Macy kcf_provider_desc_t *real_provider = pd; 376*eda14cbcSMatt Macy 377*eda14cbcSMatt Macy ASSERT(KCF_PROV_REFHELD(pd)); 378*eda14cbcSMatt Macy 379*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 380*eda14cbcSMatt Macy rv = kcf_get_hardware_provider(mech->cm_type, 381*eda14cbcSMatt Macy CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd, 382*eda14cbcSMatt Macy &real_provider, CRYPTO_FG_MAC); 383*eda14cbcSMatt Macy 384*eda14cbcSMatt Macy if (rv != CRYPTO_SUCCESS) 385*eda14cbcSMatt Macy return (rv); 386*eda14cbcSMatt Macy } 387*eda14cbcSMatt Macy 388*eda14cbcSMatt Macy /* Allocate and initialize the canonical context */ 389*eda14cbcSMatt Macy if ((ctx = kcf_new_ctx(crq, real_provider, sid)) == NULL) { 390*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 391*eda14cbcSMatt Macy KCF_PROV_REFRELE(real_provider); 392*eda14cbcSMatt Macy return (CRYPTO_HOST_MEMORY); 393*eda14cbcSMatt Macy } 394*eda14cbcSMatt Macy 395*eda14cbcSMatt Macy /* The fast path for SW providers. */ 396*eda14cbcSMatt Macy if (CHECK_FASTPATH(crq, pd)) { 397*eda14cbcSMatt Macy crypto_mechanism_t lmech; 398*eda14cbcSMatt Macy 399*eda14cbcSMatt Macy lmech = *mech; 400*eda14cbcSMatt Macy KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech); 401*eda14cbcSMatt Macy rv = KCF_PROV_MAC_INIT(real_provider, ctx, &lmech, key, tmpl, 402*eda14cbcSMatt Macy KCF_SWFP_RHNDL(crq)); 403*eda14cbcSMatt Macy KCF_PROV_INCRSTATS(pd, rv); 404*eda14cbcSMatt Macy } else { 405*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, KCF_OP_INIT, sid, mech, key, 406*eda14cbcSMatt Macy NULL, NULL, tmpl); 407*eda14cbcSMatt Macy rv = kcf_submit_request(real_provider, ctx, crq, ¶ms, 408*eda14cbcSMatt Macy B_FALSE); 409*eda14cbcSMatt Macy } 410*eda14cbcSMatt Macy 411*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 412*eda14cbcSMatt Macy KCF_PROV_REFRELE(real_provider); 413*eda14cbcSMatt Macy 414*eda14cbcSMatt Macy if ((rv == CRYPTO_SUCCESS) || (rv == CRYPTO_QUEUED)) 415*eda14cbcSMatt Macy *ctxp = (crypto_context_t)ctx; 416*eda14cbcSMatt Macy else { 417*eda14cbcSMatt Macy /* Release the hold done in kcf_new_ctx(). */ 418*eda14cbcSMatt Macy KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private); 419*eda14cbcSMatt Macy } 420*eda14cbcSMatt Macy 421*eda14cbcSMatt Macy return (rv); 422*eda14cbcSMatt Macy } 423*eda14cbcSMatt Macy 424*eda14cbcSMatt Macy /* 425*eda14cbcSMatt Macy * Same as crypto_mac_init_prov(), but relies on the KCF scheduler to 426*eda14cbcSMatt Macy * choose a provider. See crypto_mac_init_prov() comments for more 427*eda14cbcSMatt Macy * information. 428*eda14cbcSMatt Macy */ 429*eda14cbcSMatt Macy int 430*eda14cbcSMatt Macy crypto_mac_init(crypto_mechanism_t *mech, crypto_key_t *key, 431*eda14cbcSMatt Macy crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 432*eda14cbcSMatt Macy crypto_call_req_t *crq) 433*eda14cbcSMatt Macy { 434*eda14cbcSMatt Macy int error; 435*eda14cbcSMatt Macy kcf_mech_entry_t *me; 436*eda14cbcSMatt Macy kcf_provider_desc_t *pd; 437*eda14cbcSMatt Macy kcf_ctx_template_t *ctx_tmpl; 438*eda14cbcSMatt Macy crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 439*eda14cbcSMatt Macy kcf_prov_tried_t *list = NULL; 440*eda14cbcSMatt Macy 441*eda14cbcSMatt Macy retry: 442*eda14cbcSMatt Macy /* The pd is returned held */ 443*eda14cbcSMatt Macy if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 444*eda14cbcSMatt Macy list, CRYPTO_FG_MAC, CHECK_RESTRICT(crq), 0)) == NULL) { 445*eda14cbcSMatt Macy if (list != NULL) 446*eda14cbcSMatt Macy kcf_free_triedlist(list); 447*eda14cbcSMatt Macy return (error); 448*eda14cbcSMatt Macy } 449*eda14cbcSMatt Macy 450*eda14cbcSMatt Macy /* 451*eda14cbcSMatt Macy * For SW providers, check the validity of the context template 452*eda14cbcSMatt Macy * It is very rare that the generation number mis-matches, so 453*eda14cbcSMatt Macy * is acceptable to fail here, and let the consumer recover by 454*eda14cbcSMatt Macy * freeing this tmpl and create a new one for the key and new SW 455*eda14cbcSMatt Macy * provider 456*eda14cbcSMatt Macy */ 457*eda14cbcSMatt Macy 458*eda14cbcSMatt Macy if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) && 459*eda14cbcSMatt Macy ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) { 460*eda14cbcSMatt Macy if (ctx_tmpl->ct_generation != me->me_gen_swprov) { 461*eda14cbcSMatt Macy if (list != NULL) 462*eda14cbcSMatt Macy kcf_free_triedlist(list); 463*eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 464*eda14cbcSMatt Macy return (CRYPTO_OLD_CTX_TEMPLATE); 465*eda14cbcSMatt Macy } else { 466*eda14cbcSMatt Macy spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 467*eda14cbcSMatt Macy } 468*eda14cbcSMatt Macy } 469*eda14cbcSMatt Macy 470*eda14cbcSMatt Macy if (pd->pd_prov_type == CRYPTO_HW_PROVIDER && 471*eda14cbcSMatt Macy (pd->pd_flags & CRYPTO_HASH_NO_UPDATE)) { 472*eda14cbcSMatt Macy /* 473*eda14cbcSMatt Macy * The hardware provider has limited HMAC support. 474*eda14cbcSMatt Macy * So, we fallback early here to using a software provider. 475*eda14cbcSMatt Macy * 476*eda14cbcSMatt Macy * XXX - need to enhance to do the fallback later in 477*eda14cbcSMatt Macy * crypto_mac_update() if the size of accumulated input data 478*eda14cbcSMatt Macy * exceeds the maximum size digestable by hardware provider. 479*eda14cbcSMatt Macy */ 480*eda14cbcSMatt Macy error = CRYPTO_BUFFER_TOO_BIG; 481*eda14cbcSMatt Macy } else { 482*eda14cbcSMatt Macy error = crypto_mac_init_prov(pd, pd->pd_sid, mech, key, 483*eda14cbcSMatt Macy spi_ctx_tmpl, ctxp, crq); 484*eda14cbcSMatt Macy } 485*eda14cbcSMatt Macy if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED && 486*eda14cbcSMatt Macy IS_RECOVERABLE(error)) { 487*eda14cbcSMatt Macy /* Add pd to the linked list of providers tried. */ 488*eda14cbcSMatt Macy if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL) 489*eda14cbcSMatt Macy goto retry; 490*eda14cbcSMatt Macy } 491*eda14cbcSMatt Macy 492*eda14cbcSMatt Macy if (list != NULL) 493*eda14cbcSMatt Macy kcf_free_triedlist(list); 494*eda14cbcSMatt Macy 495*eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 496*eda14cbcSMatt Macy return (error); 497*eda14cbcSMatt Macy } 498*eda14cbcSMatt Macy 499*eda14cbcSMatt Macy /* 500*eda14cbcSMatt Macy * crypto_mac_update() 501*eda14cbcSMatt Macy * 502*eda14cbcSMatt Macy * Arguments: 503*eda14cbcSMatt Macy * context: A crypto_context_t initialized by mac_init(). 504*eda14cbcSMatt Macy * data: The message part to be MAC'ed 505*eda14cbcSMatt Macy * cr: crypto_call_req_t calling conditions and call back info. 506*eda14cbcSMatt Macy * 507*eda14cbcSMatt Macy * Description: 508*eda14cbcSMatt Macy * Asynchronously submits a request for, or synchronously performs a 509*eda14cbcSMatt Macy * part of a MAC operation. 510*eda14cbcSMatt Macy * 511*eda14cbcSMatt Macy * Context: 512*eda14cbcSMatt Macy * Process or interrupt, according to the semantics dictated by the 'cr'. 513*eda14cbcSMatt Macy * 514*eda14cbcSMatt Macy * Returns: 515*eda14cbcSMatt Macy * See comment in the beginning of the file. 516*eda14cbcSMatt Macy */ 517*eda14cbcSMatt Macy int 518*eda14cbcSMatt Macy crypto_mac_update(crypto_context_t context, crypto_data_t *data, 519*eda14cbcSMatt Macy crypto_call_req_t *cr) 520*eda14cbcSMatt Macy { 521*eda14cbcSMatt Macy crypto_ctx_t *ctx = (crypto_ctx_t *)context; 522*eda14cbcSMatt Macy kcf_context_t *kcf_ctx; 523*eda14cbcSMatt Macy kcf_provider_desc_t *pd; 524*eda14cbcSMatt Macy kcf_req_params_t params; 525*eda14cbcSMatt Macy int rv; 526*eda14cbcSMatt Macy 527*eda14cbcSMatt Macy if ((ctx == NULL) || 528*eda14cbcSMatt Macy ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 529*eda14cbcSMatt Macy ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 530*eda14cbcSMatt Macy return (CRYPTO_INVALID_CONTEXT); 531*eda14cbcSMatt Macy } 532*eda14cbcSMatt Macy 533*eda14cbcSMatt Macy ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 534*eda14cbcSMatt Macy 535*eda14cbcSMatt Macy /* The fast path for SW providers. */ 536*eda14cbcSMatt Macy if (CHECK_FASTPATH(cr, pd)) { 537*eda14cbcSMatt Macy rv = KCF_PROV_MAC_UPDATE(pd, ctx, data, NULL); 538*eda14cbcSMatt Macy KCF_PROV_INCRSTATS(pd, rv); 539*eda14cbcSMatt Macy } else { 540*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, KCF_OP_UPDATE, 541*eda14cbcSMatt Macy ctx->cc_session, NULL, NULL, data, NULL, NULL); 542*eda14cbcSMatt Macy rv = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 543*eda14cbcSMatt Macy } 544*eda14cbcSMatt Macy 545*eda14cbcSMatt Macy return (rv); 546*eda14cbcSMatt Macy } 547*eda14cbcSMatt Macy 548*eda14cbcSMatt Macy /* 549*eda14cbcSMatt Macy * crypto_mac_final() 550*eda14cbcSMatt Macy * 551*eda14cbcSMatt Macy * Arguments: 552*eda14cbcSMatt Macy * context: A crypto_context_t initialized by mac_init(). 553*eda14cbcSMatt Macy * mac: Storage for the message authentication code. 554*eda14cbcSMatt Macy * cr: crypto_call_req_t calling conditions and call back info. 555*eda14cbcSMatt Macy * 556*eda14cbcSMatt Macy * Description: 557*eda14cbcSMatt Macy * Asynchronously submits a request for, or synchronously performs a 558*eda14cbcSMatt Macy * part of a message authentication operation. 559*eda14cbcSMatt Macy * 560*eda14cbcSMatt Macy * Context: 561*eda14cbcSMatt Macy * Process or interrupt, according to the semantics dictated by the 'cr'. 562*eda14cbcSMatt Macy * 563*eda14cbcSMatt Macy * Returns: 564*eda14cbcSMatt Macy * See comment in the beginning of the file. 565*eda14cbcSMatt Macy */ 566*eda14cbcSMatt Macy int 567*eda14cbcSMatt Macy crypto_mac_final(crypto_context_t context, crypto_data_t *mac, 568*eda14cbcSMatt Macy crypto_call_req_t *cr) 569*eda14cbcSMatt Macy { 570*eda14cbcSMatt Macy crypto_ctx_t *ctx = (crypto_ctx_t *)context; 571*eda14cbcSMatt Macy kcf_context_t *kcf_ctx; 572*eda14cbcSMatt Macy kcf_provider_desc_t *pd; 573*eda14cbcSMatt Macy kcf_req_params_t params; 574*eda14cbcSMatt Macy int rv; 575*eda14cbcSMatt Macy 576*eda14cbcSMatt Macy if ((ctx == NULL) || 577*eda14cbcSMatt Macy ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 578*eda14cbcSMatt Macy ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 579*eda14cbcSMatt Macy return (CRYPTO_INVALID_CONTEXT); 580*eda14cbcSMatt Macy } 581*eda14cbcSMatt Macy 582*eda14cbcSMatt Macy ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 583*eda14cbcSMatt Macy 584*eda14cbcSMatt Macy /* The fast path for SW providers. */ 585*eda14cbcSMatt Macy if (CHECK_FASTPATH(cr, pd)) { 586*eda14cbcSMatt Macy rv = KCF_PROV_MAC_FINAL(pd, ctx, mac, NULL); 587*eda14cbcSMatt Macy KCF_PROV_INCRSTATS(pd, rv); 588*eda14cbcSMatt Macy } else { 589*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, KCF_OP_FINAL, 590*eda14cbcSMatt Macy ctx->cc_session, NULL, NULL, NULL, mac, NULL); 591*eda14cbcSMatt Macy rv = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 592*eda14cbcSMatt Macy } 593*eda14cbcSMatt Macy 594*eda14cbcSMatt Macy /* Release the hold done in kcf_new_ctx() during init step. */ 595*eda14cbcSMatt Macy KCF_CONTEXT_COND_RELEASE(rv, kcf_ctx); 596*eda14cbcSMatt Macy return (rv); 597*eda14cbcSMatt Macy } 598*eda14cbcSMatt Macy 599*eda14cbcSMatt Macy /* 600*eda14cbcSMatt Macy * See comments for crypto_mac_update() and crypto_mac_final(). 601*eda14cbcSMatt Macy */ 602*eda14cbcSMatt Macy int 603*eda14cbcSMatt Macy crypto_mac_single(crypto_context_t context, crypto_data_t *data, 604*eda14cbcSMatt Macy crypto_data_t *mac, crypto_call_req_t *cr) 605*eda14cbcSMatt Macy { 606*eda14cbcSMatt Macy crypto_ctx_t *ctx = (crypto_ctx_t *)context; 607*eda14cbcSMatt Macy kcf_context_t *kcf_ctx; 608*eda14cbcSMatt Macy kcf_provider_desc_t *pd; 609*eda14cbcSMatt Macy int error; 610*eda14cbcSMatt Macy kcf_req_params_t params; 611*eda14cbcSMatt Macy 612*eda14cbcSMatt Macy 613*eda14cbcSMatt Macy if ((ctx == NULL) || 614*eda14cbcSMatt Macy ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) || 615*eda14cbcSMatt Macy ((pd = kcf_ctx->kc_prov_desc) == NULL)) { 616*eda14cbcSMatt Macy return (CRYPTO_INVALID_CONTEXT); 617*eda14cbcSMatt Macy } 618*eda14cbcSMatt Macy 619*eda14cbcSMatt Macy 620*eda14cbcSMatt Macy /* The fast path for SW providers. */ 621*eda14cbcSMatt Macy if (CHECK_FASTPATH(cr, pd)) { 622*eda14cbcSMatt Macy error = KCF_PROV_MAC(pd, ctx, data, mac, NULL); 623*eda14cbcSMatt Macy KCF_PROV_INCRSTATS(pd, error); 624*eda14cbcSMatt Macy } else { 625*eda14cbcSMatt Macy KCF_WRAP_MAC_OPS_PARAMS(¶ms, KCF_OP_SINGLE, pd->pd_sid, 626*eda14cbcSMatt Macy NULL, NULL, data, mac, NULL); 627*eda14cbcSMatt Macy error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); 628*eda14cbcSMatt Macy } 629*eda14cbcSMatt Macy 630*eda14cbcSMatt Macy /* Release the hold done in kcf_new_ctx() during init step. */ 631*eda14cbcSMatt Macy KCF_CONTEXT_COND_RELEASE(error, kcf_ctx); 632*eda14cbcSMatt Macy return (error); 633*eda14cbcSMatt Macy } 634*eda14cbcSMatt Macy 635*eda14cbcSMatt Macy #if defined(_KERNEL) 636*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_prov); 637*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac); 638*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_verify_prov); 639*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_verify); 640*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_init_prov); 641*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_init); 642*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_update); 643*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_final); 644*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_single); 645*eda14cbcSMatt Macy #endif 646