xref: /onnv-gate/usr/src/uts/common/crypto/api/kcf_keys.c (revision 12304:bcfa0838b31e)
1904Smcpowers /*
2904Smcpowers  * CDDL HEADER START
3904Smcpowers  *
4904Smcpowers  * The contents of this file are subject to the terms of the
51808Smcpowers  * Common Development and Distribution License (the "License").
61808Smcpowers  * 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*12304SValerie.Fenwick@Oracle.COM  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23904Smcpowers  */
24904Smcpowers 
25904Smcpowers #include <sys/errno.h>
26904Smcpowers #include <sys/types.h>
27904Smcpowers #include <sys/kmem.h>
28904Smcpowers #include <sys/cmn_err.h>
29904Smcpowers #include <sys/sysmacros.h>
30904Smcpowers #include <sys/crypto/common.h>
31904Smcpowers #include <sys/crypto/impl.h>
32904Smcpowers #include <sys/crypto/api.h>
33904Smcpowers #include <sys/crypto/spi.h>
34904Smcpowers #include <sys/crypto/sched_impl.h>
35904Smcpowers 
36904Smcpowers #define	CRYPTO_OPS_OFFSET(f)		offsetof(crypto_ops_t, co_##f)
37904Smcpowers #define	CRYPTO_KEY_OFFSET(f)		offsetof(crypto_key_ops_t, f)
38904Smcpowers 
39904Smcpowers int
crypto_key_generate(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * handle,crypto_call_req_t * crq)40904Smcpowers crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid,
41904Smcpowers     crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count,
42904Smcpowers     crypto_object_id_t *handle, crypto_call_req_t *crq)
43904Smcpowers {
44904Smcpowers 	kcf_req_params_t params;
45904Smcpowers 	kcf_provider_desc_t *pd = provider;
46904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
47904Smcpowers 	int rv;
48904Smcpowers 
49904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
50904Smcpowers 
51904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
5210444SVladimir.Kotal@Sun.COM 		rv = kcf_get_hardware_provider(mech->cm_type, NULL,
53*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
54*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_FG_GENERATE);
55904Smcpowers 
56904Smcpowers 		if (rv != CRYPTO_SUCCESS)
57904Smcpowers 			return (rv);
58904Smcpowers 	}
59904Smcpowers 
60904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
61904Smcpowers 		rv = KCF_PROV_KEY_GENERATE(real_provider, sid,
62904Smcpowers 		    mech, attrs, count, handle, KCF_SWFP_RHNDL(crq));
63904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
64904Smcpowers 	} else {
65904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_GENERATE, sid,
66904Smcpowers 		    mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0);
67904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
68904Smcpowers 		    &params, B_FALSE);
69904Smcpowers 	}
70904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
71904Smcpowers 		KCF_PROV_REFRELE(real_provider);
72904Smcpowers 
73904Smcpowers 	return (rv);
74904Smcpowers }
75904Smcpowers 
76904Smcpowers int
crypto_key_generate_pair(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_object_attribute_t * pub_attrs,uint_t pub_count,crypto_object_attribute_t * pri_attrs,uint_t pri_count,crypto_object_id_t * pub_handle,crypto_object_id_t * pri_handle,crypto_call_req_t * crq)77904Smcpowers crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid,
78904Smcpowers     crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs,
79904Smcpowers     uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count,
80904Smcpowers     crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle,
81904Smcpowers     crypto_call_req_t *crq)
82904Smcpowers {
83904Smcpowers 	kcf_req_params_t params;
84904Smcpowers 	kcf_provider_desc_t *pd = provider;
85904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
86904Smcpowers 	int rv;
87904Smcpowers 
88904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
89904Smcpowers 
90904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
9110444SVladimir.Kotal@Sun.COM 		rv = kcf_get_hardware_provider(mech->cm_type, NULL,
92*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
93*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_FG_GENERATE_KEY_PAIR);
94904Smcpowers 
95904Smcpowers 		if (rv != CRYPTO_SUCCESS)
96904Smcpowers 			return (rv);
97904Smcpowers 	}
98904Smcpowers 
99904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
100904Smcpowers 		rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech,
101904Smcpowers 		    pub_attrs, pub_count, pri_attrs, pri_count, pub_handle,
102904Smcpowers 		    pri_handle, KCF_SWFP_RHNDL(crq));
103904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
104904Smcpowers 	} else {
105904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_GENERATE_PAIR,
106904Smcpowers 		    sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs,
107904Smcpowers 		    pri_count, pri_handle, NULL, NULL, 0);
108904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
109904Smcpowers 		    &params, B_FALSE);
110904Smcpowers 	}
111904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
112904Smcpowers 		KCF_PROV_REFRELE(real_provider);
113904Smcpowers 
114904Smcpowers 	return (rv);
115904Smcpowers }
116904Smcpowers 
117904Smcpowers int
crypto_key_wrap(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * wrapping_key,crypto_object_id_t * key,uchar_t * wrapped_key,size_t * wrapped_key_len,crypto_call_req_t * crq)118904Smcpowers crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid,
119904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *wrapping_key,
120904Smcpowers     crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len,
121904Smcpowers     crypto_call_req_t *crq)
122904Smcpowers {
123904Smcpowers 	kcf_req_params_t params;
124904Smcpowers 	kcf_provider_desc_t *pd = provider;
125904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
126904Smcpowers 	int rv;
127904Smcpowers 
128904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
129904Smcpowers 
130904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
13110444SVladimir.Kotal@Sun.COM 		rv = kcf_get_hardware_provider(mech->cm_type, wrapping_key,
132*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
133*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_FG_WRAP);
134904Smcpowers 
135904Smcpowers 		if (rv != CRYPTO_SUCCESS)
136904Smcpowers 			return (rv);
137904Smcpowers 	}
138904Smcpowers 
139904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
140904Smcpowers 		rv = KCF_PROV_KEY_WRAP(real_provider, sid, mech, wrapping_key,
141904Smcpowers 		    key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq));
142904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
143904Smcpowers 	} else {
144904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_WRAP, sid, mech,
145904Smcpowers 		    NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key,
146904Smcpowers 		    wrapped_key_len);
147904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
148904Smcpowers 		    &params, B_FALSE);
149904Smcpowers 	}
150904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
151904Smcpowers 		KCF_PROV_REFRELE(real_provider);
152904Smcpowers 
153904Smcpowers 	return (rv);
154904Smcpowers }
155904Smcpowers 
156904Smcpowers int
crypto_key_unwrap(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * unwrapping_key,uchar_t * wrapped_key,size_t * wrapped_key_len,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * key,crypto_call_req_t * crq)157904Smcpowers crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid,
158904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *unwrapping_key,
159904Smcpowers     uchar_t *wrapped_key, size_t *wrapped_key_len,
160904Smcpowers     crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key,
161904Smcpowers     crypto_call_req_t *crq)
162904Smcpowers {
163904Smcpowers 	kcf_req_params_t params;
164904Smcpowers 	kcf_provider_desc_t *pd = provider;
165904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
166904Smcpowers 	int rv;
167904Smcpowers 
168904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
169904Smcpowers 
170904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
17110444SVladimir.Kotal@Sun.COM 		rv = kcf_get_hardware_provider(mech->cm_type, unwrapping_key,
172*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
173*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_FG_UNWRAP);
174904Smcpowers 
175904Smcpowers 		if (rv != CRYPTO_SUCCESS)
176904Smcpowers 			return (rv);
177904Smcpowers 	}
178904Smcpowers 
179904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
180904Smcpowers 		rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech,
181904Smcpowers 		    unwrapping_key, wrapped_key, wrapped_key_len, attrs,
182904Smcpowers 		    count, key, KCF_SWFP_RHNDL(crq));
183904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
184904Smcpowers 	} else {
185904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_UNWRAP, sid, mech,
186904Smcpowers 		    attrs, count, key, NULL, 0, NULL, unwrapping_key,
187904Smcpowers 		    wrapped_key, wrapped_key_len);
188904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
189904Smcpowers 		    &params, B_FALSE);
190904Smcpowers 	}
191904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
192904Smcpowers 		KCF_PROV_REFRELE(real_provider);
193904Smcpowers 
194904Smcpowers 	return (rv);
195904Smcpowers }
196904Smcpowers 
197904Smcpowers int
crypto_key_derive(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * base_key,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * new_key,crypto_call_req_t * crq)198904Smcpowers crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid,
199904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *base_key,
200904Smcpowers     crypto_object_attribute_t *attrs, uint_t count,
201904Smcpowers     crypto_object_id_t *new_key, crypto_call_req_t *crq)
202904Smcpowers {
203904Smcpowers 	kcf_req_params_t params;
204904Smcpowers 	kcf_provider_desc_t *pd = provider;
205904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
206904Smcpowers 	int rv;
207904Smcpowers 
208904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
209904Smcpowers 
210904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
21110444SVladimir.Kotal@Sun.COM 		rv = kcf_get_hardware_provider(mech->cm_type, base_key,
212*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
213*12304SValerie.Fenwick@Oracle.COM 		    CRYPTO_FG_DERIVE);
214904Smcpowers 
215904Smcpowers 		if (rv != CRYPTO_SUCCESS)
216904Smcpowers 			return (rv);
217904Smcpowers 	}
218904Smcpowers 
219904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
220904Smcpowers 		rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key,
221904Smcpowers 		    attrs, count, new_key, KCF_SWFP_RHNDL(crq));
222904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
223904Smcpowers 	} else {
224904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_DERIVE, sid, mech,
225904Smcpowers 		    attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL);
226904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
227904Smcpowers 		    &params, B_FALSE);
228904Smcpowers 	}
229904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
230904Smcpowers 		KCF_PROV_REFRELE(real_provider);
231904Smcpowers 
232904Smcpowers 	return (rv);
233904Smcpowers }
234