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 53caafd89Smcpowers * Common Development and Distribution License (the "License"). 63caafd89Smcpowers * 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 */ 21ba5f469cSkrishna 227c478bd9Sstevel@tonic-gate /* 23b232b5fcSZdenek Kotala * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <errno.h> 287c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 297c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctl.h> 307c478bd9Sstevel@tonic-gate #include "kernelGlobal.h" 317c478bd9Sstevel@tonic-gate #include "kernelObject.h" 327c478bd9Sstevel@tonic-gate #include "kernelSession.h" 33ba5f469cSkrishna #include "kernelEmulate.h" 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate CK_RV 367c478bd9Sstevel@tonic-gate C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 377c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE hKey) 387c478bd9Sstevel@tonic-gate { 397c478bd9Sstevel@tonic-gate CK_RV rv; 407c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 417c478bd9Sstevel@tonic-gate kernel_object_t *key_p; 427c478bd9Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE; 437c478bd9Sstevel@tonic-gate crypto_sign_init_t sign_init; 447c478bd9Sstevel@tonic-gate crypto_mech_type_t k_mech_type; 457c478bd9Sstevel@tonic-gate int r; 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate if (!kernel_initialized) 487c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate if (pMechanism == NULL) { 517c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 527c478bd9Sstevel@tonic-gate } 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* Get the kernel's internal mechanism number. */ 557c478bd9Sstevel@tonic-gate rv = kernel_mech(pMechanism->mechanism, &k_mech_type); 567c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 577c478bd9Sstevel@tonic-gate return (rv); 587c478bd9Sstevel@tonic-gate } 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* Obtain the session pointer. */ 617c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 627c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 637c478bd9Sstevel@tonic-gate return (rv); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* Obtain the object pointer. */ 667c478bd9Sstevel@tonic-gate HANDLE2OBJECT(hKey, key_p, rv); 677c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 6801223cbaSmcpowers REFRELE(session_p, ses_lock_held); 6901223cbaSmcpowers return (rv); 707c478bd9Sstevel@tonic-gate } 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* Check to see if key object supports signature. */ 737c478bd9Sstevel@tonic-gate if (key_p->is_lib_obj && !(key_p->bool_attr_mask & SIGN_BOOL_ON)) { 747c478bd9Sstevel@tonic-gate rv = CKR_KEY_TYPE_INCONSISTENT; 757c478bd9Sstevel@tonic-gate goto clean_exit; 767c478bd9Sstevel@tonic-gate } 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 797c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* 827c478bd9Sstevel@tonic-gate * This active flag will remain ON until application calls either 837c478bd9Sstevel@tonic-gate * C_Sign or C_SignFinal to actually obtain the signature. 847c478bd9Sstevel@tonic-gate */ 857c478bd9Sstevel@tonic-gate session_p->sign.flags = CRYPTO_OPERATION_ACTIVE; 867c478bd9Sstevel@tonic-gate sign_init.si_session = session_p->k_session; 877c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 887c478bd9Sstevel@tonic-gate ses_lock_held = B_FALSE; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate if (!key_p->is_lib_obj) { 917c478bd9Sstevel@tonic-gate sign_init.si_key.ck_format = CRYPTO_KEY_REFERENCE; 927c478bd9Sstevel@tonic-gate sign_init.si_key.ck_obj_id = key_p->k_handle; 937c478bd9Sstevel@tonic-gate } else { 947c478bd9Sstevel@tonic-gate if (key_p->class == CKO_SECRET_KEY) { 957c478bd9Sstevel@tonic-gate sign_init.si_key.ck_format = CRYPTO_KEY_RAW; 967c478bd9Sstevel@tonic-gate sign_init.si_key.ck_data = 977c478bd9Sstevel@tonic-gate get_symmetric_key_value(key_p); 987c478bd9Sstevel@tonic-gate if (sign_init.si_key.ck_data == NULL) { 997c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 1007c478bd9Sstevel@tonic-gate goto clean_exit; 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate sign_init.si_key.ck_length = 1037c478bd9Sstevel@tonic-gate OBJ_SEC(key_p)->sk_value_len << 3; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate } else if (key_p->key_type == CKK_RSA) { 1067c478bd9Sstevel@tonic-gate rv = get_rsa_private_key(key_p, &sign_init.si_key); 1077c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1087c478bd9Sstevel@tonic-gate goto clean_exit; 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate } else if (key_p->key_type == CKK_DSA) { 1117c478bd9Sstevel@tonic-gate rv = get_dsa_private_key(key_p, &sign_init.si_key); 1127c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1137c478bd9Sstevel@tonic-gate goto clean_exit; 1147c478bd9Sstevel@tonic-gate } 115034448feSmcpowers } else if (key_p->key_type == CKK_EC) { 116034448feSmcpowers rv = get_ec_private_key(key_p, &sign_init.si_key); 117034448feSmcpowers if (rv != CKR_OK) { 118034448feSmcpowers goto clean_exit; 119034448feSmcpowers } 1207c478bd9Sstevel@tonic-gate } else { 1217c478bd9Sstevel@tonic-gate rv = CKR_KEY_TYPE_INCONSISTENT; 1227c478bd9Sstevel@tonic-gate goto clean_exit; 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate sign_init.si_mech.cm_type = k_mech_type; 1277c478bd9Sstevel@tonic-gate sign_init.si_mech.cm_param = pMechanism->pParameter; 1287c478bd9Sstevel@tonic-gate sign_init.si_mech.cm_param_len = pMechanism->ulParameterLen; 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_SIGN_INIT, &sign_init)) < 0) { 1317c478bd9Sstevel@tonic-gate if (errno != EINTR) 1327c478bd9Sstevel@tonic-gate break; 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate if (r < 0) { 1357c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 1367c478bd9Sstevel@tonic-gate } else { 1377c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(sign_init.si_return_value); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate 140*4df55fdeSJanie Lu if (rv == CKR_OK && SLOT_HAS_LIMITED_HMAC(session_p) && 141ba5f469cSkrishna is_hmac(pMechanism->mechanism)) { 142ba5f469cSkrishna if (key_p->is_lib_obj && key_p->class == CKO_SECRET_KEY) { 143ba5f469cSkrishna (void) pthread_mutex_lock(&session_p->session_mutex); 144ba5f469cSkrishna session_p->sign.flags |= CRYPTO_EMULATE; 145ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 146ba5f469cSkrishna rv = emulate_init(session_p, pMechanism, 147ba5f469cSkrishna &(sign_init.si_key), OP_SIGN); 148ba5f469cSkrishna } else { 149ba5f469cSkrishna rv = CKR_ARGUMENTS_BAD; 150ba5f469cSkrishna } 151ba5f469cSkrishna } 152ba5f469cSkrishna 1537c478bd9Sstevel@tonic-gate if (key_p->is_lib_obj) { 1547c478bd9Sstevel@tonic-gate if (key_p->class == CKO_SECRET_KEY) { 1557c478bd9Sstevel@tonic-gate free(sign_init.si_key.ck_data); 1563caafd89Smcpowers } else { 1577c478bd9Sstevel@tonic-gate free_key_attributes(&sign_init.si_key); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1627c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 1637c478bd9Sstevel@tonic-gate session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE; 1647c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate clean_exit: 16801223cbaSmcpowers OBJ_REFRELE(key_p); 1697c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 1707c478bd9Sstevel@tonic-gate return (rv); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate CK_RV 1757c478bd9Sstevel@tonic-gate C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, 1767c478bd9Sstevel@tonic-gate CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) 1777c478bd9Sstevel@tonic-gate { 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate CK_RV rv; 1807c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 1817c478bd9Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE; 1827c478bd9Sstevel@tonic-gate crypto_sign_t sign; 1837c478bd9Sstevel@tonic-gate int r; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if (!kernel_initialized) 1867c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate /* Obtain the session pointer */ 1897c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 1907c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1917c478bd9Sstevel@tonic-gate return (rv); 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate if (pulSignatureLen == NULL) { 1947c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 1957c478bd9Sstevel@tonic-gate goto clean_exit; 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 1997c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* Application must call C_SignInit before calling C_Sign. */ 2027c478bd9Sstevel@tonic-gate if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 2037c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 2047c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* 2087c478bd9Sstevel@tonic-gate * C_Sign must be called without intervening C_SignUpdate 2097c478bd9Sstevel@tonic-gate * calls. 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate if (session_p->sign.flags & CRYPTO_OPERATION_UPDATE) { 2127c478bd9Sstevel@tonic-gate /* 2137c478bd9Sstevel@tonic-gate * C_Sign can not be used to terminate a multi-part 2147c478bd9Sstevel@tonic-gate * operation, so we'll leave the active sign operation 2157c478bd9Sstevel@tonic-gate * flag on and let the application continue with the 2167c478bd9Sstevel@tonic-gate * sign update operation. 2177c478bd9Sstevel@tonic-gate */ 2187c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 2197c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 222ba5f469cSkrishna if (session_p->sign.flags & CRYPTO_EMULATE) { 223ba5f469cSkrishna if ((ulDataLen < SLOT_THRESHOLD(session_p)) || 224*4df55fdeSJanie Lu (ulDataLen > SLOT_HMAC_MAX_INDATA_LEN(session_p))) { 225ba5f469cSkrishna session_p->sign.flags |= CRYPTO_EMULATE_USING_SW; 226ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 227b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 228ba5f469cSkrishna 229ba5f469cSkrishna rv = do_soft_hmac_sign(get_spp(&session_p->sign), 230ba5f469cSkrishna pData, ulDataLen, 231ba5f469cSkrishna pSignature, pulSignatureLen, OP_SINGLE); 232ba5f469cSkrishna goto done; 233ba5f469cSkrishna } else { 234ba5f469cSkrishna free_soft_ctx(get_sp(&session_p->sign), OP_SIGN); 235ba5f469cSkrishna } 236ba5f469cSkrishna } 237ba5f469cSkrishna 2387c478bd9Sstevel@tonic-gate sign.cs_session = session_p->k_session; 2397c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 2407c478bd9Sstevel@tonic-gate ses_lock_held = B_FALSE; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate sign.cs_datalen = ulDataLen; 2437c478bd9Sstevel@tonic-gate sign.cs_databuf = (char *)pData; 2447c478bd9Sstevel@tonic-gate sign.cs_signlen = *pulSignatureLen; 2457c478bd9Sstevel@tonic-gate sign.cs_signbuf = (char *)pSignature; 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_SIGN, &sign)) < 0) { 2487c478bd9Sstevel@tonic-gate if (errno != EINTR) 2497c478bd9Sstevel@tonic-gate break; 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate if (r < 0) { 2527c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 2537c478bd9Sstevel@tonic-gate } else { 2547c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(sign.cs_return_value); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL) 2587c478bd9Sstevel@tonic-gate *pulSignatureLen = sign.cs_signlen; 2597c478bd9Sstevel@tonic-gate 260ba5f469cSkrishna done: 2617c478bd9Sstevel@tonic-gate if ((rv == CKR_BUFFER_TOO_SMALL) || 2627c478bd9Sstevel@tonic-gate (rv == CKR_OK && pSignature == NULL)) { 2637c478bd9Sstevel@tonic-gate /* 2647c478bd9Sstevel@tonic-gate * We will not terminate the active sign operation flag, 2657c478bd9Sstevel@tonic-gate * when the application-supplied buffer is too small, or 2667c478bd9Sstevel@tonic-gate * the application asks for the length of buffer to hold 2677c478bd9Sstevel@tonic-gate * the signature. 2687c478bd9Sstevel@tonic-gate */ 2697c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 2707c478bd9Sstevel@tonic-gate return (rv); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate clean_exit: 2747c478bd9Sstevel@tonic-gate /* 2757c478bd9Sstevel@tonic-gate * Terminates the active sign operation. 2767c478bd9Sstevel@tonic-gate * Application needs to call C_SignInit again for next 2777c478bd9Sstevel@tonic-gate * sign operation. 2787c478bd9Sstevel@tonic-gate */ 2797c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 280b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 281ba5f469cSkrishna 282ba5f469cSkrishna REINIT_OPBUF(&session_p->sign); 2837c478bd9Sstevel@tonic-gate session_p->sign.flags = 0; 2847c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate return (rv); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate CK_RV 2917c478bd9Sstevel@tonic-gate C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 2927c478bd9Sstevel@tonic-gate CK_ULONG ulPartLen) 2937c478bd9Sstevel@tonic-gate { 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate CK_RV rv; 2967c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 2977c478bd9Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE; 2987c478bd9Sstevel@tonic-gate crypto_sign_update_t sign_update; 2997c478bd9Sstevel@tonic-gate int r; 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate if (!kernel_initialized) 3027c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate /* Obtain the session pointer */ 3057c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 3067c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 3077c478bd9Sstevel@tonic-gate return (rv); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if (pPart == NULL) { 3107c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 3117c478bd9Sstevel@tonic-gate goto clean_exit; 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 3157c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate /* 3187c478bd9Sstevel@tonic-gate * Application must call C_SignInit before calling 3197c478bd9Sstevel@tonic-gate * C_SignUpdate. 3207c478bd9Sstevel@tonic-gate */ 3217c478bd9Sstevel@tonic-gate if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 3227c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 3237c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate session_p->sign.flags |= CRYPTO_OPERATION_UPDATE; 3277c478bd9Sstevel@tonic-gate 328ba5f469cSkrishna if (session_p->sign.flags & CRYPTO_EMULATE) { 329ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 330b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 331ba5f469cSkrishna rv = emulate_update(session_p, pPart, ulPartLen, OP_SIGN); 332ba5f469cSkrishna goto done; 333ba5f469cSkrishna } 334ba5f469cSkrishna 3357c478bd9Sstevel@tonic-gate sign_update.su_session = session_p->k_session; 3367c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 3377c478bd9Sstevel@tonic-gate ses_lock_held = B_FALSE; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate sign_update.su_datalen = ulPartLen; 3407c478bd9Sstevel@tonic-gate sign_update.su_databuf = (char *)pPart; 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_SIGN_UPDATE, &sign_update)) < 0) { 3437c478bd9Sstevel@tonic-gate if (errno != EINTR) 3447c478bd9Sstevel@tonic-gate break; 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate if (r < 0) { 3477c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 3487c478bd9Sstevel@tonic-gate } else { 3497c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(sign_update.su_return_value); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate 352ba5f469cSkrishna done: 3537c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 3547c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 3557c478bd9Sstevel@tonic-gate return (rv); 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate clean_exit: 3597c478bd9Sstevel@tonic-gate /* 3607c478bd9Sstevel@tonic-gate * After an error occurred, terminate the current sign 3617c478bd9Sstevel@tonic-gate * operation by resetting the active and update flags. 3627c478bd9Sstevel@tonic-gate */ 3637c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 364b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 365ba5f469cSkrishna REINIT_OPBUF(&session_p->sign); 3667c478bd9Sstevel@tonic-gate session_p->sign.flags = 0; 3677c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate return (rv); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate CK_RV 3747c478bd9Sstevel@tonic-gate C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, 3757c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulSignatureLen) 3767c478bd9Sstevel@tonic-gate { 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate CK_RV rv; 3797c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 3807c478bd9Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE; 3817c478bd9Sstevel@tonic-gate crypto_sign_final_t sign_final; 3827c478bd9Sstevel@tonic-gate int r; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate if (!kernel_initialized) 3857c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate /* Obtain the session pointer */ 3887c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 3897c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 3907c478bd9Sstevel@tonic-gate return (rv); 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate if (pulSignatureLen == NULL) { 3937c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 3947c478bd9Sstevel@tonic-gate goto clean_exit; 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 3987c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate /* 4017c478bd9Sstevel@tonic-gate * Application must call C_SignInit before calling 4027c478bd9Sstevel@tonic-gate * C_SignFinal. 4037c478bd9Sstevel@tonic-gate */ 4047c478bd9Sstevel@tonic-gate if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 4057c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 4067c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate 409ba5f469cSkrishna /* The order of checks is important here */ 410ba5f469cSkrishna if (session_p->sign.flags & CRYPTO_EMULATE_USING_SW) { 411ba5f469cSkrishna if (session_p->sign.flags & CRYPTO_EMULATE_UPDATE_DONE) { 412ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 413b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 414ba5f469cSkrishna rv = do_soft_hmac_sign(get_spp(&session_p->sign), 415ba5f469cSkrishna NULL, 0, pSignature, pulSignatureLen, OP_FINAL); 416ba5f469cSkrishna } else { 417ba5f469cSkrishna /* 418ba5f469cSkrishna * We end up here if an earlier C_SignFinal() call 419ba5f469cSkrishna * took the C_Sign() path and it had returned 420ba5f469cSkrishna * CKR_BUFFER_TOO_SMALL. 421ba5f469cSkrishna */ 422ba5f469cSkrishna digest_buf_t *bufp = session_p->sign.context; 423ba5f469cSkrishna (void) pthread_mutex_unlock(&session_p->session_mutex); 424b232b5fcSZdenek Kotala ses_lock_held = B_FALSE; 425ba5f469cSkrishna if (bufp == NULL || bufp->buf == NULL) { 426ba5f469cSkrishna rv = CKR_ARGUMENTS_BAD; 427ba5f469cSkrishna goto clean_exit; 428ba5f469cSkrishna } 429ba5f469cSkrishna rv = do_soft_hmac_sign(get_spp(&session_p->sign), 430ba5f469cSkrishna bufp->buf, bufp->indata_len, 431ba5f469cSkrishna pSignature, pulSignatureLen, OP_SINGLE); 432ba5f469cSkrishna } 433ba5f469cSkrishna goto done; 434ba5f469cSkrishna } else if (session_p->sign.flags & CRYPTO_EMULATE) { 435ba5f469cSkrishna digest_buf_t *bufp = session_p->sign.context; 436ba5f469cSkrishna 437ba5f469cSkrishna /* 438ba5f469cSkrishna * We are emulating a single-part operation now. 439ba5f469cSkrishna * So, clear the flag. 440ba5f469cSkrishna */ 441ba5f469cSkrishna session_p->sign.flags &= ~CRYPTO_OPERATION_UPDATE; 442ba5f469cSkrishna if (bufp == NULL || bufp->buf == NULL) { 443ba5f469cSkrishna rv = CKR_ARGUMENTS_BAD; 444ba5f469cSkrishna goto clean_exit; 445ba5f469cSkrishna } 446ba5f469cSkrishna REFRELE(session_p, ses_lock_held); 447ba5f469cSkrishna rv = C_Sign(hSession, bufp->buf, bufp->indata_len, 448ba5f469cSkrishna pSignature, pulSignatureLen); 449ba5f469cSkrishna return (rv); 450ba5f469cSkrishna } 451ba5f469cSkrishna 4527c478bd9Sstevel@tonic-gate sign_final.sf_session = session_p->k_session; 4537c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 4547c478bd9Sstevel@tonic-gate ses_lock_held = B_FALSE; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate sign_final.sf_signlen = *pulSignatureLen; 4577c478bd9Sstevel@tonic-gate sign_final.sf_signbuf = (char *)pSignature; 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_SIGN_FINAL, &sign_final)) < 0) { 4607c478bd9Sstevel@tonic-gate if (errno != EINTR) 4617c478bd9Sstevel@tonic-gate break; 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate if (r < 0) { 4647c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 4657c478bd9Sstevel@tonic-gate } else { 4667c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(sign_final.sf_return_value); 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL) 4707c478bd9Sstevel@tonic-gate *pulSignatureLen = sign_final.sf_signlen; 4717c478bd9Sstevel@tonic-gate 472ba5f469cSkrishna done: 4737c478bd9Sstevel@tonic-gate if ((rv == CKR_BUFFER_TOO_SMALL) || 4747c478bd9Sstevel@tonic-gate (rv == CKR_OK && pSignature == NULL)) { 4757c478bd9Sstevel@tonic-gate /* 4767c478bd9Sstevel@tonic-gate * We will not terminate the active sign operation flag, 4777c478bd9Sstevel@tonic-gate * when the application-supplied buffer is too small, or 4787c478bd9Sstevel@tonic-gate * the application asks for the length of buffer to hold 4797c478bd9Sstevel@tonic-gate * the signature. 4807c478bd9Sstevel@tonic-gate */ 4817c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 4827c478bd9Sstevel@tonic-gate return (rv); 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate clean_exit: 4867c478bd9Sstevel@tonic-gate /* Terminates the active sign operation */ 4877c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 488b232b5fcSZdenek Kotala ses_lock_held = B_TRUE; 489ba5f469cSkrishna REINIT_OPBUF(&session_p->sign); 4907c478bd9Sstevel@tonic-gate session_p->sign.flags = 0; 4917c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate return (rv); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate CK_RV 4987c478bd9Sstevel@tonic-gate C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 4997c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE hKey) 5007c478bd9Sstevel@tonic-gate { 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate CK_RV rv; 5037c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 5047c478bd9Sstevel@tonic-gate kernel_object_t *key_p; 5057c478bd9Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE; 5067c478bd9Sstevel@tonic-gate crypto_sign_recover_init_t sr_init; 5077c478bd9Sstevel@tonic-gate crypto_mech_type_t k_mech_type; 5087c478bd9Sstevel@tonic-gate int r; 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate if (!kernel_initialized) 5117c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate if (pMechanism == NULL) { 5147c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 5157c478bd9Sstevel@tonic-gate } 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* Get the kernel's internal mechanism number. */ 5187c478bd9Sstevel@tonic-gate rv = kernel_mech(pMechanism->mechanism, &k_mech_type); 5197c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 5207c478bd9Sstevel@tonic-gate return (rv); 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate /* Obtain the session pointer. */ 5237c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 5247c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 5257c478bd9Sstevel@tonic-gate return (rv); 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate /* Obtain the object pointer. */ 5287c478bd9Sstevel@tonic-gate HANDLE2OBJECT(hKey, key_p, rv); 5297c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 53001223cbaSmcpowers REFRELE(session_p, ses_lock_held); 53101223cbaSmcpowers return (rv); 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate /* 5357c478bd9Sstevel@tonic-gate * Check to see if key object is a RSA key and if it supports 5367c478bd9Sstevel@tonic-gate * sign_recover. 5377c478bd9Sstevel@tonic-gate */ 5387c478bd9Sstevel@tonic-gate if (key_p->is_lib_obj && !((key_p->key_type == CKK_RSA) && 5397c478bd9Sstevel@tonic-gate (key_p->bool_attr_mask & SIGN_RECOVER_BOOL_ON))) { 5407c478bd9Sstevel@tonic-gate rv = CKR_KEY_TYPE_INCONSISTENT; 5417c478bd9Sstevel@tonic-gate goto clean_exit; 5427c478bd9Sstevel@tonic-gate } 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 5457c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate /* 5487c478bd9Sstevel@tonic-gate * This active flag will remain ON until application calls 5497c478bd9Sstevel@tonic-gate * C_SignRecover to actually obtain the signature. 5507c478bd9Sstevel@tonic-gate */ 5517c478bd9Sstevel@tonic-gate session_p->sign.flags = CRYPTO_OPERATION_ACTIVE; 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate /* Set up the key data */ 5547c478bd9Sstevel@tonic-gate if (!key_p->is_lib_obj) { 5557c478bd9Sstevel@tonic-gate sr_init.ri_key.ck_format = CRYPTO_KEY_REFERENCE; 5567c478bd9Sstevel@tonic-gate sr_init.ri_key.ck_obj_id = key_p->k_handle; 5577c478bd9Sstevel@tonic-gate } else { 5587c478bd9Sstevel@tonic-gate if (key_p->key_type == CKK_RSA) { 5597c478bd9Sstevel@tonic-gate if (get_rsa_private_key(key_p, &sr_init.ri_key) != 5607c478bd9Sstevel@tonic-gate CKR_OK) { 5617c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 5627c478bd9Sstevel@tonic-gate goto clean_exit; 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate } else { 5657c478bd9Sstevel@tonic-gate rv = CKR_KEY_TYPE_INCONSISTENT; 5667c478bd9Sstevel@tonic-gate goto clean_exit; 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate sr_init.ri_session = session_p->k_session; 5717c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 5727c478bd9Sstevel@tonic-gate ses_lock_held = B_FALSE; 5737c478bd9Sstevel@tonic-gate sr_init.ri_mech.cm_type = k_mech_type; 5747c478bd9Sstevel@tonic-gate sr_init.ri_mech.cm_param = pMechanism->pParameter; 5757c478bd9Sstevel@tonic-gate sr_init.ri_mech.cm_param_len = pMechanism->ulParameterLen; 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_SIGN_RECOVER_INIT, &sr_init)) < 0) { 5787c478bd9Sstevel@tonic-gate if (errno != EINTR) 5797c478bd9Sstevel@tonic-gate break; 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate if (r < 0) { 5827c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 5837c478bd9Sstevel@tonic-gate } else { 5847c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(sr_init.ri_return_value); 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate if (key_p->is_lib_obj) { 5887c478bd9Sstevel@tonic-gate free_key_attributes(&sr_init.ri_key); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 5927c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 5937c478bd9Sstevel@tonic-gate session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE; 5947c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 5957c478bd9Sstevel@tonic-gate } 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate clean_exit: 59801223cbaSmcpowers OBJ_REFRELE(key_p); 5997c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 6007c478bd9Sstevel@tonic-gate return (rv); 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate CK_RV 6057c478bd9Sstevel@tonic-gate C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 6067c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) 6077c478bd9Sstevel@tonic-gate { 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate CK_RV rv; 6107c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 6117c478bd9Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE; 6127c478bd9Sstevel@tonic-gate crypto_sign_recover_t sign_recover; 6137c478bd9Sstevel@tonic-gate int r; 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate if (!kernel_initialized) 6167c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate /* Obatin the session pointer */ 6197c478bd9Sstevel@tonic-gate rv = handle2session(hSession, &session_p); 6207c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 6217c478bd9Sstevel@tonic-gate return (rv); 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate if (pulSignatureLen == NULL) { 6247c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 6257c478bd9Sstevel@tonic-gate goto clean_exit; 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 6297c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate /* Application must call C_SignInit before calling C_Sign. */ 6327c478bd9Sstevel@tonic-gate if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) { 6337c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 6347c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED); 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate sign_recover.sr_session = session_p->k_session; 6387c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 6397c478bd9Sstevel@tonic-gate ses_lock_held = B_FALSE; 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate sign_recover.sr_datalen = ulDataLen; 6427c478bd9Sstevel@tonic-gate sign_recover.sr_databuf = (char *)pData; 6437c478bd9Sstevel@tonic-gate sign_recover.sr_signlen = *pulSignatureLen; 6447c478bd9Sstevel@tonic-gate sign_recover.sr_signbuf = (char *)pSignature; 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_SIGN_RECOVER, &sign_recover)) < 0) { 6477c478bd9Sstevel@tonic-gate if (errno != EINTR) 6487c478bd9Sstevel@tonic-gate break; 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate if (r < 0) { 6517c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 6527c478bd9Sstevel@tonic-gate } else { 6537c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(sign_recover.sr_return_value); 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL) 6577c478bd9Sstevel@tonic-gate *pulSignatureLen = sign_recover.sr_signlen; 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate if ((rv == CKR_BUFFER_TOO_SMALL) || 6607c478bd9Sstevel@tonic-gate (rv == CKR_OK && pSignature == NULL)) { 6617c478bd9Sstevel@tonic-gate /* 6627c478bd9Sstevel@tonic-gate * We will not terminate the active sign operation flag, 6637c478bd9Sstevel@tonic-gate * when the application-supplied buffer is too small, or 6647c478bd9Sstevel@tonic-gate * the application asks for the length of buffer to hold 6657c478bd9Sstevel@tonic-gate * the signature. 6667c478bd9Sstevel@tonic-gate */ 6677c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 6687c478bd9Sstevel@tonic-gate return (rv); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate clean_exit: 6727c478bd9Sstevel@tonic-gate /* 6737c478bd9Sstevel@tonic-gate * Terminates the active sign operation. 6747c478bd9Sstevel@tonic-gate * Application needs to call C_SignInit again for next 6757c478bd9Sstevel@tonic-gate * sign operation. 6767c478bd9Sstevel@tonic-gate */ 6777c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 6787c478bd9Sstevel@tonic-gate ses_lock_held = B_TRUE; 679b232b5fcSZdenek Kotala session_p->sign.flags = 0; 6807c478bd9Sstevel@tonic-gate REFRELE(session_p, ses_lock_held); 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate return (rv); 6837c478bd9Sstevel@tonic-gate } 684