xref: /onnv-gate/usr/src/uts/common/crypto/api/kcf_keys.c (revision 904:4f885c862682)
1*904Smcpowers /*
2*904Smcpowers  * CDDL HEADER START
3*904Smcpowers  *
4*904Smcpowers  * The contents of this file are subject to the terms of the
5*904Smcpowers  * Common Development and Distribution License, Version 1.0 only
6*904Smcpowers  * (the "License").  You may not use this file except in compliance
7*904Smcpowers  * with the License.
8*904Smcpowers  *
9*904Smcpowers  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*904Smcpowers  * or http://www.opensolaris.org/os/licensing.
11*904Smcpowers  * See the License for the specific language governing permissions
12*904Smcpowers  * and limitations under the License.
13*904Smcpowers  *
14*904Smcpowers  * When distributing Covered Code, include this CDDL HEADER in each
15*904Smcpowers  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*904Smcpowers  * If applicable, add the following below this CDDL HEADER, with the
17*904Smcpowers  * fields enclosed by brackets "[]" replaced with your own identifying
18*904Smcpowers  * information: Portions Copyright [yyyy] [name of copyright owner]
19*904Smcpowers  *
20*904Smcpowers  * CDDL HEADER END
21*904Smcpowers  */
22*904Smcpowers /*
23*904Smcpowers  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*904Smcpowers  * Use is subject to license terms.
25*904Smcpowers  */
26*904Smcpowers 
27*904Smcpowers 
28*904Smcpowers #pragma ident	"%Z%%M%	%I%	%E% SMI"
29*904Smcpowers 
30*904Smcpowers #include <sys/errno.h>
31*904Smcpowers #include <sys/types.h>
32*904Smcpowers #include <sys/kmem.h>
33*904Smcpowers #include <sys/cmn_err.h>
34*904Smcpowers #include <sys/sysmacros.h>
35*904Smcpowers #include <sys/crypto/common.h>
36*904Smcpowers #include <sys/crypto/impl.h>
37*904Smcpowers #include <sys/crypto/api.h>
38*904Smcpowers #include <sys/crypto/spi.h>
39*904Smcpowers #include <sys/crypto/sched_impl.h>
40*904Smcpowers 
41*904Smcpowers #define	CRYPTO_OPS_OFFSET(f)		offsetof(crypto_ops_t, co_##f)
42*904Smcpowers #define	CRYPTO_KEY_OFFSET(f)		offsetof(crypto_key_ops_t, f)
43*904Smcpowers 
44*904Smcpowers int
45*904Smcpowers crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid,
46*904Smcpowers     crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count,
47*904Smcpowers     crypto_object_id_t *handle, crypto_call_req_t *crq)
48*904Smcpowers {
49*904Smcpowers 	kcf_req_params_t params;
50*904Smcpowers 	kcf_provider_desc_t *pd = provider;
51*904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
52*904Smcpowers 	int rv;
53*904Smcpowers 
54*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
55*904Smcpowers 
56*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
57*904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
58*904Smcpowers 		    CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops),
59*904Smcpowers 		    CRYPTO_KEY_OFFSET(key_generate), CHECK_RESTRICT(crq),
60*904Smcpowers 		    pd, &real_provider);
61*904Smcpowers 
62*904Smcpowers 		if (rv != CRYPTO_SUCCESS)
63*904Smcpowers 			return (rv);
64*904Smcpowers 	}
65*904Smcpowers 
66*904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
67*904Smcpowers 		rv = KCF_PROV_KEY_GENERATE(real_provider, sid,
68*904Smcpowers 		    mech, attrs, count, handle, KCF_SWFP_RHNDL(crq));
69*904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
70*904Smcpowers 	} else {
71*904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_GENERATE, sid,
72*904Smcpowers 		    mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0);
73*904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
74*904Smcpowers 		    &params, B_FALSE);
75*904Smcpowers 	}
76*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
77*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
78*904Smcpowers 
79*904Smcpowers 	return (rv);
80*904Smcpowers }
81*904Smcpowers 
82*904Smcpowers int
83*904Smcpowers crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid,
84*904Smcpowers     crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs,
85*904Smcpowers     uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count,
86*904Smcpowers     crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle,
87*904Smcpowers     crypto_call_req_t *crq)
88*904Smcpowers {
89*904Smcpowers 	kcf_req_params_t params;
90*904Smcpowers 	kcf_provider_desc_t *pd = provider;
91*904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
92*904Smcpowers 	int rv;
93*904Smcpowers 
94*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
95*904Smcpowers 
96*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
97*904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
98*904Smcpowers 		    CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops),
99*904Smcpowers 		    CRYPTO_KEY_OFFSET(key_generate_pair), CHECK_RESTRICT(crq),
100*904Smcpowers 		    pd, &real_provider);
101*904Smcpowers 
102*904Smcpowers 		if (rv != CRYPTO_SUCCESS)
103*904Smcpowers 			return (rv);
104*904Smcpowers 	}
105*904Smcpowers 
106*904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
107*904Smcpowers 		rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech,
108*904Smcpowers 		    pub_attrs, pub_count, pri_attrs, pri_count, pub_handle,
109*904Smcpowers 		    pri_handle, KCF_SWFP_RHNDL(crq));
110*904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
111*904Smcpowers 	} else {
112*904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_GENERATE_PAIR,
113*904Smcpowers 		    sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs,
114*904Smcpowers 		    pri_count, pri_handle, NULL, NULL, 0);
115*904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
116*904Smcpowers 		    &params, B_FALSE);
117*904Smcpowers 	}
118*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
119*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
120*904Smcpowers 
121*904Smcpowers 	return (rv);
122*904Smcpowers }
123*904Smcpowers 
124*904Smcpowers int
125*904Smcpowers crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid,
126*904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *wrapping_key,
127*904Smcpowers     crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len,
128*904Smcpowers     crypto_call_req_t *crq)
129*904Smcpowers {
130*904Smcpowers 	kcf_req_params_t params;
131*904Smcpowers 	kcf_provider_desc_t *pd = provider;
132*904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
133*904Smcpowers 	int rv;
134*904Smcpowers 
135*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
136*904Smcpowers 
137*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
138*904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
139*904Smcpowers 		    CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops),
140*904Smcpowers 		    CRYPTO_KEY_OFFSET(key_wrap), CHECK_RESTRICT(crq),
141*904Smcpowers 		    pd, &real_provider);
142*904Smcpowers 
143*904Smcpowers 		if (rv != CRYPTO_SUCCESS)
144*904Smcpowers 			return (rv);
145*904Smcpowers 	}
146*904Smcpowers 
147*904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
148*904Smcpowers 		rv = KCF_PROV_KEY_WRAP(real_provider, sid, mech, wrapping_key,
149*904Smcpowers 		    key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq));
150*904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
151*904Smcpowers 	} else {
152*904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_WRAP, sid, mech,
153*904Smcpowers 		    NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key,
154*904Smcpowers 		    wrapped_key_len);
155*904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
156*904Smcpowers 		    &params, B_FALSE);
157*904Smcpowers 	}
158*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
159*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
160*904Smcpowers 
161*904Smcpowers 	return (rv);
162*904Smcpowers }
163*904Smcpowers 
164*904Smcpowers int
165*904Smcpowers crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid,
166*904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *unwrapping_key,
167*904Smcpowers     uchar_t *wrapped_key, size_t *wrapped_key_len,
168*904Smcpowers     crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key,
169*904Smcpowers     crypto_call_req_t *crq)
170*904Smcpowers {
171*904Smcpowers 	kcf_req_params_t params;
172*904Smcpowers 	kcf_provider_desc_t *pd = provider;
173*904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
174*904Smcpowers 	int rv;
175*904Smcpowers 
176*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
177*904Smcpowers 
178*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
179*904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
180*904Smcpowers 		    CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops),
181*904Smcpowers 		    CRYPTO_KEY_OFFSET(key_unwrap), CHECK_RESTRICT(crq),
182*904Smcpowers 		    pd, &real_provider);
183*904Smcpowers 
184*904Smcpowers 		if (rv != CRYPTO_SUCCESS)
185*904Smcpowers 			return (rv);
186*904Smcpowers 	}
187*904Smcpowers 
188*904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
189*904Smcpowers 		rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech,
190*904Smcpowers 		    unwrapping_key, wrapped_key, wrapped_key_len, attrs,
191*904Smcpowers 		    count, key, KCF_SWFP_RHNDL(crq));
192*904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
193*904Smcpowers 	} else {
194*904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_UNWRAP, sid, mech,
195*904Smcpowers 		    attrs, count, key, NULL, 0, NULL, unwrapping_key,
196*904Smcpowers 		    wrapped_key, wrapped_key_len);
197*904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
198*904Smcpowers 		    &params, B_FALSE);
199*904Smcpowers 	}
200*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
201*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
202*904Smcpowers 
203*904Smcpowers 	return (rv);
204*904Smcpowers }
205*904Smcpowers 
206*904Smcpowers int
207*904Smcpowers crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid,
208*904Smcpowers     crypto_mechanism_t *mech, crypto_key_t *base_key,
209*904Smcpowers     crypto_object_attribute_t *attrs, uint_t count,
210*904Smcpowers     crypto_object_id_t *new_key, crypto_call_req_t *crq)
211*904Smcpowers {
212*904Smcpowers 	kcf_req_params_t params;
213*904Smcpowers 	kcf_provider_desc_t *pd = provider;
214*904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
215*904Smcpowers 	int rv;
216*904Smcpowers 
217*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
218*904Smcpowers 
219*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
220*904Smcpowers 		rv = kcf_get_hardware_provider(mech->cm_type,
221*904Smcpowers 		    CRYPTO_MECH_INVALID, CRYPTO_OPS_OFFSET(key_ops),
222*904Smcpowers 		    CRYPTO_KEY_OFFSET(key_derive), CHECK_RESTRICT(crq),
223*904Smcpowers 		    pd, &real_provider);
224*904Smcpowers 
225*904Smcpowers 		if (rv != CRYPTO_SUCCESS)
226*904Smcpowers 			return (rv);
227*904Smcpowers 	}
228*904Smcpowers 
229*904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
230*904Smcpowers 		rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key,
231*904Smcpowers 		    attrs, count, new_key, KCF_SWFP_RHNDL(crq));
232*904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
233*904Smcpowers 	} else {
234*904Smcpowers 		KCF_WRAP_KEY_OPS_PARAMS(&params, KCF_OP_KEY_DERIVE, sid, mech,
235*904Smcpowers 		    attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL);
236*904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
237*904Smcpowers 		    &params, B_FALSE);
238*904Smcpowers 	}
239*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
240*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
241*904Smcpowers 
242*904Smcpowers 	return (rv);
243*904Smcpowers }
244