xref: /onnv-gate/usr/src/uts/common/crypto/api/kcf_session.c (revision 12304:bcfa0838b31e)
1904Smcpowers /*
2904Smcpowers  * CDDL HEADER START
3904Smcpowers  *
4904Smcpowers  * The contents of this file are subject to the terms of the
5*12304SValerie.Fenwick@Oracle.COM  * Common Development and Distribution License (the "License").
6*12304SValerie.Fenwick@Oracle.COM  * 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 
26904Smcpowers #include <sys/errno.h>
27904Smcpowers #include <sys/types.h>
28904Smcpowers #include <sys/kmem.h>
29904Smcpowers #include <sys/cmn_err.h>
30904Smcpowers #include <sys/sysmacros.h>
31904Smcpowers #include <sys/crypto/common.h>
32904Smcpowers #include <sys/crypto/impl.h>
33904Smcpowers #include <sys/crypto/api.h>
34904Smcpowers #include <sys/crypto/spi.h>
35904Smcpowers #include <sys/crypto/sched_impl.h>
36904Smcpowers 
37904Smcpowers #define	CRYPTO_OPS_OFFSET(f)		offsetof(crypto_ops_t, co_##f)
38904Smcpowers #define	CRYPTO_OBJECT_OFFSET(f)		offsetof(crypto_object_ops_t, f)
39904Smcpowers #define	CRYPTO_SESSION_OFFSET(f)	offsetof(crypto_session_ops_t, f)
40904Smcpowers 
41904Smcpowers int
crypto_session_open(crypto_provider_t provider,crypto_session_id_t * sidp,crypto_call_req_t * crq)42904Smcpowers crypto_session_open(crypto_provider_t provider, crypto_session_id_t *sidp,
43904Smcpowers crypto_call_req_t *crq)
44904Smcpowers {
45904Smcpowers 	kcf_req_params_t params;
46904Smcpowers 	kcf_provider_desc_t *real_provider;
47904Smcpowers 	kcf_provider_desc_t *pd = provider;
48904Smcpowers 
49904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
50904Smcpowers 
51904Smcpowers 	/* find a provider that supports session ops */
52904Smcpowers 	(void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops),
53*12304SValerie.Fenwick@Oracle.COM 	    CRYPTO_SESSION_OFFSET(session_open), pd, &real_provider);
54904Smcpowers 
55904Smcpowers 	if (real_provider != NULL) {
56904Smcpowers 		int rv;
57904Smcpowers 
58904Smcpowers 		ASSERT(real_provider == pd ||
59904Smcpowers 		    pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER);
60904Smcpowers 
61904Smcpowers 		if (CHECK_FASTPATH(crq, pd)) {
62904Smcpowers 			rv = KCF_PROV_SESSION_OPEN(real_provider, sidp,
63904Smcpowers 			    KCF_SWFP_RHNDL(crq), pd);
64904Smcpowers 			KCF_PROV_INCRSTATS(pd, rv);
65904Smcpowers 		} else {
66904Smcpowers 			KCF_WRAP_SESSION_OPS_PARAMS(&params,
67904Smcpowers 			    KCF_OP_SESSION_OPEN, sidp, 0, CRYPTO_USER, NULL,
68904Smcpowers 			    0, pd);
69904Smcpowers 			rv = kcf_submit_request(real_provider, NULL, crq,
70904Smcpowers 			    &params, B_FALSE);
71904Smcpowers 		}
72904Smcpowers 		KCF_PROV_REFRELE(real_provider);
73904Smcpowers 
74904Smcpowers 		if (rv != CRYPTO_SUCCESS) {
75904Smcpowers 			return (rv);
76904Smcpowers 		}
77904Smcpowers 	}
78904Smcpowers 	return (CRYPTO_SUCCESS);
79904Smcpowers }
80904Smcpowers 
81904Smcpowers int
crypto_session_close(crypto_provider_t provider,crypto_session_id_t sid,crypto_call_req_t * crq)82904Smcpowers crypto_session_close(crypto_provider_t provider, crypto_session_id_t sid,
83904Smcpowers     crypto_call_req_t *crq)
84904Smcpowers {
85904Smcpowers 	int rv;
86904Smcpowers 	kcf_req_params_t params;
87904Smcpowers 	kcf_provider_desc_t *real_provider;
88904Smcpowers 	kcf_provider_desc_t *pd = provider;
89904Smcpowers 
90904Smcpowers 	if (pd == NULL)
91*12304SValerie.Fenwick@Oracle.COM 		return (CRYPTO_ARGUMENTS_BAD);
92904Smcpowers 
93904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
94904Smcpowers 
95904Smcpowers 	/* find a provider that supports session ops */
96904Smcpowers 	(void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops),
97*12304SValerie.Fenwick@Oracle.COM 	    CRYPTO_SESSION_OFFSET(session_close), pd, &real_provider);
98904Smcpowers 
99904Smcpowers 	ASSERT(real_provider == pd ||
100904Smcpowers 	    pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER);
101904Smcpowers 
102904Smcpowers 	/* edge case is where the logical provider has no members */
103904Smcpowers 	if (real_provider != NULL) {
104904Smcpowers 		/* The fast path for SW providers. */
105904Smcpowers 		if (CHECK_FASTPATH(crq, pd)) {
106904Smcpowers 			rv = KCF_PROV_SESSION_CLOSE(real_provider,
107904Smcpowers 			    sid, KCF_SWFP_RHNDL(crq), pd);
108904Smcpowers 			KCF_PROV_INCRSTATS(pd, rv);
109904Smcpowers 		} else {
110904Smcpowers 			KCF_WRAP_SESSION_OPS_PARAMS(&params,
111904Smcpowers 			    KCF_OP_SESSION_CLOSE, NULL, sid,
112904Smcpowers 			    CRYPTO_USER, NULL, 0, pd);
113904Smcpowers 			rv = kcf_submit_request(real_provider, NULL, crq,
114904Smcpowers 			    &params, B_FALSE);
115904Smcpowers 		}
116904Smcpowers 		KCF_PROV_REFRELE(real_provider);
117904Smcpowers 	}
118904Smcpowers 	return (CRYPTO_SUCCESS);
119904Smcpowers }
120904Smcpowers 
121904Smcpowers int
crypto_session_login(crypto_provider_t provider,crypto_session_id_t sid,crypto_user_type_t type,char * pin,ulong_t len,crypto_call_req_t * crq)122904Smcpowers crypto_session_login(crypto_provider_t provider, crypto_session_id_t sid,
123904Smcpowers     crypto_user_type_t type, char *pin, ulong_t len, crypto_call_req_t *crq)
124904Smcpowers {
125904Smcpowers 	kcf_req_params_t params;
126904Smcpowers 	kcf_provider_desc_t *pd = provider;
127904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
128904Smcpowers 	int rv;
129904Smcpowers 
130904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
131904Smcpowers 
132904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
133904Smcpowers 		rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(
134904Smcpowers 		    session_ops), CRYPTO_SESSION_OFFSET(session_login),
135*12304SValerie.Fenwick@Oracle.COM 		    pd, &real_provider);
136904Smcpowers 
137904Smcpowers 		if (rv != CRYPTO_SUCCESS)
138904Smcpowers 			return (rv);
139904Smcpowers 	}
140904Smcpowers 
141904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
142904Smcpowers 		rv = KCF_PROV_SESSION_LOGIN(real_provider, sid,
143904Smcpowers 		    type, pin, len, KCF_SWFP_RHNDL(crq));
144904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
145904Smcpowers 	} else {
146904Smcpowers 		KCF_WRAP_SESSION_OPS_PARAMS(&params, KCF_OP_SESSION_LOGIN,
147904Smcpowers 		    NULL, sid, type, pin, len, real_provider);
148904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
149904Smcpowers 		    &params, B_FALSE);
150904Smcpowers 	}
151904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
152904Smcpowers 		KCF_PROV_REFRELE(real_provider);
153904Smcpowers 
154904Smcpowers 	return (rv);
155904Smcpowers }
156904Smcpowers 
157904Smcpowers int
crypto_session_logout(crypto_provider_t provider,crypto_session_id_t sid,crypto_call_req_t * crq)158904Smcpowers crypto_session_logout(crypto_provider_t provider, crypto_session_id_t sid,
159904Smcpowers     crypto_call_req_t *crq)
160904Smcpowers {
161904Smcpowers 	kcf_req_params_t params;
162904Smcpowers 	kcf_provider_desc_t *pd = provider;
163904Smcpowers 	kcf_provider_desc_t *real_provider = pd;
164904Smcpowers 	int rv;
165904Smcpowers 
166904Smcpowers 	ASSERT(KCF_PROV_REFHELD(pd));
167904Smcpowers 
168904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
169904Smcpowers 		rv = kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(
170904Smcpowers 		    session_ops), CRYPTO_SESSION_OFFSET(session_logout),
171*12304SValerie.Fenwick@Oracle.COM 		    pd, &real_provider);
172904Smcpowers 
173904Smcpowers 		if (rv != CRYPTO_SUCCESS)
174904Smcpowers 			return (rv);
175904Smcpowers 	}
176904Smcpowers 
177904Smcpowers 	if (CHECK_FASTPATH(crq, real_provider)) {
178904Smcpowers 		rv = KCF_PROV_SESSION_LOGOUT(real_provider, sid,
179904Smcpowers 		    KCF_SWFP_RHNDL(crq));
180904Smcpowers 		KCF_PROV_INCRSTATS(pd, rv);
181904Smcpowers 	} else {
182904Smcpowers 		KCF_WRAP_SESSION_OPS_PARAMS(&params, KCF_OP_SESSION_LOGOUT,
183904Smcpowers 		    NULL, sid, 0, NULL, 0, real_provider);
184904Smcpowers 		rv = kcf_submit_request(real_provider, NULL, crq,
185904Smcpowers 		    &params, B_FALSE);
186904Smcpowers 	}
187904Smcpowers 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
188904Smcpowers 		KCF_PROV_REFRELE(real_provider);
189904Smcpowers 
190904Smcpowers 	return (rv);
191904Smcpowers }
192