1894b2776Smcpowers /* 2894b2776Smcpowers * CDDL HEADER START 3894b2776Smcpowers * 4894b2776Smcpowers * The contents of this file are subject to the terms of the 572eff6e2Smcpowers * Common Development and Distribution License (the "License"). 672eff6e2Smcpowers * 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 #include <sys/errno.h> 26894b2776Smcpowers #include <sys/types.h> 27894b2776Smcpowers #include <sys/kmem.h> 28894b2776Smcpowers #include <sys/cmn_err.h> 29894b2776Smcpowers #include <sys/sysmacros.h> 30894b2776Smcpowers #include <sys/crypto/common.h> 31894b2776Smcpowers #include <sys/crypto/impl.h> 32894b2776Smcpowers #include <sys/crypto/api.h> 33894b2776Smcpowers #include <sys/crypto/spi.h> 34894b2776Smcpowers #include <sys/crypto/sched_impl.h> 35894b2776Smcpowers 36894b2776Smcpowers #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f) 37894b2776Smcpowers #define CRYPTO_KEY_OFFSET(f) offsetof(crypto_key_ops_t, f) 38894b2776Smcpowers 39894b2776Smcpowers int 40894b2776Smcpowers crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid, 41894b2776Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count, 42894b2776Smcpowers crypto_object_id_t *handle, crypto_call_req_t *crq) 43894b2776Smcpowers { 44894b2776Smcpowers kcf_req_params_t params; 45894b2776Smcpowers kcf_provider_desc_t *pd = provider; 46894b2776Smcpowers kcf_provider_desc_t *real_provider = pd; 47894b2776Smcpowers int rv; 48894b2776Smcpowers 49894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 50894b2776Smcpowers 51894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 52436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, NULL, 53*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider, 54*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_GENERATE); 55894b2776Smcpowers 56894b2776Smcpowers if (rv != CRYPTO_SUCCESS) 57894b2776Smcpowers return (rv); 58894b2776Smcpowers } 59894b2776Smcpowers 60894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 61894b2776Smcpowers rv = KCF_PROV_KEY_GENERATE(real_provider, sid, 62894b2776Smcpowers mech, attrs, count, handle, KCF_SWFP_RHNDL(crq)); 63894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 64894b2776Smcpowers } else { 65894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE, sid, 66894b2776Smcpowers mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0); 67894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 68894b2776Smcpowers ¶ms, B_FALSE); 69894b2776Smcpowers } 70894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 71894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 72894b2776Smcpowers 73894b2776Smcpowers return (rv); 74894b2776Smcpowers } 75894b2776Smcpowers 76894b2776Smcpowers int 77894b2776Smcpowers crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid, 78894b2776Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs, 79894b2776Smcpowers uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count, 80894b2776Smcpowers crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle, 81894b2776Smcpowers crypto_call_req_t *crq) 82894b2776Smcpowers { 83894b2776Smcpowers kcf_req_params_t params; 84894b2776Smcpowers kcf_provider_desc_t *pd = provider; 85894b2776Smcpowers kcf_provider_desc_t *real_provider = pd; 86894b2776Smcpowers int rv; 87894b2776Smcpowers 88894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 89894b2776Smcpowers 90894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 91436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, NULL, 92*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider, 93*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_GENERATE_KEY_PAIR); 94894b2776Smcpowers 95894b2776Smcpowers if (rv != CRYPTO_SUCCESS) 96894b2776Smcpowers return (rv); 97894b2776Smcpowers } 98894b2776Smcpowers 99894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 100894b2776Smcpowers rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech, 101894b2776Smcpowers pub_attrs, pub_count, pri_attrs, pri_count, pub_handle, 102894b2776Smcpowers pri_handle, KCF_SWFP_RHNDL(crq)); 103894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 104894b2776Smcpowers } else { 105894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE_PAIR, 106894b2776Smcpowers sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs, 107894b2776Smcpowers pri_count, pri_handle, NULL, NULL, 0); 108894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 109894b2776Smcpowers ¶ms, B_FALSE); 110894b2776Smcpowers } 111894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 112894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 113894b2776Smcpowers 114894b2776Smcpowers return (rv); 115894b2776Smcpowers } 116894b2776Smcpowers 117894b2776Smcpowers int 118894b2776Smcpowers crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid, 119894b2776Smcpowers crypto_mechanism_t *mech, crypto_key_t *wrapping_key, 120894b2776Smcpowers crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len, 121894b2776Smcpowers crypto_call_req_t *crq) 122894b2776Smcpowers { 123894b2776Smcpowers kcf_req_params_t params; 124894b2776Smcpowers kcf_provider_desc_t *pd = provider; 125894b2776Smcpowers kcf_provider_desc_t *real_provider = pd; 126894b2776Smcpowers int rv; 127894b2776Smcpowers 128894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 129894b2776Smcpowers 130894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 131436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, wrapping_key, 132*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider, 133*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_WRAP); 134894b2776Smcpowers 135894b2776Smcpowers if (rv != CRYPTO_SUCCESS) 136894b2776Smcpowers return (rv); 137894b2776Smcpowers } 138894b2776Smcpowers 139894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 140894b2776Smcpowers rv = KCF_PROV_KEY_WRAP(real_provider, sid, mech, wrapping_key, 141894b2776Smcpowers key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq)); 142894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 143894b2776Smcpowers } else { 144894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_WRAP, sid, mech, 145894b2776Smcpowers NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key, 146894b2776Smcpowers wrapped_key_len); 147894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 148894b2776Smcpowers ¶ms, B_FALSE); 149894b2776Smcpowers } 150894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 151894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 152894b2776Smcpowers 153894b2776Smcpowers return (rv); 154894b2776Smcpowers } 155894b2776Smcpowers 156894b2776Smcpowers int 157894b2776Smcpowers crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid, 158894b2776Smcpowers crypto_mechanism_t *mech, crypto_key_t *unwrapping_key, 159894b2776Smcpowers uchar_t *wrapped_key, size_t *wrapped_key_len, 160894b2776Smcpowers crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key, 161894b2776Smcpowers crypto_call_req_t *crq) 162894b2776Smcpowers { 163894b2776Smcpowers kcf_req_params_t params; 164894b2776Smcpowers kcf_provider_desc_t *pd = provider; 165894b2776Smcpowers kcf_provider_desc_t *real_provider = pd; 166894b2776Smcpowers int rv; 167894b2776Smcpowers 168894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 169894b2776Smcpowers 170894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 171436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, unwrapping_key, 172*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider, 173*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_UNWRAP); 174894b2776Smcpowers 175894b2776Smcpowers if (rv != CRYPTO_SUCCESS) 176894b2776Smcpowers return (rv); 177894b2776Smcpowers } 178894b2776Smcpowers 179894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 180894b2776Smcpowers rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech, 181894b2776Smcpowers unwrapping_key, wrapped_key, wrapped_key_len, attrs, 182894b2776Smcpowers count, key, KCF_SWFP_RHNDL(crq)); 183894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 184894b2776Smcpowers } else { 185894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_UNWRAP, sid, mech, 186894b2776Smcpowers attrs, count, key, NULL, 0, NULL, unwrapping_key, 187894b2776Smcpowers wrapped_key, wrapped_key_len); 188894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 189894b2776Smcpowers ¶ms, B_FALSE); 190894b2776Smcpowers } 191894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 192894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 193894b2776Smcpowers 194894b2776Smcpowers return (rv); 195894b2776Smcpowers } 196894b2776Smcpowers 197894b2776Smcpowers int 198894b2776Smcpowers crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid, 199894b2776Smcpowers crypto_mechanism_t *mech, crypto_key_t *base_key, 200894b2776Smcpowers crypto_object_attribute_t *attrs, uint_t count, 201894b2776Smcpowers crypto_object_id_t *new_key, crypto_call_req_t *crq) 202894b2776Smcpowers { 203894b2776Smcpowers kcf_req_params_t params; 204894b2776Smcpowers kcf_provider_desc_t *pd = provider; 205894b2776Smcpowers kcf_provider_desc_t *real_provider = pd; 206894b2776Smcpowers int rv; 207894b2776Smcpowers 208894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd)); 209894b2776Smcpowers 210894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 211436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, base_key, 212*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider, 213*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_DERIVE); 214894b2776Smcpowers 215894b2776Smcpowers if (rv != CRYPTO_SUCCESS) 216894b2776Smcpowers return (rv); 217894b2776Smcpowers } 218894b2776Smcpowers 219894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) { 220894b2776Smcpowers rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key, 221894b2776Smcpowers attrs, count, new_key, KCF_SWFP_RHNDL(crq)); 222894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv); 223894b2776Smcpowers } else { 224894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_DERIVE, sid, mech, 225894b2776Smcpowers attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL); 226894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq, 227894b2776Smcpowers ¶ms, B_FALSE); 228894b2776Smcpowers } 229894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 230894b2776Smcpowers KCF_PROV_REFRELE(real_provider); 231894b2776Smcpowers 232894b2776Smcpowers return (rv); 233894b2776Smcpowers } 234