示例#1
0
CK_RV
C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
{
	kms_session_t *session_p;
	CK_RV rv;
	boolean_t ses_lock_held = B_FALSE;

	if (!kms_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	if (pInfo == NULL)
		return (CKR_ARGUMENTS_BAD);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/* Provide information for the specified session */
	pInfo->slotID = session_p->ses_slotid;
	pInfo->flags = session_p->flags;
	pInfo->ulDeviceError = 0;
	pInfo->state = get_ses_state(session_p);

	/*
	 * Decrement the session reference count.
	 */
	REFRELE(session_p, ses_lock_held);

	return (rv);
}
示例#2
0
CK_RV
C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
    CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey,
    CK_OBJECT_HANDLE hAuthenticationKey)
{
	soft_session_t *session_p;
	CK_RV rv;
	boolean_t lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if ((pOperationState == NULL_PTR) ||
	    (ulOperationStateLen == 0)) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	rv = soft_set_operationstate(session_p, pOperationState,
	    ulOperationStateLen, hEncryptionKey, hAuthenticationKey);

clean_exit:
	SES_REFRELE(session_p, lock_held);
	return (rv);
}
示例#3
0
CK_RV
C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
    CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obatin the session pointer */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pData == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/* Application must call C_VerifyInit before calling C_Verify. */
	if (!(session_p->verify.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	/*
	 * C_Verify must be called without intervening C_VerifyUpdate
	 * calls.
	 */
	if (session_p->verify.flags & CRYPTO_OPERATION_UPDATE) {
		/*
		 * C_Verify can not be used to terminate a multi-part
		 * operation, so we'll leave the active verify operation
		 * flag on and let the application continue with the
		 * verify update operation.
		 */
		SES_REFRELE(session_p, lock_held);
		return (CKR_FUNCTION_FAILED);
	}

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_verify(session_p, pData, ulDataLen, pSignature,
	    ulSignatureLen);

clean_exit:
	/* Clear context, free key, and release session counter */
	cpk_sign_verify_cleanup(session_p, B_FALSE, B_FALSE);

	return (rv);
}
示例#4
0
文件: cpkSign.c 项目: weicz/cpkcrypto
CK_RV
C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
    CK_ULONG ulPartLen)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (ulPartLen == 0) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OK);
	}

	if (pPart == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/*
	 * Application must call C_SignInit before calling
	 * C_SignUpdate.
	 */
	if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	session_p->sign.flags |= CRYPTO_OPERATION_UPDATE;

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_sign_update(session_p, pPart, ulPartLen);

	if (rv == CKR_OK) {
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

clean_exit:
	/* After error, clear context, free key, & release session counter */
	cpk_sign_verify_cleanup(session_p, B_TRUE, B_FALSE);

	return (rv);

}
示例#5
0
文件: cpkSign.c 项目: weicz/cpkcrypto
CK_RV
C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
    CK_ULONG_PTR pulSignatureLen)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pulSignatureLen == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/*
	 * Application must call C_SignInit before calling
	 * C_SignFinal.
	 */
	if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_sign_final(session_p, pSignature, pulSignatureLen);

	if ((rv == CKR_BUFFER_TOO_SMALL) ||
	    (pSignature == NULL && rv == CKR_OK)) {
		/*
		 * We will not terminate the active sign operation flag,
		 * when the application-supplied buffer is too small, or
		 * the application asks for the length of buffer to hold
		 * the signature.
		 */
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

clean_exit:
	/* Clear contexts, free key, and release session counter */
	cpk_sign_verify_cleanup(session_p, B_TRUE, B_FALSE);

	return (rv);
}
示例#6
0
CK_RV
C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
    CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pData == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	if (pulEncryptedDataLen == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	if (session_p->encrypt.flags & CRYPTO_OPERATION_UPDATE) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_FUNCTION_FAILED);
	}

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_encrypt(session_p, pData, ulDataLen, pEncryptedData,
	    pulEncryptedDataLen);

	if ((rv == CKR_BUFFER_TOO_SMALL) ||
	    (pEncryptedData == NULL && rv == CKR_OK)) {
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

clean_exit:
	cpk_crypt_cleanup(session_p, B_TRUE, B_FALSE);
	return (rv);
}
示例#7
0
CK_RV
C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    CK_OBJECT_HANDLE hKey)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	cpk_object_t	*key_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pMechanism == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	HANDLE2OBJECT(hKey, key_p, rv);
	if (rv != CKR_OK)
		goto clean_exit;


	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
		cpk_crypt_cleanup(session_p, B_TRUE, lock_held);
	}

	session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_encrypt_init(session_p, pMechanism, key_p);

	if (rv != CKR_OK) {
		(void) pthread_mutex_lock(&session_p->session_mutex);
		session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
		lock_held = B_TRUE;
	}

	OBJ_REFRELE(key_p);
