static int _activate_by_passphrase(struct crypt_device *cd,
	const char *name,
	int keyslot,
	const char *passphrase,
	size_t passphrase_size,
	uint32_t flags)
{
	int r;
	struct volume_key *vk = NULL;

	if ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd))
		return -EINVAL;

	if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name)
		return -EINVAL;

	r = _check_header_data_overlap(cd, name);
	if (r < 0)
		return r;

	if (flags & CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF)
		cd->memory_hard_pbkdf_lock_enabled = true;

	/* plain, use hashed passphrase */
	if (isPLAIN(cd->type)) {
		r = -EINVAL;
		if (!name)
			goto out;

		r = process_key(cd, cd->u.plain.hdr.hash,
				cd->u.plain.key_size,
				passphrase, passphrase_size, &vk);
		if (r < 0)
			goto out;

		r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags);
		keyslot = 0;
	} else if (isLUKS1(cd->type)) {
		r = LUKS_open_key_with_hdr(keyslot, passphrase,
					   passphrase_size, &cd->u.luks1.hdr, &vk, cd);
		if (r >= 0) {
			keyslot = r;
			if (name)
				r = LUKS1_activate(cd, name, vk, flags);
		}
	} else if (isLUKS2(cd->type)) {
		r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags);
		keyslot = r;
	} else if (isBITLK(cd->type)) {
		r = BITLK_activate_by_passphrase(cd, name, passphrase, passphrase_size,
						 &cd->u.bitlk.params, flags);
		keyslot = 0;
	} else {
		log_err(cd, _("Device type is not properly initialized."));
		r = -EINVAL;
	}
out:
	if (r < 0)
		crypt_drop_keyring_key(cd, vk);
	crypt_free_volume_key(vk);

	cd->memory_hard_pbkdf_lock_enabled = false;

	return r < 0 ? r : keyslot;
}
static int _activate_by_passphrase(struct crypt_device *cd,
	const char *name,
	int keyslot,
	const char *passphrase,
	size_t passphrase_size,
	uint32_t flags)
{
	int r;
	struct volume_key *vk = NULL;

	if ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd))
		return -EINVAL;

	if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name)
		return -EINVAL;

	r = _check_header_data_overlap(cd, name);
	if (r < 0)
		return r;

	if (flags & CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF)
		cd->memory_hard_pbkdf_lock_enabled = true;

	 
	if (isPLAIN(cd->type)) {
		r = -EINVAL;
		if (!name)
			goto out;

		r = process_key(cd, cd->u.plain.hdr.hash,
				cd->u.plain.key_size,
				passphrase, passphrase_size, &vk);
		if (r < 0)
			goto out;

		r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags);
		keyslot = 0;
	} else if (isLUKS1(cd->type)) {
		r = LUKS_open_key_with_hdr(keyslot, passphrase,
					   passphrase_size, &cd->u.luks1.hdr, &vk, cd);
		if (r >= 0) {
			keyslot = r;
			if (name)
				r = LUKS1_activate(cd, name, vk, flags);
		}
	} else if (isLUKS2(cd->type)) {
		r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags);
		keyslot = r;
	} else if (isBITLK(cd->type)) {
		r = BITLK_activate_by_passphrase(cd, name, passphrase, passphrase_size,
						 &cd->u.bitlk.params, flags);
		keyslot = 0;
	} else {
		log_err(cd, _("Device type is not properly initialized."));
		r = -EINVAL;
	}
out:
	if (r < 0)
		crypt_drop_keyring_key(cd, vk);
	crypt_free_volume_key(vk);

	cd->memory_hard_pbkdf_lock_enabled = false;

	return r < 0 ? r : keyslot;
}