nvme: Allow reauth from sysfs

Allow userspace to trigger a reauth (REPLACETLSPSK) from sysfs.
This can be done by writing  a zero to the sysfs file.

echo 0 > /sys/devices/virtual/nvme-fabrics/ctl/nvme0/tls_configured_key

In order to use the new keys for the admin queue we call controller
reset. This isn't ideal, but I can't find a simpler way to reset the
admin queue TLS connection.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
Alistair Francis
2025-12-02 15:17:55 +10:00
committed by Keith Busch
parent 56d25f1a6e
commit ed6a9f7dab
2 changed files with 56 additions and 1 deletions

View File

@@ -0,0 +1,13 @@
What: /sys/devices/virtual/nvme-fabrics/ctl/.../tls_configured_key
Date: November 2025
KernelVersion: 6.19
Contact: Linux NVMe mailing list <linux-nvme@lists.infradead.org>
Description:
The file is avaliable when using a secure concatanation
connection to a NVMe target. Reading the file will return
the serial of the currently negotiated key.
Writing 0 to the file will trigger a PSK reauthentication
(REPLACETLSPSK) with the target. After a reauthentication
the value returned by tls_configured_key will be the new
serial.

View File

@@ -829,7 +829,49 @@ static ssize_t tls_configured_key_show(struct device *dev,
return sysfs_emit(buf, "%08x\n", key_serial(key));
}
static DEVICE_ATTR_RO(tls_configured_key);
static ssize_t tls_configured_key_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
int error, qid;
error = kstrtoint(buf, 10, &qid);
if (error)
return error;
/*
* We currently only allow userspace to write a `0` indicating
* generate a new key.
*/
if (qid)
return -EINVAL;
if (!ctrl->opts || !ctrl->opts->concat)
return -EOPNOTSUPP;
error = nvme_auth_negotiate(ctrl, 0);
if (error < 0) {
nvme_reset_ctrl(ctrl);
return error;
}
error = nvme_auth_wait(ctrl, 0);
if (error < 0) {
nvme_reset_ctrl(ctrl);
return error;
}
/*
* We need to reset the TLS connection, so let's just
* reset the controller.
*/
nvme_reset_ctrl(ctrl);
return count;
}
static DEVICE_ATTR_RW(tls_configured_key);
static ssize_t tls_keyring_show(struct device *dev,
struct device_attribute *attr, char *buf)