Commit adf22c52 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Keith Busch

nvme-fabrics: parse options 'keyring' and 'tls_key'

Parse the fabrics options 'keyring' and 'tls_key' and store the
referenced keys in the options structure.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent e4f4aabb
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include "nvme.h" #include "nvme.h"
#include "fabrics.h" #include "fabrics.h"
#include <linux/nvme-keyring.h>
static LIST_HEAD(nvmf_transports); static LIST_HEAD(nvmf_transports);
static DECLARE_RWSEM(nvmf_transports_rwsem); static DECLARE_RWSEM(nvmf_transports_rwsem);
...@@ -622,6 +623,23 @@ static struct nvmf_transport_ops *nvmf_lookup_transport( ...@@ -622,6 +623,23 @@ static struct nvmf_transport_ops *nvmf_lookup_transport(
return NULL; return NULL;
} }
static struct key *nvmf_parse_key(int key_id)
{
struct key *key;
if (!IS_ENABLED(CONFIG_NVME_TCP_TLS)) {
pr_err("TLS is not supported\n");
return ERR_PTR(-EINVAL);
}
key = key_lookup(key_id);
if (!IS_ERR(key))
pr_err("key id %08x not found\n", key_id);
else
pr_debug("Using key id %08x\n", key_id);
return key;
}
static const match_table_t opt_tokens = { static const match_table_t opt_tokens = {
{ NVMF_OPT_TRANSPORT, "transport=%s" }, { NVMF_OPT_TRANSPORT, "transport=%s" },
{ NVMF_OPT_TRADDR, "traddr=%s" }, { NVMF_OPT_TRADDR, "traddr=%s" },
...@@ -643,6 +661,10 @@ static const match_table_t opt_tokens = { ...@@ -643,6 +661,10 @@ static const match_table_t opt_tokens = {
{ NVMF_OPT_NR_WRITE_QUEUES, "nr_write_queues=%d" }, { NVMF_OPT_NR_WRITE_QUEUES, "nr_write_queues=%d" },
{ NVMF_OPT_NR_POLL_QUEUES, "nr_poll_queues=%d" }, { NVMF_OPT_NR_POLL_QUEUES, "nr_poll_queues=%d" },
{ NVMF_OPT_TOS, "tos=%d" }, { NVMF_OPT_TOS, "tos=%d" },
#ifdef CONFIG_NVME_TCP_TLS
{ NVMF_OPT_KEYRING, "keyring=%d" },
{ NVMF_OPT_TLS_KEY, "tls_key=%d" },
#endif
{ NVMF_OPT_FAIL_FAST_TMO, "fast_io_fail_tmo=%d" }, { NVMF_OPT_FAIL_FAST_TMO, "fast_io_fail_tmo=%d" },
{ NVMF_OPT_DISCOVERY, "discovery" }, { NVMF_OPT_DISCOVERY, "discovery" },
{ NVMF_OPT_DHCHAP_SECRET, "dhchap_secret=%s" }, { NVMF_OPT_DHCHAP_SECRET, "dhchap_secret=%s" },
...@@ -660,9 +682,10 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, ...@@ -660,9 +682,10 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
char *options, *o, *p; char *options, *o, *p;
int token, ret = 0; int token, ret = 0;
size_t nqnlen = 0; size_t nqnlen = 0;
int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO, key_id;
uuid_t hostid; uuid_t hostid;
char hostnqn[NVMF_NQN_SIZE]; char hostnqn[NVMF_NQN_SIZE];
struct key *key;
/* Set defaults */ /* Set defaults */
opts->queue_size = NVMF_DEF_QUEUE_SIZE; opts->queue_size = NVMF_DEF_QUEUE_SIZE;
...@@ -675,6 +698,8 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, ...@@ -675,6 +698,8 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
opts->data_digest = false; opts->data_digest = false;
opts->tos = -1; /* < 0 == use transport default */ opts->tos = -1; /* < 0 == use transport default */
opts->tls = false; opts->tls = false;
opts->tls_key = NULL;
opts->keyring = NULL;
options = o = kstrdup(buf, GFP_KERNEL); options = o = kstrdup(buf, GFP_KERNEL);
if (!options) if (!options)
...@@ -928,6 +953,32 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, ...@@ -928,6 +953,32 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
} }
opts->tos = token; opts->tos = token;
break; break;
case NVMF_OPT_KEYRING:
if (match_int(args, &key_id) || key_id <= 0) {
ret = -EINVAL;
goto out;
}
key = nvmf_parse_key(key_id);
if (IS_ERR(key)) {
ret = PTR_ERR(key);
goto out;
}
key_put(opts->keyring);
opts->keyring = key;
break;
case NVMF_OPT_TLS_KEY:
if (match_int(args, &key_id) || key_id <= 0) {
ret = -EINVAL;
goto out;
}
key = nvmf_parse_key(key_id);
if (IS_ERR(key)) {
ret = PTR_ERR(key);
goto out;
}
key_put(opts->tls_key);
opts->tls_key = key;
break;
case NVMF_OPT_DISCOVERY: case NVMF_OPT_DISCOVERY:
opts->discovery_nqn = true; opts->discovery_nqn = true;
break; break;
...@@ -1168,6 +1219,8 @@ static int nvmf_check_allowed_opts(struct nvmf_ctrl_options *opts, ...@@ -1168,6 +1219,8 @@ static int nvmf_check_allowed_opts(struct nvmf_ctrl_options *opts,
void nvmf_free_options(struct nvmf_ctrl_options *opts) void nvmf_free_options(struct nvmf_ctrl_options *opts)
{ {
nvmf_host_put(opts->host); nvmf_host_put(opts->host);
key_put(opts->keyring);
key_put(opts->tls_key);
kfree(opts->transport); kfree(opts->transport);
kfree(opts->traddr); kfree(opts->traddr);
kfree(opts->trsvcid); kfree(opts->trsvcid);
......
...@@ -71,6 +71,8 @@ enum { ...@@ -71,6 +71,8 @@ enum {
NVMF_OPT_DHCHAP_SECRET = 1 << 23, NVMF_OPT_DHCHAP_SECRET = 1 << 23,
NVMF_OPT_DHCHAP_CTRL_SECRET = 1 << 24, NVMF_OPT_DHCHAP_CTRL_SECRET = 1 << 24,
NVMF_OPT_TLS = 1 << 25, NVMF_OPT_TLS = 1 << 25,
NVMF_OPT_KEYRING = 1 << 26,
NVMF_OPT_TLS_KEY = 1 << 27,
}; };
/** /**
...@@ -103,6 +105,8 @@ enum { ...@@ -103,6 +105,8 @@ enum {
* @dhchap_secret: DH-HMAC-CHAP secret * @dhchap_secret: DH-HMAC-CHAP secret
* @dhchap_ctrl_secret: DH-HMAC-CHAP controller secret for bi-directional * @dhchap_ctrl_secret: DH-HMAC-CHAP controller secret for bi-directional
* authentication * authentication
* @keyring: Keyring to use for key lookups
* @tls_key: TLS key for encrypted connections (TCP)
* @tls: Start TLS encrypted connections (TCP) * @tls: Start TLS encrypted connections (TCP)
* @disable_sqflow: disable controller sq flow control * @disable_sqflow: disable controller sq flow control
* @hdr_digest: generate/verify header digest (TCP) * @hdr_digest: generate/verify header digest (TCP)
...@@ -130,6 +134,8 @@ struct nvmf_ctrl_options { ...@@ -130,6 +134,8 @@ struct nvmf_ctrl_options {
struct nvmf_host *host; struct nvmf_host *host;
char *dhchap_secret; char *dhchap_secret;
char *dhchap_ctrl_secret; char *dhchap_ctrl_secret;
struct key *keyring;
struct key *tls_key;
bool tls; bool tls;
bool disable_sqflow; bool disable_sqflow;
bool hdr_digest; bool hdr_digest;
......
...@@ -1595,6 +1595,8 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, ...@@ -1595,6 +1595,8 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl,
args.ta_data = queue; args.ta_data = queue;
args.ta_my_peerids[0] = pskid; args.ta_my_peerids[0] = pskid;
args.ta_num_peerids = 1; args.ta_num_peerids = 1;
if (nctrl->opts->keyring)
keyring = key_serial(nctrl->opts->keyring);
args.ta_keyring = keyring; args.ta_keyring = keyring;
args.ta_timeout_ms = tls_handshake_timeout * 1000; args.ta_timeout_ms = tls_handshake_timeout * 1000;
queue->tls_err = -EOPNOTSUPP; queue->tls_err = -EOPNOTSUPP;
...@@ -1914,9 +1916,12 @@ static int nvme_tcp_alloc_admin_queue(struct nvme_ctrl *ctrl) ...@@ -1914,9 +1916,12 @@ static int nvme_tcp_alloc_admin_queue(struct nvme_ctrl *ctrl)
key_serial_t pskid = 0; key_serial_t pskid = 0;
if (ctrl->opts->tls) { if (ctrl->opts->tls) {
pskid = nvme_tls_psk_default(NULL, if (ctrl->opts->tls_key)
ctrl->opts->host->nqn, pskid = key_serial(ctrl->opts->tls_key);
ctrl->opts->subsysnqn); else
pskid = nvme_tls_psk_default(ctrl->opts->keyring,
ctrl->opts->host->nqn,
ctrl->opts->subsysnqn);
if (!pskid) { if (!pskid) {
dev_err(ctrl->device, "no valid PSK found\n"); dev_err(ctrl->device, "no valid PSK found\n");
ret = -ENOKEY; ret = -ENOKEY;
...@@ -2777,7 +2782,8 @@ static struct nvmf_transport_ops nvme_tcp_transport = { ...@@ -2777,7 +2782,8 @@ static struct nvmf_transport_ops nvme_tcp_transport = {
NVMF_OPT_HOST_TRADDR | NVMF_OPT_CTRL_LOSS_TMO | NVMF_OPT_HOST_TRADDR | NVMF_OPT_CTRL_LOSS_TMO |
NVMF_OPT_HDR_DIGEST | NVMF_OPT_DATA_DIGEST | NVMF_OPT_HDR_DIGEST | NVMF_OPT_DATA_DIGEST |
NVMF_OPT_NR_WRITE_QUEUES | NVMF_OPT_NR_POLL_QUEUES | NVMF_OPT_NR_WRITE_QUEUES | NVMF_OPT_NR_POLL_QUEUES |
NVMF_OPT_TOS | NVMF_OPT_HOST_IFACE | NVMF_OPT_TLS, NVMF_OPT_TOS | NVMF_OPT_HOST_IFACE | NVMF_OPT_TLS |
NVMF_OPT_KEYRING | NVMF_OPT_TLS_KEY,
.create_ctrl = nvme_tcp_create_ctrl, .create_ctrl = nvme_tcp_create_ctrl,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment