xref: /illumos-gate/usr/src/uts/common/crypto/api/kcf_object.c (revision 948f2876ce2a3010558f4f6937e16086ebcd36f2)
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(&params, 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 		    &params, 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(&params, 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 		    &params, 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(&params, 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 		    &params, 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(&params,
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 		    &params, 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(&params,
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 		    &params, 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(&params, 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 		    &params, 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(&params, 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 		    &params, 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(&params, 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, &params,
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(&params, 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 		    &params, B_FALSE);
378 	}
379 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
380 		KCF_PROV_REFRELE(real_provider);
381 
382 	return (rv);
383 }
384