8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softDigest.c
blob56d43ba5c910568bd6358ac4beabc2c2a96c0f56
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 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <pthread.h>
27 #include <security/cryptoki.h>
28 #include "softGlobal.h"
29 #include "softOps.h"
30 #include "softSession.h"
33 CK_RV
34 C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
37 CK_RV rv;
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
46 * reference count.
48 rv = handle2session(hSession, &session_p);
49 if (rv != CKR_OK)
50 return (rv);
52 if (pMechanism == NULL) {
53 rv = CKR_ARGUMENTS_BAD;
54 goto clean_exit;
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
72 * the message digest.
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);
80 if (rv != CKR_OK) {
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);
89 return (rv);
92 clean_exit:
94 * Decrement the session reference count.
95 * We do not hold the session lock.
97 lock_held = B_FALSE;
98 SES_REFRELE(session_p, lock_held);
99 return (rv);
103 CK_RV
104 C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
105 CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
108 CK_RV rv;
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
117 * reference count.
119 rv = handle2session(hSession, &session_p);
120 if (rv != CKR_OK)
121 return (rv);
123 if (pData == NULL || pulDigestLen == NULL) {
124 rv = CKR_ARGUMENTS_BAD;
125 goto clean_exit;
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
144 * calls.
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.
176 lock_held = B_FALSE;
177 SES_REFRELE(session_p, lock_held);
178 return (rv);
181 clean_exit:
183 * Terminates the active digest operation.
184 * Application needs to call C_DigestInit again for next
185 * digest operation.
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);
198 return (rv);
202 CK_RV
203 C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
204 CK_ULONG ulPartLen)
207 CK_RV rv;
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
216 * reference count.
218 rv = handle2session(hSession, &session_p);
219 if (rv != CKR_OK)
220 return (rv);
222 if (pPart == NULL) {
223 rv = CKR_ARGUMENTS_BAD;
224 goto clean_exit;
227 /* Acquire the session lock */
228 (void) pthread_mutex_lock(&session_p->session_mutex);
231 * Application must call C_DigestInit before calling
232 * C_DigestUpdate.
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);
251 if (rv == CKR_OK) {
253 * Decrement the session reference count.
254 * We do not hold the session lock.
256 lock_held = B_FALSE;
257 SES_REFRELE(session_p, lock_held);
258 return (CKR_OK);
261 clean_exit:
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);
277 return (rv);
281 CK_RV
282 C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
285 CK_RV rv;
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
295 * reference count.
297 rv = handle2session(hSession, &session_p);
298 if (rv != CKR_OK)
299 return (rv);
301 /* Obtain the object pointer. */
302 HANDLE2OBJECT(hKey, key_p, rv);
303 if (rv != CKR_OK)
304 goto clean_exit;
306 (void) pthread_mutex_lock(&session_p->session_mutex);
309 * Application must call C_DigestInit before calling
310 * C_DigestKey.
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.
318 OBJ_REFRELE(key_p);
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);
334 if (rv == CKR_OK) {
336 * Decrement the session reference count.
337 * We do not hold the session lock.
339 lock_held = B_FALSE;
340 OBJ_REFRELE(key_p);
341 SES_REFRELE(session_p, lock_held);
342 return (CKR_OK);
345 OBJ_REFRELE(key_p);
346 clean_exit:
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);
361 return (rv);
365 CK_RV
366 C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
367 CK_ULONG_PTR pulDigestLen)
370 CK_RV rv;
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
379 * reference count.
381 rv = handle2session(hSession, &session_p);
382 if (rv != CKR_OK)
383 return (rv);
385 if (pulDigestLen == NULL) {
386 rv = CKR_ARGUMENTS_BAD;
387 goto clean_exit;
390 /* Acquire the session lock */
391 (void) pthread_mutex_lock(&session_p->session_mutex);
394 * Application must call C_DigestInit before calling
395 * C_DigestFinal.
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.
422 lock_held = B_FALSE;
423 SES_REFRELE(session_p, lock_held);
424 return (rv);
427 clean_exit:
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);
440 return (rv);