diff options
-rw-r--r-- | pkcs11.c | 122 |
1 files changed, 98 insertions, 24 deletions
@@ -137,13 +137,6 @@ * like CKA_KEY_TYPE, so it's just something we look up given the key * object handle. * - * At the moment we don't need to keep any signature or digest state - * in the session structure, which is good since the current hash - * cores don't allow us to extract state anyway. This makes it - * impossible to implement the incremental operations - * (C_DigestUpdate(), C_SignUpdate()) but also simplifies our current - * task. - * * General idea is that we have separate descriptors/handles/state for * each operation that we're allowed to do in parallel, so sign, * verify, digest, encrypt, decrypt, wrapkey, and unwrapkey all need @@ -165,6 +158,10 @@ typedef struct p11_session { CK_OBJECT_HANDLE sign_key_handle, /* Key for C_Sign*() */ verify_key_handle; /* Key for C_Verify() */ + hal_hash_state_t + *digest_state, /* Hash state for C_Digest*() */ + *sign_digest_state, /* Hash state for C_Sign*() */ + *verify_digest_state; /* Hash state for C_Verify*() */ } p11_session_t; /* @@ -1491,7 +1488,9 @@ static void p11_session_free(p11_session_t *session) return; sql_finalize_and_clear(&session->find_query); - + hal_hash_cleanup(&session->digest_state); + hal_hash_cleanup(&session->sign_digest_state); + hal_hash_cleanup(&session->verify_digest_state); free(session); } @@ -3293,6 +3292,9 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, if (session->digest_descriptor == NULL) lose(CKR_OPERATION_NOT_INITIALIZED); + if (session->digest_state != NULL) + lose(CKR_OPERATION_ACTIVE); + rv = *pulDigestLen < session->digest_descriptor->digest_length ? CKR_BUFFER_TOO_SMALL : CKR_OK; *pulDigestLen = session->digest_descriptor->digest_length; @@ -3322,6 +3324,94 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, mutex_unlock_return_with_rv(rv, p11_global_mutex); } +CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) +{ + ENTER_PUBLIC_FUNCTION(C_DigestUpdate); + + p11_session_t *session; + CK_RV rv = CKR_OK; + + mutex_lock_or_return_failure(p11_global_mutex); + + if ((session = p11_session_find(hSession)) == NULL) + lose(CKR_SESSION_HANDLE_INVALID); + + if (pPart == NULL) + lose(CKR_ARGUMENTS_BAD); + + if (session->digest_descriptor == NULL) + lose(CKR_OPERATION_NOT_INITIALIZED); + + if (!session->digest_descriptor->can_restore_state) + lose(CKR_FUNCTION_FAILED); + + if (session->digest_state == NULL) { + hal_error_t err = hal_hash_initialize(session->digest_descriptor, + &session->digest_state, NULL, 0); + if (err == HAL_ERROR_ALLOCATION_FAILURE) + lose(CKR_HOST_MEMORY); + else if (err != HAL_OK) + lose(CKR_FUNCTION_FAILED); + } + + if (!hal_check(hal_hash_update(session->digest_state, pPart, ulPartLen))) + lose(CKR_FUNCTION_FAILED); + + return mutex_unlock(p11_global_mutex); + + fail: + if (session != NULL) { + hal_hash_cleanup(&session->digest_state); + session->digest_descriptor = NULL; + } + mutex_unlock_return_with_rv(rv, p11_global_mutex); +} + +CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen) +{ + ENTER_PUBLIC_FUNCTION(C_DigestFinal); + + p11_session_t *session; + CK_RV rv = CKR_OK; + + mutex_lock_or_return_failure(p11_global_mutex); + + if ((session = p11_session_find(hSession)) == NULL) + lose(CKR_SESSION_HANDLE_INVALID); + + if (pulDigestLen == NULL) + lose(CKR_ARGUMENTS_BAD); + + if (session->digest_descriptor == NULL || session->digest_state == NULL) + lose(CKR_OPERATION_NOT_INITIALIZED); + + rv = *pulDigestLen < session->digest_descriptor->digest_length ? CKR_BUFFER_TOO_SMALL : CKR_OK; + + *pulDigestLen = session->digest_descriptor->digest_length; + + if (pDigest == NULL) + return mutex_unlock(p11_global_mutex); + + if (rv == CKR_BUFFER_TOO_SMALL) + lose(CKR_BUFFER_TOO_SMALL); + + if (!hal_check(hal_hash_finalize(session->digest_state, pDigest, *pulDigestLen))) + lose(CKR_FUNCTION_FAILED); + + rv = CKR_OK; /* Fall through */ + + fail: + if (session != NULL) { + hal_hash_cleanup(&session->digest_state); + session->digest_descriptor = NULL; + } + mutex_unlock_return_with_rv(rv, p11_global_mutex); +} + CK_RV C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) @@ -4108,14 +4198,6 @@ CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, return CKR_FUNCTION_NOT_SUPPORTED; } -CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ - ENTER_PUBLIC_FUNCTION(C_DigestUpdate); - return CKR_FUNCTION_NOT_SUPPORTED; -} - CK_RV C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { @@ -4123,14 +4205,6 @@ CK_RV C_DigestKey(CK_SESSION_HANDLE hSession, return CKR_FUNCTION_NOT_SUPPORTED; } -CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pDigest, - CK_ULONG_PTR pulDigestLen) -{ - ENTER_PUBLIC_FUNCTION(C_DigestFinal); - return CKR_FUNCTION_NOT_SUPPORTED; -} - CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) |