17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f243d98aSkrishna * Common Development and Distribution License (the "License"). 6f243d98aSkrishna * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22d288ba74SAnthony Scarpino * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <md5.h> 277c478bd9Sstevel@tonic-gate #include <pthread.h> 287c478bd9Sstevel@tonic-gate #include <syslog.h> 297c478bd9Sstevel@tonic-gate #include <stdlib.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <strings.h> 327c478bd9Sstevel@tonic-gate #include <sys/sha1.h> 337c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 347c478bd9Sstevel@tonic-gate #include "softGlobal.h" 357c478bd9Sstevel@tonic-gate #include "softSession.h" 367c478bd9Sstevel@tonic-gate #include "softObject.h" 377c478bd9Sstevel@tonic-gate #include "softOps.h" 387c478bd9Sstevel@tonic-gate #include "softKeystore.h" 397c478bd9Sstevel@tonic-gate #include "softKeystoreUtil.h" 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate CK_ULONG soft_session_cnt = 0; /* the number of opened sessions */ 437c478bd9Sstevel@tonic-gate CK_ULONG soft_session_rw_cnt = 0; /* the number of opened R/W sessions */ 447c478bd9Sstevel@tonic-gate 45588a1af0SAlexandr Nedvedicky #define DIGEST_MECH_OK(_m_) ((_m_) == CKM_MD5 || (_m_) == CKM_SHA_1) 46588a1af0SAlexandr Nedvedicky 477c478bd9Sstevel@tonic-gate /* 487c478bd9Sstevel@tonic-gate * Delete all the sessions. First, obtain the global session 497c478bd9Sstevel@tonic-gate * list lock. Then start to delete one session at a time. 507c478bd9Sstevel@tonic-gate * Release the global session list lock before returning to 517c478bd9Sstevel@tonic-gate * caller. 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate CK_RV 54a62b4373Sdarrenm soft_delete_all_sessions(boolean_t force) 557c478bd9Sstevel@tonic-gate { 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 587c478bd9Sstevel@tonic-gate CK_RV rv1; 597c478bd9Sstevel@tonic-gate soft_session_t *session_p; 607c478bd9Sstevel@tonic-gate soft_session_t *session_p1; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* Acquire the global session list lock */ 637c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_sessionlist_mutex); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate session_p = soft_session_list; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* Delete all the sessions in the session list */ 687c478bd9Sstevel@tonic-gate while (session_p) { 697c478bd9Sstevel@tonic-gate session_p1 = session_p->next; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate /* 727c478bd9Sstevel@tonic-gate * Delete a session by calling soft_delete_session() 737c478bd9Sstevel@tonic-gate * with a session pointer and a boolean arguments. 747c478bd9Sstevel@tonic-gate * Boolean value TRUE is used to indicate that the 757c478bd9Sstevel@tonic-gate * caller holds the lock on the global session list. 76a62b4373Sdarrenm * 777c478bd9Sstevel@tonic-gate */ 78a62b4373Sdarrenm rv1 = soft_delete_session(session_p, force, B_TRUE); 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* Record the very first error code */ 817c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 827c478bd9Sstevel@tonic-gate rv = rv1; 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate session_p = session_p1; 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* No session left */ 897c478bd9Sstevel@tonic-gate soft_session_list = NULL; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate /* Release the global session list lock */ 927c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_sessionlist_mutex); 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate return (rv); 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * Create a new session struct, and add it to the session linked list. 1017c478bd9Sstevel@tonic-gate * 1027c478bd9Sstevel@tonic-gate * This function will acquire the global session list lock, and release 1037c478bd9Sstevel@tonic-gate * it after adding the session to the session linked list. 1047c478bd9Sstevel@tonic-gate */ 1057c478bd9Sstevel@tonic-gate CK_RV 1067c478bd9Sstevel@tonic-gate soft_add_session(CK_FLAGS flags, CK_VOID_PTR pApplication, 1077c478bd9Sstevel@tonic-gate CK_NOTIFY notify, CK_ULONG *sessionhandle_p) 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate soft_session_t *new_sp = NULL; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate /* Allocate a new session struct */ 1137c478bd9Sstevel@tonic-gate new_sp = calloc(1, sizeof (soft_session_t)); 1147c478bd9Sstevel@tonic-gate if (new_sp == NULL) { 1157c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate new_sp->magic_marker = SOFTTOKEN_SESSION_MAGIC; 1197c478bd9Sstevel@tonic-gate new_sp->pApplication = pApplication; 1207c478bd9Sstevel@tonic-gate new_sp->Notify = notify; 1217c478bd9Sstevel@tonic-gate new_sp->flags = flags; 1227c478bd9Sstevel@tonic-gate new_sp->state = CKS_RO_PUBLIC_SESSION; 1237c478bd9Sstevel@tonic-gate new_sp->object_list = NULL; 1247c478bd9Sstevel@tonic-gate new_sp->ses_refcnt = 0; 1257c478bd9Sstevel@tonic-gate new_sp->ses_close_sync = 0; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_giant_mutex); 1287c478bd9Sstevel@tonic-gate if (soft_slot.authenticated) { 1297c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 1307c478bd9Sstevel@tonic-gate if (flags & CKF_RW_SESSION) { 1317c478bd9Sstevel@tonic-gate new_sp->state = CKS_RW_USER_FUNCTIONS; 1327c478bd9Sstevel@tonic-gate } else { 1337c478bd9Sstevel@tonic-gate new_sp->state = CKS_RO_USER_FUNCTIONS; 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate } else { 1367c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 1377c478bd9Sstevel@tonic-gate if (flags & CKF_RW_SESSION) { 1387c478bd9Sstevel@tonic-gate new_sp->state = CKS_RW_PUBLIC_SESSION; 1397c478bd9Sstevel@tonic-gate } else { 1407c478bd9Sstevel@tonic-gate new_sp->state = CKS_RO_PUBLIC_SESSION; 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate /* Initialize the lock for the newly created session */ 1457c478bd9Sstevel@tonic-gate if (pthread_mutex_init(&new_sp->session_mutex, NULL) != 0) { 1467c478bd9Sstevel@tonic-gate free(new_sp); 1477c478bd9Sstevel@tonic-gate return (CKR_CANT_LOCK); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate (void) pthread_cond_init(&new_sp->ses_free_cond, NULL); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate /* Acquire the global session list lock */ 1537c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_sessionlist_mutex); 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate /* Insert the new session in front of session list */ 1567c478bd9Sstevel@tonic-gate if (soft_session_list == NULL) { 1577c478bd9Sstevel@tonic-gate soft_session_list = new_sp; 1587c478bd9Sstevel@tonic-gate new_sp->next = NULL; 1597c478bd9Sstevel@tonic-gate new_sp->prev = NULL; 1607c478bd9Sstevel@tonic-gate } else { 1617c478bd9Sstevel@tonic-gate soft_session_list->prev = new_sp; 1627c478bd9Sstevel@tonic-gate new_sp->next = soft_session_list; 1637c478bd9Sstevel@tonic-gate new_sp->prev = NULL; 1647c478bd9Sstevel@tonic-gate soft_session_list = new_sp; 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* Type casting the address of a session struct to a session handle */ 1687c478bd9Sstevel@tonic-gate *sessionhandle_p = (CK_ULONG)new_sp; 1697c478bd9Sstevel@tonic-gate ++soft_session_cnt; 1707c478bd9Sstevel@tonic-gate if (flags & CKF_RW_SESSION) 1717c478bd9Sstevel@tonic-gate ++soft_session_rw_cnt; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate if (soft_session_cnt == 1) 1747c478bd9Sstevel@tonic-gate /* 1757c478bd9Sstevel@tonic-gate * This is the first session to be opened, so we can set 1767c478bd9Sstevel@tonic-gate * validate the public token objects in token list now. 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate soft_validate_token_objects(B_TRUE); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* Release the global session list lock */ 1817c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_sessionlist_mutex); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate return (CKR_OK); 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate /* 1887c478bd9Sstevel@tonic-gate * This function adds the to-be-freed session to a linked list. 1897c478bd9Sstevel@tonic-gate * When the number of sessions queued in the linked list reaches the 1907c478bd9Sstevel@tonic-gate * maximum threshold MAX_SES_TO_BE_FREED, it will free the first 1917c478bd9Sstevel@tonic-gate * session (FIFO) in the list. 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate void 1947c478bd9Sstevel@tonic-gate session_delay_free(soft_session_t *sp) 1957c478bd9Sstevel@tonic-gate { 1967c478bd9Sstevel@tonic-gate soft_session_t *tmp; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&ses_delay_freed.ses_to_be_free_mutex); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* Add the newly deleted session at the end of the list */ 2017c478bd9Sstevel@tonic-gate sp->next = NULL; 2027c478bd9Sstevel@tonic-gate if (ses_delay_freed.first == NULL) { 2037c478bd9Sstevel@tonic-gate ses_delay_freed.last = sp; 2047c478bd9Sstevel@tonic-gate ses_delay_freed.first = sp; 2057c478bd9Sstevel@tonic-gate } else { 2067c478bd9Sstevel@tonic-gate ses_delay_freed.last->next = sp; 2077c478bd9Sstevel@tonic-gate ses_delay_freed.last = sp; 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate if (++ses_delay_freed.count >= MAX_SES_TO_BE_FREED) { 2117c478bd9Sstevel@tonic-gate /* 2127c478bd9Sstevel@tonic-gate * Free the first session in the list only if 2137c478bd9Sstevel@tonic-gate * the total count reaches maximum threshold. 2147c478bd9Sstevel@tonic-gate */ 2157c478bd9Sstevel@tonic-gate ses_delay_freed.count--; 2167c478bd9Sstevel@tonic-gate tmp = ses_delay_freed.first->next; 2177c478bd9Sstevel@tonic-gate free(ses_delay_freed.first); 2187c478bd9Sstevel@tonic-gate ses_delay_freed.first = tmp; 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&ses_delay_freed.ses_to_be_free_mutex); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate /* 2247c478bd9Sstevel@tonic-gate * Delete a session: 2257c478bd9Sstevel@tonic-gate * - Remove the session from the session linked list. 2267c478bd9Sstevel@tonic-gate * Holding the lock on the global session list is needed to do this. 2277c478bd9Sstevel@tonic-gate * - Release all the objects created by the session. 2287c478bd9Sstevel@tonic-gate * 2297c478bd9Sstevel@tonic-gate * The boolean argument lock_held is used to indicate that whether 2307c478bd9Sstevel@tonic-gate * the caller of this function holds the lock on the global session 2317c478bd9Sstevel@tonic-gate * list or not. 2327c478bd9Sstevel@tonic-gate * - When called by soft_delete_all_sessions(), which is called by 2337c478bd9Sstevel@tonic-gate * C_Finalize() or C_CloseAllSessions() -- the lock_held = TRUE. 2347c478bd9Sstevel@tonic-gate * - When called by C_CloseSession() -- the lock_held = FALSE. 2357c478bd9Sstevel@tonic-gate * 2367c478bd9Sstevel@tonic-gate * When the caller does not hold the lock on the global session 2377c478bd9Sstevel@tonic-gate * list, this function will acquire that lock in order to proceed, 2387c478bd9Sstevel@tonic-gate * and also release that lock before returning to caller. 2397c478bd9Sstevel@tonic-gate */ 2407c478bd9Sstevel@tonic-gate CK_RV 241a62b4373Sdarrenm soft_delete_session(soft_session_t *session_p, 242a62b4373Sdarrenm boolean_t force, boolean_t lock_held) 2437c478bd9Sstevel@tonic-gate { 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* 2467c478bd9Sstevel@tonic-gate * Check to see if the caller holds the lock on the global 2477c478bd9Sstevel@tonic-gate * session list. If not, we need to acquire that lock in 2487c478bd9Sstevel@tonic-gate * order to proceed. 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate if (!lock_held) { 2517c478bd9Sstevel@tonic-gate /* Acquire the global session list lock */ 2527c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_sessionlist_mutex); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate /* 2567c478bd9Sstevel@tonic-gate * Remove the session from the session linked list first. 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate if (soft_session_list == session_p) { 2597c478bd9Sstevel@tonic-gate /* Session is the first one in the list */ 2607c478bd9Sstevel@tonic-gate if (session_p->next) { 2617c478bd9Sstevel@tonic-gate soft_session_list = session_p->next; 2627c478bd9Sstevel@tonic-gate session_p->next->prev = NULL; 2637c478bd9Sstevel@tonic-gate } else { 2647c478bd9Sstevel@tonic-gate /* Session is the only one in the list */ 2657c478bd9Sstevel@tonic-gate soft_session_list = NULL; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate } else { 2687c478bd9Sstevel@tonic-gate /* Session is not the first one in the list */ 2697c478bd9Sstevel@tonic-gate if (session_p->next) { 2707c478bd9Sstevel@tonic-gate /* Session is in the middle of the list */ 2717c478bd9Sstevel@tonic-gate session_p->prev->next = session_p->next; 2727c478bd9Sstevel@tonic-gate session_p->next->prev = session_p->prev; 2737c478bd9Sstevel@tonic-gate } else { 2747c478bd9Sstevel@tonic-gate /* Session is the last one in the list */ 2757c478bd9Sstevel@tonic-gate session_p->prev->next = NULL; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate --soft_session_cnt; 2807c478bd9Sstevel@tonic-gate if (session_p->flags & CKF_RW_SESSION) 2817c478bd9Sstevel@tonic-gate --soft_session_rw_cnt; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate if (!lock_held) { 2847c478bd9Sstevel@tonic-gate /* 2857c478bd9Sstevel@tonic-gate * If the global session list lock is obtained by 2867c478bd9Sstevel@tonic-gate * this function, then release that lock after 2877c478bd9Sstevel@tonic-gate * removing the session from session linked list. 2887c478bd9Sstevel@tonic-gate * We want the releasing of the objects of the 2897c478bd9Sstevel@tonic-gate * session, and freeing of the session itself to 2907c478bd9Sstevel@tonic-gate * be done without holding the global session list 2917c478bd9Sstevel@tonic-gate * lock. 2927c478bd9Sstevel@tonic-gate */ 2937c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_sessionlist_mutex); 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /* Acquire the individual session lock */ 2987c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 2997c478bd9Sstevel@tonic-gate /* 3007c478bd9Sstevel@tonic-gate * Make sure another thread hasn't freed the session. 3017c478bd9Sstevel@tonic-gate */ 3027c478bd9Sstevel@tonic-gate if (session_p->magic_marker != SOFTTOKEN_SESSION_MAGIC) { 3037c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 3047c478bd9Sstevel@tonic-gate return (CKR_OK); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate /* 3087c478bd9Sstevel@tonic-gate * The deletion of a session must be blocked when the session 3097c478bd9Sstevel@tonic-gate * reference count is not zero. This means if any session related 3107c478bd9Sstevel@tonic-gate * operation starts prior to the session close operation gets in, 3117c478bd9Sstevel@tonic-gate * the session closing thread must wait for the non-closing 3127c478bd9Sstevel@tonic-gate * operation to be completed before it can proceed the close 3137c478bd9Sstevel@tonic-gate * operation. 314a62b4373Sdarrenm * 315a62b4373Sdarrenm * Unless we are being forced to shut everything down, this only 316a62b4373Sdarrenm * happens if the libraries _fini() is running not of someone 317a62b4373Sdarrenm * explicitly called C_Finalize(). 3187c478bd9Sstevel@tonic-gate */ 319a62b4373Sdarrenm if (force) 320a62b4373Sdarrenm session_p->ses_refcnt = 0; 321a62b4373Sdarrenm 3227c478bd9Sstevel@tonic-gate while (session_p->ses_refcnt != 0) { 3237c478bd9Sstevel@tonic-gate /* 3247c478bd9Sstevel@tonic-gate * We set the SESSION_REFCNT_WAITING flag before we put 3257c478bd9Sstevel@tonic-gate * this closing thread in a wait state, so other non-closing 3267c478bd9Sstevel@tonic-gate * operation thread will signal to wake it up only when 3277c478bd9Sstevel@tonic-gate * the session reference count becomes zero and this flag 3287c478bd9Sstevel@tonic-gate * is set. 3297c478bd9Sstevel@tonic-gate */ 3307c478bd9Sstevel@tonic-gate session_p->ses_close_sync |= SESSION_REFCNT_WAITING; 3317c478bd9Sstevel@tonic-gate (void) pthread_cond_wait(&session_p->ses_free_cond, 3327c478bd9Sstevel@tonic-gate &session_p->session_mutex); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate session_p->ses_close_sync &= ~SESSION_REFCNT_WAITING; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate /* 3387c478bd9Sstevel@tonic-gate * Remove all the objects created in this session. 3397c478bd9Sstevel@tonic-gate */ 3401f49a79aSZdenek Kotala soft_delete_all_objects_in_session(session_p, force); 3417c478bd9Sstevel@tonic-gate 342429cc41dSVladimir Kotal /* 343429cc41dSVladimir Kotal * Mark session as no longer valid. This can only be done after all 344429cc41dSVladimir Kotal * objects created by this session are free'd since the marker is 345429cc41dSVladimir Kotal * still needed in the process of removing objects from the session. 346429cc41dSVladimir Kotal */ 347429cc41dSVladimir Kotal session_p->magic_marker = 0; 348429cc41dSVladimir Kotal 349429cc41dSVladimir Kotal (void) pthread_cond_destroy(&session_p->ses_free_cond); 350429cc41dSVladimir Kotal 3517c478bd9Sstevel@tonic-gate /* In case application did not call Final */ 3527c478bd9Sstevel@tonic-gate if (session_p->digest.context != NULL) 3537c478bd9Sstevel@tonic-gate free(session_p->digest.context); 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate if (session_p->encrypt.context != NULL) 3567c478bd9Sstevel@tonic-gate /* 3577c478bd9Sstevel@tonic-gate * 1st B_TRUE: encrypt 3587c478bd9Sstevel@tonic-gate * 2nd B_TRUE: caller is holding session_mutex. 3597c478bd9Sstevel@tonic-gate */ 3607c478bd9Sstevel@tonic-gate soft_crypt_cleanup(session_p, B_TRUE, B_TRUE); 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate if (session_p->decrypt.context != NULL) 3637c478bd9Sstevel@tonic-gate /* 3647c478bd9Sstevel@tonic-gate * 1st B_FALSE: decrypt 3657c478bd9Sstevel@tonic-gate * 2nd B_TRUE: caller is holding session_mutex. 3667c478bd9Sstevel@tonic-gate */ 3677c478bd9Sstevel@tonic-gate soft_crypt_cleanup(session_p, B_FALSE, B_TRUE); 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate if (session_p->sign.context != NULL) 3707c478bd9Sstevel@tonic-gate free(session_p->sign.context); 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate if (session_p->verify.context != NULL) 3737c478bd9Sstevel@tonic-gate free(session_p->verify.context); 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate if (session_p->find_objects.context != NULL) { 3767c478bd9Sstevel@tonic-gate find_context_t *fcontext; 3777c478bd9Sstevel@tonic-gate fcontext = (find_context_t *)session_p->find_objects.context; 3787c478bd9Sstevel@tonic-gate free(fcontext->objs_found); 3797c478bd9Sstevel@tonic-gate free(fcontext); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate /* Reset SESSION_IS_CLOSIN flag. */ 3837c478bd9Sstevel@tonic-gate session_p->ses_close_sync &= ~SESSION_IS_CLOSING; 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 3867c478bd9Sstevel@tonic-gate /* Destroy the individual session lock */ 3877c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&session_p->session_mutex); 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* Delay freeing the session */ 3907c478bd9Sstevel@tonic-gate session_delay_free(session_p); 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate return (CKR_OK); 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate /* 3977c478bd9Sstevel@tonic-gate * This function is used to type cast a session handle to a pointer to 3987c478bd9Sstevel@tonic-gate * the session struct. Also, it does the following things: 3997c478bd9Sstevel@tonic-gate * 1) Check to see if the session struct is tagged with a session 4007c478bd9Sstevel@tonic-gate * magic number. This is to detect when an application passes 4017c478bd9Sstevel@tonic-gate * a bogus session pointer. 402f243d98aSkrishna * 2) Acquire the lock on the designated session. 4037c478bd9Sstevel@tonic-gate * 3) Check to see if the session is in the closing state that another 4047c478bd9Sstevel@tonic-gate * thread is performing. 4057c478bd9Sstevel@tonic-gate * 4) Increment the session reference count by one. This is to prevent 4067c478bd9Sstevel@tonic-gate * this session from being closed by other thread. 407f243d98aSkrishna * 5) Release the lock held on the designated session. 4087c478bd9Sstevel@tonic-gate */ 4097c478bd9Sstevel@tonic-gate CK_RV 4107c478bd9Sstevel@tonic-gate handle2session(CK_SESSION_HANDLE hSession, soft_session_t **session_p) 4117c478bd9Sstevel@tonic-gate { 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate soft_session_t *sp = (soft_session_t *)(hSession); 4147c478bd9Sstevel@tonic-gate 415f243d98aSkrishna /* 416f243d98aSkrishna * No need to hold soft_sessionlist_mutex as we are 417f243d98aSkrishna * just reading the value and 32-bit reads are atomic. 418f243d98aSkrishna */ 4197c478bd9Sstevel@tonic-gate if (all_sessions_closing) { 4207c478bd9Sstevel@tonic-gate return (CKR_SESSION_CLOSED); 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate if ((sp == NULL) || 4247c478bd9Sstevel@tonic-gate (sp->magic_marker != SOFTTOKEN_SESSION_MAGIC)) { 4257c478bd9Sstevel@tonic-gate return (CKR_SESSION_HANDLE_INVALID); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&sp->session_mutex); 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate if (sp->ses_close_sync & SESSION_IS_CLOSING) { 4307c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&sp->session_mutex); 4317c478bd9Sstevel@tonic-gate return (CKR_SESSION_CLOSED); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /* Increment session ref count. */ 4357c478bd9Sstevel@tonic-gate sp->ses_refcnt++; 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&sp->session_mutex); 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate *session_p = sp; 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate return (CKR_OK); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate /* 4457c478bd9Sstevel@tonic-gate * The format to be saved in the pOperationState will be: 4467c478bd9Sstevel@tonic-gate * 1. internal_op_state_t 4477c478bd9Sstevel@tonic-gate * 2. crypto_active_op_t 4487c478bd9Sstevel@tonic-gate * 3. actual context of the active operation 4497c478bd9Sstevel@tonic-gate */ 4507c478bd9Sstevel@tonic-gate CK_RV 4517c478bd9Sstevel@tonic-gate soft_get_operationstate(soft_session_t *session_p, CK_BYTE_PTR pOperationState, 4527c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulOperationStateLen) 4537c478bd9Sstevel@tonic-gate { 4547c478bd9Sstevel@tonic-gate 455588a1af0SAlexandr Nedvedicky internal_op_state_t *p_op_state; 4567c478bd9Sstevel@tonic-gate CK_ULONG op_data_len = 0; 457588a1af0SAlexandr Nedvedicky CK_RV rv = CKR_OK; 458588a1af0SAlexandr Nedvedicky 459588a1af0SAlexandr Nedvedicky if (pulOperationStateLen == NULL) 460588a1af0SAlexandr Nedvedicky return (CKR_ARGUMENTS_BAD); 461588a1af0SAlexandr Nedvedicky 462588a1af0SAlexandr Nedvedicky (void) pthread_mutex_lock(&session_p->session_mutex); 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate /* Check to see if encrypt operation is active. */ 4657c478bd9Sstevel@tonic-gate if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) { 466588a1af0SAlexandr Nedvedicky rv = CKR_STATE_UNSAVEABLE; 467588a1af0SAlexandr Nedvedicky goto unlock_session; 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate /* Check to see if decrypt operation is active. */ 4717c478bd9Sstevel@tonic-gate if (session_p->decrypt.flags & CRYPTO_OPERATION_ACTIVE) { 472588a1af0SAlexandr Nedvedicky rv = CKR_STATE_UNSAVEABLE; 473588a1af0SAlexandr Nedvedicky goto unlock_session; 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate /* Check to see if sign operation is active. */ 4777c478bd9Sstevel@tonic-gate if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) { 478588a1af0SAlexandr Nedvedicky rv = CKR_STATE_UNSAVEABLE; 479588a1af0SAlexandr Nedvedicky goto unlock_session; 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate /* Check to see if verify operation is active. */ 4837c478bd9Sstevel@tonic-gate if (session_p->verify.flags & CRYPTO_OPERATION_ACTIVE) { 484588a1af0SAlexandr Nedvedicky rv = CKR_STATE_UNSAVEABLE; 485588a1af0SAlexandr Nedvedicky goto unlock_session; 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate /* Check to see if digest operation is active. */ 4897c478bd9Sstevel@tonic-gate if (session_p->digest.flags & CRYPTO_OPERATION_ACTIVE) { 4907c478bd9Sstevel@tonic-gate op_data_len = sizeof (internal_op_state_t) + 4917c478bd9Sstevel@tonic-gate sizeof (crypto_active_op_t); 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate switch (session_p->digest.mech.mechanism) { 4947c478bd9Sstevel@tonic-gate case CKM_MD5: 4957c478bd9Sstevel@tonic-gate op_data_len += sizeof (MD5_CTX); 4967c478bd9Sstevel@tonic-gate break; 4977c478bd9Sstevel@tonic-gate case CKM_SHA_1: 4987c478bd9Sstevel@tonic-gate op_data_len += sizeof (SHA1_CTX); 4997c478bd9Sstevel@tonic-gate break; 5007c478bd9Sstevel@tonic-gate default: 501588a1af0SAlexandr Nedvedicky rv = CKR_STATE_UNSAVEABLE; 502588a1af0SAlexandr Nedvedicky goto unlock_session; 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate if (pOperationState == NULL_PTR) { 5067c478bd9Sstevel@tonic-gate *pulOperationStateLen = op_data_len; 507588a1af0SAlexandr Nedvedicky goto unlock_session; 5087c478bd9Sstevel@tonic-gate } else { 5097c478bd9Sstevel@tonic-gate if (*pulOperationStateLen < op_data_len) { 5107c478bd9Sstevel@tonic-gate *pulOperationStateLen = op_data_len; 511588a1af0SAlexandr Nedvedicky rv = CKR_BUFFER_TOO_SMALL; 512588a1af0SAlexandr Nedvedicky goto unlock_session; 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate /* Save internal_op_state_t */ 517588a1af0SAlexandr Nedvedicky /* LINTED E_BAD_PTR_CAST_ALIGN */ 518588a1af0SAlexandr Nedvedicky p_op_state = (internal_op_state_t *)pOperationState; 519588a1af0SAlexandr Nedvedicky p_op_state->op_len = op_data_len; 520588a1af0SAlexandr Nedvedicky p_op_state->op_active = DIGEST_OP; 521588a1af0SAlexandr Nedvedicky p_op_state->op_session_state = session_p->state; 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate /* Save crypto_active_op_t */ 5247c478bd9Sstevel@tonic-gate (void) memcpy((CK_BYTE *)pOperationState + 5257c478bd9Sstevel@tonic-gate sizeof (internal_op_state_t), 5267c478bd9Sstevel@tonic-gate &session_p->digest, 5277c478bd9Sstevel@tonic-gate sizeof (crypto_active_op_t)); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate switch (session_p->digest.mech.mechanism) { 5307c478bd9Sstevel@tonic-gate case CKM_MD5: 5317c478bd9Sstevel@tonic-gate /* Save MD5_CTX for the active digest operation */ 5327c478bd9Sstevel@tonic-gate (void) memcpy((CK_BYTE *)pOperationState + 5337c478bd9Sstevel@tonic-gate sizeof (internal_op_state_t) + 5347c478bd9Sstevel@tonic-gate sizeof (crypto_active_op_t), 5357c478bd9Sstevel@tonic-gate session_p->digest.context, 5367c478bd9Sstevel@tonic-gate sizeof (MD5_CTX)); 5377c478bd9Sstevel@tonic-gate break; 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate case CKM_SHA_1: 5407c478bd9Sstevel@tonic-gate /* Save SHA1_CTX for the active digest operation */ 5417c478bd9Sstevel@tonic-gate (void) memcpy((CK_BYTE *)pOperationState + 5427c478bd9Sstevel@tonic-gate sizeof (internal_op_state_t) + 5437c478bd9Sstevel@tonic-gate sizeof (crypto_active_op_t), 5447c478bd9Sstevel@tonic-gate session_p->digest.context, 5457c478bd9Sstevel@tonic-gate sizeof (SHA1_CTX)); 5467c478bd9Sstevel@tonic-gate break; 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate default: 549588a1af0SAlexandr Nedvedicky rv = CKR_STATE_UNSAVEABLE; 5507c478bd9Sstevel@tonic-gate } 551d288ba74SAnthony Scarpino } else { 552d288ba74SAnthony Scarpino rv = CKR_OPERATION_NOT_INITIALIZED; 553d288ba74SAnthony Scarpino goto unlock_session; 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate *pulOperationStateLen = op_data_len; 5577c478bd9Sstevel@tonic-gate 558588a1af0SAlexandr Nedvedicky unlock_session: 559588a1af0SAlexandr Nedvedicky (void) pthread_mutex_unlock(&session_p->session_mutex); 560588a1af0SAlexandr Nedvedicky 561588a1af0SAlexandr Nedvedicky return (rv); 562588a1af0SAlexandr Nedvedicky 563588a1af0SAlexandr Nedvedicky } 564588a1af0SAlexandr Nedvedicky 565588a1af0SAlexandr Nedvedicky static CK_BYTE_PTR alloc_digest(CK_ULONG mech) 566588a1af0SAlexandr Nedvedicky { 567588a1af0SAlexandr Nedvedicky CK_BYTE_PTR ret_val; 568588a1af0SAlexandr Nedvedicky 569588a1af0SAlexandr Nedvedicky switch (mech) { 570588a1af0SAlexandr Nedvedicky case CKM_MD5: 571588a1af0SAlexandr Nedvedicky ret_val = (CK_BYTE_PTR) malloc(sizeof (MD5_CTX)); 572588a1af0SAlexandr Nedvedicky break; 573588a1af0SAlexandr Nedvedicky case CKM_SHA_1: 574588a1af0SAlexandr Nedvedicky ret_val = (CK_BYTE_PTR) malloc(sizeof (SHA1_CTX)); 575588a1af0SAlexandr Nedvedicky break; 576588a1af0SAlexandr Nedvedicky default: ret_val = NULL; 577588a1af0SAlexandr Nedvedicky } 578588a1af0SAlexandr Nedvedicky 579588a1af0SAlexandr Nedvedicky return (ret_val); 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate /* 5837c478bd9Sstevel@tonic-gate * The format to be restored from the pOperationState will be: 5847c478bd9Sstevel@tonic-gate * 1. internal_op_state_t 5857c478bd9Sstevel@tonic-gate * 2. crypto_active_op_t 5867c478bd9Sstevel@tonic-gate * 3. actual context of the saved operation 5877c478bd9Sstevel@tonic-gate */ 5887c478bd9Sstevel@tonic-gate CK_RV 5897c478bd9Sstevel@tonic-gate soft_set_operationstate(soft_session_t *session_p, CK_BYTE_PTR pOperationState, 5907c478bd9Sstevel@tonic-gate CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, 5917c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE hAuthenticationKey) 5927c478bd9Sstevel@tonic-gate { 5937c478bd9Sstevel@tonic-gate 594588a1af0SAlexandr Nedvedicky CK_RV rv = CKR_OK; 595588a1af0SAlexandr Nedvedicky internal_op_state_t *p_op_state; 596588a1af0SAlexandr Nedvedicky crypto_active_op_t *p_active_op; 5977c478bd9Sstevel@tonic-gate CK_ULONG offset = 0; 598588a1af0SAlexandr Nedvedicky CK_ULONG mech; 599588a1af0SAlexandr Nedvedicky void *free_it = NULL; 6007c478bd9Sstevel@tonic-gate 601588a1af0SAlexandr Nedvedicky /* LINTED E_BAD_PTR_CAST_ALIGN */ 602588a1af0SAlexandr Nedvedicky p_op_state = (internal_op_state_t *)pOperationState; 6037c478bd9Sstevel@tonic-gate 604588a1af0SAlexandr Nedvedicky if (p_op_state->op_len != ulOperationStateLen) { 6057c478bd9Sstevel@tonic-gate /* 6067c478bd9Sstevel@tonic-gate * The supplied data length does not match with 6077c478bd9Sstevel@tonic-gate * the saved data length. 6087c478bd9Sstevel@tonic-gate */ 6097c478bd9Sstevel@tonic-gate return (CKR_SAVED_STATE_INVALID); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 612588a1af0SAlexandr Nedvedicky if (p_op_state->op_active != DIGEST_OP) 613588a1af0SAlexandr Nedvedicky return (CKR_SAVED_STATE_INVALID); 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate if ((hAuthenticationKey != 0) || (hEncryptionKey != 0)) { 6167c478bd9Sstevel@tonic-gate return (CKR_KEY_NOT_NEEDED); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate 619588a1af0SAlexandr Nedvedicky offset = sizeof (internal_op_state_t); 620588a1af0SAlexandr Nedvedicky /* LINTED E_BAD_PTR_CAST_ALIGN */ 621588a1af0SAlexandr Nedvedicky p_active_op = (crypto_active_op_t *)(pOperationState + offset); 622588a1af0SAlexandr Nedvedicky offset += sizeof (crypto_active_op_t); 623588a1af0SAlexandr Nedvedicky mech = p_active_op->mech.mechanism; 6247c478bd9Sstevel@tonic-gate 625588a1af0SAlexandr Nedvedicky if (!DIGEST_MECH_OK(mech)) { 6267c478bd9Sstevel@tonic-gate return (CKR_SAVED_STATE_INVALID); 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate /* 630588a1af0SAlexandr Nedvedicky * We may reuse digest.context in case the digest mechanisms (the one, 631588a1af0SAlexandr Nedvedicky * which belongs to session and the operation, which we are restoring) 632588a1af0SAlexandr Nedvedicky * are the same. If digest mechanisms are different, we have to release 633588a1af0SAlexandr Nedvedicky * the digest context, which belongs to session and allocate a new one. 6347c478bd9Sstevel@tonic-gate */ 6357c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 636588a1af0SAlexandr Nedvedicky 637588a1af0SAlexandr Nedvedicky if (session_p->state != p_op_state->op_session_state) { 638588a1af0SAlexandr Nedvedicky /* 639588a1af0SAlexandr Nedvedicky * The supplied session state does not match with 640588a1af0SAlexandr Nedvedicky * the saved session state. 641588a1af0SAlexandr Nedvedicky */ 642588a1af0SAlexandr Nedvedicky rv = CKR_SAVED_STATE_INVALID; 643588a1af0SAlexandr Nedvedicky goto unlock_session; 644588a1af0SAlexandr Nedvedicky } 645588a1af0SAlexandr Nedvedicky 646588a1af0SAlexandr Nedvedicky if (session_p->digest.context && 647588a1af0SAlexandr Nedvedicky (session_p->digest.mech.mechanism != mech)) { 648588a1af0SAlexandr Nedvedicky free_it = session_p->digest.context; 649588a1af0SAlexandr Nedvedicky session_p->digest.context = NULL; 650588a1af0SAlexandr Nedvedicky } 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate if (session_p->digest.context == NULL) { 653588a1af0SAlexandr Nedvedicky session_p->digest.context = alloc_digest(mech); 654588a1af0SAlexandr Nedvedicky 655588a1af0SAlexandr Nedvedicky if (session_p->digest.context == NULL) { 656588a1af0SAlexandr Nedvedicky /* 657588a1af0SAlexandr Nedvedicky * put back original context into session in case 658588a1af0SAlexandr Nedvedicky * allocation of new context has failed. 659588a1af0SAlexandr Nedvedicky */ 660588a1af0SAlexandr Nedvedicky session_p->digest.context = free_it; 661588a1af0SAlexandr Nedvedicky free_it = NULL; 662588a1af0SAlexandr Nedvedicky rv = CKR_HOST_MEMORY; 663588a1af0SAlexandr Nedvedicky goto unlock_session; 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate 667588a1af0SAlexandr Nedvedicky /* Restore crypto_active_op_t */ 668588a1af0SAlexandr Nedvedicky session_p->digest.mech.mechanism = mech; 669588a1af0SAlexandr Nedvedicky session_p->digest.flags = p_active_op->flags; 670588a1af0SAlexandr Nedvedicky 671588a1af0SAlexandr Nedvedicky switch (mech) { 672588a1af0SAlexandr Nedvedicky case CKM_MD5: 6737c478bd9Sstevel@tonic-gate /* Restore MD5_CTX from the saved digest operation */ 6747c478bd9Sstevel@tonic-gate (void) memcpy((CK_BYTE *)session_p->digest.context, 6757c478bd9Sstevel@tonic-gate (CK_BYTE *)pOperationState + offset, 6767c478bd9Sstevel@tonic-gate sizeof (MD5_CTX)); 6777c478bd9Sstevel@tonic-gate break; 6787c478bd9Sstevel@tonic-gate case CKM_SHA_1: 6797c478bd9Sstevel@tonic-gate /* Restore SHA1_CTX from the saved digest operation */ 6807c478bd9Sstevel@tonic-gate (void) memcpy((CK_BYTE *)session_p->digest.context, 6817c478bd9Sstevel@tonic-gate (CK_BYTE *)pOperationState + offset, 6827c478bd9Sstevel@tonic-gate sizeof (SHA1_CTX)); 683588a1af0SAlexandr Nedvedicky break; 684588a1af0SAlexandr Nedvedicky default: 685588a1af0SAlexandr Nedvedicky /* never reached */ 686588a1af0SAlexandr Nedvedicky rv = CKR_SAVED_STATE_INVALID; 687588a1af0SAlexandr Nedvedicky } 6887c478bd9Sstevel@tonic-gate 689588a1af0SAlexandr Nedvedicky unlock_session: 6907c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 6917c478bd9Sstevel@tonic-gate 692588a1af0SAlexandr Nedvedicky if (free_it != NULL) 693588a1af0SAlexandr Nedvedicky free(free_it); 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate return (rv); 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate CK_RV 7007c478bd9Sstevel@tonic-gate soft_login(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) 7017c478bd9Sstevel@tonic-gate { 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate /* 7047c478bd9Sstevel@tonic-gate * Authenticate the input PIN. 7057c478bd9Sstevel@tonic-gate */ 7067c478bd9Sstevel@tonic-gate return (soft_verify_pin(pPin, ulPinLen)); 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate void 7117c478bd9Sstevel@tonic-gate soft_logout(void) 7127c478bd9Sstevel@tonic-gate { 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate /* 7157c478bd9Sstevel@tonic-gate * Delete all the private token objects from the "token_object_list". 7167c478bd9Sstevel@tonic-gate */ 7177c478bd9Sstevel@tonic-gate soft_delete_all_in_core_token_objects(PRIVATE_TOKEN); 7187c478bd9Sstevel@tonic-gate return; 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate } 7214daf2311Srupertk 7224daf2311Srupertk void 723*83140133SZdenek Kotala soft_acquire_all_session_mutexes(soft_session_t *session_p) 7244daf2311Srupertk { 7254daf2311Srupertk /* Iterate through sessions acquiring all mutexes */ 7264daf2311Srupertk while (session_p) { 7271f49a79aSZdenek Kotala soft_object_t *object_p; 7281f49a79aSZdenek Kotala 7294daf2311Srupertk (void) pthread_mutex_lock(&session_p->session_mutex); 7301f49a79aSZdenek Kotala object_p = session_p->object_list; 7311f49a79aSZdenek Kotala 7321f49a79aSZdenek Kotala /* Lock also all objects related to session */ 7331f49a79aSZdenek Kotala while (object_p) { 7341f49a79aSZdenek Kotala (void) pthread_mutex_lock(&object_p->object_mutex); 7351f49a79aSZdenek Kotala object_p = object_p->next; 7361f49a79aSZdenek Kotala } 7374daf2311Srupertk session_p = session_p->next; 7384daf2311Srupertk } 7394daf2311Srupertk } 7404daf2311Srupertk 7414daf2311Srupertk void 742*83140133SZdenek Kotala soft_release_all_session_mutexes(soft_session_t *session_p) 7434daf2311Srupertk { 7444daf2311Srupertk /* Iterate through sessions releasing all mutexes */ 7454daf2311Srupertk while (session_p) { 7464daf2311Srupertk /* 7474daf2311Srupertk * N.B. Ideally, should go in opposite order to guarantee 7484daf2311Srupertk * lock-order requirements but there is no tail pointer. 7494daf2311Srupertk */ 7501f49a79aSZdenek Kotala soft_object_t *object_p = session_p->object_list; 7511f49a79aSZdenek Kotala 7521f49a79aSZdenek Kotala /* Unlock also all objects related to session */ 7531f49a79aSZdenek Kotala while (object_p) { 7541f49a79aSZdenek Kotala (void) pthread_mutex_unlock(&object_p->object_mutex); 7551f49a79aSZdenek Kotala object_p = object_p->next; 7561f49a79aSZdenek Kotala } 7574daf2311Srupertk (void) pthread_mutex_unlock(&session_p->session_mutex); 7584daf2311Srupertk session_p = session_p->next; 7594daf2311Srupertk } 7604daf2311Srupertk } 761