1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/errno.h> 30 #include <sys/types.h> 31 #include <sys/kmem.h> 32 #include <sys/cmn_err.h> 33 #include <sys/sysmacros.h> 34 #include <sys/crypto/common.h> 35 #include <sys/crypto/impl.h> 36 #include <sys/crypto/api.h> 37 #include <sys/crypto/spi.h> 38 #include <sys/crypto/sched_impl.h> 39 40 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f) 41 #define CRYPTO_KEY_OFFSET(f) offsetof(crypto_key_ops_t, f) 42 43 int 44 crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid, 45 crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count, 46 crypto_object_id_t *handle, crypto_call_req_t *crq) 47 { 48 kcf_req_params_t params; 49 kcf_provider_desc_t *pd = provider; 50 kcf_provider_desc_t *real_provider = pd; 51 int rv; 52 53 ASSERT(KCF_PROV_REFHELD(pd)); 54 55 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 56 rv = kcf_get_hardware_provider(mech->cm_type, 57 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 58 pd, &real_provider, CRYPTO_FG_GENERATE); 59 60 if (rv != CRYPTO_SUCCESS) 61 return (rv); 62 } 63 64 if (CHECK_FASTPATH(crq, real_provider)) { 65 rv = KCF_PROV_KEY_GENERATE(real_provider, sid, 66 mech, attrs, count, handle, KCF_SWFP_RHNDL(crq)); 67 KCF_PROV_INCRSTATS(pd, rv); 68 } else { 69 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE, sid, 70 mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0); 71 rv = kcf_submit_request(real_provider, NULL, crq, 72 ¶ms, B_FALSE); 73 } 74 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 75 KCF_PROV_REFRELE(real_provider); 76 77 return (rv); 78 } 79 80 int 81 crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid, 82 crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs, 83 uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count, 84 crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle, 85 crypto_call_req_t *crq) 86 { 87 kcf_req_params_t params; 88 kcf_provider_desc_t *pd = provider; 89 kcf_provider_desc_t *real_provider = pd; 90 int rv; 91 92 ASSERT(KCF_PROV_REFHELD(pd)); 93 94 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 95 rv = kcf_get_hardware_provider(mech->cm_type, 96 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 97 pd, &real_provider, CRYPTO_FG_GENERATE_KEY_PAIR); 98 99 if (rv != CRYPTO_SUCCESS) 100 return (rv); 101 } 102 103 if (CHECK_FASTPATH(crq, real_provider)) { 104 rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech, 105 pub_attrs, pub_count, pri_attrs, pri_count, pub_handle, 106 pri_handle, KCF_SWFP_RHNDL(crq)); 107 KCF_PROV_INCRSTATS(pd, rv); 108 } else { 109 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE_PAIR, 110 sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs, 111 pri_count, pri_handle, NULL, NULL, 0); 112 rv = kcf_submit_request(real_provider, NULL, crq, 113 ¶ms, B_FALSE); 114 } 115 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 116 KCF_PROV_REFRELE(real_provider); 117 118 return (rv); 119 } 120 121 int 122 crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid, 123 crypto_mechanism_t *mech, crypto_key_t *wrapping_key, 124 crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len, 125 crypto_call_req_t *crq) 126 { 127 kcf_req_params_t params; 128 kcf_provider_desc_t *pd = provider; 129 kcf_provider_desc_t *real_provider = pd; 130 int rv; 131 132 ASSERT(KCF_PROV_REFHELD(pd)); 133 134 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 135 rv = kcf_get_hardware_provider(mech->cm_type, 136 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 137 pd, &real_provider, CRYPTO_FG_WRAP); 138 139 if (rv != CRYPTO_SUCCESS) 140 return (rv); 141 } 142 143 if (CHECK_FASTPATH(crq, real_provider)) { 144 rv = KCF_PROV_KEY_WRAP(real_provider, sid, mech, wrapping_key, 145 key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq)); 146 KCF_PROV_INCRSTATS(pd, rv); 147 } else { 148 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_WRAP, sid, mech, 149 NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key, 150 wrapped_key_len); 151 rv = kcf_submit_request(real_provider, NULL, crq, 152 ¶ms, B_FALSE); 153 } 154 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 155 KCF_PROV_REFRELE(real_provider); 156 157 return (rv); 158 } 159 160 int 161 crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid, 162 crypto_mechanism_t *mech, crypto_key_t *unwrapping_key, 163 uchar_t *wrapped_key, size_t *wrapped_key_len, 164 crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key, 165 crypto_call_req_t *crq) 166 { 167 kcf_req_params_t params; 168 kcf_provider_desc_t *pd = provider; 169 kcf_provider_desc_t *real_provider = pd; 170 int rv; 171 172 ASSERT(KCF_PROV_REFHELD(pd)); 173 174 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 175 rv = kcf_get_hardware_provider(mech->cm_type, 176 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 177 pd, &real_provider, CRYPTO_FG_UNWRAP); 178 179 if (rv != CRYPTO_SUCCESS) 180 return (rv); 181 } 182 183 if (CHECK_FASTPATH(crq, real_provider)) { 184 rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech, 185 unwrapping_key, wrapped_key, wrapped_key_len, attrs, 186 count, key, KCF_SWFP_RHNDL(crq)); 187 KCF_PROV_INCRSTATS(pd, rv); 188 } else { 189 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_UNWRAP, sid, mech, 190 attrs, count, key, NULL, 0, NULL, unwrapping_key, 191 wrapped_key, wrapped_key_len); 192 rv = kcf_submit_request(real_provider, NULL, crq, 193 ¶ms, B_FALSE); 194 } 195 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 196 KCF_PROV_REFRELE(real_provider); 197 198 return (rv); 199 } 200 201 int 202 crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid, 203 crypto_mechanism_t *mech, crypto_key_t *base_key, 204 crypto_object_attribute_t *attrs, uint_t count, 205 crypto_object_id_t *new_key, crypto_call_req_t *crq) 206 { 207 kcf_req_params_t params; 208 kcf_provider_desc_t *pd = provider; 209 kcf_provider_desc_t *real_provider = pd; 210 int rv; 211 212 ASSERT(KCF_PROV_REFHELD(pd)); 213 214 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 215 rv = kcf_get_hardware_provider(mech->cm_type, 216 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), 217 pd, &real_provider, CRYPTO_FG_DERIVE); 218 219 if (rv != CRYPTO_SUCCESS) 220 return (rv); 221 } 222 223 if (CHECK_FASTPATH(crq, real_provider)) { 224 rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key, 225 attrs, count, new_key, KCF_SWFP_RHNDL(crq)); 226 KCF_PROV_INCRSTATS(pd, rv); 227 } else { 228 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_DERIVE, sid, mech, 229 attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL); 230 rv = kcf_submit_request(real_provider, NULL, crq, 231 ¶ms, B_FALSE); 232 } 233 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 234 KCF_PROV_REFRELE(real_provider); 235 236 return (rv); 237 } 238