int crypt_volume_key_verify(struct crypt_device *cd,
	const char *volume_key,
	size_t volume_key_size)
{
	struct volume_key *vk;
	int r;

	if ((r = _onlyLUKS(cd, CRYPT_CD_UNRESTRICTED)))
		return r;

	vk = crypt_alloc_volume_key(volume_key_size, volume_key);
	if (!vk)
		return -ENOMEM;

	if (isLUKS1(cd->type))
		r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
	else if (isLUKS2(cd->type))
		r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
	else
		r = -EINVAL;


	if (r == -EPERM)
		log_err(cd, _("Volume key does not match the volume."));

	crypt_free_volume_key(vk);

	return r >= 0 ? 0 : r;
}
int crypt_volume_key_verify(struct crypt_device *cd,
	const char *volume_key,
	size_t volume_key_size)
{
	struct volume_key *vk;
	int r;

	if ((r = _onlyLUKS(cd, CRYPT_CD_UNRESTRICTED)))
		return r;

	vk = crypt_alloc_volume_key(volume_key_size, volume_key);
	if (!vk)
		return -ENOMEM;

	if (isLUKS1(cd->type))
		r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
	else if (isLUKS2(cd->type))
		r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
	else
		r = -EINVAL;


	if (r == -EPERM)
		log_err(cd, _("Volume key does not match the volume."));

	crypt_free_volume_key(vk);

	return r >= 0 ? 0 : r;
}