1904Smcpowers /* 2904Smcpowers * CDDL HEADER START 3904Smcpowers * 4904Smcpowers * The contents of this file are subject to the terms of the 5*1808Smcpowers * Common Development and Distribution License (the "License"). 6*1808Smcpowers * You may not use this file except in compliance with the License. 7904Smcpowers * 8904Smcpowers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9904Smcpowers * or http://www.opensolaris.org/os/licensing. 10904Smcpowers * See the License for the specific language governing permissions 11904Smcpowers * and limitations under the License. 12904Smcpowers * 13904Smcpowers * When distributing Covered Code, include this CDDL HEADER in each 14904Smcpowers * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15904Smcpowers * If applicable, add the following below this CDDL HEADER, with the 16904Smcpowers * fields enclosed by brackets "[]" replaced with your own identifying 17904Smcpowers * information: Portions Copyright [yyyy] [name of copyright owner] 18904Smcpowers * 19904Smcpowers * CDDL HEADER END 20904Smcpowers */ 21904Smcpowers /* 22*1808Smcpowers * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23904Smcpowers * Use is subject to license terms. 24904Smcpowers */ 25904Smcpowers 26904Smcpowers 27904Smcpowers #pragma ident "%Z%%M% %I% %E% SMI" 28904Smcpowers 29904Smcpowers #include <sys/errno.h> 30904Smcpowers #include <sys/types.h> 31904Smcpowers #include <sys/kmem.h> 32904Smcpowers #include <sys/cmn_err.h> 33904Smcpowers #include <sys/sysmacros.h> 34904Smcpowers #include <sys/crypto/common.h> 35904Smcpowers #include <sys/crypto/impl.h> 36904Smcpowers #include <sys/crypto/api.h> 37904Smcpowers #include <sys/crypto/spi.h> 38904Smcpowers #include <sys/crypto/sched_impl.h> 39904Smcpowers 40904Smcpowers #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f) 41904Smcpowers #define CRYPTO_KEY_OFFSET(f) offsetof(crypto_key_ops_t, f) 42904Smcpowers 43904Smcpowers int 44904Smcpowers crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid, 45904Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count, 46904Smcpowers crypto_object_id_t *handle, crypto_call_req_t *crq) 47904Smcpowers { 48904Smcpowers kcf_req_params_t params; 49904Smcpowers kcf_provider_desc_t *pd = provider; 50904Smcpowers kcf_provider_desc_t *real_provider = pd; 51904Smcpowers int rv; 52904Smcpowers 53904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 54904Smcpowers 55904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 56904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 57*1808Smcpowers CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 58*1808Smcpowers pd, &real_provider, CRYPTO_FG_GENERATE); 59904Smcpowers 60904Smcpowers if (rv != CRYPTO_SUCCESS) 61904Smcpowers return (rv); 62904Smcpowers } 63904Smcpowers 64904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 65904Smcpowers rv = KCF_PROV_KEY_GENERATE(real_provider, sid, 66904Smcpowers mech, attrs, count, handle, KCF_SWFP_RHNDL(crq)); 67904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 68904Smcpowers } else { 69904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE, sid, 70904Smcpowers mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0); 71904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 72904Smcpowers ¶ms, B_FALSE); 73904Smcpowers } 74904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 75904Smcpowers KCF_PROV_REFRELE(real_provider); 76904Smcpowers 77904Smcpowers return (rv); 78904Smcpowers } 79904Smcpowers 80904Smcpowers int 81904Smcpowers crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid, 82904Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs, 83904Smcpowers uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count, 84904Smcpowers crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle, 85904Smcpowers crypto_call_req_t *crq) 86904Smcpowers { 87904Smcpowers kcf_req_params_t params; 88904Smcpowers kcf_provider_desc_t *pd = provider; 89904Smcpowers kcf_provider_desc_t *real_provider = pd; 90904Smcpowers int rv; 91904Smcpowers 92904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 93904Smcpowers 94904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 95904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 96*1808Smcpowers CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 97*1808Smcpowers pd, &real_provider, CRYPTO_FG_GENERATE_KEY_PAIR); 98904Smcpowers 99904Smcpowers if (rv != CRYPTO_SUCCESS) 100904Smcpowers return (rv); 101904Smcpowers } 102904Smcpowers 103904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 104904Smcpowers rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech, 105904Smcpowers pub_attrs, pub_count, pri_attrs, pri_count, pub_handle, 106904Smcpowers pri_handle, KCF_SWFP_RHNDL(crq)); 107904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 108904Smcpowers } else { 109904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE_PAIR, 110904Smcpowers sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs, 111904Smcpowers pri_count, pri_handle, NULL, NULL, 0); 112904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 113904Smcpowers ¶ms, B_FALSE); 114904Smcpowers } 115904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 116904Smcpowers KCF_PROV_REFRELE(real_provider); 117904Smcpowers 118904Smcpowers return (rv); 119904Smcpowers } 120904Smcpowers 121904Smcpowers int 122904Smcpowers crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid, 123904Smcpowers crypto_mechanism_t *mech, crypto_key_t *wrapping_key, 124904Smcpowers crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len, 125904Smcpowers crypto_call_req_t *crq) 126904Smcpowers { 127904Smcpowers kcf_req_params_t params; 128904Smcpowers kcf_provider_desc_t *pd = provider; 129904Smcpowers kcf_provider_desc_t *real_provider = pd; 130904Smcpowers int rv; 131904Smcpowers 132904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 133904Smcpowers 134904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 135904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 136*1808Smcpowers CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 137*1808Smcpowers pd, &real_provider, CRYPTO_FG_WRAP); 138904Smcpowers 139904Smcpowers if (rv != CRYPTO_SUCCESS) 140904Smcpowers return (rv); 141904Smcpowers } 142904Smcpowers 143904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 144904Smcpowers rv = KCF_PROV_KEY_WRAP(real_provider, sid, mech, wrapping_key, 145904Smcpowers key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq)); 146904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 147904Smcpowers } else { 148904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_WRAP, sid, mech, 149904Smcpowers NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key, 150904Smcpowers wrapped_key_len); 151904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 152904Smcpowers ¶ms, B_FALSE); 153904Smcpowers } 154904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 155904Smcpowers KCF_PROV_REFRELE(real_provider); 156904Smcpowers 157904Smcpowers return (rv); 158904Smcpowers } 159904Smcpowers 160904Smcpowers int 161904Smcpowers crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid, 162904Smcpowers crypto_mechanism_t *mech, crypto_key_t *unwrapping_key, 163904Smcpowers uchar_t *wrapped_key, size_t *wrapped_key_len, 164904Smcpowers crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key, 165904Smcpowers crypto_call_req_t *crq) 166904Smcpowers { 167904Smcpowers kcf_req_params_t params; 168904Smcpowers kcf_provider_desc_t *pd = provider; 169904Smcpowers kcf_provider_desc_t *real_provider = pd; 170904Smcpowers int rv; 171904Smcpowers 172904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 173904Smcpowers 174904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 175904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 176*1808Smcpowers CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 177*1808Smcpowers pd, &real_provider, CRYPTO_FG_UNWRAP); 178904Smcpowers 179904Smcpowers if (rv != CRYPTO_SUCCESS) 180904Smcpowers return (rv); 181904Smcpowers } 182904Smcpowers 183904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 184904Smcpowers rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech, 185904Smcpowers unwrapping_key, wrapped_key, wrapped_key_len, attrs, 186904Smcpowers count, key, KCF_SWFP_RHNDL(crq)); 187904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 188904Smcpowers } else { 189904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_UNWRAP, sid, mech, 190904Smcpowers attrs, count, key, NULL, 0, NULL, unwrapping_key, 191904Smcpowers wrapped_key, wrapped_key_len); 192904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 193904Smcpowers ¶ms, B_FALSE); 194904Smcpowers } 195904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 196904Smcpowers KCF_PROV_REFRELE(real_provider); 197904Smcpowers 198904Smcpowers return (rv); 199904Smcpowers } 200904Smcpowers 201904Smcpowers int 202904Smcpowers crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid, 203904Smcpowers crypto_mechanism_t *mech, crypto_key_t *base_key, 204904Smcpowers crypto_object_attribute_t *attrs, uint_t count, 205904Smcpowers crypto_object_id_t *new_key, crypto_call_req_t *crq) 206904Smcpowers { 207904Smcpowers kcf_req_params_t params; 208904Smcpowers kcf_provider_desc_t *pd = provider; 209904Smcpowers kcf_provider_desc_t *real_provider = pd; 210904Smcpowers int rv; 211904Smcpowers 212904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 213904Smcpowers 214904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 215904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 216*1808Smcpowers CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 217*1808Smcpowers pd, &real_provider, CRYPTO_FG_DERIVE); 218904Smcpowers 219904Smcpowers if (rv != CRYPTO_SUCCESS) 220904Smcpowers return (rv); 221904Smcpowers } 222904Smcpowers 223904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 224904Smcpowers rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key, 225904Smcpowers attrs, count, new_key, KCF_SWFP_RHNDL(crq)); 226904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 227904Smcpowers } else { 228904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_DERIVE, sid, mech, 229904Smcpowers attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL); 230904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 231904Smcpowers ¶ms, B_FALSE); 232904Smcpowers } 233904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 234904Smcpowers KCF_PROV_REFRELE(real_provider); 235904Smcpowers 236904Smcpowers return (rv); 237904Smcpowers } 238