2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * Delete all the sessions. First, obtain the global session 2N/A * list lock. Then start to delete one session at a time. 2N/A * Release the global session list lock before returning to 2N/A /* Acquire the global session list lock */ 2N/A /* Delete all the sessions in the session list */ 2N/A * Delete a session by calling soft_delete_session() 2N/A * with a session pointer and a boolean arguments. 2N/A * Boolean value TRUE is used to indicate that the 2N/A * caller holds the lock on the global session list. 2N/A /* Record the very first error code */ 2N/A /* No session left */ 2N/A /* Release the global session list lock */ 2N/A * Create a new session struct, and add it to the session linked list. 2N/A * This function will acquire the global session list lock, and release 2N/A * it after adding the session to the session linked list. 2N/A /* Allocate a new session struct */ 2N/A /* Initialize the lock for the newly created session */ 2N/A /* Acquire the global session list lock */ 2N/A /* Insert the new session in front of session list */ 2N/A /* Type casting the address of a session struct to a session handle */ 2N/A * This is the first session to be opened, so we can set 2N/A * validate the public token objects in token list now. 2N/A /* Release the global session list lock */ 2N/A * This function adds the to-be-freed session to a linked list. 2N/A * When the number of sessions queued in the linked list reaches the 2N/A * maximum threshold MAX_SES_TO_BE_FREED, it will free the first 2N/A * session (FIFO) in the list. 2N/A /* Add the newly deleted session at the end of the list */ 2N/A * Free the first session in the list only if 2N/A * the total count reaches maximum threshold. 2N/A * - Remove the session from the session linked list. 2N/A * Holding the lock on the global session list is needed to do this. 2N/A * - Release all the objects created by the session. 2N/A * The boolean argument lock_held is used to indicate that whether 2N/A * the caller of this function holds the lock on the global session 2N/A * - When called by soft_delete_all_sessions(), which is called by 2N/A * C_Finalize() or C_CloseAllSessions() -- the lock_held = TRUE. 2N/A * - When called by C_CloseSession() -- the lock_held = FALSE. 2N/A * When the caller does not hold the lock on the global session 2N/A * list, this function will acquire that lock in order to proceed, 2N/A * and also release that lock before returning to caller. 2N/A * Check to see if the caller holds the lock on the global 2N/A * session list. If not, we need to acquire that lock in 2N/A /* Acquire the global session list lock */ 2N/A * Remove the session from the session linked list first. 2N/A /* Session is the first one in the list */ 2N/A /* Session is the only one in the list */ 2N/A /* Session is not the first one in the list */ 2N/A /* Session is in the middle of the list */ 2N/A /* Session is the last one in the list */ 2N/A * If the global session list lock is obtained by 2N/A * this function, then release that lock after 2N/A * removing the session from session linked list. 2N/A * We want the releasing of the objects of the 2N/A * session, and freeing of the session itself to 2N/A * be done without holding the global session list 2N/A /* Acquire the individual session lock */ 2N/A * Make sure another thread hasn't freed the session. 2N/A * The deletion of a session must be blocked when the session 2N/A * reference count is not zero. This means if any session related 2N/A * operation starts prior to the session close operation gets in, 2N/A * the session closing thread must wait for the non-closing 2N/A * operation to be completed before it can proceed the close 2N/A * Unless we are being forced to shut everything down, this only 2N/A * happens if the libraries _fini() is running not of someone 2N/A * explicitly called C_Finalize(). 2N/A * We set the SESSION_REFCNT_WAITING flag before we put 2N/A * this closing thread in a wait state, so other non-closing 2N/A * operation thread will signal to wake it up only when 2N/A * the session reference count becomes zero and this flag 2N/A * Remove all the objects created in this session. 2N/A * Mark session as no longer valid. This can only be done after all 2N/A * objects created by this session are free'd since the marker is 2N/A * still needed in the process of removing objects from the session. 2N/A /* In case application did not call Final */ 2N/A * 1st B_TRUE: encrypt 2N/A * 2nd B_TRUE: caller is holding session_mutex. 2N/A * 1st B_FALSE: decrypt 2N/A * 2nd B_TRUE: caller is holding session_mutex. 2N/A /* Reset SESSION_IS_CLOSIN flag. */ 2N/A /* Destroy the individual session lock */ 2N/A /* Delay freeing the session */ 2N/A * This function is used to type cast a session handle to a pointer to 2N/A * the session struct. Also, it does the following things: 2N/A * 1) Check to see if the session struct is tagged with a session 2N/A * magic number. This is to detect when an application passes 2N/A * a bogus session pointer. 2N/A * 2) Acquire the lock on the designated session. 2N/A * 3) Check to see if the session is in the closing state that another 2N/A * thread is performing. 2N/A * 4) Increment the session reference count by one. This is to prevent 2N/A * this session from being closed by other thread. 2N/A * 5) Release the lock held on the designated session. 2N/A * The format to be saved in the pOperationState will be: 2N/A * 1. internal_op_state_t 2N/A * 2. crypto_active_op_t 2N/A * 3. actual context of the active operation 2N/A /* Check to see if encrypt operation is active. */ 2N/A /* Check to see if decrypt operation is active. */ 2N/A /* Check to see if sign operation is active. */ 2N/A /* Check to see if verify operation is active. */ 2N/A /* Check to see if digest operation is active. */ 2N/A /* Save internal_op_state_t */ 2N/A /* Save crypto_active_op_t */ 2N/A /* Save MD5_CTX for the active digest operation */ 2N/A /* Save SHA1_CTX for the active digest operation */ 2N/A /* Save SHA2_CTX for the active digest operation */ 2N/A * The format to be restored from the pOperationState will be: 2N/A * 1. internal_op_state_t 2N/A * 2. crypto_active_op_t 2N/A * 3. actual context of the saved operation 2N/A * The supplied data length does not match with 2N/A * the saved data length. 2N/A * We may reuse digest.context in case the digest mechanisms (the one, 2N/A * which belongs to session and the operation, which we are restoring) 2N/A * are the same. If digest mechanisms are different, we have to release 2N/A * the digest context, which belongs to session and allocate a new one. 2N/A * The supplied session state does not match with 2N/A * the saved session state. 2N/A * put back original context into session in case 2N/A * allocation of new context has failed. 2N/A /* Restore crypto_active_op_t */ 2N/A /* Restore MD5_CTX from the saved digest operation */ 2N/A /* Restore SHA1_CTX from the saved digest operation */ 2N/A /* Restore SHA2_CTX from the saved digest operation */ 2N/A * Authenticate the input PIN. 2N/A * Delete all the private token objects from the "token_object_list". 2N/A * Acquire all session mutexes and their objects. 2N/A * 1. session_p->session_mutex 2N/A * when sessions are locked we can lock their objects and 2N/A * for each session go through the session_p->object_list 2N/A * 2. objp->object_mutex 2N/A * Note 1: We have to lock all sessions first and after that we can lock their 2N/A * objects, because sometimes a function is called with a session and an object 2N/A * which does not belong to the session. Because session lock is acquired always 2N/A * before the object lock, it avoids deadlock. 2N/A * Note 2: The unlocking of the sessions and objects list should optimally be 2N/A * in the opposite order, but currently no thread locks two sessions or objects 2N/A /* Iterate through sessions acquiring all mutexes */ 2N/A /* Iterate through sessions acquiring all object's mutexes */ 2N/A /* Lock also all objects related to session */ 2N/A /* Iterate through sessions releasing all object's mutexes */ 2N/A /* Unlock also all objects related to session */ 2N/A /* Iterate through sessions releasing all mutexes */ 2N/A /* Check to see if the operation is already active. */ 2N/A /* This active flag will remain ON during the entire operation. */