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(¶ms,
67904Smcpowers KCF_OP_SESSION_OPEN, sidp, 0, CRYPTO_USER, NULL,
68904Smcpowers 0, pd);
69904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
70904Smcpowers ¶ms, 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(¶ms,
111904Smcpowers KCF_OP_SESSION_CLOSE, NULL, sid,
112904Smcpowers CRYPTO_USER, NULL, 0, pd);
113904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
114904Smcpowers ¶ms, 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(¶ms, KCF_OP_SESSION_LOGIN,
147904Smcpowers NULL, sid, type, pin, len, real_provider);
148904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
149904Smcpowers ¶ms, 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(¶ms, KCF_OP_SESSION_LOGOUT,
183904Smcpowers NULL, sid, 0, NULL, 0, real_provider);
184904Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
185904Smcpowers ¶ms, B_FALSE);
186904Smcpowers }
187904Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
188904Smcpowers KCF_PROV_REFRELE(real_provider);
189904Smcpowers
190904Smcpowers return (rv);
191904Smcpowers }
192