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_KEY_OFFSET(f) offsetof(crypto_key_ops_t, f) 43*904Smcpowers 44*904Smcpowers int 45*904Smcpowers crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid, 46*904Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count, 47*904Smcpowers crypto_object_id_t *handle, crypto_call_req_t *crq) 48*904Smcpowers { 49*904Smcpowers kcf_req_params_t params; 50*904Smcpowers kcf_provider_desc_t *pd = provider; 51*904Smcpowers kcf_provider_desc_t *real_provider = pd; 52*904Smcpowers int rv; 53*904Smcpowers 54*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 55*904Smcpowers 56*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 57*904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 58*904Smcpowers CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops), 59*904Smcpowers CRYPTO_KEY_OFFSET(key_generate), CHECK_RESTRICT(crq), 60*904Smcpowers pd, &real_provider); 61*904Smcpowers 62*904Smcpowers if (rv != CRYPTO_SUCCESS) 63*904Smcpowers return (rv); 64*904Smcpowers } 65*904Smcpowers 66*904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 67*904Smcpowers rv = KCF_PROV_KEY_GENERATE(real_provider, sid, 68*904Smcpowers mech, attrs, count, handle, KCF_SWFP_RHNDL(crq)); 69*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 70*904Smcpowers } else { 71*904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE, sid, 72*904Smcpowers mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0); 73*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 74*904Smcpowers ¶ms, B_FALSE); 75*904Smcpowers } 76*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 77*904Smcpowers KCF_PROV_REFRELE(real_provider); 78*904Smcpowers 79*904Smcpowers return (rv); 80*904Smcpowers } 81*904Smcpowers 82*904Smcpowers int 83*904Smcpowers crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid, 84*904Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs, 85*904Smcpowers uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count, 86*904Smcpowers crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle, 87*904Smcpowers crypto_call_req_t *crq) 88*904Smcpowers { 89*904Smcpowers kcf_req_params_t params; 90*904Smcpowers kcf_provider_desc_t *pd = provider; 91*904Smcpowers kcf_provider_desc_t *real_provider = pd; 92*904Smcpowers int rv; 93*904Smcpowers 94*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 95*904Smcpowers 96*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 97*904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 98*904Smcpowers CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops), 99*904Smcpowers CRYPTO_KEY_OFFSET(key_generate_pair), CHECK_RESTRICT(crq), 100*904Smcpowers pd, &real_provider); 101*904Smcpowers 102*904Smcpowers if (rv != CRYPTO_SUCCESS) 103*904Smcpowers return (rv); 104*904Smcpowers } 105*904Smcpowers 106*904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 107*904Smcpowers rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech, 108*904Smcpowers pub_attrs, pub_count, pri_attrs, pri_count, pub_handle, 109*904Smcpowers pri_handle, KCF_SWFP_RHNDL(crq)); 110*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 111*904Smcpowers } else { 112*904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE_PAIR, 113*904Smcpowers sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs, 114*904Smcpowers pri_count, pri_handle, NULL, NULL, 0); 115*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 116*904Smcpowers ¶ms, B_FALSE); 117*904Smcpowers } 118*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 119*904Smcpowers KCF_PROV_REFRELE(real_provider); 120*904Smcpowers 121*904Smcpowers return (rv); 122*904Smcpowers } 123*904Smcpowers 124*904Smcpowers int 125*904Smcpowers crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid, 126*904Smcpowers crypto_mechanism_t *mech, crypto_key_t *wrapping_key, 127*904Smcpowers crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len, 128*904Smcpowers crypto_call_req_t *crq) 129*904Smcpowers { 130*904Smcpowers kcf_req_params_t params; 131*904Smcpowers kcf_provider_desc_t *pd = provider; 132*904Smcpowers kcf_provider_desc_t *real_provider = pd; 133*904Smcpowers int rv; 134*904Smcpowers 135*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 136*904Smcpowers 137*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 138*904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 139*904Smcpowers CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops), 140*904Smcpowers CRYPTO_KEY_OFFSET(key_wrap), CHECK_RESTRICT(crq), 141*904Smcpowers 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_KEY_WRAP(real_provider, sid, mech, wrapping_key, 149*904Smcpowers key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq)); 150*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 151*904Smcpowers } else { 152*904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_WRAP, sid, mech, 153*904Smcpowers NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key, 154*904Smcpowers wrapped_key_len); 155*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 156*904Smcpowers ¶ms, B_FALSE); 157*904Smcpowers } 158*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 159*904Smcpowers KCF_PROV_REFRELE(real_provider); 160*904Smcpowers 161*904Smcpowers return (rv); 162*904Smcpowers } 163*904Smcpowers 164*904Smcpowers int 165*904Smcpowers crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid, 166*904Smcpowers crypto_mechanism_t *mech, crypto_key_t *unwrapping_key, 167*904Smcpowers uchar_t *wrapped_key, size_t *wrapped_key_len, 168*904Smcpowers crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key, 169*904Smcpowers crypto_call_req_t *crq) 170*904Smcpowers { 171*904Smcpowers kcf_req_params_t params; 172*904Smcpowers kcf_provider_desc_t *pd = provider; 173*904Smcpowers kcf_provider_desc_t *real_provider = pd; 174*904Smcpowers int rv; 175*904Smcpowers 176*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 177*904Smcpowers 178*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 179*904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 180*904Smcpowers CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops), 181*904Smcpowers CRYPTO_KEY_OFFSET(key_unwrap), CHECK_RESTRICT(crq), 182*904Smcpowers pd, &real_provider); 183*904Smcpowers 184*904Smcpowers if (rv != CRYPTO_SUCCESS) 185*904Smcpowers return (rv); 186*904Smcpowers } 187*904Smcpowers 188*904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 189*904Smcpowers rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech, 190*904Smcpowers unwrapping_key, wrapped_key, wrapped_key_len, attrs, 191*904Smcpowers count, key, KCF_SWFP_RHNDL(crq)); 192*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 193*904Smcpowers } else { 194*904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_UNWRAP, sid, mech, 195*904Smcpowers attrs, count, key, NULL, 0, NULL, unwrapping_key, 196*904Smcpowers wrapped_key, wrapped_key_len); 197*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 198*904Smcpowers ¶ms, B_FALSE); 199*904Smcpowers } 200*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 201*904Smcpowers KCF_PROV_REFRELE(real_provider); 202*904Smcpowers 203*904Smcpowers return (rv); 204*904Smcpowers } 205*904Smcpowers 206*904Smcpowers int 207*904Smcpowers crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid, 208*904Smcpowers crypto_mechanism_t *mech, crypto_key_t *base_key, 209*904Smcpowers crypto_object_attribute_t *attrs, uint_t count, 210*904Smcpowers crypto_object_id_t *new_key, crypto_call_req_t *crq) 211*904Smcpowers { 212*904Smcpowers kcf_req_params_t params; 213*904Smcpowers kcf_provider_desc_t *pd = provider; 214*904Smcpowers kcf_provider_desc_t *real_provider = pd; 215*904Smcpowers int rv; 216*904Smcpowers 217*904Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 218*904Smcpowers 219*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 220*904Smcpowers rv = kcf_get_hardware_provider(mech->cm_type, 221*904Smcpowers CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops), 222*904Smcpowers CRYPTO_KEY_OFFSET(key_derive), CHECK_RESTRICT(crq), 223*904Smcpowers pd, &real_provider); 224*904Smcpowers 225*904Smcpowers if (rv != CRYPTO_SUCCESS) 226*904Smcpowers return (rv); 227*904Smcpowers } 228*904Smcpowers 229*904Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 230*904Smcpowers rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key, 231*904Smcpowers attrs, count, new_key, KCF_SWFP_RHNDL(crq)); 232*904Smcpowers KCF_PROV_INCRSTATS(pd, rv); 233*904Smcpowers } else { 234*904Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_DERIVE, sid, mech, 235*904Smcpowers attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL); 236*904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 237*904Smcpowers ¶ms, B_FALSE); 238*904Smcpowers } 239*904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 240*904Smcpowers KCF_PROV_REFRELE(real_provider); 241*904Smcpowers 242*904Smcpowers return (rv); 243*904Smcpowers } 244