/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include "tpmtok_int.h" #include "tpmtok_defs.h" extern pthread_rwlock_t obj_list_rw_mutex; void SC_SetFunctionList(void); struct ST_FCN_LIST function_list; int debugfile = 0; pid_t initedpid = 0; // for initialized pid CK_C_INITIALIZE_ARGS cinit_args = {NULL, NULL, NULL, NULL, 0, NULL}; extern void stlogterm(); extern void stloginit(); extern void stlogit2(int type, char *fmt, ...); extern void stlogit(char *fmt, ...); CK_BBOOL st_Initialized() { return (initedpid == getpid()); } void Fork_Initializer(void) { stlogterm(); stloginit(); // Initialize Logging so we can capture EVERYTHING // Force logout. This cleans out the private session and list // and cleans out the private object map (void) session_mgr_logout_all(); // Clean out the public object map // First parm is no longer used.. (void) object_mgr_purge_map((SESSION *)0xFFFF, PUBLIC); (void) object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE); // This should clear the entire session list out (void) session_mgr_close_all_sessions(); next_session_handle = 1; next_object_handle = 1; while (priv_token_obj_list) { priv_token_obj_list = dlist_remove_node(priv_token_obj_list, priv_token_obj_list); } while (publ_token_obj_list) { publ_token_obj_list = dlist_remove_node(publ_token_obj_list, publ_token_obj_list); } } #define SESSION_HANDLE sSession.sessionh #define SESS_SET \ CK_SESSION_HANDLE hSession = sSession.sessionh; static CK_RV validate_mechanism(CK_MECHANISM_PTR pMechanism) { CK_ULONG i; for (i = 0; i < mech_list_len; i++) { if (pMechanism->mechanism == mech_list[i].mech_type) { return (CKR_OK); } } return (CKR_MECHANISM_INVALID); } #define VALID_MECH(p) \ if (validate_mechanism(p) != CKR_OK) { \ rc = CKR_MECHANISM_INVALID; \ goto done; \ } CK_RV ST_Initialize(void *FunctionList, CK_SLOT_ID SlotNumber, unsigned char *Correlator) { CK_RV rc = CKR_OK; struct ST_FCN_LIST *flist = (struct ST_FCN_LIST *)FunctionList; TSS_HCONTEXT hContext = 0; stlogterm(); stloginit(); if (st_Initialized() == TRUE) { return (CKR_OK); } // assume that the upper API prevents multiple calls of initialize // since that only happens on C_Initialize and that is the // resonsibility of the upper layer.. initialized = FALSE; // check for other completing this before creating mutexes... // make sure that the same process tried to to the init... // thread issues should be caught up above... if (st_Initialized() == TRUE) { goto done; } Fork_Initializer(); (void) pthread_mutex_init(&pkcs_mutex, NULL); (void) pthread_mutex_init(&obj_list_mutex, NULL); (void) pthread_rwlock_init(&obj_list_rw_mutex, NULL); (void) pthread_mutex_init(&sess_list_mutex, NULL); (void) pthread_mutex_init(&login_mutex, NULL); if (st_Initialized() == FALSE) { if ((rc = attach_shm()) != CKR_OK) goto done; nv_token_data = &global_shm->nv_token_data; initialized = TRUE; initedpid = getpid(); SC_SetFunctionList(); if (flist != NULL) (*flist) = function_list; /* Always call the token_specific_init function.... */ rc = token_specific.t_init((char *)Correlator, SlotNumber, &hContext); if (rc != 0) { /* * The token could not be initialized, return OK, but * present no slots. */ rc = CKR_OK; goto done; } else { /* Mark the token as available */ global_shm->token_available = TRUE; } } rc = load_token_data(hContext, nv_token_data); if (rc != CKR_OK) { goto done; } rc = load_public_token_objects(); if (rc != CKR_OK) goto done; (void) XProcLock(xproclock); global_shm->publ_loaded = TRUE; (void) XProcUnLock(xproclock); init_slot_info(nv_token_data); done: if (hContext) Tspi_Context_Close(hContext); return (rc); } /*ARGSUSED*/ CK_RV SC_Finalize(void *argptr) { CK_RV rc; TSS_HCONTEXT hContext; if (st_Initialized() == FALSE) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } rc = pthread_mutex_lock(&pkcs_mutex); if (rc != CKR_OK) { return (rc); } // // If somebody else has taken care of things, leave... // if (st_Initialized() == FALSE) { (void) pthread_mutex_unlock(&pkcs_mutex); return (CKR_CRYPTOKI_NOT_INITIALIZED); } if (open_tss_context(&hContext)) { (void) pthread_mutex_unlock(&pkcs_mutex); return (CKR_FUNCTION_FAILED); } initialized = FALSE; if (token_specific.t_final != NULL) { token_specific.t_final(hContext); } (void) session_mgr_close_all_sessions(); (void) object_mgr_purge_token_objects(hContext); (void) Tspi_Context_Close(hContext); (void) detach_shm(); rc = pthread_mutex_unlock(&pkcs_mutex); if (rc != CKR_OK) { return (rc); } return (CKR_OK); } /*ARGSUSED*/ CK_RV SC_GetTokenInfo(CK_SLOT_ID sid, CK_TOKEN_INFO_PTR pInfo) { CK_RV rc = CKR_OK; time_t now; if (st_Initialized() == FALSE) return (CKR_CRYPTOKI_NOT_INITIALIZED); if (pInfo == NULL) return (CKR_FUNCTION_FAILED); if (sid != TPM_SLOTID) return (CKR_SLOT_ID_INVALID); (void) memcpy(pInfo, &nv_token_data->token_info, sizeof (CK_TOKEN_INFO)); now = time((time_t *)NULL); (void) strftime((char *)pInfo->utcTime, 16, "%X", localtime(&now)); return (rc); } /*ARGSUSED*/ CK_RV SC_GetMechanismList( CK_SLOT_ID sid, CK_MECHANISM_TYPE_PTR pMechList, CK_ULONG_PTR count) { CK_ULONG i; CK_RV rc = CKR_OK; if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (count == NULL) { rc = CKR_FUNCTION_FAILED; goto done; } if (sid != TPM_SLOTID) { rc = CKR_SLOT_ID_INVALID; goto done; } if (pMechList == NULL) { *count = mech_list_len; rc = CKR_OK; goto done; } if (*count < mech_list_len) { *count = mech_list_len; rc = CKR_BUFFER_TOO_SMALL; goto done; } for (i = 0; i < mech_list_len; i++) pMechList[i] = mech_list[i].mech_type; *count = mech_list_len; rc = CKR_OK; done: if (debugfile) { stlogit2(debugfile, "% - 25s: rc = 0x%08x, # mechanisms: %d\n", "C_GetMechanismList", rc, *count); } return (rc); } /*ARGSUSED*/ CK_RV SC_GetMechanismInfo( CK_SLOT_ID sid, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { CK_ULONG i; CK_RV rc = CKR_OK; if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (pInfo == NULL) { rc = CKR_FUNCTION_FAILED; goto done; } if (sid != TPM_SLOTID) { rc = CKR_SLOT_ID_INVALID; goto done; } for (i = 0; i < mech_list_len; i++) { if (mech_list[i].mech_type == type) { (void) memcpy(pInfo, &mech_list[i].mech_info, sizeof (CK_MECHANISM_INFO)); rc = CKR_OK; goto done; } } rc = CKR_MECHANISM_INVALID; done: if (debugfile) { stlogit2(debugfile, "% - 25s: " "rc = 0x%08x, mech type = 0x%08x\n", "C_GetMechanismInfo", rc, type); } return (rc); } /*ARGSUSED*/ CK_RV SC_InitToken( CK_SLOT_ID sid, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel) { CK_RV rc = CKR_OK; CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; TOKEN_DATA newtoken; TSS_HCONTEXT hContext = 0; if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (sid != TPM_SLOTID) { rc = CKR_SLOT_ID_INVALID; goto done; } if (! pPin || ! pLabel) { rc = CKR_ARGUMENTS_BAD; goto done; } if (open_tss_context(&hContext)) { rc = CKR_FUNCTION_FAILED; goto done; } rc = load_token_data(hContext, &newtoken); if (rc != CKR_OK) { goto done; } if (newtoken.token_info.flags & CKF_SO_PIN_LOCKED) { rc = CKR_PIN_LOCKED; goto done; } rc = token_specific.t_verify_so_pin(hContext, pPin, ulPinLen); if (rc != CKR_OK) { rc = CKR_PIN_INCORRECT; goto done; } /* * Before we reconstruct all the data, we should delete the * token objects from the filesystem. * * Construct a string to delete the token objects. */ (void) object_mgr_destroy_token_objects(hContext); (void) init_token_data(hContext, &newtoken); (void) init_slot_info(&newtoken); /* change the label */ (void) strncpy((char *)newtoken.token_info.label, (char *)pLabel, sizeof (newtoken.token_info.label)); (void) memcpy(newtoken.so_pin_sha, hash_sha, SHA1_DIGEST_LENGTH); newtoken.token_info.flags |= CKF_TOKEN_INITIALIZED; rc = save_token_data(&newtoken); done: if (hContext) (void) Tspi_Context_Close(hContext); return (rc); } CK_RV SC_InitPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; CK_FLAGS * flags = NULL; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pPin) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_LOCKED; goto done; } if (sess->session_info.state != CKS_RW_SO_FUNCTIONS) { rc = CKR_USER_NOT_LOGGED_IN; goto done; } rc = token_specific.t_init_pin(sess->hContext, pPin, ulPinLen); if (rc == CKR_OK) { flags = &nv_token_data->token_info.flags; *flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW); rc = save_token_data(nv_token_data); if (rc != CKR_OK) { goto done; } } done: if (debugfile) { stlogit2(debugfile, "% - 25s: session = %08x\n", "C_InitPin", rc, hSession); } return (rc); } CK_RV SC_SetPIN(ST_SESSION_HANDLE sSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_LOCKED; goto done; } rc = token_specific.t_set_pin(sSession, pOldPin, ulOldLen, pNewPin, ulNewLen); done: if (debugfile) { stlogit2(debugfile, "% - 25s: session = %08x\n", "C_SetPin", rc, hSession); } return (rc); } CK_RV SC_OpenSession( CK_SLOT_ID sid, CK_FLAGS flags, CK_SESSION_HANDLE_PTR phSession) { SESSION *sess; CK_RV rc = CKR_OK; TSS_HCONTEXT hContext; if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if ((flags & CKF_RW_SESSION) == 0) { if (session_mgr_so_session_exists()) { return (CKR_SESSION_READ_WRITE_SO_EXISTS); } } if (sid != TPM_SLOTID) { rc = CKR_SLOT_ID_INVALID; goto done; } if (open_tss_context(&hContext)) { rc = CKR_FUNCTION_FAILED; goto done; } rc = pthread_mutex_lock(&pkcs_mutex); if (rc != CKR_OK) { (void) pthread_mutex_unlock(&pkcs_mutex); Tspi_Context_Close(hContext); goto done; } token_specific.t_session(sid); (void) pthread_mutex_unlock(&pkcs_mutex); rc = session_mgr_new(flags, &sess); if (rc != CKR_OK) { Tspi_Context_Close(hContext); goto done; } *phSession = sess->handle; sess->session_info.slotID = sid; /* Open a new context for each session */ sess->hContext = hContext; done: return (rc); } CK_RV SC_CloseSession(ST_SESSION_HANDLE sSession) { SESSION *sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (!sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (token_specific.t_final != NULL) { token_specific.t_final(sess->hContext); } rc = session_mgr_close_session(sess); done: return (rc); } /*ARGSUSED*/ CK_RV SC_CloseAllSessions(CK_SLOT_ID sid) { CK_RV rc = CKR_OK; if (st_Initialized() == FALSE) return (CKR_CRYPTOKI_NOT_INITIALIZED); if (sid != TPM_SLOTID) return (CKR_SLOT_ID_INVALID); rc = session_mgr_close_all_sessions(); return (rc); } CK_RV SC_GetSessionInfo(ST_SESSION_HANDLE sSession, CK_SESSION_INFO_PTR pInfo) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pInfo) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } (void) memcpy(pInfo, &sess->session_info, sizeof (CK_SESSION_INFO)); done: return (rc); } CK_RV SC_GetOperationState(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pulOperationStateLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if (! pOperationState) length_only = TRUE; sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_get_op_state(sess, length_only, pOperationState, pulOperationStateLen); done: return (rc); } CK_RV SC_SetOperationState(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } if (!pOperationState || (ulOperationStateLen == 0)) { return (CKR_ARGUMENTS_BAD); } sess = session_mgr_find(hSession); if (! sess) { return (CKR_SESSION_HANDLE_INVALID); } rc = session_mgr_set_op_state(sess, hEncryptionKey, hAuthenticationKey, pOperationState); return (rc); } CK_RV SC_Login(ST_SESSION_HANDLE sSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { SESSION * sess = NULL; CK_FLAGS * flags = NULL, flagcheck, flagmask; CK_RV rc = CKR_OK; SESS_SET // In v2.11, logins should be exclusive, since token // specific flags may need to be set for a bad login. - KEY rc = pthread_mutex_lock(&login_mutex); if (rc != CKR_OK) { return (CKR_FUNCTION_FAILED); } if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } flags = &nv_token_data->token_info.flags; if (pPin == NULL) { set_login_flags(userType, flags); rc = CKR_ARGUMENTS_BAD; goto done; } if (ulPinLen < MIN_PIN_LEN || ulPinLen > MAX_PIN_LEN) { set_login_flags(userType, flags); rc = CKR_PIN_LEN_RANGE; goto done; } /* * PKCS #11 v2.01 requires that all sessions have the same login status: * --> all sessions are public, all are SO or all are USER */ if (userType == CKU_USER) { if (session_mgr_so_session_exists()) { rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_user_session_exists()) { rc = CKR_USER_ALREADY_LOGGED_IN; } } else if (userType == CKU_SO) { if (session_mgr_user_session_exists()) { rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_so_session_exists()) { rc = CKR_USER_ALREADY_LOGGED_IN; } if (session_mgr_readonly_exists()) { rc = CKR_SESSION_READ_ONLY_EXISTS; } } else { rc = CKR_USER_TYPE_INVALID; } if (rc != CKR_OK) goto done; if (userType == CKU_USER) { flagcheck = CKF_USER_PIN_LOCKED; flagmask = (CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW); } else { flagcheck = CKF_SO_PIN_LOCKED; flagmask = (CKF_SO_PIN_LOCKED | CKF_SO_PIN_FINAL_TRY | CKF_SO_PIN_COUNT_LOW); } if (*flags & flagcheck) { rc = CKR_PIN_LOCKED; goto done; } /* call the pluggable login function here */ rc = token_specific.t_login(sess->hContext, userType, pPin, ulPinLen); if (rc == CKR_OK) { *flags &= ~(flagmask); } else if (rc == CKR_PIN_INCORRECT) { set_login_flags(userType, flags); goto done; } else { goto done; } rc = session_mgr_login_all(userType); done: if (rc == CKR_OK) rc = save_token_data(nv_token_data); (void) pthread_mutex_unlock(&login_mutex); return (rc); } CK_RV SC_Logout(ST_SESSION_HANDLE sSession) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } // all sessions have the same state so we just have to check one // if (session_mgr_public_session_exists()) { rc = CKR_USER_NOT_LOGGED_IN; goto done; } (void) session_mgr_logout_all(); rc = token_specific.t_logout(sess->hContext); done: return (rc); } CK_RV SC_CreateObject(ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_add(sess, pTemplate, ulCount, phObject); done: return (rc); } CK_RV SC_CopyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_copy(sess, pTemplate, ulCount, hObject, phNewObject); done: return (rc); } CK_RV SC_DestroyObject(ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_destroy_object(sess, hObject); done: return (rc); } CK_RV SC_GetObjectSize( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_object_size(sess->hContext, hObject, pulSize); done: return (rc); } CK_RV SC_GetAttributeValue(ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_attribute_values(sess, hObject, pTemplate, ulCount); done: return (rc); } CK_RV SC_SetAttributeValue(ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_set_attribute_values(sess, hObject, pTemplate, ulCount); done: return (rc); } CK_RV SC_FindObjectsInit(ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->find_active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = object_mgr_find_init(sess, pTemplate, ulCount); done: return (rc); } CK_RV SC_FindObjects(ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount) { SESSION * sess = NULL; CK_ULONG count = 0; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! phObject || ! pulObjectCount) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! sess->find_list) { rc = CKR_FUNCTION_FAILED; goto done; } count = MIN(ulMaxObjectCount, (sess->find_count - sess->find_idx)); (void) memcpy(phObject, sess->find_list + sess->find_idx, count * sizeof (CK_OBJECT_HANDLE)); *pulObjectCount = count; sess->find_idx += count; rc = CKR_OK; done: return (rc); } CK_RV SC_FindObjectsFinal(ST_SESSION_HANDLE sSession) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (sess->find_list) free(sess->find_list); sess->find_list = NULL; sess->find_len = 0; sess->find_idx = 0; sess->find_active = FALSE; rc = CKR_OK; done: return (rc); } CK_RV SC_EncryptInit(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->encr_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = encr_mgr_init(sess, &sess->encr_ctx, OP_ENCRYPT_INIT, pMechanism, hKey); done: return (rc); } CK_RV SC_Encrypt(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (! pData || ! pulEncryptedDataLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if (sess->encr_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pEncryptedData) length_only = TRUE; rc = encr_mgr_encrypt(sess, length_only, &sess->encr_ctx, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) encr_mgr_cleanup(&sess->encr_ctx); return (rc); } #if 0 CK_RV SC_EncryptUpdate(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pPart || ! pulEncryptedPartLen) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_update(sess, length_only, &sess->encr_ctx, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen); done: if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) (void) encr_mgr_cleanup(&sess->encr_ctx); return (rc); } CK_RV SC_EncryptFinal(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pulLastEncryptedPartLen) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pLastEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_final(sess, length_only, &sess->encr_ctx, pLastEncryptedPart, pulLastEncryptedPartLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) encr_mgr_cleanup(&sess->encr_ctx); return (rc); } #endif CK_RV SC_DecryptInit(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->decr_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = decr_mgr_init(sess, &sess->decr_ctx, OP_DECRYPT_INIT, pMechanism, hKey); done: return (rc); } CK_RV SC_Decrypt(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (! pEncryptedData || ! pulDataLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if (sess->decr_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pData) length_only = TRUE; rc = decr_mgr_decrypt(sess, length_only, &sess->decr_ctx, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) decr_mgr_cleanup(&sess->decr_ctx); return (rc); } CK_RV SC_DigestInit(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->digest_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = digest_mgr_init(sess, &sess->digest_ctx, pMechanism); done: return (rc); } CK_RV SC_Digest(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (! pData || ! pulDigestLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if (sess->digest_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pDigest) length_only = TRUE; rc = digest_mgr_digest(sess, length_only, &sess->digest_ctx, pData, ulDataLen, pDigest, pulDigestLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) digest_mgr_cleanup(&sess->digest_ctx); return (rc); } CK_RV SC_DigestUpdate(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pPart && ulPartLen != 0) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (pPart) { rc = digest_mgr_digest_update(sess, &sess->digest_ctx, pPart, ulPartLen); } done: if (rc != CKR_OK) (void) digest_mgr_cleanup(&sess->digest_ctx); return (rc); } CK_RV SC_DigestKey(ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = digest_mgr_digest_key(sess, &sess->digest_ctx, hKey); done: if (rc != CKR_OK) (void) digest_mgr_cleanup(&sess->digest_ctx); return (rc); } CK_RV SC_DigestFinal(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pulDigestLen) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pDigest) length_only = TRUE; rc = digest_mgr_digest_final(sess, &sess->digest_ctx, pDigest, pulDigestLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) digest_mgr_cleanup(&sess->digest_ctx); return (rc); } CK_RV SC_SignInit(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } VALID_MECH(pMechanism); if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = sign_mgr_init(sess, &sess->sign_ctx, pMechanism, FALSE, hKey); done: return (rc); } CK_RV SC_Sign(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (!pData || !pulSignatureLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if (sess->sign_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pSignature) length_only = TRUE; rc = sign_mgr_sign(sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) sign_mgr_cleanup(&sess->sign_ctx); return (rc); } CK_RV SC_SignUpdate(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pPart) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = sign_mgr_sign_update(sess, &sess->sign_ctx, pPart, ulPartLen); done: if (rc != CKR_OK) (void) sign_mgr_cleanup(&sess->sign_ctx); return (rc); } CK_RV SC_SignFinal(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pulSignatureLen) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pSignature) length_only = TRUE; rc = sign_mgr_sign_final(sess, length_only, &sess->sign_ctx, pSignature, pulSignatureLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) sign_mgr_cleanup(&sess->sign_ctx); return (rc); } CK_RV SC_SignRecoverInit(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = sign_mgr_init(sess, &sess->sign_ctx, pMechanism, TRUE, hKey); done: return (rc); } CK_RV SC_SignRecover(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (!pData || !pulSignatureLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if ((sess->sign_ctx.active == FALSE) || (sess->sign_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pSignature) length_only = TRUE; rc = sign_mgr_sign_recover(sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) sign_mgr_cleanup(&sess->sign_ctx); return (rc); } CK_RV SC_VerifyInit(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = verify_mgr_init(sess, &sess->verify_ctx, pMechanism, FALSE, hKey); done: return (rc); } CK_RV SC_Verify(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (! pData || ! pSignature) { rc = CKR_ARGUMENTS_BAD; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = verify_mgr_verify(sess, &sess->verify_ctx, pData, ulDataLen, pSignature, ulSignatureLen); done: (void) verify_mgr_cleanup(&sess->verify_ctx); return (rc); } CK_RV SC_VerifyUpdate(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pPart) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = verify_mgr_verify_update(sess, &sess->verify_ctx, pPart, ulPartLen); done: if (rc != CKR_OK) (void) verify_mgr_cleanup(&sess->verify_ctx); return (rc); } CK_RV SC_VerifyFinal(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pSignature) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = verify_mgr_verify_final(sess, &sess->verify_ctx, pSignature, ulSignatureLen); done: (void) verify_mgr_cleanup(&sess->verify_ctx); return (rc); } CK_RV SC_VerifyRecoverInit(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; goto done; } rc = verify_mgr_init(sess, &sess->verify_ctx, pMechanism, TRUE, hKey); done: return (rc); } CK_RV SC_VerifyRecover(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (!pSignature || !pulDataLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if ((sess->verify_ctx.active == FALSE) || (sess->verify_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pData) length_only = TRUE; rc = verify_mgr_verify_recover(sess, length_only, &sess->verify_ctx, pSignature, ulSignatureLen, pData, pulDataLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) verify_mgr_cleanup(&sess->verify_ctx); return (rc); } CK_RV SC_GenerateKeyPair(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism || ! phPublicKey || ! phPrivateKey || (! pPublicKeyTemplate && (ulPublicKeyAttributeCount != 0)) || (! pPrivateKeyTemplate && (ulPrivateKeyAttributeCount != 0))) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_generate_key_pair(sess, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey); done: return (rc); } CK_RV SC_WrapKey(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism || ! pulWrappedKeyLen) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); if (! pWrappedKey) length_only = TRUE; sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_wrap_key(sess, length_only, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen); done: return (rc); } CK_RV SC_UnwrapKey(ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pMechanism || ! pWrappedKey || (! pTemplate && ulCount != 0) || ! phKey) { rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_unwrap_key(sess, pMechanism, pTemplate, ulCount, pWrappedKey, ulWrappedKeyLen, hUnwrappingKey, phKey); done: return (rc); } /*ARGSUSED*/ CK_RV SC_SeedRandom(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) { if (st_Initialized() == FALSE) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } if (pSeed == NULL || ulSeedLen == 0) return (CKR_ARGUMENTS_BAD); return (CKR_OK); } CK_RV SC_GenerateRandom(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) { SESSION *sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pRandomData && ulRandomLen != 0) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = token_rng(sess->hContext, pRandomData, ulRandomLen); done: return (rc); } void SC_SetFunctionList(void) { function_list.ST_Initialize = ST_Initialize; function_list.ST_Finalize = SC_Finalize; function_list.ST_GetTokenInfo = SC_GetTokenInfo; function_list.ST_GetMechanismList = SC_GetMechanismList; function_list.ST_GetMechanismInfo = SC_GetMechanismInfo; function_list.ST_InitToken = SC_InitToken; function_list.ST_InitPIN = SC_InitPIN; function_list.ST_SetPIN = SC_SetPIN; function_list.ST_OpenSession = SC_OpenSession; function_list.ST_CloseSession = SC_CloseSession; function_list.ST_GetSessionInfo = SC_GetSessionInfo; function_list.ST_GetOperationState = SC_GetOperationState; function_list.ST_SetOperationState = SC_SetOperationState; function_list.ST_Login = SC_Login; function_list.ST_Logout = SC_Logout; function_list.ST_CreateObject = SC_CreateObject; function_list.ST_CopyObject = SC_CopyObject; function_list.ST_DestroyObject = SC_DestroyObject; function_list.ST_GetObjectSize = SC_GetObjectSize; function_list.ST_GetAttributeValue = SC_GetAttributeValue; function_list.ST_SetAttributeValue = SC_SetAttributeValue; function_list.ST_FindObjectsInit = SC_FindObjectsInit; function_list.ST_FindObjects = SC_FindObjects; function_list.ST_FindObjectsFinal = SC_FindObjectsFinal; function_list.ST_EncryptInit = SC_EncryptInit; function_list.ST_Encrypt = SC_Encrypt; function_list.ST_EncryptUpdate = NULL /* SC_EncryptUpdate */; function_list.ST_EncryptFinal = NULL /* SC_EncryptFinal */; function_list.ST_DecryptInit = SC_DecryptInit; function_list.ST_Decrypt = SC_Decrypt; function_list.ST_DecryptUpdate = NULL /* SC_DecryptUpdate */; function_list.ST_DecryptFinal = NULL /* SC_DecryptFinal */; function_list.ST_DigestInit = SC_DigestInit; function_list.ST_Digest = SC_Digest; function_list.ST_DigestUpdate = SC_DigestUpdate; function_list.ST_DigestKey = SC_DigestKey; function_list.ST_DigestFinal = SC_DigestFinal; function_list.ST_SignInit = SC_SignInit; function_list.ST_Sign = SC_Sign; function_list.ST_SignUpdate = SC_SignUpdate; function_list.ST_SignFinal = SC_SignFinal; function_list.ST_SignRecoverInit = SC_SignRecoverInit; function_list.ST_SignRecover = SC_SignRecover; function_list.ST_VerifyInit = SC_VerifyInit; function_list.ST_Verify = SC_Verify; function_list.ST_VerifyUpdate = SC_VerifyUpdate; function_list.ST_VerifyFinal = SC_VerifyFinal; function_list.ST_VerifyRecoverInit = SC_VerifyRecoverInit; function_list.ST_VerifyRecover = SC_VerifyRecover; function_list.ST_DigestEncryptUpdate = NULL; function_list.ST_DecryptDigestUpdate = NULL; function_list.ST_SignEncryptUpdate = NULL; function_list.ST_DecryptVerifyUpdate = NULL; function_list.ST_GenerateKey = NULL; function_list.ST_GenerateKeyPair = SC_GenerateKeyPair; function_list.ST_WrapKey = SC_WrapKey; function_list.ST_UnwrapKey = SC_UnwrapKey; function_list.ST_DeriveKey = NULL; function_list.ST_SeedRandom = SC_SeedRandom; function_list.ST_GenerateRandom = SC_GenerateRandom; function_list.ST_GetFunctionStatus = NULL; function_list.ST_CancelFunction = NULL; }