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_VerifyInit(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 verification. */
64 if (!(key_p
->bool_attr_mask
& VERIFY_BOOL_ON
)) {
65 rv
= CKR_KEY_FUNCTION_NOT_PERMITTED
;
69 (void) pthread_mutex_lock(&session_p
->session_mutex
);
72 /* Check to see if verify operation is already active. */
73 if (session_p
->verify
.flags
& CRYPTO_OPERATION_ACTIVE
) {
74 /* free the memory to avoid memory leak */
75 soft_sign_verify_cleanup(session_p
, B_FALSE
, B_TRUE
);
79 * This active flag will remain ON until application calls either
80 * C_Verify or C_VerifyFinal to verify a signature on data.
82 session_p
->verify
.flags
= CRYPTO_OPERATION_ACTIVE
;
84 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
87 rv
= soft_verify_init(session_p
, pMechanism
, key_p
);
90 (void) pthread_mutex_lock(&session_p
->session_mutex
);
91 session_p
->verify
.flags
&= ~CRYPTO_OPERATION_ACTIVE
;
98 SES_REFRELE(session_p
, lock_held
);
104 C_Verify(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
,
105 CK_BYTE_PTR pSignature
, CK_ULONG ulSignatureLen
)
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
);
121 rv
= CKR_ARGUMENTS_BAD
;
125 (void) pthread_mutex_lock(&session_p
->session_mutex
);
128 /* Application must call C_VerifyInit before calling C_Verify. */
129 if (!(session_p
->verify
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
130 SES_REFRELE(session_p
, lock_held
);
131 return (CKR_OPERATION_NOT_INITIALIZED
);
135 * C_Verify must be called without intervening C_VerifyUpdate
138 if (session_p
->verify
.flags
& CRYPTO_OPERATION_UPDATE
) {
140 * C_Verify can not be used to terminate a multi-part
141 * operation, so we'll leave the active verify operation
142 * flag on and let the application continue with the
143 * verify 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_verify(session_p
, pData
, ulDataLen
, pSignature
,
156 /* Clear context, free key, and release session counter */
157 soft_sign_verify_cleanup(session_p
, B_FALSE
, B_FALSE
);
163 C_VerifyUpdate(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pPart
,
168 soft_session_t
*session_p
;
169 boolean_t lock_held
= B_FALSE
;
171 if (!softtoken_initialized
)
172 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
174 /* Obtain the session pointer */
175 rv
= handle2session(hSession
, &session_p
);
179 if (ulPartLen
== 0) {
180 SES_REFRELE(session_p
, lock_held
);
185 rv
= CKR_ARGUMENTS_BAD
;
189 (void) pthread_mutex_lock(&session_p
->session_mutex
);
193 * Application must call C_VerifyInit before calling
196 if (!(session_p
->verify
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
197 SES_REFRELE(session_p
, lock_held
);
198 return (CKR_OPERATION_NOT_INITIALIZED
);
201 session_p
->verify
.flags
|= CRYPTO_OPERATION_UPDATE
;
203 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
206 rv
= soft_verify_update(session_p
, pPart
, ulPartLen
);
209 SES_REFRELE(session_p
, lock_held
);
214 /* After error, clear context, free key, & release session counter */
215 soft_sign_verify_cleanup(session_p
, B_FALSE
, B_FALSE
);
222 C_VerifyFinal(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pSignature
,
223 CK_ULONG ulSignatureLen
)
227 soft_session_t
*session_p
;
228 boolean_t lock_held
= B_FALSE
;
230 if (!softtoken_initialized
)
231 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
233 /* Obtain the session pointer */
234 rv
= handle2session(hSession
, &session_p
);
238 (void) pthread_mutex_lock(&session_p
->session_mutex
);
242 * Application must call C_VerifyInit before calling
245 if (!(session_p
->verify
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
246 SES_REFRELE(session_p
, lock_held
);
247 return (CKR_OPERATION_NOT_INITIALIZED
);
250 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
253 rv
= soft_verify_final(session_p
, pSignature
, ulSignatureLen
);
256 /* Clear contexts, free key, and release session counter */
257 soft_sign_verify_cleanup(session_p
, B_FALSE
, B_FALSE
);
263 C_VerifyRecoverInit(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
264 CK_OBJECT_HANDLE hKey
)
268 soft_session_t
*session_p
;
269 soft_object_t
*key_p
;
270 boolean_t lock_held
= B_FALSE
;
272 if (!softtoken_initialized
)
273 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
275 /* Obtain the session pointer. */
276 rv
= handle2session(hSession
, &session_p
);
280 if (pMechanism
== NULL
) {
281 rv
= CKR_ARGUMENTS_BAD
;
285 /* Obtain the object pointer. */
286 HANDLE2OBJECT(hKey
, key_p
, rv
);
291 /* Check to see if key object supports verify_recover. */
292 if (!(key_p
->bool_attr_mask
& VERIFY_RECOVER_BOOL_ON
)) {
293 rv
= CKR_KEY_FUNCTION_NOT_PERMITTED
;
297 (void) pthread_mutex_lock(&session_p
->session_mutex
);
300 /* Check to see if verify operation is already active. */
301 if (session_p
->verify
.flags
& CRYPTO_OPERATION_ACTIVE
) {
302 /* free the memory to avoid memory leak */
303 soft_sign_verify_cleanup(session_p
, B_FALSE
, B_TRUE
);
307 * This active flag will remain ON until application calls either
308 * C_VerifyRecover to actually obtain the recovered message.
310 session_p
->verify
.flags
= CRYPTO_OPERATION_ACTIVE
;
312 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
315 rv
= soft_verify_recover_init(session_p
, pMechanism
, key_p
);
318 (void) pthread_mutex_lock(&session_p
->session_mutex
);
319 session_p
->verify
.flags
&= ~CRYPTO_OPERATION_ACTIVE
;
326 SES_REFRELE(session_p
, lock_held
);
332 C_VerifyRecover(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pSignature
,
333 CK_ULONG ulSignatureLen
, CK_BYTE_PTR pData
, CK_ULONG_PTR pulDataLen
)
337 soft_session_t
*session_p
;
338 boolean_t lock_held
= B_FALSE
;
340 if (!softtoken_initialized
)
341 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
343 /* Obatin the session pointer */
344 rv
= handle2session(hSession
, &session_p
);
348 if ((pSignature
== NULL
) || (pulDataLen
== NULL
)) {
349 rv
= CKR_ARGUMENTS_BAD
;
353 (void) pthread_mutex_lock(&session_p
->session_mutex
);
356 if (!(session_p
->verify
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
357 SES_REFRELE(session_p
, lock_held
);
358 return (CKR_OPERATION_NOT_INITIALIZED
);
361 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
364 rv
= soft_verify_recover(session_p
, pSignature
,
365 ulSignatureLen
, pData
, pulDataLen
);
367 if ((rv
== CKR_BUFFER_TOO_SMALL
) ||
368 (pData
== NULL
&& rv
== CKR_OK
)) {
370 * We will not terminate the active verify operation flag,
371 * when the application-supplied buffer is too small, or
372 * the application asks for the length of buffer to hold
375 SES_REFRELE(session_p
, lock_held
);
380 /* Clear context, free key, and release session counter */
381 soft_sign_verify_cleanup(session_p
, B_FALSE
, B_FALSE
);