clean_exit:
	SES_REFRELE(session_p, lock_held);
	return (rv);
}
示例#8
0
CK_RV
C_CloseSession(CK_SESSION_HANDLE hSession)
{
	CK_RV rv;

	kms_session_t *session_p;
	boolean_t ses_lock_held = B_FALSE;

	if (!kms_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	(void) pthread_mutex_lock(&session_p->session_mutex);
	ses_lock_held = B_TRUE;

	/*
	 * Set SESSION_IS_CLOSING flag so any access to this
	 * session will be rejected.
	 */
	if (session_p->ses_close_sync & SESSION_IS_CLOSING) {
		REFRELE(session_p, ses_lock_held);
		return (CKR_SESSION_CLOSED);
	}
	session_p->ses_close_sync |= SESSION_IS_CLOSING;

	/*
	 * Decrement the session reference count.
	 * We hold the session lock, and REFRELE()
	 * will release the session lock for us.
	 */
	REFRELE(session_p, ses_lock_held);

	/*
	 * Delete a session by calling kms_delete_session() with
	 * a session pointer and two boolean arguments. The 3rd argument
	 * boolean value FALSE indicates that the caller does not
	 * hold the slot lock.  The 4th argument boolean value B_FALSE
	 * indicates that we want to delete all the objects completely.
	 *
	 * kms_delete_session() will reset SESSION_IS_CLOSING
	 * flag after it is done.
	 */
	kms_delete_session(session_p, B_FALSE, B_FALSE);
	return (rv);
}
示例#9
0
CK_RV
C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
    CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
{

	soft_session_t *session_p;
	CK_RV rv;
	boolean_t lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (!soft_keystore_status(KEYSTORE_LOAD)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_DEVICE_REMOVED);
	}

	if ((ulOldPinLen < MIN_PIN_LEN) || (ulOldPinLen > MAX_PIN_LEN) ||
	    (ulNewPinLen < MIN_PIN_LEN) ||(ulNewPinLen > MAX_PIN_LEN)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_PIN_LEN_RANGE);
	}

	if ((pOldPin == NULL_PTR) || (pNewPin == NULL_PTR)) {
		/*
		 * We don't support CKF_PROTECTED_AUTHENTICATION_PATH
		 */
		SES_REFRELE(session_p, lock_held);
		return (CKR_ARGUMENTS_BAD);
	}

	/* check the state of the session */
	if ((session_p->state != CKS_RW_PUBLIC_SESSION) &&
	    (session_p->state != CKS_RW_USER_FUNCTIONS)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_SESSION_READ_ONLY);
	}

	rv = soft_setpin(pOldPin, ulOldPinLen, pNewPin, ulNewPinLen);

	SES_REFRELE(session_p, lock_held);
	return (rv);
}
示例#10
0
CK_RV
C_Logout(CK_SESSION_HANDLE hSession)
{
	CK_RV	rv = CKR_OK;
	kms_session_t *session_p;
	kms_slot_t	*pslot;
	boolean_t ses_lock_held = B_FALSE;

	if (!kms_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/* Acquire the slot lock. */
	pslot = get_slotinfo();
	(void) pthread_mutex_lock(&pslot->sl_mutex);

	/* Check if the user or SO was logged in  */
	if (pslot->sl_state == CKU_PUBLIC) {
		rv = CKR_USER_NOT_LOGGED_IN;
		goto clean_exit;
	}

	KMS_UnloadProfile(&session_p->kmsProfile);

	/*
	 * If this slot was logged in as USER previously, we need to clean up
	 * all private object wrappers in library for this slot.
	 */
	kms_cleanup_pri_objects_in_slot(pslot, session_p);

	if (rv == CKR_OK) {
		/* Reset the slot's session state. */
		pslot->sl_state = CKU_PUBLIC;
	}

clean_exit:
	REFRELE(session_p, ses_lock_held);
	(void) pthread_mutex_unlock(&pslot->sl_mutex);
	return (rv);
}
示例#11
0
CK_RV
C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
{

	soft_session_t *session_p;
	CK_RV rv;
	boolean_t lock_held = B_TRUE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pInfo == NULL) {
		lock_held = B_FALSE;
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);

	/* Provide information for the specified session */
	pInfo->slotID = SOFTTOKEN_SLOTID;
	pInfo->state = session_p->state;
	pInfo->flags = session_p->flags;
	pInfo->ulDeviceError = 0;

clean_exit:
	/*
	 * Decrement the session reference count.
	 * We hold the session lock, and SES_REFRELE()
	 * will release the session lock for us.
	 */
	SES_REFRELE(session_p, lock_held);

	return (rv);
}
示例#12
0
CK_RV
C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
    CK_ULONG ulSignatureLen)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/*
	 * Application must call C_VerifyInit before calling
	 * C_VerifyFinal.
	 */
	if (!(session_p->verify.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_verify_final(session_p, pSignature, ulSignatureLen);

	/* Clear contexts, free key, and release session counter */
	cpk_sign_verify_cleanup(session_p, B_FALSE, B_FALSE);

	return (rv);
}
示例#13
0
CK_RV
C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
    CK_ULONG_PTR pulOperationStateLen)
{
	soft_session_t *session_p;
	CK_RV rv;
	boolean_t lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/*
	 * Only check if pulOperationStateLen is NULL_PTR.
	 * No need to check if pOperationState is NULL_PTR because
	 * application might just ask for the length of buffer to hold
	 * the OperationState.
	 */
	if (pulOperationStateLen == NULL_PTR) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	rv = soft_get_operationstate(session_p, pOperationState,
	    pulOperationStateLen);

clean_exit:
	SES_REFRELE(session_p, lock_held);
	return (rv);

}
示例#14
0
CK_RV
C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    CK_OBJECT_HANDLE hKey)
{

	CK_RV		rv;
	soft_session_t	*session_p;
	soft_object_t	*key_p;
	boolean_t	lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pMechanism == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	/* Obtain the object pointer. */
	HANDLE2OBJECT(hKey, key_p, rv);
	if (rv != CKR_OK)
		goto clean_exit;

	/* Check to see if key object allows for encryption. */
	if (!(key_p->bool_attr_mask & ENCRYPT_BOOL_ON)) {
		rv = CKR_KEY_FUNCTION_NOT_PERMITTED;
		goto clean_exit1;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/* Check to see if encrypt operation is already active. */
	if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
		/* free the memory to avoid memory leak */
		soft_crypt_cleanup(session_p, B_TRUE, lock_held);
	}

	/*
	 * This active flag will remain ON until application calls either
	 * C_Encrypt or C_EncryptFinal to actually obtain the final piece
	 * of ciphertext.
	 */
	session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = soft_encrypt_init(session_p, pMechanism, key_p);

	if (rv != CKR_OK) {
		(void) pthread_mutex_lock(&session_p->session_mutex);
		session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
		lock_held = B_TRUE;
	}

clean_exit1:
	OBJ_REFRELE(key_p);
clean_exit:
	SES_REFRELE(session_p, lock_held);
	return (rv);
}
示例#15
0
CK_RV
C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart,
    CK_ULONG_PTR pulLastEncryptedPartLen)
{

	CK_RV		rv;
	soft_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pulLastEncryptedPartLen == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/*
	 * Application must call C_EncryptInit before calling
	 * C_EncryptFinal.
	 */
	if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = soft_encrypt_final(session_p, pLastEncryptedPart,
	    pulLastEncryptedPartLen);

	if ((rv == CKR_BUFFER_TOO_SMALL) ||
	    (pLastEncryptedPart == NULL && rv == CKR_OK)) {
		/*
		 * We will not terminate the active encrypt operation flag,
		 * when the application-supplied buffer is too small, or
		 * the application asks for the length of buffer to hold
		 * the ciphertext.
		 */
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

	/* Terminates the active encrypt operation. */
	(void) pthread_mutex_lock(&session_p->session_mutex);
	session_p->encrypt.flags = 0;
	lock_held = B_TRUE;
	SES_REFRELE(session_p, lock_held);

	return (rv);

clean_exit:
	/* Terminates the active encrypt operation. */
	soft_crypt_cleanup(session_p, B_TRUE, lock_held);

	return (rv);
}
示例#16
0
CK_RV
C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
    CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
    CK_ULONG_PTR pulEncryptedPartLen)
{

	CK_RV		rv;
	soft_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/*
	 * Only check if input buffer is null.  How to handle zero input
	 * length depends on the mechanism in use.  For secret key mechanisms,
	 * unpadded ones yeild zero length output, but padded ones always
	 * result in greater than zero length output.
	 */
	if (pPart == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	/*
	 * Only check if pulEncryptedPartLen is NULL.
	 * No need to check if pEncryptedPart is NULL because
	 * application might just ask for the length of buffer to hold
	 * the ciphertext.
	 */
	if (pulEncryptedPartLen == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/*
	 * Application must call C_EncryptInit before calling
	 * C_EncryptUpdate.
	 */
	if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	session_p->encrypt.flags |= CRYPTO_OPERATION_UPDATE;

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = soft_encrypt_update(session_p, pPart, ulPartLen,
	    pEncryptedPart, pulEncryptedPartLen);

	/*
	 * If CKR_OK or CKR_BUFFER_TOO_SMALL, don't terminate the
	 * current encryption operation.
	 */
	if ((rv == CKR_OK) || (rv == CKR_BUFFER_TOO_SMALL)) {
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

clean_exit:
	/*
	 * After an error occurred, terminate the current encrypt
	 * operation by resetting the active and update flags.
	 */
	soft_crypt_cleanup(session_p, B_TRUE, lock_held);

	return (rv);
}
示例#17
0
CK_RV
C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
    CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
{

	CK_RV		rv;
	soft_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/*
	 * Only check if input buffer is null.  How to handle zero input
	 * length depends on the mechanism in use.  For secret key mechanisms,
	 * unpadded ones yield zero length output, but padded ones always
	 * result in greater than zero length output.
	 */
	if (pData == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	/*
	 * Only check if pulEncryptedDataLen is NULL.
	 * No need to check if pEncryptedData is NULL because
	 * application might just ask for the length of buffer to hold
	 * the ciphertext.
	 */
	if (pulEncryptedDataLen == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/* Application must call C_EncryptInit before calling C_Encrypt. */
	if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	/*
	 * C_Encrypt must be called without intervening C_EncryptUpdate
	 * calls.
	 */
	if (session_p->encrypt.flags & CRYPTO_OPERATION_UPDATE) {
		/*
		 * C_Encrypt can not be used to terminate a multi-part
		 * operation, so we'll leave the active encrypt operation
		 * flag on and let the application continue with the
		 * encrypt update operation.
		 */
		SES_REFRELE(session_p, lock_held);
		return (CKR_FUNCTION_FAILED);
	}

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = soft_encrypt(session_p, pData, ulDataLen, pEncryptedData,
	    pulEncryptedDataLen);

	if ((rv == CKR_BUFFER_TOO_SMALL) ||
	    (pEncryptedData == NULL && rv == CKR_OK)) {
		/*
		 * We will not terminate the active encrypt operation flag,
		 * when the application-supplied buffer is too small, or
		 * the application asks for the length of buffer to hold
		 * the ciphertext.
		 */
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

clean_exit:
	/* Clear context, free key, and release session counter */
	soft_crypt_cleanup(session_p, B_TRUE, B_FALSE);
	return (rv);
}
示例#18
0
CK_RV
C_Logout(CK_SESSION_HANDLE hSession)
{

	soft_session_t *session_p, *sp;
	CK_RV rv;
	boolean_t lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	(void) pthread_mutex_lock(&soft_giant_mutex);
	if (!soft_slot.authenticated) {
		if (!soft_slot.userpin_change_needed) {
			/*
			 * Only if the PIN has been initialized in the keystore.
			 */
			(void) pthread_mutex_unlock(&soft_giant_mutex);
			SES_REFRELE(session_p, lock_held);
			return (CKR_USER_NOT_LOGGED_IN);
		} else {
			soft_slot.userpin_change_needed = 0;
			(void) pthread_mutex_unlock(&soft_giant_mutex);
			SES_REFRELE(session_p, lock_held);
			return (CKR_OK);
		}
	}

	soft_logout();
	soft_slot.authenticated = 0;
	(void) pthread_mutex_unlock(&soft_giant_mutex);

	/* Acquire the global session list lock */
	(void) pthread_mutex_lock(&soft_sessionlist_mutex);

	sp = soft_session_list;

	while (sp) {
		(void) pthread_mutex_lock(&sp->session_mutex);

		if (sp->flags & CKF_RW_SESSION) {
			sp->state = CKS_RW_PUBLIC_SESSION;
		} else {
			sp->state = CKS_RO_PUBLIC_SESSION;
		}
		(void) pthread_mutex_unlock(&sp->session_mutex);
		sp = sp->next;
	}

	(void) pthread_mutex_unlock(&soft_sessionlist_mutex);

	SES_REFRELE(session_p, lock_held);
	return (rv);

}
示例#19
0
CK_RV
C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
    CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
{
	CK_RV			rv = CKR_OK;
	kernel_session_t	*session_p;
	kernel_object_t		*basekey_p;
	kernel_object_t		*new_objp;
	kernel_slot_t		*pslot;
	boolean_t		ses_lock_held = B_FALSE;
	CK_BBOOL		is_pri_obj;
	CK_BBOOL		is_token_obj = FALSE;
	crypto_mech_type_t	k_mech_type;
	crypto_derive_key_t	obj_dk;
	int r;

	if (!kernel_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pMechanism == NULL) {
		REFRELE(session_p, ses_lock_held);
		return (CKR_ARGUMENTS_BAD);
	}

	if ((pTemplate == NULL && ulAttributeCount != 0) ||
	    (pTemplate != NULL && ulAttributeCount == 0)) {
		REFRELE(session_p, ses_lock_held);
		return (CKR_ARGUMENTS_BAD);
	}

	/* Obtain the base key object pointer. */
	HANDLE2OBJECT(hBaseKey, basekey_p, rv);
	if (rv != CKR_OK) {
		REFRELE(session_p, ses_lock_held);
		return (rv);
	}

	/* Get the kernel's internal mechanism number. */
	rv = kernel_mech(pMechanism->mechanism, &k_mech_type);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Create an object wrapper in the library for the generated key. */
	new_objp = calloc(1, sizeof (kernel_object_t));
	if (new_objp == NULL) {
		rv = CKR_HOST_MEMORY;
		goto failed_exit;
	}

	/* Process the attributes */
	rv = process_object_attributes(pTemplate, ulAttributeCount,
	    &obj_dk.dk_attributes, &is_token_obj);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Cannot create a token object with a READ-ONLY session. */
	if (is_token_obj && session_p->ses_RO) {
		free_object_attributes(obj_dk.dk_attributes, ulAttributeCount);
		rv = CKR_SESSION_READ_ONLY;
		goto failed_exit;
	}

	/* Call the CRYPTO_DERIVE_KEY ioctl */
	obj_dk.dk_session = session_p->k_session;
	obj_dk.dk_mechanism.cm_type = k_mech_type;
	obj_dk.dk_mechanism.cm_param = pMechanism->pParameter;
	obj_dk.dk_mechanism.cm_param_len = pMechanism->ulParameterLen;
	obj_dk.dk_base_key.ck_format = CRYPTO_KEY_REFERENCE;
	obj_dk.dk_base_key.ck_obj_id = basekey_p->k_handle;
	obj_dk.dk_count = ulAttributeCount;

	while ((r = ioctl(kernel_fd, CRYPTO_DERIVE_KEY, &obj_dk)) < 0) {
		if (errno != EINTR)
			break;
	}
	if (r < 0) {
		rv = CKR_FUNCTION_FAILED;
	} else {
		rv = crypto2pkcs11_error_number(obj_dk.dk_return_value);
	}

	free_object_attributes(obj_dk.dk_attributes, ulAttributeCount);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Get the CKA_PRIVATE value for the derived key. */
	rv = get_cka_private_value(session_p, obj_dk.dk_object_handle,
	    &is_pri_obj);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/*
	 * Store the kernel object handle into the new derived key object
	 * and finish the object initialization.
	 */
	new_objp->is_lib_obj = B_FALSE;
	new_objp->k_handle = obj_dk.dk_object_handle;
	new_objp->session_handle = (CK_SESSION_HANDLE)session_p;
	new_objp->extra_attrlistp = NULL;

	if (is_pri_obj)
		new_objp->bool_attr_mask |= PRIVATE_BOOL_ON;
	else
		new_objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;

	if (is_token_obj)
		new_objp->bool_attr_mask |= TOKEN_BOOL_ON;
	else
		new_objp->bool_attr_mask &= ~TOKEN_BOOL_ON;

	(void) pthread_mutex_init(&new_objp->object_mutex, NULL);
	new_objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;

	/*
	 * Add the new derived object to the slot's token list if it is a
	 * token object. Otherwise, add it to the session's object list.
	 */
	if (is_token_obj) {
		pslot = slot_table[session_p->ses_slotid];
		kernel_add_token_object_to_slot(new_objp, pslot);
	} else {
		kernel_add_object_to_session(new_objp, session_p);
	}

	*phKey = (CK_OBJECT_HANDLE)new_objp;
	OBJ_REFRELE(basekey_p);
	REFRELE(session_p, ses_lock_held);
	return (rv);

failed_exit:
	OBJ_REFRELE(basekey_p);
	if (new_objp != NULL) {
		(void) free(new_objp);
	}

	REFRELE(session_p, ses_lock_held);
	return (rv);
}
示例#20
0
CK_RV
C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey,
    CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
    CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
{
	CK_RV			rv = CKR_OK;
	kernel_session_t	*session_p;
	kernel_object_t		*unwrappingkey_p;
	kernel_object_t		*new_objp = NULL;
	kernel_slot_t		*pslot;
	boolean_t		ses_lock_held = B_FALSE;
	CK_BBOOL		is_pri_obj;
	CK_BBOOL		is_token_obj = FALSE;
	CK_MECHANISM_INFO	info;
	uint32_t		k_mi_flags;
	CK_BYTE			*clear_key_val = NULL;
	CK_ULONG 		ulDataLen;
	CK_ATTRIBUTE_PTR	newTemplate = NULL;
	CK_ULONG		templ_size;
	crypto_mech_type_t	k_mech_type;
	crypto_object_unwrap_key_t obj_unwrapkey;
	int r;

	if (!kernel_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	if (pMechanism == NULL || pWrappedKey == NULL || phKey == NULL) {
		return (CKR_ARGUMENTS_BAD);
	}

	if ((pTemplate == NULL) && (ulAttributeCount != 0)) {
		return (CKR_ARGUMENTS_BAD);
	}

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/* Obtain the wrapping key object pointer. */
	HANDLE2OBJECT(hUnwrappingKey, unwrappingkey_p, rv);
	if (rv != CKR_OK) {
		REFRELE(session_p, ses_lock_held);
		return (rv);
	}

	/*
	 * If the HW provider doesn't support C_UnwrapKey, we will try
	 * to emulate it in the library.
	 */
	pslot = slot_table[session_p->ses_slotid];
	if ((pslot->sl_func_list.fl_object_create == B_FALSE) &&
	    (pslot->sl_func_list.fl_key_unwrap == B_FALSE)) {
		rv = get_mechanism_info(pslot, pMechanism->mechanism, &info,
		    &k_mi_flags);
		if (rv != CKR_OK) {
			goto failed_exit;
		}

		/*
		 * If the mechanism flag doesn't have CKF_UNWRAP, and it's
		 * an unwrapping of a secret key object, then help this
		 * out with a decryption followed by an object creation.
		 */
		if (!(k_mi_flags & CRYPTO_FG_UNWRAP) &&
		    (k_mi_flags & CRYPTO_FG_DECRYPT) &&
		    (is_secret_key_template(pTemplate, ulAttributeCount))) {

			/* First allocate space for the recovered key value */
			clear_key_val = malloc(ulWrappedKeyLen);
			if (clear_key_val == NULL) {
				rv = CKR_HOST_MEMORY;
				goto failed_exit;
			}

			rv = kernel_decrypt_init(session_p, unwrappingkey_p,
			    pMechanism);
			if (rv != CKR_OK) {
				goto failed_exit;
			}

			ulDataLen = ulWrappedKeyLen;
			rv = kernel_decrypt(session_p, pWrappedKey,
			    ulWrappedKeyLen, clear_key_val, &ulDataLen);
			if (rv != CKR_OK) {
				goto failed_exit;
			}

			/* Now add the CKA_VALUE attribute to template */
			templ_size = ulAttributeCount * sizeof (CK_ATTRIBUTE);
			newTemplate = malloc(templ_size +
			    sizeof (CK_ATTRIBUTE));
			if (newTemplate == NULL) {
				rv = CKR_HOST_MEMORY;
				goto failed_exit;
			}

			bcopy(pTemplate, newTemplate, templ_size);
			newTemplate[ulAttributeCount].type = CKA_VALUE;
			newTemplate[ulAttributeCount].pValue = clear_key_val;
			newTemplate[ulAttributeCount].ulValueLen = ulDataLen;

			/* Finally create the key, based on the new template */
			rv = kernel_add_object(newTemplate,
			    ulAttributeCount + 1, phKey, session_p);
			(void) free(clear_key_val);
			(void) free(newTemplate);
			OBJ_REFRELE(unwrappingkey_p);
			REFRELE(session_p, ses_lock_held);
			return (rv);
		} else {
			rv = CKR_FUNCTION_FAILED;
			goto failed_exit;
		}
	}

	/*
	 * If we come here, the HW provider must have registered the unwrapkey
	 * entry.  Therefore, the unwrap key will be performed in the HW
	 * provider.
	 */
	rv = kernel_mech(pMechanism->mechanism, &k_mech_type);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Create an object wrapper for the new key in the library first */
	new_objp = calloc(1, sizeof (kernel_object_t));
	if (new_objp == NULL) {
		rv = CKR_HOST_MEMORY;
		goto failed_exit;
	}

	/* Process the attributes */
	rv = process_object_attributes(pTemplate, ulAttributeCount,
	    &obj_unwrapkey.uk_attributes, &is_token_obj);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Cannot create a token object with a READ-ONLY session. */
	if (is_token_obj && session_p->ses_RO) {
		free_object_attributes(obj_unwrapkey.uk_attributes,
		    ulAttributeCount);
		rv = CKR_SESSION_READ_ONLY;
		goto failed_exit;
	}

	/* Make the CRYPTO_UNWRAP_KEY ioctl call. */
	obj_unwrapkey.uk_session = session_p->k_session;
	obj_unwrapkey.uk_mechanism.cm_type = k_mech_type;
	obj_unwrapkey.uk_mechanism.cm_param = pMechanism->pParameter;
	obj_unwrapkey.uk_mechanism.cm_param_len = pMechanism->ulParameterLen;
	obj_unwrapkey.uk_unwrapping_key.ck_format = CRYPTO_KEY_REFERENCE;
	obj_unwrapkey.uk_unwrapping_key.ck_obj_id = unwrappingkey_p->k_handle;
	obj_unwrapkey.uk_wrapped_key = (char *)pWrappedKey;
	obj_unwrapkey.uk_wrapped_key_len = ulWrappedKeyLen;
	obj_unwrapkey.uk_count = ulAttributeCount;

	while ((r = ioctl(kernel_fd, CRYPTO_UNWRAP_KEY, &obj_unwrapkey)) < 0) {
		if (errno != EINTR)
			break;
	}
	if (r < 0) {
		rv = CKR_FUNCTION_FAILED;
	} else {
		rv = crypto2pkcs11_error_number(obj_unwrapkey.uk_return_value);
	}

	free_object_attributes(obj_unwrapkey.uk_attributes, ulAttributeCount);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Get the CKA_PRIVATE value for the unwrapped key. */
	rv = get_cka_private_value(session_p, obj_unwrapkey.uk_object_handle,
	    &is_pri_obj);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/*
	 * Store the kernel object handle in the new key object wrapper and
	 * initialize it.
	 */
	new_objp->k_handle = obj_unwrapkey.uk_object_handle;
	new_objp->is_lib_obj = B_FALSE;
	new_objp->session_handle = (CK_SESSION_HANDLE)session_p;
	new_objp->extra_attrlistp = NULL;

	if (is_pri_obj)
		new_objp->bool_attr_mask |= PRIVATE_BOOL_ON;
	else
		new_objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;

	if (is_token_obj)
		new_objp->bool_attr_mask |= TOKEN_BOOL_ON;
	else
		new_objp->bool_attr_mask &= ~TOKEN_BOOL_ON;

	(void) pthread_mutex_init(&new_objp->object_mutex, NULL);
	new_objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;

	/*
	 * Add the new object to the slot's token object list if it is a
	 * a token object. Otherwise, add it to the session's object list.
	 */
	if (is_token_obj) {
		pslot = slot_table[session_p->ses_slotid];
		kernel_add_token_object_to_slot(new_objp, pslot);
	} else {
		kernel_add_object_to_session(new_objp, session_p);
	}

	*phKey = (CK_OBJECT_HANDLE)new_objp;
	OBJ_REFRELE(unwrappingkey_p);
	REFRELE(session_p, ses_lock_held);
	return (rv);

failed_exit:
	OBJ_REFRELE(unwrappingkey_p);
	if (new_objp != NULL)
		(void) free(new_objp);

	if (clear_key_val != NULL)
		(void) free(clear_key_val);

	if (newTemplate != NULL)
		(void) free(newTemplate);

	REFRELE(session_p, ses_lock_held);
	return (rv);
}
示例#21
0
CK_RV
C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
    CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
{
	CK_RV			rv = CKR_OK;
	kernel_session_t	*session_p;
	boolean_t		ses_lock_held = B_FALSE;
	kernel_object_t		*wrappingkey_p;
	kernel_object_t		*key_p;
	crypto_mech_type_t	k_mech_type;
	crypto_object_wrap_key_t obj_wrapkey;
	int r;

	if (!kernel_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	if (pulWrappedKeyLen == NULL || pMechanism == NULL) {
		return (CKR_ARGUMENTS_BAD);
	}

	/*
	 * Obtain the session pointer.  Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/* Get the kernel's internal mechanism number. */
	rv = kernel_mech(pMechanism->mechanism, &k_mech_type);
	if (rv != CKR_OK) {
		REFRELE(session_p, ses_lock_held);
		return (rv);
	}

	/* Obtain the wrapping key object pointer. */
	HANDLE2OBJECT(hWrappingKey, wrappingkey_p, rv);
	if (rv != CKR_OK) {
		REFRELE(session_p, ses_lock_held);
		return (rv);
	}

	/* Obtain the to_be_wrapped key object pointer. */
	HANDLE2OBJECT(hKey, key_p, rv);
	if (rv != CKR_OK) {
		OBJ_REFRELE(wrappingkey_p);
		REFRELE(session_p, ses_lock_held);
		return (rv);
	}

	/* Make the CRYPTO_OBJECT_WRAP_KEY ioctl call. */
	obj_wrapkey.wk_session = session_p->k_session;
	obj_wrapkey.wk_mechanism.cm_type = k_mech_type;
	obj_wrapkey.wk_mechanism.cm_param = pMechanism->pParameter;
	obj_wrapkey.wk_mechanism.cm_param_len = pMechanism->ulParameterLen;
	obj_wrapkey.wk_wrapping_key.ck_format = CRYPTO_KEY_REFERENCE;
	obj_wrapkey.wk_wrapping_key.ck_obj_id = wrappingkey_p->k_handle;
	obj_wrapkey.wk_object_handle = key_p->k_handle;
	obj_wrapkey.wk_wrapped_key_len = *pulWrappedKeyLen;
	obj_wrapkey.wk_wrapped_key = (char *)pWrappedKey;

	while ((r = ioctl(kernel_fd, CRYPTO_WRAP_KEY, &obj_wrapkey)) < 0) {
		if (errno != EINTR)
			break;
	}
	if (r < 0) {
		rv = CKR_FUNCTION_FAILED;
	} else {
		rv = crypto2pkcs11_error_number(obj_wrapkey.wk_return_value);
	}

	/*
	 * Besides rv == CKR_OK, we will set the value of pulWrappedKeyLen
	 * when the applciation-supplied wrapped key buffer is too small.
	 * The situation that the application only asks for the length of
	 * the wrapped key is covered in rv == CKR_OK.
	 */
	if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL) {
		*pulWrappedKeyLen = obj_wrapkey.wk_wrapped_key_len;
	}

	OBJ_REFRELE(key_p);
	OBJ_REFRELE(wrappingkey_p);
	REFRELE(session_p, ses_lock_held);
	return (rv);
}
示例#22
0
CK_RV
C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
    CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
{
	CK_RV	rv = CKR_OK;
	kms_session_t *session_p;
	kms_slot_t	*pslot;
	boolean_t ses_lock_held = B_FALSE;

	if (!kms_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	if ((userType != CKU_SO) && (userType != CKU_USER)) {
		return (CKR_USER_TYPE_INVALID);
	}

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/* Acquire the slot lock */
	pslot = get_slotinfo();
	(void) pthread_mutex_lock(&pslot->sl_mutex);

	/* Check if the slot is logged in already */
	if ((pslot->sl_state == CKU_USER) || (pslot->sl_state == CKU_SO)) {
		rv = CKR_USER_ALREADY_LOGGED_IN;
		goto clean_exit;
	}

	/* To login as SO, every session in this slot needs to be R/W */
	if (userType == CKU_SO) {
		kms_session_t  *sp;
		boolean_t	found;

		found = B_FALSE;
		sp = pslot->sl_sess_list;
		while (sp) {
			/*
			 * Need not to lock individual sessions before
			 * accessing their "ses_RO" and "next" fields,
			 * because they are always accessed under the
			 * slot's mutex protection.
			 */
			if (sp->ses_RO) {
				found = B_TRUE;
				break;
			}
			sp = sp->next;
		}

		if (found) {
			rv = CKR_SESSION_READ_ONLY_EXISTS;
			goto clean_exit;
		}
	}

	/*
	 * Login to KMS by attempting to load the profile using
	 * the given password.
	 */
	rv = KMS_LoadProfile(
	    &session_p->kmsProfile,
	    &session_p->configInfo,
	    (const char *)pPin,
	    (size_t)ulPinLen);

	if (rv == CKR_OK) {
		/* Set the slot's session state. */
		pslot->sl_state = userType;
	}

clean_exit:

	REFRELE(session_p, ses_lock_held);
	(void) pthread_mutex_unlock(&pslot->sl_mutex);
	return (rv);
}
示例#23
0
文件: cpkSign.c 项目: weicz/cpkcrypto
CK_RV
C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
    CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obatin the session pointer */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if ((pData == NULL) || (pulSignatureLen == NULL)) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/* Application must call C_SignInit before calling C_Sign. */
	if (!(session_p->sign.flags & CRYPTO_OPERATION_ACTIVE)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_OPERATION_NOT_INITIALIZED);
	}

	/*
	 * C_Sign must be called without intervening C_SignUpdate
	 * calls.
	 */
	if (session_p->sign.flags & CRYPTO_OPERATION_UPDATE) {
		/*
		 * C_Sign can not be used to terminate a multi-part
		 * operation, so we'll leave the active sign operation
		 * flag on and let the application continue with the
		 * sign update operation.
		 */
		SES_REFRELE(session_p, lock_held);
		return (CKR_FUNCTION_FAILED);
	}

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_sign(session_p, pData, ulDataLen, pSignature,
	    pulSignatureLen);

	if ((rv == CKR_BUFFER_TOO_SMALL) ||
	    (pSignature == NULL && rv == CKR_OK)) {
		/*
		 * We will not terminate the active sign operation flag,
		 * when the application-supplied buffer is too small, or
		 * the application asks for the length of buffer to hold
		 * the signature.
		 */
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

clean_exit:
	/* Clear contexts, free key, and release session counter */
	cpk_sign_verify_cleanup(session_p, B_TRUE, B_FALSE);
	return (rv);
}
示例#24
0
CK_RV
C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin,
    CK_ULONG ulPinLen)
{

	soft_session_t *session_p, *sp;
	CK_RV rv;
	boolean_t lock_held = B_FALSE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	/* Check the load status of keystore */
	if (!soft_keystore_status(KEYSTORE_LOAD)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_DEVICE_REMOVED);
	}

	if (userType != CKU_USER) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_USER_TYPE_INVALID);
	}

	if ((ulPinLen < MIN_PIN_LEN) || (ulPinLen > MAX_PIN_LEN)) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_PIN_LEN_RANGE);
	}

	if (pPin == NULL_PTR) {
		/*
		 * We don't support CKF_PROTECTED_AUTHENTICATION_PATH
		 */
		SES_REFRELE(session_p, lock_held);
		return (CKR_ARGUMENTS_BAD);
	}

	(void) pthread_mutex_lock(&soft_giant_mutex);
	if (soft_slot.authenticated) {
		(void) pthread_mutex_unlock(&soft_giant_mutex);
		SES_REFRELE(session_p, lock_held);
		return (CKR_USER_ALREADY_LOGGED_IN);
	}

	rv = soft_login(pPin, ulPinLen);
	if (rv == CKR_OK) {
		if (soft_slot.userpin_change_needed) {
			/*
			 * This is the special case when the PIN is never
			 * initialized in the keystore, which will always
			 * return CKR_OK with "userpin_change_needed" set.
			 */
			(void) pthread_mutex_unlock(&soft_giant_mutex);
			SES_REFRELE(session_p, lock_held);
			return (rv);
		}

		soft_slot.authenticated = 1;
		(void) pthread_mutex_unlock(&soft_giant_mutex);
	} else {
		(void) pthread_mutex_unlock(&soft_giant_mutex);
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

	/*
	 * Load all the private token objects from keystore.
	 */
	rv = soft_get_token_objects_from_keystore(PRI_TOKENOBJS);
	if (rv != CKR_OK) {
		SES_REFRELE(session_p, lock_held);
		return (rv);
	}

	/* Acquire the global session list lock */
	(void) pthread_mutex_lock(&soft_sessionlist_mutex);

	sp = soft_session_list;

	while (sp) {
		(void) pthread_mutex_lock(&sp->session_mutex);

		if (sp->flags & CKF_RW_SESSION) {
			sp->state = CKS_RW_USER_FUNCTIONS;
		} else {
			sp->state = CKS_RO_USER_FUNCTIONS;
		}
		(void) pthread_mutex_unlock(&sp->session_mutex);
		sp = sp->next;
	}

	(void) pthread_mutex_unlock(&soft_sessionlist_mutex);

	SES_REFRELE(session_p, lock_held);
	return (rv);

}
示例#25
0
CK_RV
C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    CK_OBJECT_HANDLE hKey)
{

	CK_RV		rv;
	cpk_session_t	*session_p;
	cpk_object_t	*key_p;
	boolean_t	lock_held = B_FALSE;

	if (!cpktoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if (pMechanism == NULL) {
		rv = CKR_ARGUMENTS_BAD;
		goto clean_exit;
	}

	/* Obtain the object pointer. */
	HANDLE2OBJECT(hKey, key_p, rv);
	if (rv != CKR_OK) {
		goto clean_exit;
	}

	(void) pthread_mutex_lock(&session_p->session_mutex);
	lock_held = B_TRUE;

	/* Check to see if verify operation is already active. */
	if (session_p->verify.flags & CRYPTO_OPERATION_ACTIVE) {
		/* free the memory to avoid memory leak */
		cpk_sign_verify_cleanup(session_p, B_FALSE, B_TRUE);
	}

	/*
	 * This active flag will remain ON until application calls either
	 * C_Verify or C_VerifyFinal to verify a signature on data.
	 */
	session_p->verify.flags = CRYPTO_OPERATION_ACTIVE;

	(void) pthread_mutex_unlock(&session_p->session_mutex);
	lock_held = B_FALSE;

	rv = cpk_verify_init(session_p, pMechanism, key_p);

	if (rv != CKR_OK) {
		(void) pthread_mutex_lock(&session_p->session_mutex);
		session_p->verify.flags &= ~CRYPTO_OPERATION_ACTIVE;
		lock_held = B_TRUE;
	}

	OBJ_REFRELE(key_p);
clean_exit:
	SES_REFRELE(session_p, lock_held);

	return (rv);
}
示例#26
0
CK_RV
C_GenerateKeyPair(CK_SESSION_HANDLE hSession, 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)
{
	CK_RV			rv = CKR_OK;
	kernel_session_t	*session_p;
	kernel_object_t		*new_pub_objp = NULL;
	kernel_object_t		*new_pri_objp = NULL;
	kernel_slot_t		*pslot;
	boolean_t		ses_lock_held = B_FALSE;
	CK_BBOOL		is_pri_obj1;
	CK_BBOOL		is_pri_obj2;
	CK_BBOOL		is_token_obj1 = FALSE;
	CK_BBOOL		is_token_obj2 = FALSE;
	crypto_mech_type_t	k_mech_type;
	crypto_object_generate_key_pair_t 	obj_kp;
	int r;

	if (!kernel_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/* Obtain the session pointer. */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	if ((pMechanism == NULL) || (phPublicKey == NULL) ||
	    (phPrivateKey == NULL)) {
		rv = CKR_ARGUMENTS_BAD;
		goto failed_exit;
	}

	if ((pPublicKeyTemplate == NULL) && (ulPublicKeyAttributeCount != 0)) {
		rv = CKR_ARGUMENTS_BAD;
		goto failed_exit;
	}

	if ((pPrivateKeyTemplate == NULL) &&
	    (ulPrivateKeyAttributeCount != 0)) {
		rv = CKR_ARGUMENTS_BAD;
		goto failed_exit;
	}

	/* Get the kernel's internal mechanism number. */
	rv = kernel_mech(pMechanism->mechanism, &k_mech_type);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Create an object wrapper for the public key */
	new_pub_objp = calloc(1, sizeof (kernel_object_t));
	if (new_pub_objp == NULL) {
		rv = CKR_HOST_MEMORY;
		goto failed_exit;
	}

	/* Create an object wrapper for the private key. */
	new_pri_objp = calloc(1, sizeof (kernel_object_t));
	if (new_pri_objp == NULL) {
		rv = CKR_HOST_MEMORY;
		goto failed_exit;
	}

	/* Process the public key attributes. */
	rv = process_object_attributes(pPublicKeyTemplate,
	    ulPublicKeyAttributeCount, &obj_kp.kp_public_attributes,
	    &is_token_obj1);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Cannot create a token object with a READ-ONLY session. */
	if (is_token_obj1 && session_p->ses_RO) {
		free_object_attributes(obj_kp.kp_public_attributes,
		    ulPublicKeyAttributeCount);
		rv = CKR_SESSION_READ_ONLY;
		goto failed_exit;
	}

	/* Process the private key attributes. */
	rv = process_object_attributes(pPrivateKeyTemplate,
	    ulPrivateKeyAttributeCount, &obj_kp.kp_private_attributes,
	    &is_token_obj2);
	if (rv != CKR_OK) {
		free_object_attributes(obj_kp.kp_public_attributes,
		    ulPublicKeyAttributeCount);
		goto failed_exit;
	}

	/*
	 * The public key and the private key need to contain the same
	 * attribute values for CKA_TOKEN.
	 */
	if (is_token_obj1 != is_token_obj2) {
		free_object_attributes(obj_kp.kp_public_attributes,
		    ulPublicKeyAttributeCount);
		free_object_attributes(obj_kp.kp_private_attributes,
		    ulPrivateKeyAttributeCount);
		rv = CKR_ATTRIBUTE_VALUE_INVALID;
		goto failed_exit;
	}

	/* Call the CRYPTO_GENERATE_KEY_PAIR ioctl. */
	obj_kp.kp_session = session_p-> k_session;
	obj_kp.kp_mechanism.cm_type = k_mech_type;
	obj_kp.kp_mechanism.cm_param = pMechanism->pParameter;
	obj_kp.kp_mechanism.cm_param_len = pMechanism->ulParameterLen;
	obj_kp.kp_public_count = ulPublicKeyAttributeCount;
	obj_kp.kp_private_count = ulPrivateKeyAttributeCount;

	while ((r = ioctl(kernel_fd, CRYPTO_GENERATE_KEY_PAIR, &obj_kp)) < 0) {
		if (errno != EINTR)
			break;
	}
	if (r < 0) {
		rv = CKR_FUNCTION_FAILED;
	} else {
		rv = crypto2pkcs11_error_number(obj_kp.kp_return_value);
	}

	free_object_attributes(obj_kp.kp_public_attributes,
	    ulPublicKeyAttributeCount);
	free_object_attributes(obj_kp.kp_private_attributes,
	    ulPrivateKeyAttributeCount);

	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/* Get the CKA_PRIVATE value for the key pair. */
	rv = get_cka_private_value(session_p, obj_kp.kp_public_handle,
	    &is_pri_obj1);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	rv = get_cka_private_value(session_p, obj_kp.kp_private_handle,
	    &is_pri_obj2);
	if (rv != CKR_OK) {
		goto failed_exit;
	}

	/*
	 * Store the kernel public key handle into the public key object and
	 * finish the public key object initialization.
	 */
	new_pub_objp->is_lib_obj = B_FALSE;
	new_pub_objp->k_handle = obj_kp.kp_public_handle;
	new_pub_objp->session_handle = (CK_SESSION_HANDLE)session_p;
	new_pub_objp->extra_attrlistp = NULL;

	if (is_pri_obj1)
		new_pub_objp->bool_attr_mask |= PRIVATE_BOOL_ON;
	else
		new_pub_objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;

	if (is_token_obj1)
		new_pub_objp->bool_attr_mask |= TOKEN_BOOL_ON;
	else
		new_pub_objp->bool_attr_mask &= ~TOKEN_BOOL_ON;

	(void) pthread_mutex_init(&new_pub_objp->object_mutex, NULL);
	new_pub_objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;

	/*
	 * Store the kernel private key handle into the private key object
	 * and finish the private key object initialization.
	 */
	new_pri_objp->is_lib_obj = B_FALSE;
	new_pri_objp->k_handle = obj_kp.kp_private_handle;
	new_pri_objp->session_handle = (CK_SESSION_HANDLE)session_p;
	new_pri_objp->extra_attrlistp = NULL;

	if (is_pri_obj2)
		new_pri_objp->bool_attr_mask |= PRIVATE_BOOL_ON;
	else
		new_pri_objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;

	if (is_token_obj2)
		new_pri_objp->bool_attr_mask |= TOKEN_BOOL_ON;
	else
		new_pri_objp->bool_attr_mask &= ~TOKEN_BOOL_ON;

	(void) pthread_mutex_init(&new_pri_objp->object_mutex, NULL);
	new_pri_objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;

	/*
	 * Add the new pub/pri objects to the slot's token list if they are
	 * token objects. Otherwise, add them to the session's object list.
	 */
	if (is_token_obj1) { /* is_token_obj1 == is_token_obj2 */
		pslot = slot_table[session_p->ses_slotid];
		kernel_add_token_object_to_slot(new_pub_objp, pslot);
		kernel_add_token_object_to_slot(new_pri_objp, pslot);
	} else {
		kernel_add_object_to_session(new_pub_objp, session_p);
		kernel_add_object_to_session(new_pri_objp, session_p);
	}

	*phPublicKey = (CK_OBJECT_HANDLE)new_pub_objp;
	*phPrivateKey = (CK_OBJECT_HANDLE)new_pri_objp;
	REFRELE(session_p, ses_lock_held);
	return (rv);

failed_exit:
	if (new_pub_objp != NULL) {
		(void) free(new_pub_objp);
	}

	if (new_pri_objp != NULL) {
		(void) free(new_pri_objp);
	}

	REFRELE(session_p, ses_lock_held);
	return (rv);
}
示例#27
0
CK_RV
C_CloseSession(CK_SESSION_HANDLE hSession)
{

	CK_RV rv;

	soft_session_t *session_p;
	boolean_t lock_held = B_TRUE;

	if (!softtoken_initialized)
		return (CKR_CRYPTOKI_NOT_INITIALIZED);

	/*
	 * Obtain the session pointer. Also, increment the session
	 * reference count.
	 */
	rv = handle2session(hSession, &session_p);
	if (rv != CKR_OK)
		return (rv);

	(void) pthread_mutex_lock(&session_p->session_mutex);
	/*
	 * Set SESSION_IS_CLOSING flag so any access to this
	 * session will be rejected.
	 */
	if (session_p->ses_close_sync & SESSION_IS_CLOSING) {
		SES_REFRELE(session_p, lock_held);
		return (CKR_SESSION_CLOSED);
	}
	session_p->ses_close_sync |= SESSION_IS_CLOSING;

	/*
	 * Decrement the session reference count.
	 * We hold the session lock, and SES_REFRELE()
	 * will release the session lock for us.
	 */
	SES_REFRELE(session_p, lock_held);

	/*
	 * Delete a session by calling soft_delete_session() with
	 * a session pointer and a boolean arguments. Boolean
	 * value FALSE is used to indicate that the caller does not
	 * hold the lock on the global session list and also that
	 * this is not a forced session close but an explicit request.
	 *
	 * soft_delete_session() will reset SESSION_IS_CLOSING
	 * flag after it is done.
	 */
	rv = soft_delete_session(session_p, B_FALSE, B_FALSE);

	if (soft_session_cnt == 0) {
		/* Clean up private token objects from the token object list */
		soft_delete_all_in_core_token_objects(PRIVATE_TOKEN);
		/*
		 * Invalidate public token object handles instead of
		 * deleting them.
		 */
		soft_validate_token_objects(B_FALSE);
		(void) pthread_mutex_lock(&soft_giant_mutex);
		soft_slot.authenticated = 0;
		soft_slot.userpin_change_needed = 0;
		(void) pthread_mutex_unlock(&soft_giant_mutex);
	}

	return (rv);
}