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
crypto_object_create(crypto_provider_t provider,crypto_session_id_t sid,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * object_handle,crypto_call_req_t * crq)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
crypto_object_destroy(crypto_provider_t provider,crypto_session_id_t sid,crypto_object_id_t object_handle,crypto_call_req_t * crq)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
crypto_object_copy(crypto_provider_t provider,crypto_session_id_t sid,crypto_object_id_t object_handle,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * new_handle,crypto_call_req_t * crq)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
crypto_object_get_attribute_value(crypto_provider_t provider,crypto_session_id_t sid,crypto_object_id_t object_handle,crypto_object_attribute_t * attrs,uint_t count,crypto_call_req_t * crq)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
crypto_object_set_attribute_value(crypto_provider_t provider,crypto_session_id_t sid,crypto_object_id_t object_handle,crypto_object_attribute_t * attrs,uint_t count,crypto_call_req_t * crq)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
crypto_object_get_size(crypto_provider_t provider,crypto_session_id_t sid,crypto_object_id_t object_handle,size_t * size,crypto_call_req_t * crq)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
crypto_object_find_init(crypto_provider_t provider,crypto_session_id_t sid,crypto_object_attribute_t * attrs,uint_t count,void ** cookie,crypto_call_req_t * crq)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
crypto_object_find_final(crypto_provider_t provider,void * cookie,crypto_call_req_t * crq)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
crypto_object_find(crypto_provider_t provider,void * cookie,crypto_object_id_t * handles,uint_t * count,uint_t max_count,crypto_call_req_t * crq)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