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