int LUKS2_keyslot_wipe(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	int keyslot,
	int wipe_area_only)
{
	struct device *device = crypt_metadata_device(cd);
	uint64_t area_offset, area_length;
	int r;
	json_object *jobj_keyslot, *jobj_keyslots;
	const keyslot_handler *h;

	h = LUKS2_keyslot_handler(cd, keyslot);

	if (!json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots))
		return -EINVAL;

	jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
	if (!jobj_keyslot)
		return -ENOENT;

	if (wipe_area_only)
		log_dbg(cd, "Wiping keyslot %d area only.", keyslot);

	r = LUKS2_device_write_lock(cd, hdr, device);
	if (r)
		return r;

	/* secure deletion of possible key material in keyslot area */
	r = crypt_keyslot_area(cd, keyslot, &area_offset, &area_length);
	if (r && r != -ENOENT)
		goto out;

	if (!r) {
		r = crypt_wipe_device(cd, device, CRYPT_WIPE_SPECIAL, area_offset,
			      area_length, area_length, NULL, NULL);
		if (r) {
			if (r == -EACCES) {
				log_err(cd, _("Cannot write to device %s, permission denied."),
					device_path(device));
				r = -EINVAL;
			} else
				log_err(cd, _("Cannot wipe device %s."), device_path(device));
			goto out;
		}
	}

	if (wipe_area_only)
		goto out;

	/* Slot specific wipe */
	if (h) {
		r = h->wipe(cd, keyslot);
		if (r < 0)
			goto out;
	} else
		log_dbg(cd, "Wiping keyslot %d without specific-slot handler loaded.", keyslot);

	json_object_object_del_by_uint(jobj_keyslots, keyslot);

	r = LUKS2_hdr_write(cd, hdr);
out:
	device_write_unlock(cd, crypt_metadata_device(cd));
	return r;
}
int LUKS2_keyslot_wipe(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	int keyslot,
	int wipe_area_only)
{
	struct device *device = crypt_metadata_device(cd);
	uint64_t area_offset, area_length;
	int r;
	json_object *jobj_keyslot, *jobj_keyslots;
	const keyslot_handler *h;

	h = LUKS2_keyslot_handler(cd, keyslot);

	if (!json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots))
		return -EINVAL;

	jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
	if (!jobj_keyslot)
		return -ENOENT;

	if (wipe_area_only)
		log_dbg(cd, "Wiping keyslot %d area only.", keyslot);

	r = LUKS2_device_write_lock(cd, hdr, device);
	if (r)
		return r;

	 
	r = crypt_keyslot_area(cd, keyslot, &area_offset, &area_length);
	if (r && r != -ENOENT)
		goto out;

	if (!r) {
		r = crypt_wipe_device(cd, device, CRYPT_WIPE_SPECIAL, area_offset,
			      area_length, area_length, NULL, NULL);
		if (r) {
			if (r == -EACCES) {
				log_err(cd, _("Cannot write to device %s, permission denied."),
					device_path(device));
				r = -EINVAL;
			} else
				log_err(cd, _("Cannot wipe device %s."), device_path(device));
			goto out;
		}
	}

	if (wipe_area_only)
		goto out;

	 
	if (h) {
		r = h->wipe(cd, keyslot);
		if (r < 0)
			goto out;
	} else
		log_dbg(cd, "Wiping keyslot %d without specific-slot handler loaded.", keyslot);

	json_object_object_del_by_uint(jobj_keyslots, keyslot);

	r = LUKS2_hdr_write(cd, hdr);
out:
	device_write_unlock(cd, crypt_metadata_device(cd));
	return r;
}