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