static int verify_and_update_segment_digest(struct crypt_device *cd,
		struct luks2_hdr *hdr, int keyslot,
		const char *volume_key, size_t volume_key_size,
		const char *password, size_t password_size)
{
	int digest, r;
	struct volume_key *vk = NULL;

	if (keyslot < 0 || (volume_key && !volume_key_size))
		return -EINVAL;

	if (volume_key)
		vk = crypt_alloc_volume_key(volume_key_size, volume_key);
	else {
		r = LUKS2_keyslot_open(cd, keyslot, CRYPT_ANY_SEGMENT, password, password_size, &vk);
		if (r != keyslot) {
			r = -EINVAL;
			goto out;
		}
	}

	if (!vk)
		return -ENOMEM;

	/* check volume_key (param) digest matches keyslot digest */
	r = LUKS2_digest_verify(cd, hdr, vk, keyslot);
	if (r < 0)
		goto out;
	digest = r;

	/* nothing to do, volume key in keyslot is already assigned to default segment */
	r = LUKS2_digest_verify_by_segment(cd, hdr, CRYPT_DEFAULT_SEGMENT, vk);
	if (r >= 0)
		goto out;

	/* FIXME: check new volume key is usable with current default segment */

	r = update_volume_key_segment_digest(cd, &cd->u.luks2.hdr, digest, 1);
	if (r)
		log_err(cd, _("Failed to assign keyslot %u as the new volume key."), keyslot);
out:
	crypt_free_volume_key(vk);
	return r < 0 ? r : keyslot;
}
static int verify_and_update_segment_digest(struct crypt_device *cd,
		struct luks2_hdr *hdr, int keyslot,
		const char *volume_key, size_t volume_key_size,
		const char *password, size_t password_size)
{
	int digest, r;
	struct volume_key *vk = NULL;

	if (keyslot < 0 || (volume_key && !volume_key_size))
		return -EINVAL;

	if (volume_key)
		vk = crypt_alloc_volume_key(volume_key_size, volume_key);
	else {
		r = LUKS2_keyslot_open(cd, keyslot, CRYPT_ANY_SEGMENT, password, password_size, &vk);
		if (r != keyslot) {
			r = -EINVAL;
			goto out;
		}
	}

	if (!vk)
		return -ENOMEM;

	 
	r = LUKS2_digest_verify(cd, hdr, vk, keyslot);
	if (r < 0)
		goto out;
	digest = r;

	 
	r = LUKS2_digest_verify_by_segment(cd, hdr, CRYPT_DEFAULT_SEGMENT, vk);
	if (r >= 0)
		goto out;

	 

	r = update_volume_key_segment_digest(cd, &cd->u.luks2.hdr, digest, 1);
	if (r)
		log_err(cd, _("Failed to assign keyslot %u as the new volume key."), keyslot);
out:
	crypt_free_volume_key(vk);
	return r < 0 ? r : keyslot;
}