1894b2776Smcpowers /*
2894b2776Smcpowers * CDDL HEADER START
3894b2776Smcpowers *
4894b2776Smcpowers * The contents of this file are subject to the terms of the
572eff6e2Smcpowers * Common Development and Distribution License (the "License").
672eff6e2Smcpowers * You may not use this file except in compliance with the License.
7894b2776Smcpowers *
8894b2776Smcpowers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9894b2776Smcpowers * or http://www.opensolaris.org/os/licensing.
10894b2776Smcpowers * See the License for the specific language governing permissions
11894b2776Smcpowers * and limitations under the License.
12894b2776Smcpowers *
13894b2776Smcpowers * When distributing Covered Code, include this CDDL HEADER in each
14894b2776Smcpowers * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15894b2776Smcpowers * If applicable, add the following below this CDDL HEADER, with the
16894b2776Smcpowers * fields enclosed by brackets "[]" replaced with your own identifying
17894b2776Smcpowers * information: Portions Copyright [yyyy] [name of copyright owner]
18894b2776Smcpowers *
19894b2776Smcpowers * CDDL HEADER END
20894b2776Smcpowers */
21894b2776Smcpowers /*
22*9b009fc1SValerie Bubb Fenwick * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23894b2776Smcpowers */
24894b2776Smcpowers
25894b2776Smcpowers #include <sys/errno.h>
26894b2776Smcpowers #include <sys/types.h>
27894b2776Smcpowers #include <sys/kmem.h>
28894b2776Smcpowers #include <sys/cmn_err.h>
29894b2776Smcpowers #include <sys/sysmacros.h>
30894b2776Smcpowers #include <sys/crypto/common.h>
31894b2776Smcpowers #include <sys/crypto/impl.h>
32894b2776Smcpowers #include <sys/crypto/api.h>
33894b2776Smcpowers #include <sys/crypto/spi.h>
34894b2776Smcpowers #include <sys/crypto/sched_impl.h>
35894b2776Smcpowers
36894b2776Smcpowers #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f)
37894b2776Smcpowers #define CRYPTO_KEY_OFFSET(f) offsetof(crypto_key_ops_t, f)
38894b2776Smcpowers
39894b2776Smcpowers int
crypto_key_generate(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * handle,crypto_call_req_t * crq)40894b2776Smcpowers crypto_key_generate(crypto_provider_t provider, crypto_session_id_t sid,
41894b2776Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *attrs, uint_t count,
42894b2776Smcpowers crypto_object_id_t *handle, crypto_call_req_t *crq)
43894b2776Smcpowers {
44894b2776Smcpowers kcf_req_params_t params;
45894b2776Smcpowers kcf_provider_desc_t *pd = provider;
46894b2776Smcpowers kcf_provider_desc_t *real_provider = pd;
47894b2776Smcpowers int rv;
48894b2776Smcpowers
49894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd));
50894b2776Smcpowers
51894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
52436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, NULL,
53*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
54*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_GENERATE);
55894b2776Smcpowers
56894b2776Smcpowers if (rv != CRYPTO_SUCCESS)
57894b2776Smcpowers return (rv);
58894b2776Smcpowers }
59894b2776Smcpowers
60894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) {
61894b2776Smcpowers rv = KCF_PROV_KEY_GENERATE(real_provider, sid,
62894b2776Smcpowers mech, attrs, count, handle, KCF_SWFP_RHNDL(crq));
63894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv);
64894b2776Smcpowers } else {
65894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE, sid,
66894b2776Smcpowers mech, attrs, count, handle, NULL, 0, NULL, NULL, NULL, 0);
67894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
68894b2776Smcpowers ¶ms, B_FALSE);
69894b2776Smcpowers }
70894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
71894b2776Smcpowers KCF_PROV_REFRELE(real_provider);
72894b2776Smcpowers
73894b2776Smcpowers return (rv);
74894b2776Smcpowers }
75894b2776Smcpowers
76894b2776Smcpowers int
crypto_key_generate_pair(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_object_attribute_t * pub_attrs,uint_t pub_count,crypto_object_attribute_t * pri_attrs,uint_t pri_count,crypto_object_id_t * pub_handle,crypto_object_id_t * pri_handle,crypto_call_req_t * crq)77894b2776Smcpowers crypto_key_generate_pair(crypto_provider_t provider, crypto_session_id_t sid,
78894b2776Smcpowers crypto_mechanism_t *mech, crypto_object_attribute_t *pub_attrs,
79894b2776Smcpowers uint_t pub_count, crypto_object_attribute_t *pri_attrs, uint_t pri_count,
80894b2776Smcpowers crypto_object_id_t *pub_handle, crypto_object_id_t *pri_handle,
81894b2776Smcpowers crypto_call_req_t *crq)
82894b2776Smcpowers {
83894b2776Smcpowers kcf_req_params_t params;
84894b2776Smcpowers kcf_provider_desc_t *pd = provider;
85894b2776Smcpowers kcf_provider_desc_t *real_provider = pd;
86894b2776Smcpowers int rv;
87894b2776Smcpowers
88894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd));
89894b2776Smcpowers
90894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
91436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, NULL,
92*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
93*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_GENERATE_KEY_PAIR);
94894b2776Smcpowers
95894b2776Smcpowers if (rv != CRYPTO_SUCCESS)
96894b2776Smcpowers return (rv);
97894b2776Smcpowers }
98894b2776Smcpowers
99894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) {
100894b2776Smcpowers rv = KCF_PROV_KEY_GENERATE_PAIR(real_provider, sid, mech,
101894b2776Smcpowers pub_attrs, pub_count, pri_attrs, pri_count, pub_handle,
102894b2776Smcpowers pri_handle, KCF_SWFP_RHNDL(crq));
103894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv);
104894b2776Smcpowers } else {
105894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE_PAIR,
106894b2776Smcpowers sid, mech, pub_attrs, pub_count, pub_handle, pri_attrs,
107894b2776Smcpowers pri_count, pri_handle, NULL, NULL, 0);
108894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
109894b2776Smcpowers ¶ms, B_FALSE);
110894b2776Smcpowers }
111894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
112894b2776Smcpowers KCF_PROV_REFRELE(real_provider);
113894b2776Smcpowers
114894b2776Smcpowers return (rv);
115894b2776Smcpowers }
116894b2776Smcpowers
117894b2776Smcpowers int
crypto_key_wrap(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * wrapping_key,crypto_object_id_t * key,uchar_t * wrapped_key,size_t * wrapped_key_len,crypto_call_req_t * crq)118894b2776Smcpowers crypto_key_wrap(crypto_provider_t provider, crypto_session_id_t sid,
119894b2776Smcpowers crypto_mechanism_t *mech, crypto_key_t *wrapping_key,
120894b2776Smcpowers crypto_object_id_t *key, uchar_t *wrapped_key, size_t *wrapped_key_len,
121894b2776Smcpowers crypto_call_req_t *crq)
122894b2776Smcpowers {
123894b2776Smcpowers kcf_req_params_t params;
124894b2776Smcpowers kcf_provider_desc_t *pd = provider;
125894b2776Smcpowers kcf_provider_desc_t *real_provider = pd;
126894b2776Smcpowers int rv;
127894b2776Smcpowers
128894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd));
129894b2776Smcpowers
130894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
131436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, wrapping_key,
132*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
133*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_WRAP);
134894b2776Smcpowers
135894b2776Smcpowers if (rv != CRYPTO_SUCCESS)
136894b2776Smcpowers return (rv);
137894b2776Smcpowers }
138894b2776Smcpowers
139894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) {
140894b2776Smcpowers rv = KCF_PROV_KEY_WRAP(real_provider, sid, mech, wrapping_key,
141894b2776Smcpowers key, wrapped_key, wrapped_key_len, KCF_SWFP_RHNDL(crq));
142894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv);
143894b2776Smcpowers } else {
144894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_WRAP, sid, mech,
145894b2776Smcpowers NULL, 0, key, NULL, 0, NULL, wrapping_key, wrapped_key,
146894b2776Smcpowers wrapped_key_len);
147894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
148894b2776Smcpowers ¶ms, B_FALSE);
149894b2776Smcpowers }
150894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
151894b2776Smcpowers KCF_PROV_REFRELE(real_provider);
152894b2776Smcpowers
153894b2776Smcpowers return (rv);
154894b2776Smcpowers }
155894b2776Smcpowers
156894b2776Smcpowers int
crypto_key_unwrap(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * unwrapping_key,uchar_t * wrapped_key,size_t * wrapped_key_len,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * key,crypto_call_req_t * crq)157894b2776Smcpowers crypto_key_unwrap(crypto_provider_t provider, crypto_session_id_t sid,
158894b2776Smcpowers crypto_mechanism_t *mech, crypto_key_t *unwrapping_key,
159894b2776Smcpowers uchar_t *wrapped_key, size_t *wrapped_key_len,
160894b2776Smcpowers crypto_object_attribute_t *attrs, uint_t count, crypto_object_id_t *key,
161894b2776Smcpowers crypto_call_req_t *crq)
162894b2776Smcpowers {
163894b2776Smcpowers kcf_req_params_t params;
164894b2776Smcpowers kcf_provider_desc_t *pd = provider;
165894b2776Smcpowers kcf_provider_desc_t *real_provider = pd;
166894b2776Smcpowers int rv;
167894b2776Smcpowers
168894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd));
169894b2776Smcpowers
170894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
171436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, unwrapping_key,
172*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
173*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_UNWRAP);
174894b2776Smcpowers
175894b2776Smcpowers if (rv != CRYPTO_SUCCESS)
176894b2776Smcpowers return (rv);
177894b2776Smcpowers }
178894b2776Smcpowers
179894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) {
180894b2776Smcpowers rv = KCF_PROV_KEY_UNWRAP(real_provider, sid, mech,
181894b2776Smcpowers unwrapping_key, wrapped_key, wrapped_key_len, attrs,
182894b2776Smcpowers count, key, KCF_SWFP_RHNDL(crq));
183894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv);
184894b2776Smcpowers } else {
185894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_UNWRAP, sid, mech,
186894b2776Smcpowers attrs, count, key, NULL, 0, NULL, unwrapping_key,
187894b2776Smcpowers wrapped_key, wrapped_key_len);
188894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
189894b2776Smcpowers ¶ms, B_FALSE);
190894b2776Smcpowers }
191894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
192894b2776Smcpowers KCF_PROV_REFRELE(real_provider);
193894b2776Smcpowers
194894b2776Smcpowers return (rv);
195894b2776Smcpowers }
196894b2776Smcpowers
197894b2776Smcpowers int
crypto_key_derive(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * base_key,crypto_object_attribute_t * attrs,uint_t count,crypto_object_id_t * new_key,crypto_call_req_t * crq)198894b2776Smcpowers crypto_key_derive(crypto_provider_t provider, crypto_session_id_t sid,
199894b2776Smcpowers crypto_mechanism_t *mech, crypto_key_t *base_key,
200894b2776Smcpowers crypto_object_attribute_t *attrs, uint_t count,
201894b2776Smcpowers crypto_object_id_t *new_key, crypto_call_req_t *crq)
202894b2776Smcpowers {
203894b2776Smcpowers kcf_req_params_t params;
204894b2776Smcpowers kcf_provider_desc_t *pd = provider;
205894b2776Smcpowers kcf_provider_desc_t *real_provider = pd;
206894b2776Smcpowers int rv;
207894b2776Smcpowers
208894b2776Smcpowers ASSERT(KCF_PROV_REFHELD(pd));
209894b2776Smcpowers
210894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
211436935a1SVladimir Kotal rv = kcf_get_hardware_provider(mech->cm_type, base_key,
212*9b009fc1SValerie Bubb Fenwick CRYPTO_MECH_INVALID, NULL, pd, &real_provider,
213*9b009fc1SValerie Bubb Fenwick CRYPTO_FG_DERIVE);
214894b2776Smcpowers
215894b2776Smcpowers if (rv != CRYPTO_SUCCESS)
216894b2776Smcpowers return (rv);
217894b2776Smcpowers }
218894b2776Smcpowers
219894b2776Smcpowers if (CHECK_FASTPATH(crq, real_provider)) {
220894b2776Smcpowers rv = KCF_PROV_KEY_DERIVE(real_provider, sid, mech, base_key,
221894b2776Smcpowers attrs, count, new_key, KCF_SWFP_RHNDL(crq));
222894b2776Smcpowers KCF_PROV_INCRSTATS(pd, rv);
223894b2776Smcpowers } else {
224894b2776Smcpowers KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_DERIVE, sid, mech,
225894b2776Smcpowers attrs, count, new_key, NULL, 0, NULL, base_key, NULL, NULL);
226894b2776Smcpowers rv = kcf_submit_request(real_provider, NULL, crq,
227894b2776Smcpowers ¶ms, B_FALSE);
228894b2776Smcpowers }
229894b2776Smcpowers if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
230894b2776Smcpowers KCF_PROV_REFRELE(real_provider);
231894b2776Smcpowers
232894b2776Smcpowers return (rv);
233894b2776Smcpowers }
234