1894b2776Smcpowers /* 2894b2776Smcpowers * CDDL HEADER START 3894b2776Smcpowers * 4894b2776Smcpowers * The contents of this file are subject to the terms of the 5*9b009fc1SValerie Bubb Fenwick * Common Development and Distribution License (the "License"). 6*9b009fc1SValerie Bubb Fenwick * You may not use this file except in compliance with the License. 7894b2776Smcpowers * 8894b2776Smcpowers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9894b2776Smcpowers * or http://www.opensolaris.org/os/licensing. 10894b2776Smcpowers * See the License for the specific language governing permissions 11894b2776Smcpowers * and limitations under the License. 12894b2776Smcpowers * 13894b2776Smcpowers * When distributing Covered Code, include this CDDL HEADER in each 14894b2776Smcpowers * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15894b2776Smcpowers * If applicable, add the following below this CDDL HEADER, with the 16894b2776Smcpowers * fields enclosed by brackets "[]" replaced with your own identifying 17894b2776Smcpowers * information: Portions Copyright [yyyy] [name of copyright owner] 18894b2776Smcpowers * 19894b2776Smcpowers * CDDL HEADER END 20894b2776Smcpowers */ 21894b2776Smcpowers /* 22*9b009fc1SValerie Bubb Fenwick * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23894b2776Smcpowers */ 24894b2776Smcpowers 25894b2776Smcpowers 26894b2776Smcpowers #include <sys/errno.h> 27894b2776Smcpowers #include <sys/types.h> 28894b2776Smcpowers #include <sys/kmem.h> 29894b2776Smcpowers #include <sys/cmn_err.h> 30894b2776Smcpowers #include <sys/sysmacros.h> 31894b2776Smcpowers #include <sys/crypto/common.h> 32894b2776Smcpowers #include <sys/crypto/impl.h> 33894b2776Smcpowers #include <sys/crypto/api.h> 34894b2776Smcpowers #include <sys/crypto/spi.h> 35894b2776Smcpowers #include <sys/crypto/sched_impl.h> 36894b2776Smcpowers 37894b2776Smcpowers #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f) 38894b2776Smcpowers #define CRYPTO_OBJECT_OFFSET(f) offsetof(crypto_object_ops_t, f) 39894b2776Smcpowers #define CRYPTO_SESSION_OFFSET(f) offsetof(crypto_session_ops_t, f) 40894b2776Smcpowers 41894b2776Smcpowers int 42894b2776Smcpowers crypto_session_open(crypto_provider_t provider, crypto_session_id_t *sidp, 43894b2776Smcpowers crypto_call_req_t *crq) 44894b2776Smcpowers { 45894b2776Smcpowers kcf_req_params_t params; 46894b2776Smcpowers kcf_provider_desc_t *real_provider; 47894b2776Smcpowers kcf_provider_desc_t *pd = provider; 48894b2776Smcpowers 49894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 50894b2776Smcpowers 51894b2776Smcpowers /* find a provider that supports session ops */ 52894b2776Smcpowers (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops), 53*9b009fc1SValerie Bubb Fenwick CRYPTO_SESSION_OFFSET(session_open), pd, &real_provider); 54894b2776Smcpowers 55894b2776Smcpowers if (real_provider != NULL) { 56894b2776Smcpowers int rv; 57894b2776Smcpowers 58894b2776Smcpowers ASSERT(real_provider == pd || 59894b2776Smcpowers pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER); 60894b2776Smcpowers 61894b2776Smcpowers if (CHECK_FASTPATH(crq, pd)) { 62894b2776Smcpowers rv = KCF_PROV_SESSION_OPEN(real_provider, sidp, 63894b2776Smcpowers KCF_SWFP_RHNDL(crq), pd); 64894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 65894b2776Smcpowers } else { 66894b2776Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, 67894b2776Smcpowers KCF_OP_SESSION_OPEN, sidp, 0, CRYPTO_USER, NULL, 68894b2776Smcpowers 0, pd); 69894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 70894b2776Smcpowers ¶ms, B_FALSE); 71894b2776Smcpowers } 72894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 73894b2776Smcpowers 74894b2776Smcpowers if (rv != CRYPTO_SUCCESS) { 75894b2776Smcpowers return (rv); 76894b2776Smcpowers } 77894b2776Smcpowers } 78894b2776Smcpowers return (CRYPTO_SUCCESS); 79894b2776Smcpowers } 80894b2776Smcpowers 81894b2776Smcpowers int 82894b2776Smcpowers crypto_session_close(crypto_provider_t provider, crypto_session_id_t sid, 83894b2776Smcpowers crypto_call_req_t *crq) 84894b2776Smcpowers { 85894b2776Smcpowers int rv; 86894b2776Smcpowers kcf_req_params_t params; 87894b2776Smcpowers kcf_provider_desc_t *real_provider; 88894b2776Smcpowers kcf_provider_desc_t *pd = provider; 89894b2776Smcpowers 90894b2776Smcpowers if (pd == NULL) 91894b2776Smcpowers return (CRYPTO_ARGUMENTS_BAD); 92894b2776Smcpowers 93894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 94894b2776Smcpowers 95894b2776Smcpowers /* find a provider that supports session ops */ 96894b2776Smcpowers (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops), 97*9b009fc1SValerie Bubb Fenwick CRYPTO_SESSION_OFFSET(session_close), pd, &real_provider); 98894b2776Smcpowers 99894b2776Smcpowers ASSERT(real_provider == pd || 100894b2776Smcpowers pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER); 101894b2776Smcpowers 102894b2776Smcpowers /* edge case is where the logical provider has no members */ 103894b2776Smcpowers if (real_provider != NULL) { 104894b2776Smcpowers /* The fast path for SW providers. */ 105894b2776Smcpowers if (CHECK_FASTPATH(crq, pd)) { 106894b2776Smcpowers rv = KCF_PROV_SESSION_CLOSE(real_provider, 107894b2776Smcpowers sid, KCF_SWFP_RHNDL(crq), pd); 108894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 109894b2776Smcpowers } else { 110894b2776Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, 111894b2776Smcpowers KCF_OP_SESSION_CLOSE, NULL, sid, 112894b2776Smcpowers CRYPTO_USER, NULL, 0, pd); 113894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 114894b2776Smcpowers ¶ms, B_FALSE); 115894b2776Smcpowers } 116894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 117894b2776Smcpowers } 118894b2776Smcpowers return (CRYPTO_SUCCESS); 119894b2776Smcpowers } 120894b2776Smcpowers 121894b2776Smcpowers int 122894b2776Smcpowers crypto_session_login(crypto_provider_t provider, crypto_session_id_t sid, 123894b2776Smcpowers crypto_user_type_t type, char *pin, ulong_t len, crypto_call_req_t *crq) 124894b2776Smcpowers { 125894b2776Smcpowers kcf_req_params_t params; 126894b2776Smcpowers kcf_provider_desc_t *pd = provider; 127894b2776Smcpowers kcf_provider_desc_t *real_provider = pd; 128894b2776Smcpowers int rv; 129894b2776Smcpowers 130894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 131894b2776Smcpowers 132894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 133894b2776Smcpowers rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 134894b2776Smcpowers session_ops), CRYPTO_SESSION_OFFSET(session_login), 135*9b009fc1SValerie Bubb Fenwick pd, &real_provider); 136894b2776Smcpowers 137894b2776Smcpowers if (rv != CRYPTO_SUCCESS) 138894b2776Smcpowers return (rv); 139894b2776Smcpowers } 140894b2776Smcpowers 141894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 142894b2776Smcpowers rv = KCF_PROV_SESSION_LOGIN(real_provider, sid, 143894b2776Smcpowers type, pin, len, KCF_SWFP_RHNDL(crq)); 144894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 145894b2776Smcpowers } else { 146894b2776Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_LOGIN, 147894b2776Smcpowers NULL, sid, type, pin, len, real_provider); 148894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 149894b2776Smcpowers ¶ms, B_FALSE); 150894b2776Smcpowers } 151894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 152894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 153894b2776Smcpowers 154894b2776Smcpowers return (rv); 155894b2776Smcpowers } 156894b2776Smcpowers 157894b2776Smcpowers int 158894b2776Smcpowers crypto_session_logout(crypto_provider_t provider, crypto_session_id_t sid, 159894b2776Smcpowers crypto_call_req_t *crq) 160894b2776Smcpowers { 161894b2776Smcpowers kcf_req_params_t params; 162894b2776Smcpowers kcf_provider_desc_t *pd = provider; 163894b2776Smcpowers kcf_provider_desc_t *real_provider = pd; 164894b2776Smcpowers int rv; 165894b2776Smcpowers 166894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 167894b2776Smcpowers 168894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 169894b2776Smcpowers rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 170894b2776Smcpowers session_ops), CRYPTO_SESSION_OFFSET(session_logout), 171*9b009fc1SValerie Bubb Fenwick pd, &real_provider); 172894b2776Smcpowers 173894b2776Smcpowers if (rv != CRYPTO_SUCCESS) 174894b2776Smcpowers return (rv); 175894b2776Smcpowers } 176894b2776Smcpowers 177894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 178894b2776Smcpowers rv = KCF_PROV_SESSION_LOGOUT(real_provider, sid, 179894b2776Smcpowers KCF_SWFP_RHNDL(crq)); 180894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 181894b2776Smcpowers } else { 182894b2776Smcpowers KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_LOGOUT, 183894b2776Smcpowers NULL, sid, 0, NULL, 0, real_provider); 184894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 185894b2776Smcpowers ¶ms, B_FALSE); 186894b2776Smcpowers } 187894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 188894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 189894b2776Smcpowers 190894b2776Smcpowers return (rv); 191894b2776Smcpowers } 192