xref: /onnv-gate/usr/src/uts/common/crypto/api/kcf_keys.c (revision 1808:a9c9c8edb499)
1904Smcpowers /*
2904Smcpowers  * CDDL HEADER START
3904Smcpowers  *
4904Smcpowers  * The contents of this file are subject to the terms of the
5*1808Smcpowers  * Common Development and Distribution License (the "License").
6*1808Smcpowers  * You may not use this file except in compliance with the License.
7904Smcpowers  *
8904Smcpowers  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9904Smcpowers  * or http://www.opensolaris.org/os/licensing.
10904Smcpowers  * See the License for the specific language governing permissions
11904Smcpowers  * and limitations under the License.
12904Smcpowers  *
13904Smcpowers  * When distributing Covered Code, include this CDDL HEADER in each
14904Smcpowers  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15904Smcpowers  * If applicable, add the following below this CDDL HEADER, with the
16904Smcpowers  * fields enclosed by brackets "[]" replaced with your own identifying
17904Smcpowers  * information: Portions Copyright [yyyy] [name of copyright owner]
18904Smcpowers  *
19904Smcpowers  * CDDL HEADER END
20904Smcpowers  */
21904Smcpowers /*
22*1808Smcpowers  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23904Smcpowers  * Use is subject to license terms.
24904Smcpowers  */
25904Smcpowers 
26904Smcpowers 
27904Smcpowers #pragma ident	"%Z%%M%	%I%	%E% SMI"
28904Smcpowers 
29904Smcpowers #include <sys/errno.h>
30904Smcpowers #include <sys/types.h>
31904Smcpowers #include <sys/kmem.h>
32904Smcpowers #include <sys/cmn_err.h>
33904Smcpowers #include <sys/sysmacros.h>
34904Smcpowers #include <sys/crypto/common.h>
35904Smcpowers #include <sys/crypto/impl.h>
36904Smcpowers #include <sys/crypto/api.h>
37904Smcpowers #include <sys/crypto/spi.h>
38904Smcpowers #include <sys/crypto/sched_impl.h>
39904Smcpowers 
40904Smcpowers #define	CRYPTO_OPS_OFFSET(f)		offsetof(crypto_ops_t, co_##f)
41904Smcpowers #define	CRYPTO_KEY_OFFSET(f)		offsetof(crypto_key_ops_t, f)
42904Smcpowers 
43904Smcpowers int
44904Smcpowers crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid,
45904Smcpowers     crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count,
46904Smcpowers     crypto_object_id_t *handle, crypto_call_req_t *crq)
47904Smcpowers {
48904Smcpowers 	kcf_req_params_t params;
49904Smcpowers 	kcf_provider_desc_t *pd = provider;
50904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
51904Smcpowers 	int rv;
52904Smcpowers 
53904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
54904Smcpowers 
55904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
56904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
57*1808Smcpowers 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq),
58*1808Smcpowers 		    pd, &real_provider, CRYPTO_FG_GENERATE);
59904Smcpowers 
60904Smcpowers 		if (rv != CRYPTO_SUCCESS)
61904Smcpowers 			return (rv);
62904Smcpowers 	}
63904Smcpowers 
64904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
65904Smcpowers 		rv = KCF_PROV_KEY_GENERATE(real_provider, sid,
66904Smcpowers 		    mech, attrs, count, handle, KCF_SWFP_RHNDL(crq));
67904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
68904Smcpowers 	} else {
69904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_GENERATE, sid,
70904Smcpowers 		    mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0);
71904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
72904Smcpowers 		    &params, B_FALSE);
73904Smcpowers 	}
74904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
75904Smcpowers 		KCF_PROV_REFRELE(real_provider);
76904Smcpowers 
77904Smcpowers 	return (rv);
78904Smcpowers }
79904Smcpowers 
80904Smcpowers int
81904Smcpowers crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid,
82904Smcpowers     crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs,
83904Smcpowers     uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count,
84904Smcpowers     crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle,
85904Smcpowers     crypto_call_req_t *crq)
86904Smcpowers {
87904Smcpowers 	kcf_req_params_t params;
88904Smcpowers 	kcf_provider_desc_t *pd = provider;
89904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
90904Smcpowers 	int rv;
91904Smcpowers 
92904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
93904Smcpowers 
94904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
95904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
96*1808Smcpowers 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq),
97*1808Smcpowers 		    pd, &real_provider, CRYPTO_FG_GENERATE_KEY_PAIR);
98904Smcpowers 
99904Smcpowers 		if (rv != CRYPTO_SUCCESS)
100904Smcpowers 			return (rv);
101904Smcpowers 	}
102904Smcpowers 
103904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
104904Smcpowers 		rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech,
105904Smcpowers 		    pub_attrs, pub_count, pri_attrs, pri_count, pub_handle,
106904Smcpowers 		    pri_handle, KCF_SWFP_RHNDL(crq));
107904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
108904Smcpowers 	} else {
109904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_GENERATE_PAIR,
110904Smcpowers 		    sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs,
111904Smcpowers 		    pri_count, pri_handle, NULL, NULL, 0);
112904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
113904Smcpowers 		    &params, B_FALSE);
114904Smcpowers 	}
115904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
116904Smcpowers 		KCF_PROV_REFRELE(real_provider);
117904Smcpowers 
118904Smcpowers 	return (rv);
119904Smcpowers }
120904Smcpowers 
121904Smcpowers int
122904Smcpowers crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid,
123904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *wrapping_key,
124904Smcpowers     crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len,
125904Smcpowers     crypto_call_req_t *crq)
126904Smcpowers {
127904Smcpowers 	kcf_req_params_t params;
128904Smcpowers 	kcf_provider_desc_t *pd = provider;
129904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
130904Smcpowers 	int rv;
131904Smcpowers 
132904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
133904Smcpowers 
134904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
135904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
136*1808Smcpowers 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq),
137*1808Smcpowers 		    pd, &real_provider, CRYPTO_FG_WRAP);
138904Smcpowers 
139904Smcpowers 		if (rv != CRYPTO_SUCCESS)
140904Smcpowers 			return (rv);
141904Smcpowers 	}
142904Smcpowers 
143904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
144904Smcpowers 		rv = KCF_PROV_KEY_WRAP(real_provider, sid, mech, wrapping_key,
145904Smcpowers 		    key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq));
146904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
147904Smcpowers 	} else {
148904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_WRAP, sid, mech,
149904Smcpowers 		    NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key,
150904Smcpowers 		    wrapped_key_len);
151904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
152904Smcpowers 		    &params, B_FALSE);
153904Smcpowers 	}
154904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
155904Smcpowers 		KCF_PROV_REFRELE(real_provider);
156904Smcpowers 
157904Smcpowers 	return (rv);
158904Smcpowers }
159904Smcpowers 
160904Smcpowers int
161904Smcpowers crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid,
162904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *unwrapping_key,
163904Smcpowers     uchar_t *wrapped_key, size_t *wrapped_key_len,
164904Smcpowers     crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key,
165904Smcpowers     crypto_call_req_t *crq)
166904Smcpowers {
167904Smcpowers 	kcf_req_params_t params;
168904Smcpowers 	kcf_provider_desc_t *pd = provider;
169904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
170904Smcpowers 	int rv;
171904Smcpowers 
172904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
173904Smcpowers 
174904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
175904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
176*1808Smcpowers 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq),
177*1808Smcpowers 		    pd, &real_provider, CRYPTO_FG_UNWRAP);
178904Smcpowers 
179904Smcpowers 		if (rv != CRYPTO_SUCCESS)
180904Smcpowers 			return (rv);
181904Smcpowers 	}
182904Smcpowers 
183904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
184904Smcpowers 		rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech,
185904Smcpowers 		    unwrapping_key, wrapped_key, wrapped_key_len, attrs,
186904Smcpowers 		    count, key, KCF_SWFP_RHNDL(crq));
187904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
188904Smcpowers 	} else {
189904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_UNWRAP, sid, mech,
190904Smcpowers 		    attrs, count, key, NULL, 0, NULL, unwrapping_key,
191904Smcpowers 		    wrapped_key, wrapped_key_len);
192904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
193904Smcpowers 		    &params, B_FALSE);
194904Smcpowers 	}
195904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
196904Smcpowers 		KCF_PROV_REFRELE(real_provider);
197904Smcpowers 
198904Smcpowers 	return (rv);
199904Smcpowers }
200904Smcpowers 
201904Smcpowers int
202904Smcpowers crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid,
203904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *base_key,
204904Smcpowers     crypto_object_attribute_t *attrs, uint_t count,
205904Smcpowers     crypto_object_id_t *new_key, crypto_call_req_t *crq)
206904Smcpowers {
207904Smcpowers 	kcf_req_params_t params;
208904Smcpowers 	kcf_provider_desc_t *pd = provider;
209904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
210904Smcpowers 	int rv;
211904Smcpowers 
212904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
213904Smcpowers 
214904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
215904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
216*1808Smcpowers 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq),
217*1808Smcpowers 		    pd, &real_provider, CRYPTO_FG_DERIVE);
218904Smcpowers 
219904Smcpowers 		if (rv != CRYPTO_SUCCESS)
220904Smcpowers 			return (rv);
221904Smcpowers 	}
222904Smcpowers 
223904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
224904Smcpowers 		rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key,
225904Smcpowers 		    attrs, count, new_key, KCF_SWFP_RHNDL(crq));
226904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
227904Smcpowers 	} else {
228904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_DERIVE, sid, mech,
229904Smcpowers 		    attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL);
230904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
231904Smcpowers 		    &params, B_FALSE);
232904Smcpowers 	}
233904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
234904Smcpowers 		KCF_PROV_REFRELE(real_provider);
235904Smcpowers 
236904Smcpowers 	return (rv);
237904Smcpowers }
238