4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/errno.h>
27 #include <sys/types.h>
29 #include <sys/cmn_err.h>
30 #include <sys/sysmacros.h>
31 #include <sys/crypto/common.h>
32 #include <sys/crypto/impl.h>
33 #include <sys/crypto/api.h>
34 #include <sys/crypto/spi.h>
35 #include <sys/crypto/sched_impl.h>
37 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f)
38 #define CRYPTO_OBJECT_OFFSET(f) offsetof(crypto_object_ops_t, f)
39 #define CRYPTO_SESSION_OFFSET(f) offsetof(crypto_session_ops_t, f)
42 crypto_session_open(crypto_provider_t provider
, crypto_session_id_t
*sidp
,
43 crypto_call_req_t
*crq
)
45 kcf_req_params_t params
;
46 kcf_provider_desc_t
*real_provider
;
47 kcf_provider_desc_t
*pd
= provider
;
49 ASSERT(KCF_PROV_REFHELD(pd
));
51 /* find a provider that supports session ops */
52 (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops
),
53 CRYPTO_SESSION_OFFSET(session_open
), pd
, &real_provider
);
55 if (real_provider
!= NULL
) {
58 ASSERT(real_provider
== pd
||
59 pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
);
61 if (CHECK_FASTPATH(crq
, pd
)) {
62 rv
= KCF_PROV_SESSION_OPEN(real_provider
, sidp
,
63 KCF_SWFP_RHNDL(crq
), pd
);
64 KCF_PROV_INCRSTATS(pd
, rv
);
66 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
,
67 KCF_OP_SESSION_OPEN
, sidp
, 0, CRYPTO_USER
, NULL
,
69 rv
= kcf_submit_request(real_provider
, NULL
, crq
,
72 KCF_PROV_REFRELE(real_provider
);
74 if (rv
!= CRYPTO_SUCCESS
) {
78 return (CRYPTO_SUCCESS
);
82 crypto_session_close(crypto_provider_t provider
, crypto_session_id_t sid
,
83 crypto_call_req_t
*crq
)
86 kcf_req_params_t params
;
87 kcf_provider_desc_t
*real_provider
;
88 kcf_provider_desc_t
*pd
= provider
;
91 return (CRYPTO_ARGUMENTS_BAD
);
93 ASSERT(KCF_PROV_REFHELD(pd
));
95 /* find a provider that supports session ops */
96 (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops
),
97 CRYPTO_SESSION_OFFSET(session_close
), pd
, &real_provider
);
99 ASSERT(real_provider
== pd
||
100 pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
);
102 /* edge case is where the logical provider has no members */
103 if (real_provider
!= NULL
) {
104 /* The fast path for SW providers. */
105 if (CHECK_FASTPATH(crq
, pd
)) {
106 rv
= KCF_PROV_SESSION_CLOSE(real_provider
,
107 sid
, KCF_SWFP_RHNDL(crq
), pd
);
108 KCF_PROV_INCRSTATS(pd
, rv
);
110 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
,
111 KCF_OP_SESSION_CLOSE
, NULL
, sid
,
112 CRYPTO_USER
, NULL
, 0, pd
);
113 rv
= kcf_submit_request(real_provider
, NULL
, crq
,
116 KCF_PROV_REFRELE(real_provider
);
118 return (CRYPTO_SUCCESS
);
122 crypto_session_login(crypto_provider_t provider
, crypto_session_id_t sid
,
123 crypto_user_type_t type
, char *pin
, ulong_t len
, crypto_call_req_t
*crq
)
125 kcf_req_params_t params
;
126 kcf_provider_desc_t
*pd
= provider
;
127 kcf_provider_desc_t
*real_provider
= pd
;
130 ASSERT(KCF_PROV_REFHELD(pd
));
132 if (pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
) {
133 rv
= kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(
134 session_ops
), CRYPTO_SESSION_OFFSET(session_login
),
137 if (rv
!= CRYPTO_SUCCESS
)
141 if (CHECK_FASTPATH(crq
, real_provider
)) {
142 rv
= KCF_PROV_SESSION_LOGIN(real_provider
, sid
,
143 type
, pin
, len
, KCF_SWFP_RHNDL(crq
));
144 KCF_PROV_INCRSTATS(pd
, rv
);
146 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
, KCF_OP_SESSION_LOGIN
,
147 NULL
, sid
, type
, pin
, len
, real_provider
);
148 rv
= kcf_submit_request(real_provider
, NULL
, crq
,
151 if (pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
)
152 KCF_PROV_REFRELE(real_provider
);
158 crypto_session_logout(crypto_provider_t provider
, crypto_session_id_t sid
,
159 crypto_call_req_t
*crq
)
161 kcf_req_params_t params
;
162 kcf_provider_desc_t
*pd
= provider
;
163 kcf_provider_desc_t
*real_provider
= pd
;
166 ASSERT(KCF_PROV_REFHELD(pd
));
168 if (pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
) {
169 rv
= kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(
170 session_ops
), CRYPTO_SESSION_OFFSET(session_logout
),
173 if (rv
!= CRYPTO_SUCCESS
)
177 if (CHECK_FASTPATH(crq
, real_provider
)) {
178 rv
= KCF_PROV_SESSION_LOGOUT(real_provider
, sid
,
179 KCF_SWFP_RHNDL(crq
));
180 KCF_PROV_INCRSTATS(pd
, rv
);
182 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
, KCF_OP_SESSION_LOGOUT
,
183 NULL
, sid
, 0, NULL
, 0, real_provider
);
184 rv
= kcf_submit_request(real_provider
, NULL
, crq
,
187 if (pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
)
188 KCF_PROV_REFRELE(real_provider
);