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_OBJECT_OFFSET(f) offsetof(crypto_object_ops_t, f) 43 44 int 45 crypto_object_create(crypto_provider_t provider, crypto_session_id_t sid, 46 crypto_object_attribute_t *attrs, uint_t count, 47 crypto_object_id_t *object_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_nomech(CRYPTO_OPS_OFFSET( 58 object_ops), CRYPTO_OBJECT_OFFSET(object_create), 59 CHECK_RESTRICT(crq), pd, &real_provider); 60 61 if (rv != CRYPTO_SUCCESS) 62 return (rv); 63 } 64 65 if (CHECK_FASTPATH(crq, real_provider)) { 66 rv = KCF_PROV_OBJECT_CREATE(real_provider, sid, 67 attrs, count, object_handle, KCF_SWFP_RHNDL(crq)); 68 KCF_PROV_INCRSTATS(pd, rv); 69 } else { 70 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_CREATE, 71 sid, 0, attrs, count, object_handle, 0, 72 NULL, NULL, 0, NULL); 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_object_destroy(crypto_provider_t provider, crypto_session_id_t sid, 84 crypto_object_id_t object_handle, crypto_call_req_t *crq) 85 { 86 kcf_req_params_t params; 87 kcf_provider_desc_t *pd = provider; 88 kcf_provider_desc_t *real_provider = pd; 89 int rv; 90 91 ASSERT(KCF_PROV_REFHELD(pd)); 92 93 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 94 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 95 object_ops), CRYPTO_OBJECT_OFFSET(object_destroy), 96 CHECK_RESTRICT(crq), pd, &real_provider); 97 98 if (rv != CRYPTO_SUCCESS) 99 return (rv); 100 } 101 102 if (CHECK_FASTPATH(crq, real_provider)) { 103 rv = KCF_PROV_OBJECT_DESTROY(real_provider, sid, 104 object_handle, KCF_SWFP_RHNDL(crq)); 105 KCF_PROV_INCRSTATS(pd, rv); 106 } else { 107 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_DESTROY, 108 sid, object_handle, NULL, 0, NULL, 0, 109 NULL, NULL, 0, NULL); 110 rv = kcf_submit_request(real_provider, NULL, crq, 111 ¶ms, B_FALSE); 112 } 113 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 114 KCF_PROV_REFRELE(real_provider); 115 116 return (rv); 117 } 118 119 int 120 crypto_object_copy(crypto_provider_t provider, crypto_session_id_t sid, 121 crypto_object_id_t object_handle, crypto_object_attribute_t *attrs, 122 uint_t count, crypto_object_id_t *new_handle, crypto_call_req_t *crq) 123 { 124 kcf_req_params_t params; 125 kcf_provider_desc_t *pd = provider; 126 kcf_provider_desc_t *real_provider = pd; 127 int rv; 128 129 ASSERT(KCF_PROV_REFHELD(pd)); 130 131 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 132 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 133 object_ops), CRYPTO_OBJECT_OFFSET(object_copy), 134 CHECK_RESTRICT(crq), pd, &real_provider); 135 136 if (rv != CRYPTO_SUCCESS) 137 return (rv); 138 } 139 140 if (CHECK_FASTPATH(crq, real_provider)) { 141 rv = KCF_PROV_OBJECT_COPY(real_provider, sid, 142 object_handle, attrs, count, new_handle, 143 KCF_SWFP_RHNDL(crq)); 144 KCF_PROV_INCRSTATS(pd, rv); 145 } else { 146 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_COPY, 147 sid, object_handle, attrs, count, 148 new_handle, 0, NULL, NULL, 0, NULL); 149 rv = kcf_submit_request(real_provider, NULL, crq, 150 ¶ms, B_FALSE); 151 } 152 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 153 KCF_PROV_REFRELE(real_provider); 154 155 return (rv); 156 } 157 158 int 159 crypto_object_get_attribute_value(crypto_provider_t provider, 160 crypto_session_id_t sid, crypto_object_id_t object_handle, 161 crypto_object_attribute_t *attrs, uint_t count, crypto_call_req_t *crq) 162 { 163 kcf_req_params_t params; 164 kcf_provider_desc_t *pd = provider; 165 kcf_provider_desc_t *real_provider = pd; 166 int rv; 167 168 ASSERT(KCF_PROV_REFHELD(pd)); 169 170 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 171 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 172 object_ops), 173 CRYPTO_OBJECT_OFFSET(object_get_attribute_value), 174 CHECK_RESTRICT(crq), pd, &real_provider); 175 176 if (rv != CRYPTO_SUCCESS) 177 return (rv); 178 } 179 180 if (CHECK_FASTPATH(crq, real_provider)) { 181 rv = KCF_PROV_OBJECT_GET_ATTRIBUTE_VALUE(real_provider, 182 sid, object_handle, attrs, count, KCF_SWFP_RHNDL(crq)); 183 KCF_PROV_INCRSTATS(pd, rv); 184 } else { 185 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 186 KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE, sid, object_handle, 187 attrs, count, NULL, 0, NULL, NULL, 0, NULL); 188 rv = kcf_submit_request(real_provider, NULL, crq, 189 ¶ms, B_FALSE); 190 } 191 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 192 KCF_PROV_REFRELE(real_provider); 193 194 return (rv); 195 } 196 197 int 198 crypto_object_set_attribute_value(crypto_provider_t provider, 199 crypto_session_id_t sid, crypto_object_id_t object_handle, 200 crypto_object_attribute_t *attrs, uint_t count, crypto_call_req_t *crq) 201 { 202 kcf_req_params_t params; 203 kcf_provider_desc_t *pd = provider; 204 kcf_provider_desc_t *real_provider = pd; 205 int rv; 206 207 ASSERT(KCF_PROV_REFHELD(pd)); 208 209 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 210 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 211 object_ops), 212 CRYPTO_OBJECT_OFFSET(object_set_attribute_value), 213 CHECK_RESTRICT(crq), pd, &real_provider); 214 215 if (rv != CRYPTO_SUCCESS) 216 return (rv); 217 } 218 219 if (CHECK_FASTPATH(crq, real_provider)) { 220 rv = KCF_PROV_OBJECT_SET_ATTRIBUTE_VALUE(real_provider, 221 sid, object_handle, attrs, count, KCF_SWFP_RHNDL(crq)); 222 KCF_PROV_INCRSTATS(pd, rv); 223 } else { 224 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 225 KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE, sid, object_handle, 226 attrs, count, NULL, 0, NULL, NULL, 0, NULL); 227 rv = kcf_submit_request(real_provider, NULL, crq, 228 ¶ms, B_FALSE); 229 } 230 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 231 KCF_PROV_REFRELE(real_provider); 232 233 return (rv); 234 } 235 236 int 237 crypto_object_get_size(crypto_provider_t provider, crypto_session_id_t sid, 238 crypto_object_id_t object_handle, size_t *size, crypto_call_req_t *crq) 239 { 240 kcf_req_params_t params; 241 kcf_provider_desc_t *pd = provider; 242 kcf_provider_desc_t *real_provider = pd; 243 int rv; 244 245 ASSERT(KCF_PROV_REFHELD(pd)); 246 247 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 248 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 249 object_ops), CRYPTO_OBJECT_OFFSET(object_get_size), 250 CHECK_RESTRICT(crq), pd, &real_provider); 251 252 if (rv != CRYPTO_SUCCESS) 253 return (rv); 254 255 } 256 257 if (CHECK_FASTPATH(crq, real_provider)) { 258 rv = KCF_PROV_OBJECT_GET_SIZE(real_provider, 259 sid, object_handle, size, KCF_SWFP_RHNDL(crq)); 260 KCF_PROV_INCRSTATS(pd, rv); 261 } else { 262 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_GET_SIZE, sid, 263 object_handle, NULL, 0, NULL, size, NULL, NULL, 0, NULL); 264 rv = kcf_submit_request(real_provider, NULL, crq, 265 ¶ms, B_FALSE); 266 } 267 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 268 KCF_PROV_REFRELE(real_provider); 269 270 return (rv); 271 } 272 273 int 274 crypto_object_find_init(crypto_provider_t provider, crypto_session_id_t sid, 275 crypto_object_attribute_t *attrs, uint_t count, void **cookie, 276 crypto_call_req_t *crq) 277 { 278 kcf_req_params_t params; 279 kcf_provider_desc_t *pd = provider; 280 kcf_provider_desc_t *real_provider = pd; 281 int rv; 282 283 ASSERT(KCF_PROV_REFHELD(pd)); 284 285 if (cookie == NULL) { 286 return (CRYPTO_ARGUMENTS_BAD); 287 } 288 289 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 290 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 291 object_ops), CRYPTO_OBJECT_OFFSET(object_find_init), 292 CHECK_RESTRICT(crq), pd, &real_provider); 293 294 if (rv != CRYPTO_SUCCESS) 295 return (rv); 296 } 297 298 if (CHECK_FASTPATH(crq, real_provider)) { 299 rv = KCF_PROV_OBJECT_FIND_INIT(real_provider, 300 sid, attrs, count, cookie, KCF_SWFP_RHNDL(crq)); 301 KCF_PROV_INCRSTATS(pd, rv); 302 } else { 303 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_FIND_INIT, 304 sid, 0, attrs, count, NULL, 0, cookie, NULL, 0, NULL); 305 rv = kcf_submit_request(real_provider, NULL, crq, 306 ¶ms, B_FALSE); 307 } 308 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 309 KCF_PROV_REFRELE(real_provider); 310 311 return (rv); 312 } 313 314 int 315 crypto_object_find_final(crypto_provider_t provider, void *cookie, 316 crypto_call_req_t *crq) 317 { 318 kcf_req_params_t params; 319 kcf_provider_desc_t *pd = provider; 320 kcf_provider_desc_t *real_provider = pd; 321 int rv; 322 323 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 324 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 325 object_ops), CRYPTO_OBJECT_OFFSET(object_find_final), 326 CHECK_RESTRICT(crq), pd, &real_provider); 327 328 if (rv != CRYPTO_SUCCESS) 329 return (rv); 330 } 331 332 if (CHECK_FASTPATH(crq, real_provider)) { 333 rv = KCF_PROV_OBJECT_FIND_FINAL(real_provider, 334 cookie, KCF_SWFP_RHNDL(crq)); 335 KCF_PROV_INCRSTATS(pd, rv); 336 } else { 337 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_FIND_FINAL, 338 0, 0, NULL, 0, NULL, 0, NULL, cookie, 0, NULL); 339 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, 340 B_FALSE); 341 } 342 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 343 KCF_PROV_REFRELE(real_provider); 344 345 return (rv); 346 } 347 348 int 349 crypto_object_find(crypto_provider_t provider, void *cookie, 350 crypto_object_id_t *handles, uint_t *count, uint_t max_count, 351 crypto_call_req_t *crq) 352 { 353 kcf_req_params_t params; 354 kcf_provider_desc_t *pd = provider; 355 kcf_provider_desc_t *real_provider = pd; 356 int rv; 357 358 ASSERT(KCF_PROV_REFHELD(pd)); 359 360 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 361 rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET( 362 object_ops), CRYPTO_OBJECT_OFFSET(object_find), 363 CHECK_RESTRICT(crq), pd, &real_provider); 364 365 if (rv != CRYPTO_SUCCESS) 366 return (rv); 367 } 368 369 if (CHECK_FASTPATH(crq, real_provider)) { 370 rv = KCF_PROV_OBJECT_FIND(real_provider, cookie, handles, 371 max_count, count, KCF_SWFP_RHNDL(crq)); 372 KCF_PROV_INCRSTATS(pd, rv); 373 } else { 374 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_FIND, 0, 375 0, NULL, 0, handles, 0, NULL, cookie, max_count, count); 376 rv = kcf_submit_request(real_provider, NULL, crq, 377 ¶ms, B_FALSE); 378 } 379 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 380 KCF_PROV_REFRELE(real_provider); 381 382 return (rv); 383 } 384