int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
	int keyslot,
	const char *volume_key,
	size_t volume_key_size,
	const char *passphrase,
	size_t passphrase_size)
{
	struct volume_key *vk = NULL;
	int r;

	if (!passphrase)
		return -EINVAL;

	log_dbg(cd, "Adding new keyslot %d using volume key.", keyslot);

	if ((r = onlyLUKS(cd)))
		return r;

	if (isLUKS2(cd->type))
		return crypt_keyslot_add_by_key(cd, keyslot,
				volume_key, volume_key_size, passphrase,
				passphrase_size, 0);

	r = keyslot_verify_or_find_empty(cd, &keyslot);
	if (r < 0)
		return r;

	if (volume_key)
		vk = crypt_alloc_volume_key(volume_key_size, volume_key);
	else if (cd->volume_key)
		vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key);

	if (!vk)
		return -ENOMEM;

	r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
	if (r < 0)
		log_err(cd, _("Volume key does not match the volume."));
	else
		r = LUKS_set_key(keyslot, passphrase, passphrase_size,
			&cd->u.luks1.hdr, vk, cd);

	crypt_free_volume_key(vk);
	return (r < 0) ? r : keyslot;
}
int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
	int keyslot,
	const char *volume_key,
	size_t volume_key_size,
	const char *passphrase,
	size_t passphrase_size)
{
	struct volume_key *vk = NULL;
	int r;

	if (!passphrase)
		return -EINVAL;

	log_dbg(cd, "Adding new keyslot %d using volume key.", keyslot);

	if ((r = onlyLUKS(cd)))
		return r;

	if (isLUKS2(cd->type))
		return crypt_keyslot_add_by_key(cd, keyslot,
				volume_key, volume_key_size, passphrase,
				passphrase_size, 0);

	r = keyslot_verify_or_find_empty(cd, &keyslot);
	if (r < 0)
		return r;

	if (volume_key)
		vk = crypt_alloc_volume_key(volume_key_size, volume_key);
	else if (cd->volume_key)
		vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key);

	if (!vk)
		return -ENOMEM;

	r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
	if (r < 0)
		log_err(cd, _("Volume key does not match the volume."));
	else
		r = LUKS_set_key(keyslot, passphrase, passphrase_size,
			&cd->u.luks1.hdr, vk, cd);

	crypt_free_volume_key(vk);
	return (r < 0) ? r : keyslot;
}