Merge commit '06307114472bd8aad5ff18ccdb8e25f128ae6652'
[unleashed.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softKeys.c
blob639b754285de05230d5103aa87b6a277b6a3e68d
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <security/cryptoki.h>
27 #include "softGlobal.h"
28 #include "softSession.h"
29 #include "softKeys.h"
30 #include "softOps.h"
33 CK_RV
34 C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
35 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
38 CK_RV rv;
39 soft_session_t *session_p;
40 boolean_t lock_held = B_FALSE;
42 if (!softtoken_initialized)
43 return (CKR_CRYPTOKI_NOT_INITIALIZED);
45 /* Obtain the session pointer. */
46 rv = handle2session(hSession, &session_p);
47 if (rv != CKR_OK)
48 return (rv);
50 if ((pMechanism == NULL) || (phKey == NULL)) {
51 rv = CKR_ARGUMENTS_BAD;
52 goto clean_exit;
55 if ((pTemplate == NULL) && (ulCount != 0)) {
56 rv = CKR_ARGUMENTS_BAD;
57 goto clean_exit;
60 rv = soft_genkey(session_p, pMechanism, pTemplate,
61 ulCount, phKey);
63 clean_exit:
64 SES_REFRELE(session_p, lock_held);
65 return (rv);
70 CK_RV
71 C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
72 CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
73 CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
74 CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
77 CK_RV rv;
78 soft_session_t *session_p;
79 boolean_t lock_held = B_FALSE;
81 if (!softtoken_initialized)
82 return (CKR_CRYPTOKI_NOT_INITIALIZED);
84 /* Obtain the session pointer. */
85 rv = handle2session(hSession, &session_p);
86 if (rv != CKR_OK)
87 return (rv);
89 if ((pMechanism == NULL) || (phPublicKey == NULL) ||
90 (phPrivateKey == NULL)) {
91 rv = CKR_ARGUMENTS_BAD;
92 goto clean_exit;
95 if ((pPublicKeyTemplate == NULL) ||
96 (ulPublicKeyAttributeCount == 0)) {
97 rv = CKR_ARGUMENTS_BAD;
98 goto clean_exit;
101 if ((pPrivateKeyTemplate == NULL) &&
102 (ulPrivateKeyAttributeCount != 0)) {
103 rv = CKR_ARGUMENTS_BAD;
104 goto clean_exit;
107 rv = soft_genkey_pair(session_p, pMechanism, pPublicKeyTemplate,
108 ulPublicKeyAttributeCount, pPrivateKeyTemplate,
109 ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey);
111 clean_exit:
112 SES_REFRELE(session_p, lock_held);
113 return (rv);
116 CK_RV
117 C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
118 CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
119 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
121 CK_RV rv;
122 soft_session_t *session_p;
123 soft_object_t *wrappingkey_p;
124 soft_object_t *hkey_p;
125 boolean_t lock_held = B_FALSE;
127 if (!softtoken_initialized)
128 return (CKR_CRYPTOKI_NOT_INITIALIZED);
130 /* Obtain the session pointer. */
131 rv = handle2session(hSession, &session_p);
132 if (rv != CKR_OK)
133 return (rv);
135 if (pMechanism == NULL) {
136 rv = CKR_ARGUMENTS_BAD;
137 goto clean_exit;
140 if (pulWrappedKeyLen == NULL) {
141 rv = CKR_ARGUMENTS_BAD;
142 goto clean_exit;
145 /* Obtain the wrapping key object pointer. */
146 HANDLE2OBJECT(hWrappingKey, wrappingkey_p, rv);
147 if (rv != CKR_OK) {
148 rv = CKR_WRAPPING_KEY_HANDLE_INVALID;
149 goto clean_exit;
152 /* Obtain the to-be-wrapped key object pointer. */
153 HANDLE2OBJECT(hKey, hkey_p, rv);
154 if (rv != CKR_OK)
155 goto clean_exit1;
157 /* Check if given wrapping key may be used for wrapping. */
158 if (!(wrappingkey_p->bool_attr_mask & WRAP_BOOL_ON)) {
159 rv = CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
160 goto clean_exit2;
163 /* Check if given wrapping key may be used for encryption. */
164 if (!(wrappingkey_p->bool_attr_mask & ENCRYPT_BOOL_ON)) {
165 rv = CKR_KEY_FUNCTION_NOT_PERMITTED;
166 goto clean_exit2;
170 * Check to see if key to be wrapped is extractable.
171 * Note: this should always be true for softtoken keys.
173 if (!(hkey_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
174 rv = CKR_KEY_UNEXTRACTABLE;
175 goto clean_exit2;
178 (void) pthread_mutex_lock(&session_p->session_mutex);
179 lock_held = B_TRUE;
182 * Wrapping key objects requires calling encrypt operations.
183 * Check to see if encrypt operation is already active.
185 if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
186 /* free the memory to avoid memory leak */
187 soft_crypt_cleanup(session_p, B_TRUE, lock_held);
190 /* This active flag will remain ON while wrapping the key. */
191 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
193 (void) pthread_mutex_unlock(&session_p->session_mutex);
194 lock_held = B_FALSE;
196 rv = soft_wrapkey(session_p, pMechanism, wrappingkey_p,
197 hkey_p, pWrappedKey, pulWrappedKeyLen);
199 (void) pthread_mutex_lock(&session_p->session_mutex);
201 lock_held = B_TRUE;
202 session_p->encrypt.flags = 0;
204 if ((rv == CKR_OK && pWrappedKey == NULL) ||
205 rv == CKR_BUFFER_TOO_SMALL)
206 soft_crypt_cleanup(session_p, B_TRUE, lock_held);
208 clean_exit2:
209 OBJ_REFRELE(hkey_p);
210 clean_exit1:
211 OBJ_REFRELE(wrappingkey_p);
212 clean_exit:
213 SES_REFRELE(session_p, lock_held);
214 return (rv);
217 CK_RV
218 C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
219 CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey,
220 CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
221 CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
223 CK_RV rv;
224 soft_session_t *session_p;
225 soft_object_t *unwrappingkey_p;
226 boolean_t lock_held = B_FALSE;
228 if (!softtoken_initialized)
229 return (CKR_CRYPTOKI_NOT_INITIALIZED);
231 /* Obtain the session pointer. */
232 rv = handle2session(hSession, &session_p);
233 if (rv != CKR_OK)
234 return (rv);
236 if (pMechanism == NULL) {
237 rv = CKR_ARGUMENTS_BAD;
238 goto clean_exit;
241 if ((pTemplate == NULL) || (ulAttributeCount == 0)) {
242 rv = CKR_ARGUMENTS_BAD;
243 goto clean_exit;
246 if ((pWrappedKey == NULL) || (ulWrappedKeyLen == 0)) {
247 rv = CKR_ARGUMENTS_BAD;
248 goto clean_exit;
251 if (phKey == NULL) {
252 rv = CKR_ARGUMENTS_BAD;
253 goto clean_exit;
256 /* Obtain the unwrapping key object pointer. */
257 HANDLE2OBJECT(hUnwrappingKey, unwrappingkey_p, rv);
258 if (rv != CKR_OK) {
259 rv = CKR_UNWRAPPING_KEY_HANDLE_INVALID;
260 goto clean_exit;
263 /* Check if given unwrapping key may be used for unwrapping. */
264 if (!(unwrappingkey_p->bool_attr_mask & UNWRAP_BOOL_ON)) {
265 rv = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
266 goto clean_exit1;
269 /* Check if given unwrapping key may be used to decrypt. */
270 if (!(unwrappingkey_p->bool_attr_mask & DECRYPT_BOOL_ON)) {
271 rv = CKR_KEY_FUNCTION_NOT_PERMITTED;
272 goto clean_exit1;
275 (void) pthread_mutex_lock(&session_p->session_mutex);
276 lock_held = B_TRUE;
279 * Unwrapping key objects requires calling decrypt operations.
280 * Check to see if decrypt operation is already active.
282 if (session_p->decrypt.flags & CRYPTO_OPERATION_ACTIVE) {
283 /* free the memory to avoid memory leak */
284 soft_crypt_cleanup(session_p, B_FALSE, lock_held);
288 * This active flag will remain ON until application
289 * is done unwrapping the key.
291 session_p->decrypt.flags = CRYPTO_OPERATION_ACTIVE;
293 (void) pthread_mutex_unlock(&session_p->session_mutex);
294 lock_held = B_FALSE;
296 rv = soft_unwrapkey(session_p, pMechanism, unwrappingkey_p,
297 pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount,
298 phKey);
300 (void) pthread_mutex_lock(&session_p->session_mutex);
302 if ((rv == CKR_OK && pWrappedKey == NULL) ||
303 rv == CKR_BUFFER_TOO_SMALL)
304 soft_crypt_cleanup(session_p, B_TRUE, lock_held);
306 session_p->decrypt.flags = 0;
307 lock_held = B_TRUE;
309 clean_exit1:
310 OBJ_REFRELE(unwrappingkey_p);
311 clean_exit:
312 SES_REFRELE(session_p, lock_held);
313 return (rv);
317 CK_RV
318 C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
319 CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
320 CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
323 CK_RV rv;
324 soft_session_t *session_p;
325 soft_object_t *basekey_p;
326 boolean_t lock_held = B_FALSE;
328 if (!softtoken_initialized)
329 return (CKR_CRYPTOKI_NOT_INITIALIZED);
331 /* Obtain the session pointer. */
332 rv = handle2session(hSession, &session_p);
333 if (rv != CKR_OK)
334 return (rv);
336 if (pMechanism == NULL) {
337 rv = CKR_ARGUMENTS_BAD;
338 goto clean_exit;
341 if (((pTemplate != NULL) && (ulAttributeCount == 0)) ||
342 ((pTemplate == NULL) && (ulAttributeCount != 0))) {
343 rv = CKR_ARGUMENTS_BAD;
344 goto clean_exit;
347 /* Obtain the private key object pointer. */
348 HANDLE2OBJECT(hBaseKey, basekey_p, rv);
349 if (rv != CKR_OK)
350 goto clean_exit;
352 /* Check to see if key object allows for derivation. */
353 if (!(basekey_p->bool_attr_mask & DERIVE_BOOL_ON)) {
354 rv = CKR_KEY_FUNCTION_NOT_PERMITTED;
355 goto clean_exit1;
358 rv = soft_derivekey(session_p, pMechanism, basekey_p,
359 pTemplate, ulAttributeCount, phKey);
361 clean_exit1:
362 OBJ_REFRELE(basekey_p);
363 clean_exit:
364 SES_REFRELE(session_p, lock_held);
365 return (rv);