1*904Smcpowers /* 2*904Smcpowers * CDDL HEADER START 3*904Smcpowers * 4*904Smcpowers * The contents of this file are subject to the terms of the 5*904Smcpowers * Common Development and Distribution License, Version 1.0 only 6*904Smcpowers * (the "License"). You may not use this file except in compliance 7*904Smcpowers * with the License. 8*904Smcpowers * 9*904Smcpowers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*904Smcpowers * or http://www.opensolaris.org/os/licensing. 11*904Smcpowers * See the License for the specific language governing permissions 12*904Smcpowers * and limitations under the License. 13*904Smcpowers * 14*904Smcpowers * When distributing Covered Code, include this CDDL HEADER in each 15*904Smcpowers * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*904Smcpowers * If applicable, add the following below this CDDL HEADER, with the 17*904Smcpowers * fields enclosed by brackets "[]" replaced with your own identifying 18*904Smcpowers * information: Portions Copyright [yyyy] [name of copyright owner] 19*904Smcpowers * 20*904Smcpowers * CDDL HEADER END 21*904Smcpowers */ 22*904Smcpowers /* 23*904Smcpowers * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*904Smcpowers * Use is subject to license terms. 25*904Smcpowers */ 26*904Smcpowers 27*904Smcpowers 28*904Smcpowers #pragma ident "%Z%%M% %I% %E% SMI" 29*904Smcpowers 30*904Smcpowers #include <sys/errno.h> 31*904Smcpowers #include <sys/types.h> 32*904Smcpowers #include <sys/kmem.h> 33*904Smcpowers #include <sys/cmn_err.h> 34*904Smcpowers #include <sys/sysmacros.h> 35*904Smcpowers #include <sys/crypto/common.h> 36*904Smcpowers #include <sys/crypto/impl.h> 37*904Smcpowers #include <sys/crypto/api.h> 38*904Smcpowers #include <sys/crypto/spi.h> 39*904Smcpowers #include <sys/crypto/sched_impl.h> 40*904Smcpowers 41*904Smcpowers #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f) 42*904Smcpowers #define CRYPTO_OBJECT_OFFSET(f) offsetof(crypto_object_ops_t, f) 43*904Smcpowers #define CRYPTO_SESSION_OFFSET(f) offsetof(crypto_session_ops_t, f) 44*904Smcpowers 45*904Smcpowers int 46*904Smcpowers crypto_session_open(crypto_provider_t provider, crypto_session_id_t *sidp, 47*904Smcpowers crypto_call_req_t *crq) 48*904Smcpowers { 49*904Smcpowers kcf_req_params_t params; 50*904Smcpowers kcf_provider_desc_t *real_provider; 51*904Smcpowers kcf_provider_desc_t *pd = provider; 52*904Smcpowers 53*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 54*904Smcpowers 55*904Smcpowers /* find a provider that supports session ops */ 56*904Smcpowers (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops), 57*904Smcpowers CRYPTO_SESSION_OFFSET(session_open), 58*904Smcpowers CHECK_RESTRICT(crq), pd, &real_provider); 59*904Smcpowers 60*904Smcpowers if (real_provider != NULL) { 61*904Smcpowers int rv; 62*904Smcpowers 63*904Smcpowers ASSERT(real_provider == pd || 64*904Smcpowers pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER); 65*904Smcpowers 66*904Smcpowers if (CHECK_FASTPATH(crq, pd)) { 67*904Smcpowers rv = KCF_PROV_SESSION_OPEN(real_provider, sidp, 68*904Smcpowers KCF_SWFP_RHNDL(crq), pd); 69*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 70*904Smcpowers } else { 71*904Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, 72*904Smcpowers KCF_OP_SESSION_OPEN, sidp, 0, CRYPTO_USER, NULL, 73*904Smcpowers 0, pd); 74*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 75*904Smcpowers ¶ms, B_FALSE); 76*904Smcpowers } 77*904Smcpowers KCF_PROV_REFRELE(real_provider); 78*904Smcpowers 79*904Smcpowers if (rv != CRYPTO_SUCCESS) { 80*904Smcpowers return (rv); 81*904Smcpowers } 82*904Smcpowers } 83*904Smcpowers return (CRYPTO_SUCCESS); 84*904Smcpowers } 85*904Smcpowers 86*904Smcpowers int 87*904Smcpowers crypto_session_close(crypto_provider_t provider, crypto_session_id_t sid, 88*904Smcpowers crypto_call_req_t *crq) 89*904Smcpowers { 90*904Smcpowers int rv; 91*904Smcpowers kcf_req_params_t params; 92*904Smcpowers kcf_provider_desc_t *real_provider; 93*904Smcpowers kcf_provider_desc_t *pd = provider; 94*904Smcpowers 95*904Smcpowers if (pd == NULL) 96*904Smcpowers return (CRYPTO_ARGUMENTS_BAD); 97*904Smcpowers 98*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 99*904Smcpowers 100*904Smcpowers /* find a provider that supports session ops */ 101*904Smcpowers (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops), 102*904Smcpowers CRYPTO_SESSION_OFFSET(session_close), CHECK_RESTRICT(crq), 103*904Smcpowers pd, &real_provider); 104*904Smcpowers 105*904Smcpowers ASSERT(real_provider == pd || 106*904Smcpowers pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER); 107*904Smcpowers 108*904Smcpowers /* edge case is where the logical provider has no members */ 109*904Smcpowers if (real_provider != NULL) { 110*904Smcpowers /* The fast path for SW providers. */ 111*904Smcpowers if (CHECK_FASTPATH(crq, pd)) { 112*904Smcpowers rv = KCF_PROV_SESSION_CLOSE(real_provider, 113*904Smcpowers sid, KCF_SWFP_RHNDL(crq), pd); 114*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 115*904Smcpowers } else { 116*904Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, 117*904Smcpowers KCF_OP_SESSION_CLOSE, NULL, sid, 118*904Smcpowers CRYPTO_USER, NULL, 0, pd); 119*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 120*904Smcpowers ¶ms, B_FALSE); 121*904Smcpowers } 122*904Smcpowers KCF_PROV_REFRELE(real_provider); 123*904Smcpowers } 124*904Smcpowers return (CRYPTO_SUCCESS); 125*904Smcpowers } 126*904Smcpowers 127*904Smcpowers int 128*904Smcpowers crypto_session_login(crypto_provider_t provider, crypto_session_id_t sid, 129*904Smcpowers crypto_user_type_t type, char *pin, ulong_t len, crypto_call_req_t *crq) 130*904Smcpowers { 131*904Smcpowers kcf_req_params_t params; 132*904Smcpowers kcf_provider_desc_t *pd = provider; 133*904Smcpowers kcf_provider_desc_t *real_provider = pd; 134*904Smcpowers int rv; 135*904Smcpowers 136*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 137*904Smcpowers 138*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 139*904Smcpowers rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 140*904Smcpowers session_ops), CRYPTO_SESSION_OFFSET(session_login), 141*904Smcpowers CHECK_RESTRICT(crq), pd, &real_provider); 142*904Smcpowers 143*904Smcpowers if (rv != CRYPTO_SUCCESS) 144*904Smcpowers return (rv); 145*904Smcpowers } 146*904Smcpowers 147*904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 148*904Smcpowers rv = KCF_PROV_SESSION_LOGIN(real_provider, sid, 149*904Smcpowers type, pin, len, KCF_SWFP_RHNDL(crq)); 150*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 151*904Smcpowers } else { 152*904Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_LOGIN, 153*904Smcpowers NULL, sid, type, pin, len, real_provider); 154*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 155*904Smcpowers ¶ms, B_FALSE); 156*904Smcpowers } 157*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 158*904Smcpowers KCF_PROV_REFRELE(real_provider); 159*904Smcpowers 160*904Smcpowers return (rv); 161*904Smcpowers } 162*904Smcpowers 163*904Smcpowers int 164*904Smcpowers crypto_session_logout(crypto_provider_t provider, crypto_session_id_t sid, 165*904Smcpowers crypto_call_req_t *crq) 166*904Smcpowers { 167*904Smcpowers kcf_req_params_t params; 168*904Smcpowers kcf_provider_desc_t *pd = provider; 169*904Smcpowers kcf_provider_desc_t *real_provider = pd; 170*904Smcpowers int rv; 171*904Smcpowers 172*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 173*904Smcpowers 174*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 175*904Smcpowers rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 176*904Smcpowers session_ops), CRYPTO_SESSION_OFFSET(session_logout), 177*904Smcpowers CHECK_RESTRICT(crq), pd, &real_provider); 178*904Smcpowers 179*904Smcpowers if (rv != CRYPTO_SUCCESS) 180*904Smcpowers return (rv); 181*904Smcpowers } 182*904Smcpowers 183*904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 184*904Smcpowers rv = KCF_PROV_SESSION_LOGOUT(real_provider, sid, 185*904Smcpowers KCF_SWFP_RHNDL(crq)); 186*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 187*904Smcpowers } else { 188*904Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_LOGOUT, 189*904Smcpowers NULL, sid, 0, NULL, 0, real_provider); 190*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 191*904Smcpowers ¶ms, B_FALSE); 192*904Smcpowers } 193*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 194*904Smcpowers KCF_PROV_REFRELE(real_provider); 195*904Smcpowers 196*904Smcpowers return (rv); 197*904Smcpowers } 198