Пример #1
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);
}
Пример #2
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);
}
Пример #3
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);
}
Пример #4
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);
}
Пример #5
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);
}
Пример #6
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);
}