* [PATCH 1/8] nvme-keyring: restrict match length for version '1' identifiers
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-19 5:34 ` Christoph Hellwig
2024-07-18 14:48 ` [PATCH 2/8] nvme-tcp: sanitize TLS key handling Hannes Reinecke
` (6 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
TP8018 changed the TLS PSK identifiers to append a PSK hash value,
so to lookup identifiers we should just consider the length of
the match value, not the length of the identifiers to compare
against.
And we should modify the PSK lookup algorithm to prefer v1 identifiers
as they can be uniquely identified.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
---
drivers/nvme/common/keyring.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/nvme/common/keyring.c b/drivers/nvme/common/keyring.c
index 6f7e7a8fa5ae..c60ebbdc52b8 100644
--- a/drivers/nvme/common/keyring.c
+++ b/drivers/nvme/common/keyring.c
@@ -36,14 +36,12 @@ static bool nvme_tls_psk_match(const struct key *key,
pr_debug("%s: no key description\n", __func__);
return false;
}
- match_len = strlen(key->description);
- pr_debug("%s: id %s len %zd\n", __func__, key->description, match_len);
-
if (!match_data->raw_data) {
pr_debug("%s: no match data\n", __func__);
return false;
}
match_id = match_data->raw_data;
+ match_len = strlen(match_id);
pr_debug("%s: match '%s' '%s' len %zd\n",
__func__, match_id, key->description, match_len);
return !memcmp(key->description, match_id, match_len);
@@ -71,7 +69,7 @@ static struct key_type nvme_tls_psk_key_type = {
static struct key *nvme_tls_psk_lookup(struct key *keyring,
const char *hostnqn, const char *subnqn,
- int hmac, bool generated)
+ u8 hmac, u8 psk_ver, bool generated)
{
char *identity;
size_t identity_len = (NVMF_NQN_SIZE) * 2 + 11;
@@ -82,8 +80,8 @@ static struct key *nvme_tls_psk_lookup(struct key *keyring,
if (!identity)
return ERR_PTR(-ENOMEM);
- snprintf(identity, identity_len, "NVMe0%c%02d %s %s",
- generated ? 'G' : 'R', hmac, hostnqn, subnqn);
+ snprintf(identity, identity_len, "NVMe%u%c%02u %s %s",
+ psk_ver, generated ? 'G' : 'R', hmac, hostnqn, subnqn);
if (!keyring)
keyring = nvme_keyring;
@@ -109,19 +107,38 @@ static struct key *nvme_tls_psk_lookup(struct key *keyring,
*
* 'Retained' PSKs (ie 'generated == false')
* should be preferred to 'generated' PSKs,
+ * PSKs with hash (psk_ver 1) should be
+ * preferred to PSKs without (psk_ver 0),
* and SHA-384 should be preferred to SHA-256.
*/
static struct nvme_tls_psk_priority_list {
bool generated;
+ u8 psk_ver;
enum nvme_tcp_tls_cipher cipher;
} nvme_tls_psk_prio[] = {
{ .generated = false,
+ .psk_ver = 1,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
+ { .generated = false,
+ .psk_ver = 1,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
+ { .generated = false,
+ .psk_ver = 0,
.cipher = NVME_TCP_TLS_CIPHER_SHA384, },
{ .generated = false,
+ .psk_ver = 0,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
+ { .generated = true,
+ .psk_ver = 1,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
+ { .generated = true,
+ .psk_ver = 1,
.cipher = NVME_TCP_TLS_CIPHER_SHA256, },
{ .generated = true,
+ .psk_ver = 0,
.cipher = NVME_TCP_TLS_CIPHER_SHA384, },
{ .generated = true,
+ .psk_ver = 0,
.cipher = NVME_TCP_TLS_CIPHER_SHA256, },
};
@@ -137,10 +154,11 @@ key_serial_t nvme_tls_psk_default(struct key *keyring,
for (prio = 0; prio < ARRAY_SIZE(nvme_tls_psk_prio); prio++) {
bool generated = nvme_tls_psk_prio[prio].generated;
+ u8 ver = nvme_tls_psk_prio[prio].psk_ver;
enum nvme_tcp_tls_cipher cipher = nvme_tls_psk_prio[prio].cipher;
tls_key = nvme_tls_psk_lookup(keyring, hostnqn, subnqn,
- cipher, generated);
+ cipher, ver, generated);
if (!IS_ERR(tls_key)) {
tls_key_id = tls_key->serial;
key_put(tls_key);
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 1/8] nvme-keyring: restrict match length for version '1' identifiers
2024-07-18 14:48 ` [PATCH 1/8] nvme-keyring: restrict match length for version '1' identifiers Hannes Reinecke
@ 2024-07-19 5:34 ` Christoph Hellwig
2024-07-19 6:16 ` Hannes Reinecke
0 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2024-07-19 5:34 UTC (permalink / raw)
To: Hannes Reinecke; +Cc: Christoph Hellwig, Sagi Grimberg, Keith Busch, linux-nvme
On Thu, Jul 18, 2024 at 04:48:51PM +0200, Hannes Reinecke wrote:
> TP8018 changed the TLS PSK identifiers to append a PSK hash value,
> so to lookup identifiers we should just consider the length of
> the match value, not the length of the identifiers to compare
> against.
> And we should modify the PSK lookup algorithm to prefer v1 identifiers
> as they can be uniquely identified.
Can you reword this a bit to remove the weird "we should" and state it
in terms of requirements / recommendations from the standard. Bonus
points for adding actual references to the specifications.
> @@ -109,19 +107,38 @@ static struct key *nvme_tls_psk_lookup(struct key *keyring,
> *
> * 'Retained' PSKs (ie 'generated == false')
> * should be preferred to 'generated' PSKs,
> + * PSKs with hash (psk_ver 1) should be
> + * preferred to PSKs without (psk_ver 0),
> * and SHA-384 should be preferred to SHA-256.
Please reflow this to use up 80 characters and make the paragraph easily
readable.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/8] nvme-keyring: restrict match length for version '1' identifiers
2024-07-19 5:34 ` Christoph Hellwig
@ 2024-07-19 6:16 ` Hannes Reinecke
0 siblings, 0 replies; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-19 6:16 UTC (permalink / raw)
To: Christoph Hellwig, Hannes Reinecke; +Cc: Sagi Grimberg, Keith Busch, linux-nvme
On 7/19/24 07:34, Christoph Hellwig wrote:
> On Thu, Jul 18, 2024 at 04:48:51PM +0200, Hannes Reinecke wrote:
>> TP8018 changed the TLS PSK identifiers to append a PSK hash value,
>> so to lookup identifiers we should just consider the length of
>> the match value, not the length of the identifiers to compare
>> against.
>> And we should modify the PSK lookup algorithm to prefer v1 identifiers
>> as they can be uniquely identified.
>
> Can you reword this a bit to remove the weird "we should" and state it
> in terms of requirements / recommendations from the standard. Bonus
> points for adding actual references to the specifications.
>
Okay.
>> @@ -109,19 +107,38 @@ static struct key *nvme_tls_psk_lookup(struct key *keyring,
>> *
>> * 'Retained' PSKs (ie 'generated == false')
>> * should be preferred to 'generated' PSKs,
>> + * PSKs with hash (psk_ver 1) should be
>> + * preferred to PSKs without (psk_ver 0),
>> * and SHA-384 should be preferred to SHA-256.
>
> Please reflow this to use up 80 characters and make the paragraph easily
> readable.
>
Sure.
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 2/8] nvme-tcp: sanitize TLS key handling
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
2024-07-18 14:48 ` [PATCH 1/8] nvme-keyring: restrict match length for version '1' identifiers Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-19 5:35 ` Christoph Hellwig
2024-07-18 14:48 ` [PATCH 3/8] nvme-tcp: check for invalidated or revoked key Hannes Reinecke
` (5 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
There is a difference between TLS configured (ie the user has
provisioned/requested a key) and TLS enabled (ie the connection
is encrypted with TLS). This becomes important for secure concatenation,
where the initial authentication is run on an unencrypted connection
(ie with TLS configured, but not enabled), and then the queue is reset to
run over TLS (ie TLS configured _and_ enabled).
So to differentiate between those two states store the generated
key in opts->tls_key (as we're using the same TLS key for all queues),
the key serial of the resulting TLS handshake in ctrl->tls_pskid
(to signal that TLS on the admin queue is enabled), and a simple
flag for the queues to indicated that TLS has been enabled.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
---
drivers/nvme/host/core.c | 1 -
drivers/nvme/host/nvme.h | 2 +-
drivers/nvme/host/sysfs.c | 4 ++--
drivers/nvme/host/tcp.c | 47 ++++++++++++++++++++++++++++-----------
4 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index e78ef31eeef0..663fa14162ab 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4675,7 +4675,6 @@ static void nvme_free_ctrl(struct device *dev)
if (!subsys || ctrl->instance != subsys->instance)
ida_free(&nvme_instance_ida, ctrl->instance);
- key_put(ctrl->tls_key);
nvme_free_cels(ctrl);
nvme_mpath_uninit(ctrl);
cleanup_srcu_struct(&ctrl->srcu);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 9ac587e64166..185fb986a5cc 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -373,7 +373,7 @@ struct nvme_ctrl {
struct nvme_dhchap_key *ctrl_key;
u16 transaction;
#endif
- struct key *tls_key;
+ key_serial_t tls_pskid;
/* Power saving configuration */
u64 ps_max_latency_us;
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index ba05faaac562..72675b59a7a7 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -670,9 +670,9 @@ static ssize_t tls_key_show(struct device *dev,
{
struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
- if (!ctrl->tls_key)
+ if (!ctrl->tls_pskid)
return 0;
- return sysfs_emit(buf, "%08x", key_serial(ctrl->tls_key));
+ return sysfs_emit(buf, "%08x", ctrl->tls_pskid);
}
static DEVICE_ATTR_RO(tls_key);
#endif
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index a2a47d3ab99f..92ad5b8cc1b4 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -165,6 +165,7 @@ struct nvme_tcp_queue {
bool hdr_digest;
bool data_digest;
+ bool tls_enabled;
struct ahash_request *rcv_hash;
struct ahash_request *snd_hash;
__le32 exp_ddgst;
@@ -213,7 +214,15 @@ static inline int nvme_tcp_queue_id(struct nvme_tcp_queue *queue)
return queue - queue->ctrl->queues;
}
-static inline bool nvme_tcp_tls(struct nvme_ctrl *ctrl)
+static inline bool nvme_tcp_tls_enabled(struct nvme_tcp_queue *queue)
+{
+ if (!IS_ENABLED(CONFIG_NVME_TCP_TLS))
+ return 0;
+
+ return queue->tls_enabled;
+}
+
+static inline bool nvme_tcp_tls_configured(struct nvme_ctrl *ctrl)
{
if (!IS_ENABLED(CONFIG_NVME_TCP_TLS))
return 0;
@@ -368,7 +377,7 @@ static inline bool nvme_tcp_queue_has_pending(struct nvme_tcp_queue *queue)
static inline bool nvme_tcp_queue_more(struct nvme_tcp_queue *queue)
{
- return !nvme_tcp_tls(&queue->ctrl->ctrl) &&
+ return !nvme_tcp_tls_enabled(queue) &&
nvme_tcp_queue_has_pending(queue);
}
@@ -1427,7 +1436,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
memset(&msg, 0, sizeof(msg));
iov.iov_base = icresp;
iov.iov_len = sizeof(*icresp);
- if (nvme_tcp_tls(&queue->ctrl->ctrl)) {
+ if (nvme_tcp_tls_enabled(queue)) {
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
}
@@ -1439,7 +1448,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
goto free_icresp;
}
ret = -ENOTCONN;
- if (nvme_tcp_tls(&queue->ctrl->ctrl)) {
+ if (nvme_tcp_tls_enabled(queue)) {
ctype = tls_get_record_type(queue->sock->sk,
(struct cmsghdr *)cbuf);
if (ctype != TLS_RECORD_TYPE_DATA) {
@@ -1587,7 +1596,10 @@ static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid)
qid, pskid);
queue->tls_err = -ENOKEY;
} else {
- ctrl->ctrl.tls_key = tls_key;
+ queue->tls_enabled = true;
+ if (qid == 0)
+ ctrl->ctrl.tls_pskid = key_serial(tls_key);
+ key_put(tls_key);
queue->tls_err = 0;
}
@@ -1768,7 +1780,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid,
}
/* If PSKs are configured try to start TLS */
- if (IS_ENABLED(CONFIG_NVME_TCP_TLS) && pskid) {
+ if (nvme_tcp_tls_configured(nctrl) && pskid) {
ret = nvme_tcp_start_tls(nctrl, queue, pskid);
if (ret)
goto err_init_connect;
@@ -1829,6 +1841,8 @@ static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid)
mutex_lock(&queue->queue_lock);
if (test_and_clear_bit(NVME_TCP_Q_LIVE, &queue->flags))
__nvme_tcp_stop_queue(queue);
+ /* Stopping the queue will disable TLS */
+ queue->tls_enabled = false;
mutex_unlock(&queue->queue_lock);
}
@@ -1925,16 +1939,17 @@ static int nvme_tcp_alloc_admin_queue(struct nvme_ctrl *ctrl)
int ret;
key_serial_t pskid = 0;
- if (nvme_tcp_tls(ctrl)) {
+ if (nvme_tcp_tls_configured(ctrl)) {
if (ctrl->opts->tls_key)
pskid = key_serial(ctrl->opts->tls_key);
- else
+ else {
pskid = nvme_tls_psk_default(ctrl->opts->keyring,
ctrl->opts->host->nqn,
ctrl->opts->subsysnqn);
- if (!pskid) {
- dev_err(ctrl->device, "no valid PSK found\n");
- return -ENOKEY;
+ if (!pskid) {
+ dev_err(ctrl->device, "no valid PSK found\n");
+ return -ENOKEY;
+ }
}
}
@@ -1957,13 +1972,14 @@ static int __nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl)
{
int i, ret;
- if (nvme_tcp_tls(ctrl) && !ctrl->tls_key) {
+ if (nvme_tcp_tls_configured(ctrl) && !ctrl->tls_pskid) {
dev_err(ctrl->device, "no PSK negotiated\n");
return -ENOKEY;
}
+
for (i = 1; i < ctrl->queue_count; i++) {
ret = nvme_tcp_alloc_queue(ctrl, i,
- key_serial(ctrl->tls_key));
+ ctrl->tls_pskid);
if (ret)
goto out_free_queues;
}
@@ -2144,6 +2160,11 @@ static void nvme_tcp_teardown_admin_queue(struct nvme_ctrl *ctrl,
if (remove)
nvme_unquiesce_admin_queue(ctrl);
nvme_tcp_destroy_admin_queue(ctrl, remove);
+ if (ctrl->tls_pskid) {
+ dev_dbg(ctrl->device, "Wipe negotiated TLS_PSK %08x\n",
+ ctrl->tls_pskid);
+ ctrl->tls_pskid = 0;
+ }
}
static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl,
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 3/8] nvme-tcp: check for invalidated or revoked key
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
2024-07-18 14:48 ` [PATCH 1/8] nvme-keyring: restrict match length for version '1' identifiers Hannes Reinecke
2024-07-18 14:48 ` [PATCH 2/8] nvme-tcp: sanitize TLS key handling Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-19 5:37 ` Christoph Hellwig
2024-07-18 14:48 ` [PATCH 4/8] nvme: add a newline to the 'tls_key' sysfs attribute Hannes Reinecke
` (4 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
key_lookup() will always return a key, even if that key is revoked
or invalidated. So check for invalid keys before continuing.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
---
drivers/nvme/common/keyring.c | 21 +++++++++++++++++++++
drivers/nvme/host/fabrics.c | 2 +-
drivers/nvme/host/tcp.c | 2 +-
include/linux/nvme-keyring.h | 3 ++-
4 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/common/keyring.c b/drivers/nvme/common/keyring.c
index c60ebbdc52b8..5b886fd6c3e7 100644
--- a/drivers/nvme/common/keyring.c
+++ b/drivers/nvme/common/keyring.c
@@ -20,6 +20,27 @@ key_serial_t nvme_keyring_id(void)
}
EXPORT_SYMBOL_GPL(nvme_keyring_id);
+static bool nvme_tls_psk_revoked(struct key *psk)
+{
+ return (test_bit(KEY_FLAG_REVOKED, &psk->flags) ||
+ test_bit(KEY_FLAG_INVALIDATED, &psk->flags));
+}
+
+struct key *nvme_tls_key_lookup(key_serial_t key_id)
+{
+ struct key *key = key_lookup(key_id);
+ if (IS_ERR(key)) {
+ pr_err("key id %08x not found\n", key_id);
+ return key;
+ }
+ if (nvme_tls_psk_revoked(key)) {
+ pr_err("key id %08x revoked\n", key_id);
+ return ERR_PTR(-EKEYREVOKED);
+ }
+ return key;
+}
+EXPORT_SYMBOL_GPL(nvme_tls_key_lookup);
+
static void nvme_tls_psk_describe(const struct key *key, struct seq_file *m)
{
seq_puts(m, key->description);
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index f5f545fa0103..432efcbf9e2f 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -665,7 +665,7 @@ static struct key *nvmf_parse_key(int key_id)
return ERR_PTR(-EINVAL);
}
- key = key_lookup(key_id);
+ key = nvme_tls_key_lookup(key_id);
if (IS_ERR(key))
pr_err("key id %08x not found\n", key_id);
else
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 92ad5b8cc1b4..5885aa452aa1 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -1590,7 +1590,7 @@ static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid)
goto out_complete;
}
- tls_key = key_lookup(pskid);
+ tls_key = nvme_tls_key_lookup(pskid);
if (IS_ERR(tls_key)) {
dev_warn(ctrl->ctrl.device, "queue %d: Invalid key %x\n",
qid, pskid);
diff --git a/include/linux/nvme-keyring.h b/include/linux/nvme-keyring.h
index e10333d78dbb..e092e3e6ffb2 100644
--- a/include/linux/nvme-keyring.h
+++ b/include/linux/nvme-keyring.h
@@ -12,7 +12,7 @@ key_serial_t nvme_tls_psk_default(struct key *keyring,
const char *hostnqn, const char *subnqn);
key_serial_t nvme_keyring_id(void);
-
+struct key *nvme_tls_key_lookup(key_serial_t key_id);
#else
static inline key_serial_t nvme_tls_psk_default(struct key *keyring,
@@ -24,5 +24,6 @@ static inline key_serial_t nvme_keyring_id(void)
{
return 0;
}
+static inline struct key *nvme_tls_key_lookup(key_serial_t key_id) { return ERR_PTR(-ENOTSUPP); }
#endif /* !CONFIG_NVME_KEYRING */
#endif /* _NVME_KEYRING_H */
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 4/8] nvme: add a newline to the 'tls_key' sysfs attribute
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
` (2 preceding siblings ...)
2024-07-18 14:48 ` [PATCH 3/8] nvme-tcp: check for invalidated or revoked key Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-19 5:37 ` Christoph Hellwig
2024-07-18 14:48 ` [PATCH 5/8] nvme-sysfs: add 'tls_configured_key' " Hannes Reinecke
` (3 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
Print a newline for easier userspace handling.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
---
drivers/nvme/host/sysfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index 72675b59a7a7..c391ad6c5a88 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -672,7 +672,7 @@ static ssize_t tls_key_show(struct device *dev,
if (!ctrl->tls_pskid)
return 0;
- return sysfs_emit(buf, "%08x", ctrl->tls_pskid);
+ return sysfs_emit(buf, "%08x\n", ctrl->tls_pskid);
}
static DEVICE_ATTR_RO(tls_key);
#endif
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 5/8] nvme-sysfs: add 'tls_configured_key' sysfs attribute
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
` (3 preceding siblings ...)
2024-07-18 14:48 ` [PATCH 4/8] nvme: add a newline to the 'tls_key' sysfs attribute Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-19 5:44 ` Christoph Hellwig
2024-07-18 14:48 ` [PATCH 6/8] nvme-sysfs: add 'tls_keyring' attribute Hannes Reinecke
` (2 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
There is a difference between the negotiated TLS key (which is
always present for a TLS encrypted connection) and the configured
TLS key (which is specified with the --tls_key command line option).
To differentate between these two add a new sysfs attribute
'tls_configured_key' to hold the specified on the command line.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
---
drivers/nvme/host/sysfs.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index c391ad6c5a88..62f03aa530c8 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -675,6 +675,16 @@ static ssize_t tls_key_show(struct device *dev,
return sysfs_emit(buf, "%08x\n", ctrl->tls_pskid);
}
static DEVICE_ATTR_RO(tls_key);
+
+static ssize_t tls_configured_key_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+ struct key *key = ctrl->opts->tls_key;
+
+ return sysfs_emit(buf, "%08x\n", key_serial(key));
+}
+static DEVICE_ATTR_RO(tls_configured_key);
#endif
static struct attribute *nvme_dev_attrs[] = {
@@ -706,6 +716,7 @@ static struct attribute *nvme_dev_attrs[] = {
#endif
#ifdef CONFIG_NVME_TCP_TLS
&dev_attr_tls_key.attr,
+ &dev_attr_tls_configured_key.attr,
#endif
&dev_attr_adm_passthru_err_log_enabled.attr,
NULL
@@ -741,6 +752,10 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
if (a == &dev_attr_tls_key.attr &&
(!ctrl->opts || strcmp(ctrl->opts->transport, "tcp")))
return 0;
+ if (a == &dev_attr_tls_configured_key.attr &&
+ (!ctrl->opts || !ctrl->opts->tls_key ||
+ strcmp(ctrl->opts->transport, "tcp")))
+ return 0;
#endif
return a->mode;
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 5/8] nvme-sysfs: add 'tls_configured_key' sysfs attribute
2024-07-18 14:48 ` [PATCH 5/8] nvme-sysfs: add 'tls_configured_key' " Hannes Reinecke
@ 2024-07-19 5:44 ` Christoph Hellwig
2024-07-19 6:29 ` Hannes Reinecke
0 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2024-07-19 5:44 UTC (permalink / raw)
To: Hannes Reinecke; +Cc: Christoph Hellwig, Sagi Grimberg, Keith Busch, linux-nvme
> #ifdef CONFIG_NVME_TCP_TLS
> &dev_attr_tls_key.attr,
> + &dev_attr_tls_configured_key.attr,
> #endif
> &dev_attr_adm_passthru_err_log_enabled.attr,
> NULL
> @@ -741,6 +752,10 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
> if (a == &dev_attr_tls_key.attr &&
> (!ctrl->opts || strcmp(ctrl->opts->transport, "tcp")))
> return 0;
> + if (a == &dev_attr_tls_configured_key.attr &&
> + (!ctrl->opts || !ctrl->opts->tls_key ||
> + strcmp(ctrl->opts->transport, "tcp")))
> + return 0;
> #endif
The check for a specific transport hack was ok for a single attribute,
but it probably is time to have a separate attribute_group provided
by the transport now. Or maybe wait until we get another one..
>
> return a->mode;
> --
> 2.35.3
---end quoted text---
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 5/8] nvme-sysfs: add 'tls_configured_key' sysfs attribute
2024-07-19 5:44 ` Christoph Hellwig
@ 2024-07-19 6:29 ` Hannes Reinecke
0 siblings, 0 replies; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-19 6:29 UTC (permalink / raw)
To: Christoph Hellwig, Hannes Reinecke; +Cc: Sagi Grimberg, Keith Busch, linux-nvme
On 7/19/24 07:44, Christoph Hellwig wrote:
>> #ifdef CONFIG_NVME_TCP_TLS
>> &dev_attr_tls_key.attr,
>> + &dev_attr_tls_configured_key.attr,
>> #endif
>> &dev_attr_adm_passthru_err_log_enabled.attr,
>> NULL
>> @@ -741,6 +752,10 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
>> if (a == &dev_attr_tls_key.attr &&
>> (!ctrl->opts || strcmp(ctrl->opts->transport, "tcp")))
>> return 0;
>> + if (a == &dev_attr_tls_configured_key.attr &&
>> + (!ctrl->opts || !ctrl->opts->tls_key ||
>> + strcmp(ctrl->opts->transport, "tcp")))
>> + return 0;
>> #endif
>
> The check for a specific transport hack was ok for a single attribute,
> but it probably is time to have a separate attribute_group provided
> by the transport now. Or maybe wait until we get another one..
>
Not a bad idea. Will be doing that for the next round.
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 6/8] nvme-sysfs: add 'tls_keyring' attribute
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
` (4 preceding siblings ...)
2024-07-18 14:48 ` [PATCH 5/8] nvme-sysfs: add 'tls_configured_key' " Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-18 14:48 ` [PATCH 7/8] nvmet-auth: allow to clear DH-HMAC-CHAP keys Hannes Reinecke
2024-07-18 14:48 ` [PATCH 8/8] nvme-target: do not check authentication status for admin commands twice Hannes Reinecke
7 siblings, 0 replies; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
Add a 'tls_keyring' attribute to display the contents of the
--keyring option from the connect string. Adding this attribute
allows us to recreate the original connect string from sysfs
settings.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
---
drivers/nvme/host/sysfs.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index 62f03aa530c8..7a7a4ade59db 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -685,6 +685,16 @@ 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_keyring_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+ struct key *keyring = ctrl->opts->keyring;
+
+ return sysfs_emit(buf, "%s\n", keyring->description);
+}
+static DEVICE_ATTR_RO(tls_keyring);
#endif
static struct attribute *nvme_dev_attrs[] = {
@@ -717,6 +727,7 @@ static struct attribute *nvme_dev_attrs[] = {
#ifdef CONFIG_NVME_TCP_TLS
&dev_attr_tls_key.attr,
&dev_attr_tls_configured_key.attr,
+ &dev_attr_tls_keyring.attr,
#endif
&dev_attr_adm_passthru_err_log_enabled.attr,
NULL
@@ -756,6 +767,10 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
(!ctrl->opts || !ctrl->opts->tls_key ||
strcmp(ctrl->opts->transport, "tcp")))
return 0;
+ if (a == &dev_attr_tls_keyring.attr &&
+ (!ctrl->opts || !ctrl->opts->keyring ||
+ strcmp(ctrl->opts->transport, "tcp")))
+ return 0;
#endif
return a->mode;
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 7/8] nvmet-auth: allow to clear DH-HMAC-CHAP keys
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
` (5 preceding siblings ...)
2024-07-18 14:48 ` [PATCH 6/8] nvme-sysfs: add 'tls_keyring' attribute Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-18 14:48 ` [PATCH 8/8] nvme-target: do not check authentication status for admin commands twice Hannes Reinecke
7 siblings, 0 replies; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
As we can set DH-HMAC-CHAP keys, we should also be
able to unset them.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
---
drivers/nvme/target/auth.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c
index 8bc3f431c77f..7897d02c681d 100644
--- a/drivers/nvme/target/auth.c
+++ b/drivers/nvme/target/auth.c
@@ -25,6 +25,18 @@ int nvmet_auth_set_key(struct nvmet_host *host, const char *secret,
unsigned char key_hash;
char *dhchap_secret;
+ if (!strlen(secret)) {
+ if (set_ctrl) {
+ kfree(host->dhchap_ctrl_secret);
+ host->dhchap_ctrl_secret = NULL;
+ host->dhchap_ctrl_key_hash = 0;
+ } else {
+ kfree(host->dhchap_secret);
+ host->dhchap_secret = NULL;
+ host->dhchap_key_hash = 0;
+ }
+ return 0;
+ }
if (sscanf(secret, "DHHC-1:%hhd:%*s", &key_hash) != 1)
return -EINVAL;
if (key_hash > 3) {
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 8/8] nvme-target: do not check authentication status for admin commands twice
2024-07-18 14:48 [PATCHv6 0/8] nvme: fixes for secure concatenation Hannes Reinecke
` (6 preceding siblings ...)
2024-07-18 14:48 ` [PATCH 7/8] nvmet-auth: allow to clear DH-HMAC-CHAP keys Hannes Reinecke
@ 2024-07-18 14:48 ` Hannes Reinecke
2024-07-19 5:45 ` Christoph Hellwig
7 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2024-07-18 14:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Sagi Grimberg, Keith Busch, linux-nvme, Hannes Reinecke
nvmet_check_ctrl_status() checks the authentication status, so
we don't need to do that prior to calling it.
Signed-off-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
---
drivers/nvme/target/admin-cmd.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index f7e1156ac7ec..d64480f01f4a 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -1005,8 +1005,6 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
if (nvme_is_fabrics(cmd))
return nvmet_parse_fabrics_admin_cmd(req);
- if (unlikely(!nvmet_check_auth_status(req)))
- return NVME_SC_AUTH_REQUIRED | NVME_STATUS_DNR;
if (nvmet_is_disc_subsys(nvmet_req_subsys(req)))
return nvmet_parse_discovery_cmd(req);
--
2.35.3
^ permalink raw reply related [flat|nested] 17+ messages in thread