xref: /onnv-gate/usr/src/uts/common/crypto/api/kcf_session.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_OBJECT_OFFSET(f)		offsetof(crypto_object_ops_t, f)
43*904Smcpowers #define	CRYPTO_SESSION_OFFSET(f)	offsetof(crypto_session_ops_t, f)
44*904Smcpowers 
45*904Smcpowers int
46*904Smcpowers crypto_session_open(crypto_provider_t provider, crypto_session_id_t *sidp,
47*904Smcpowers crypto_call_req_t *crq)
48*904Smcpowers {
49*904Smcpowers 	kcf_req_params_t params;
50*904Smcpowers 	kcf_provider_desc_t *real_provider;
51*904Smcpowers 	kcf_provider_desc_t *pd = provider;
52*904Smcpowers 
53*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
54*904Smcpowers 
55*904Smcpowers 	/* find a provider that supports session ops */
56*904Smcpowers 	(void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops),
57*904Smcpowers 	    CRYPTO_SESSION_OFFSET(session_open),
58*904Smcpowers 	    CHECK_RESTRICT(crq), pd, &real_provider);
59*904Smcpowers 
60*904Smcpowers 	if (real_provider != NULL) {
61*904Smcpowers 		int rv;
62*904Smcpowers 
63*904Smcpowers 		ASSERT(real_provider == pd ||
64*904Smcpowers 		    pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER);
65*904Smcpowers 
66*904Smcpowers 		if (CHECK_FASTPATH(crq, pd)) {
67*904Smcpowers 			rv = KCF_PROV_SESSION_OPEN(real_provider, sidp,
68*904Smcpowers 			    KCF_SWFP_RHNDL(crq), pd);
69*904Smcpowers 			KCF_PROV_INCRSTATS(pd, rv);
70*904Smcpowers 		} else {
71*904Smcpowers 			KCF_WRAP_SESSION_OPS_PARAMS(&params,
72*904Smcpowers 			    KCF_OP_SESSION_OPEN, sidp, 0, CRYPTO_USER, NULL,
73*904Smcpowers 			    0, pd);
74*904Smcpowers 			rv = kcf_submit_request(real_provider, NULL, crq,
75*904Smcpowers 			    &params, B_FALSE);
76*904Smcpowers 		}
77*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
78*904Smcpowers 
79*904Smcpowers 		if (rv != CRYPTO_SUCCESS) {
80*904Smcpowers 			return (rv);
81*904Smcpowers 		}
82*904Smcpowers 	}
83*904Smcpowers 	return (CRYPTO_SUCCESS);
84*904Smcpowers }
85*904Smcpowers 
86*904Smcpowers int
87*904Smcpowers crypto_session_close(crypto_provider_t provider, crypto_session_id_t sid,
88*904Smcpowers     crypto_call_req_t *crq)
89*904Smcpowers {
90*904Smcpowers 	int rv;
91*904Smcpowers 	kcf_req_params_t params;
92*904Smcpowers 	kcf_provider_desc_t *real_provider;
93*904Smcpowers 	kcf_provider_desc_t *pd = provider;
94*904Smcpowers 
95*904Smcpowers 	if (pd == NULL)
96*904Smcpowers 	    return (CRYPTO_ARGUMENTS_BAD);
97*904Smcpowers 
98*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
99*904Smcpowers 
100*904Smcpowers 	/* find a provider that supports session ops */
101*904Smcpowers 	(void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops),
102*904Smcpowers 	    CRYPTO_SESSION_OFFSET(session_close), CHECK_RESTRICT(crq),
103*904Smcpowers 	    pd, &real_provider);
104*904Smcpowers 
105*904Smcpowers 	ASSERT(real_provider == pd ||
106*904Smcpowers 	    pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER);
107*904Smcpowers 
108*904Smcpowers 	/* edge case is where the logical provider has no members */
109*904Smcpowers 	if (real_provider != NULL) {
110*904Smcpowers 		/* The fast path for SW providers. */
111*904Smcpowers 		if (CHECK_FASTPATH(crq, pd)) {
112*904Smcpowers 			rv = KCF_PROV_SESSION_CLOSE(real_provider,
113*904Smcpowers 			    sid, KCF_SWFP_RHNDL(crq), pd);
114*904Smcpowers 			KCF_PROV_INCRSTATS(pd, rv);
115*904Smcpowers 		} else {
116*904Smcpowers 			KCF_WRAP_SESSION_OPS_PARAMS(&params,
117*904Smcpowers 			    KCF_OP_SESSION_CLOSE, NULL, sid,
118*904Smcpowers 			    CRYPTO_USER, NULL, 0, pd);
119*904Smcpowers 			rv = kcf_submit_request(real_provider, NULL, crq,
120*904Smcpowers 			    &params, B_FALSE);
121*904Smcpowers 		}
122*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
123*904Smcpowers 	}
124*904Smcpowers 	return (CRYPTO_SUCCESS);
125*904Smcpowers }
126*904Smcpowers 
127*904Smcpowers int
128*904Smcpowers crypto_session_login(crypto_provider_t provider, crypto_session_id_t sid,
129*904Smcpowers     crypto_user_type_t type, char *pin, ulong_t len, crypto_call_req_t *crq)
130*904Smcpowers {
131*904Smcpowers 	kcf_req_params_t params;
132*904Smcpowers 	kcf_provider_desc_t *pd = provider;
133*904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
134*904Smcpowers 	int rv;
135*904Smcpowers 
136*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
137*904Smcpowers 
138*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
139*904Smcpowers 		rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(
140*904Smcpowers 		    session_ops), CRYPTO_SESSION_OFFSET(session_login),
141*904Smcpowers 		    CHECK_RESTRICT(crq), 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_SESSION_LOGIN(real_provider, sid,
149*904Smcpowers 		    type, pin, len, KCF_SWFP_RHNDL(crq));
150*904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
151*904Smcpowers 	} else {
152*904Smcpowers 		KCF_WRAP_SESSION_OPS_PARAMS(&params, KCF_OP_SESSION_LOGIN,
153*904Smcpowers 		    NULL, sid, type, pin, len, real_provider);
154*904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
155*904Smcpowers 		    &params, B_FALSE);
156*904Smcpowers 	}
157*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
158*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
159*904Smcpowers 
160*904Smcpowers 	return (rv);
161*904Smcpowers }
162*904Smcpowers 
163*904Smcpowers int
164*904Smcpowers crypto_session_logout(crypto_provider_t provider, crypto_session_id_t sid,
165*904Smcpowers     crypto_call_req_t *crq)
166*904Smcpowers {
167*904Smcpowers 	kcf_req_params_t params;
168*904Smcpowers 	kcf_provider_desc_t *pd = provider;
169*904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
170*904Smcpowers 	int rv;
171*904Smcpowers 
172*904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
173*904Smcpowers 
174*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
175*904Smcpowers 		rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(
176*904Smcpowers 		    session_ops), CRYPTO_SESSION_OFFSET(session_logout),
177*904Smcpowers 		    CHECK_RESTRICT(crq), pd, &real_provider);
178*904Smcpowers 
179*904Smcpowers 		if (rv != CRYPTO_SUCCESS)
180*904Smcpowers 			return (rv);
181*904Smcpowers 	}
182*904Smcpowers 
183*904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
184*904Smcpowers 		rv = KCF_PROV_SESSION_LOGOUT(real_provider, sid,
185*904Smcpowers 		    KCF_SWFP_RHNDL(crq));
186*904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
187*904Smcpowers 	} else {
188*904Smcpowers 		KCF_WRAP_SESSION_OPS_PARAMS(&params, KCF_OP_SESSION_LOGOUT,
189*904Smcpowers 		    NULL, sid, 0, NULL, 0, real_provider);
190*904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
191*904Smcpowers 		    &params, B_FALSE);
192*904Smcpowers 	}
193*904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
194*904Smcpowers 		KCF_PROV_REFRELE(real_provider);
195*904Smcpowers 
196*904Smcpowers 	return (rv);
197*904Smcpowers }
198