diff options
author | Hannes Reinecke <hare@suse.de> | 2023-03-14 16:46:01 +0100 |
---|---|---|
committer | Hannes Reinecke <hare@suse.de> | 2023-03-29 15:55:14 +0200 |
commit | b160cccb84362674ac09fb349ab21bd2339eb28e (patch) | |
tree | 570d875b0cba4475dad6394b58ac6cb34d80500a | |
parent | 1a0c660776b337cb29d94ee8de050f21c9fd0df8 (diff) | |
download | scsi-devel-tls-netlink.v8.tar.gz |
nvmet-tcp: add configfs attribute 'param_keyring'tls-netlink.v8
Add a configfs attribute to list and change the default keyring.
Signed-off-by: Hannes Reinecke <hare@suse.de>
-rw-r--r-- | drivers/nvme/target/configfs.c | 68 | ||||
-rw-r--r-- | drivers/nvme/target/nvmet.h | 1 | ||||
-rw-r--r-- | drivers/nvme/target/tcp.c | 3 |
3 files changed, 70 insertions, 2 deletions
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 36fbf6a22d097..0a92bc8b25e51 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -15,6 +15,10 @@ #ifdef CONFIG_NVME_TARGET_AUTH #include <linux/nvme-auth.h> #endif +#include <linux/key.h> +#ifdef CONFIG_NVME_TLS +#include <linux/nvme-keyring.h> +#endif #include <crypto/hash.h> #include <crypto/kpp.h> @@ -294,6 +298,48 @@ static ssize_t nvmet_param_pi_enable_store(struct config_item *item, CONFIGFS_ATTR(nvmet_, param_pi_enable); #endif +#ifdef CONFIG_NVME_TLS +static ssize_t nvmet_param_keyring_show(struct config_item *item, + char *page) +{ + struct nvmet_port *port = to_nvmet_port(item); + + if (!port->keyring) + return sprintf(page, "\n"); + return snprintf(page, PAGE_SIZE, "%s\n", + port->keyring->description); +} + +static ssize_t nvmet_param_keyring_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_port *port = to_nvmet_port(item); + struct key *keyring; + unsigned int keyring_id; + int ret; + + if (nvmet_is_port_enabled(port, __func__)) + return -EACCES; + + ret = kstrtou32(page, 0, &keyring_id); + if (ret) { + pr_err("Invalid keyring id '%s'\n", page); + return ret; + } + keyring = key_lookup(keyring_id); + if (IS_ERR(keyring)) { + pr_err("Invalid keyring '%08x'\n", keyring_id); + return PTR_ERR(keyring); + } + if (port->keyring) + key_put(port->keyring); + port->keyring = keyring; + return count; +} + +CONFIGFS_ATTR(nvmet_, param_keyring); +#endif + static ssize_t nvmet_addr_trtype_show(struct config_item *item, char *page) { @@ -404,9 +450,12 @@ static ssize_t nvmet_addr_tsas_store(struct config_item *item, return -EINVAL; found: - nvmet_port_init_tsas_tcp(port, nvmet_addr_tsas_tcp[i].type); if (nvmet_addr_tsas_tcp[i].type == NVMF_TCP_SECTYPE_TLS13) { #ifdef CONFIG_NVME_TLS + if (!port->keyring) { + pr_err("NVMe keyring not available, cannot enable TLS 1.3\n"); + return -ENOTSUPP; + } if (NVMET_PORT_TREQ(port) == NVMF_TREQ_NOT_SPECIFIED) treq |= NVMF_TREQ_REQUIRED; else @@ -419,6 +468,8 @@ found: /* Set to 'not specified' if TLS is not enabled */ treq |= NVMF_TREQ_NOT_SPECIFIED; } + port->disc_addr.treq = treq; + nvmet_port_init_tsas_tcp(port, nvmet_addr_tsas_tcp[i].type); return count; } @@ -1825,6 +1876,8 @@ static void nvmet_port_release(struct config_item *item) flush_workqueue(nvmet_wq); list_del(&port->global_entry); + if (port->keyring) + key_put(port->keyring); kfree(port->ana_state); kfree(port); } @@ -1840,6 +1893,9 @@ static struct configfs_attribute *nvmet_port_attrs[] = { #ifdef CONFIG_BLK_DEV_INTEGRITY &nvmet_attr_param_pi_enable, #endif +#ifdef CONFIG_NVME_TLS + &nvmet_attr_param_keyring, +#endif NULL, }; @@ -1857,6 +1913,7 @@ static struct config_group *nvmet_ports_make(struct config_group *group, const char *name) { struct nvmet_port *port; + struct key *keyring = NULL; u16 portid; u32 i; @@ -1874,6 +1931,15 @@ static struct config_group *nvmet_ports_make(struct config_group *group, return ERR_PTR(-ENOMEM); } +#ifdef CONFIG_NVME_TLS + keyring = key_lookup(nvme_keyring_id()); + if (IS_ERR(keyring)) { + pr_warn("NVMe keyring not available, disabling TLS\n"); + keyring = NULL; + } +#endif + port->keyring = keyring; + for (i = 1; i <= NVMET_MAX_ANAGRPS; i++) { if (i == NVMET_DEFAULT_ANA_GRPID) port->ana_state[1] = NVME_ANA_OPTIMIZED; diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index ed3786140965f..c31e310d269aa 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -158,6 +158,7 @@ struct nvmet_port { struct config_group ana_groups_group; struct nvmet_ana_group ana_default_group; enum nvme_ana_state *ana_state; + struct key *keyring; void *priv; bool enabled; int inline_data_size; diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 75017fd5da9fe..5b1069854f152 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -8,6 +8,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/key.h> #include <linux/nvme-tcp.h> #include <net/sock.h> #include <net/tcp.h> @@ -1763,7 +1764,7 @@ static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue) args.ta_sock = queue->sock; args.ta_done = nvmet_tcp_tls_handshake_done; args.ta_data = queue; - args.ta_keyring = nvme_keyring_id(); + args.ta_keyring = key_serial(queue->port->nport->keyring); args.ta_timeout_ms = tls_handshake_timeout * 2 * 1024; ret = tls_server_hello_psk(&args, GFP_KERNEL); |