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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include <security/cryptoki.h>
28 #include "softGlobal.h"
29 #include "softObject.h"
31 #include "softSession.h"
35 C_SignInit(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
36 CK_OBJECT_HANDLE hKey
)
40 soft_session_t
*session_p
;
42 boolean_t lock_held
= B_FALSE
;
44 if (!softtoken_initialized
)
45 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
47 /* Obtain the session pointer. */
48 rv
= handle2session(hSession
, &session_p
);
52 if (pMechanism
== NULL
) {
53 rv
= CKR_ARGUMENTS_BAD
;
57 /* Obtain the object pointer. */
58 HANDLE2OBJECT(hKey
, key_p
, rv
);
63 /* Check to see if key object supports signature. */
64 if (!(key_p
->bool_attr_mask
& SIGN_BOOL_ON
)) {
65 rv
= CKR_KEY_FUNCTION_NOT_PERMITTED
;
69 (void) pthread_mutex_lock(&session_p
->session_mutex
);
72 /* Check to see if sign operation is already active. */
73 if (session_p
->sign
.flags
& CRYPTO_OPERATION_ACTIVE
) {
74 /* free the memory to avoid memory leak */
75 soft_sign_verify_cleanup(session_p
, B_TRUE
, B_TRUE
);
79 * This active flag will remain ON until application calls either
80 * C_Sign or C_SignFinal to actually obtain the signature.
82 session_p
->sign
.flags
= CRYPTO_OPERATION_ACTIVE
;
84 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
87 rv
= soft_sign_init(session_p
, pMechanism
, key_p
);
90 (void) pthread_mutex_lock(&session_p
->session_mutex
);
91 session_p
->sign
.flags
&= ~CRYPTO_OPERATION_ACTIVE
;
98 SES_REFRELE(session_p
, lock_held
);
104 C_Sign(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
,
105 CK_BYTE_PTR pSignature
, CK_ULONG_PTR pulSignatureLen
)
109 soft_session_t
*session_p
;
110 boolean_t lock_held
= B_FALSE
;
112 if (!softtoken_initialized
)
113 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
115 /* Obatin the session pointer */
116 rv
= handle2session(hSession
, &session_p
);
120 if ((pData
== NULL
) || (pulSignatureLen
== NULL
)) {
121 rv
= CKR_ARGUMENTS_BAD
;
125 (void) pthread_mutex_lock(&session_p
->session_mutex
);
128 /* Application must call C_SignInit before calling C_Sign. */
129 if (!(session_p
->sign
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
130 SES_REFRELE(session_p
, lock_held
);
131 return (CKR_OPERATION_NOT_INITIALIZED
);
135 * C_Sign must be called without intervening C_SignUpdate
138 if (session_p
->sign
.flags
& CRYPTO_OPERATION_UPDATE
) {
140 * C_Sign can not be used to terminate a multi-part
141 * operation, so we'll leave the active sign operation
142 * flag on and let the application continue with the
143 * sign update operation.
145 SES_REFRELE(session_p
, lock_held
);
146 return (CKR_FUNCTION_FAILED
);
149 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
152 rv
= soft_sign(session_p
, pData
, ulDataLen
, pSignature
,
155 if ((rv
== CKR_BUFFER_TOO_SMALL
) ||
156 (pSignature
== NULL
&& rv
== CKR_OK
)) {
158 * We will not terminate the active sign operation flag,
159 * when the application-supplied buffer is too small, or
160 * the application asks for the length of buffer to hold
163 SES_REFRELE(session_p
, lock_held
);
168 /* Clear contexts, free key, and release session counter */
169 soft_sign_verify_cleanup(session_p
, B_TRUE
, B_FALSE
);
175 C_SignUpdate(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pPart
,
180 soft_session_t
*session_p
;
181 boolean_t lock_held
= B_FALSE
;
183 if (!softtoken_initialized
)
184 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
186 /* Obtain the session pointer */
187 rv
= handle2session(hSession
, &session_p
);
191 if (ulPartLen
== 0) {
192 SES_REFRELE(session_p
, lock_held
);
197 rv
= CKR_ARGUMENTS_BAD
;
201 (void) pthread_mutex_lock(&session_p
->session_mutex
);
205 * Application must call C_SignInit before calling
208 if (!(session_p
->sign
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
209 SES_REFRELE(session_p
, lock_held
);
210 return (CKR_OPERATION_NOT_INITIALIZED
);
213 session_p
->sign
.flags
|= CRYPTO_OPERATION_UPDATE
;
215 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
218 rv
= soft_sign_update(session_p
, pPart
, ulPartLen
);
221 SES_REFRELE(session_p
, lock_held
);
226 /* After error, clear context, free key, & release session counter */
227 soft_sign_verify_cleanup(session_p
, B_TRUE
, B_FALSE
);
234 C_SignFinal(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pSignature
,
235 CK_ULONG_PTR pulSignatureLen
)
239 soft_session_t
*session_p
;
240 boolean_t lock_held
= B_FALSE
;
242 if (!softtoken_initialized
)
243 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
245 /* Obtain the session pointer */
246 rv
= handle2session(hSession
, &session_p
);
250 if (pulSignatureLen
== NULL
) {
251 rv
= CKR_ARGUMENTS_BAD
;
255 (void) pthread_mutex_lock(&session_p
->session_mutex
);
259 * Application must call C_SignInit before calling
262 if (!(session_p
->sign
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
263 SES_REFRELE(session_p
, lock_held
);
264 return (CKR_OPERATION_NOT_INITIALIZED
);
267 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
270 rv
= soft_sign_final(session_p
, pSignature
, pulSignatureLen
);
272 if ((rv
== CKR_BUFFER_TOO_SMALL
) ||
273 (pSignature
== NULL
&& rv
== CKR_OK
)) {
275 * We will not terminate the active sign operation flag,
276 * when the application-supplied buffer is too small, or
277 * the application asks for the length of buffer to hold
280 SES_REFRELE(session_p
, lock_held
);
285 /* Clear contexts, free key, and release session counter */
286 soft_sign_verify_cleanup(session_p
, B_TRUE
, B_FALSE
);
292 C_SignRecoverInit(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
293 CK_OBJECT_HANDLE hKey
)
297 soft_session_t
*session_p
;
298 soft_object_t
*key_p
;
299 boolean_t lock_held
= B_FALSE
;
301 if (!softtoken_initialized
)
302 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
304 /* Obtain the session pointer. */
305 rv
= handle2session(hSession
, &session_p
);
309 if (pMechanism
== NULL
) {
310 rv
= CKR_ARGUMENTS_BAD
;
314 /* Obtain the object pointer. */
315 HANDLE2OBJECT(hKey
, key_p
, rv
);
320 /* Check to see if key object supports sign_recover. */
321 if (!(key_p
->bool_attr_mask
& SIGN_RECOVER_BOOL_ON
)) {
322 rv
= CKR_KEY_FUNCTION_NOT_PERMITTED
;
326 (void) pthread_mutex_lock(&session_p
->session_mutex
);
329 /* Check to see if sign operation is already active. */
330 if (session_p
->sign
.flags
& CRYPTO_OPERATION_ACTIVE
) {
331 /* free the memory to avoid memory leak */
332 soft_sign_verify_cleanup(session_p
, B_TRUE
, B_TRUE
);
336 * This active flag will remain ON until application calls either
337 * C_SignRecover to actually obtain the signature.
339 session_p
->sign
.flags
= CRYPTO_OPERATION_ACTIVE
;
341 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
344 rv
= soft_sign_recover_init(session_p
, pMechanism
, key_p
);
347 (void) pthread_mutex_lock(&session_p
->session_mutex
);
348 session_p
->sign
.flags
&= ~CRYPTO_OPERATION_ACTIVE
;
355 SES_REFRELE(session_p
, lock_held
);
361 C_SignRecover(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pData
,
362 CK_ULONG ulDataLen
, CK_BYTE_PTR pSignature
, CK_ULONG_PTR pulSignatureLen
)
366 soft_session_t
*session_p
;
367 boolean_t lock_held
= B_FALSE
;
369 if (!softtoken_initialized
)
370 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
372 /* Obatin the session pointer */
373 rv
= handle2session(hSession
, &session_p
);
377 if ((pData
== NULL
) || (pulSignatureLen
== NULL
)) {
378 rv
= CKR_ARGUMENTS_BAD
;
382 (void) pthread_mutex_lock(&session_p
->session_mutex
);
385 /* Application must call C_SignRecoverInit before C_SignRecover. */
386 if (!(session_p
->sign
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
387 SES_REFRELE(session_p
, lock_held
);
388 return (CKR_OPERATION_NOT_INITIALIZED
);
391 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
394 rv
= soft_sign_recover(session_p
, pData
, ulDataLen
, pSignature
,
397 if ((rv
== CKR_BUFFER_TOO_SMALL
) ||
398 (pSignature
== NULL
&& rv
== CKR_OK
)) {
400 * We will not terminate the active sign operation flag,
401 * when the application-supplied buffer is too small, or
402 * the application asks for the length of buffer to hold
405 SES_REFRELE(session_p
, lock_held
);
410 /* Clear contexts, free key, and release session counter */
411 soft_sign_verify_cleanup(session_p
, B_TRUE
, B_FALSE
);