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 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include <security/cryptoki.h>
28 #include "softGlobal.h"
30 #include "softSession.h"
34 C_DigestInit(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
)
38 soft_session_t
*session_p
;
39 boolean_t lock_held
= B_TRUE
;
41 if (!softtoken_initialized
)
42 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
45 * Obtain the session pointer. Also, increment the session
48 rv
= handle2session(hSession
, &session_p
);
52 if (pMechanism
== NULL
) {
53 rv
= CKR_ARGUMENTS_BAD
;
57 /* Acquire the session lock */
58 (void) pthread_mutex_lock(&session_p
->session_mutex
);
60 /* Check to see if digest operation is already active */
61 if (session_p
->digest
.flags
& CRYPTO_OPERATION_ACTIVE
) {
63 * Free the memory to avoid memory leak.
64 * digest.context is only a flat structure.
66 soft_digest_cleanup(session_p
, lock_held
);
70 * This active flag will remain ON until application calls either
71 * C_Digest or C_DigestFinal to actually obtain the value of
74 session_p
->digest
.flags
= CRYPTO_OPERATION_ACTIVE
;
76 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
78 rv
= soft_digest_init(session_p
, pMechanism
);
81 (void) pthread_mutex_lock(&session_p
->session_mutex
);
82 session_p
->digest
.flags
&= ~CRYPTO_OPERATION_ACTIVE
;
84 * Decrement the session reference count.
85 * We hold the session lock, and SES_REFRELE()
86 * will release the session lock for us.
88 SES_REFRELE(session_p
, lock_held
);
94 * Decrement the session reference count.
95 * We do not hold the session lock.
98 SES_REFRELE(session_p
, lock_held
);
104 C_Digest(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
,
105 CK_BYTE_PTR pDigest
, CK_ULONG_PTR pulDigestLen
)
109 soft_session_t
*session_p
;
110 boolean_t lock_held
= B_TRUE
;
112 if (!softtoken_initialized
)
113 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
116 * Obtain the session pointer. Also, increment the session
119 rv
= handle2session(hSession
, &session_p
);
123 if (pData
== NULL
|| pulDigestLen
== NULL
) {
124 rv
= CKR_ARGUMENTS_BAD
;
128 /* Acquire the session lock */
129 (void) pthread_mutex_lock(&session_p
->session_mutex
);
131 /* Application must call C_DigestInit before calling C_Digest */
132 if (!(session_p
->digest
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
134 * Decrement the session reference count.
135 * We hold the session lock, and SES_REFRELE()
136 * will release the session lock for us.
138 SES_REFRELE(session_p
, lock_held
);
139 return (CKR_OPERATION_NOT_INITIALIZED
);
143 * C_Digest must be called without intervening C_DigestUpdate
146 if (session_p
->digest
.flags
& CRYPTO_OPERATION_UPDATE
) {
148 * C_Digest can not be used to terminate a multi-part
149 * operation, so we'll leave the active digest operation
150 * flag on and let the application continue with the
151 * digest update operation.
153 * Decrement the session reference count.
154 * We hold the session lock, and SES_REFRELE()
155 * will release the session lock for us.
157 SES_REFRELE(session_p
, lock_held
);
158 return (CKR_FUNCTION_FAILED
);
161 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
163 rv
= soft_digest(session_p
, pData
, ulDataLen
, pDigest
, pulDigestLen
);
165 if ((rv
== CKR_BUFFER_TOO_SMALL
) ||
166 (pDigest
== NULL
&& rv
== CKR_OK
)) {
168 * We will not terminate the active digest operation flag,
169 * when the application-supplied buffer is too small, or
170 * the application asks for the length of buffer to hold
171 * the message digest.
173 * Decrement the session reference count.
174 * We do not hold the session lock.
177 SES_REFRELE(session_p
, lock_held
);
183 * Terminates the active digest operation.
184 * Application needs to call C_DigestInit again for next
187 (void) pthread_mutex_lock(&session_p
->session_mutex
);
189 soft_digest_cleanup(session_p
, lock_held
);
192 * Decrement the session reference count.
193 * We hold the session lock, and SES_REFRELE()
194 * will release the session lock for us.
196 SES_REFRELE(session_p
, lock_held
);
203 C_DigestUpdate(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pPart
,
208 soft_session_t
*session_p
;
209 boolean_t lock_held
= B_TRUE
;
211 if (!softtoken_initialized
)
212 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
215 * Obtain the session pointer. Also, increment the session
218 rv
= handle2session(hSession
, &session_p
);
223 rv
= CKR_ARGUMENTS_BAD
;
227 /* Acquire the session lock */
228 (void) pthread_mutex_lock(&session_p
->session_mutex
);
231 * Application must call C_DigestInit before calling
234 if (!(session_p
->digest
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
236 * Decrement the session reference count.
237 * We hold the session lock, and SES_REFRELE()
238 * will release the session lock for us.
240 SES_REFRELE(session_p
, lock_held
);
241 return (CKR_OPERATION_NOT_INITIALIZED
);
244 /* Set update flag to protect C_Digest */
245 session_p
->digest
.flags
|= CRYPTO_OPERATION_UPDATE
;
247 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
249 rv
= soft_digest_update(session_p
, pPart
, ulPartLen
);
253 * Decrement the session reference count.
254 * We do not hold the session lock.
257 SES_REFRELE(session_p
, lock_held
);
263 * After an error occurred, terminate the current digest
264 * operation by resetting the active and update flags.
266 (void) pthread_mutex_lock(&session_p
->session_mutex
);
268 soft_digest_cleanup(session_p
, lock_held
);
271 * Decrement the session reference count.
272 * We hold the session lock, and SES_REFRELE()
273 * will release the session lock for us.
275 SES_REFRELE(session_p
, lock_held
);
282 C_DigestKey(CK_SESSION_HANDLE hSession
, CK_OBJECT_HANDLE hKey
)
286 soft_session_t
*session_p
;
287 soft_object_t
*key_p
;
288 boolean_t lock_held
= B_TRUE
;
290 if (!softtoken_initialized
)
291 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
294 * Obtain the session pointer. Also, increment the session
297 rv
= handle2session(hSession
, &session_p
);
301 /* Obtain the object pointer. */
302 HANDLE2OBJECT(hKey
, key_p
, rv
);
306 (void) pthread_mutex_lock(&session_p
->session_mutex
);
309 * Application must call C_DigestInit before calling
312 if (!(session_p
->digest
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
314 * Decrement the session reference count.
315 * We hold the session lock, and SES_REFRELE()
316 * will release the session lock for us.
319 SES_REFRELE(session_p
, lock_held
);
320 return (CKR_OPERATION_NOT_INITIALIZED
);
324 * Remember the fact that a key was thrown into the mix, so that
325 * C_DigestFinal bzero()'s the digest context before freeing it.
327 session_p
->digest
.flags
|= (CRYPTO_KEY_DIGESTED
|
328 CRYPTO_OPERATION_UPDATE
);
330 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
332 rv
= soft_digest_key(session_p
, key_p
);
336 * Decrement the session reference count.
337 * We do not hold the session lock.
341 SES_REFRELE(session_p
, lock_held
);
348 * After an error occurred, terminate the current digest
349 * operation by resetting the active and update flags.
351 (void) pthread_mutex_lock(&session_p
->session_mutex
);
353 soft_digest_cleanup(session_p
, lock_held
);
356 * Decrement the session reference count.
357 * We hold the session lock, and SES_REFRELE()
358 * will release the session lock for us.
360 SES_REFRELE(session_p
, lock_held
);
366 C_DigestFinal(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pDigest
,
367 CK_ULONG_PTR pulDigestLen
)
371 soft_session_t
*session_p
;
372 boolean_t lock_held
= B_TRUE
;
374 if (!softtoken_initialized
)
375 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
378 * Obtain the session pointer. Also, increment the session
381 rv
= handle2session(hSession
, &session_p
);
385 if (pulDigestLen
== NULL
) {
386 rv
= CKR_ARGUMENTS_BAD
;
390 /* Acquire the session lock */
391 (void) pthread_mutex_lock(&session_p
->session_mutex
);
394 * Application must call C_DigestInit before calling
397 if (!(session_p
->digest
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
399 * Decrement the session reference count.
400 * We hold the session lock, and SES_REFRELE()
401 * will release the session lock for us.
403 SES_REFRELE(session_p
, lock_held
);
404 return (CKR_OPERATION_NOT_INITIALIZED
);
407 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
409 rv
= soft_digest_final(session_p
, pDigest
, pulDigestLen
);
411 if ((rv
== CKR_BUFFER_TOO_SMALL
) ||
412 (pDigest
== NULL
&& rv
== CKR_OK
)) {
414 * We will not terminate the active digest operation flag,
415 * when the application-supplied buffer is too small, or
416 * the application asks for the length of buffer to hold
417 * the message digest.
419 * Decrement the session reference count.
420 * We do not hold the session lock.
423 SES_REFRELE(session_p
, lock_held
);
428 /* Terminates the active digest operation */
429 (void) pthread_mutex_lock(&session_p
->session_mutex
);
431 soft_digest_cleanup(session_p
, lock_held
);
434 * Decrement the session reference count.
435 * We hold the session lock, and SES_REFRELE()
436 * will release the session lock for us.
438 SES_REFRELE(session_p
, lock_held
);