forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'nvme-6.7-2023-10-17' of git://git.infradead.org/nvme into …
…for-6.7/block Pull NVMe updates from Keith: "nvme updates for Linux 6.7 - nvme-auth updates (Mark) - nvme-tcp tls (Hannes) - nvme-fc annotaions (Kees)" * tag 'nvme-6.7-2023-10-17' of git://git.infradead.org/nvme: (24 commits) nvme-auth: allow mixing of secret and hash lengths nvme-auth: use transformed key size to create resp nvme-auth: alloc nvme_dhchap_key as single buffer nvmet-tcp: use 'spin_lock_bh' for state_lock() nvme: rework NVME_AUTH Kconfig selection nvmet-tcp: peek icreq before starting TLS nvmet-tcp: control messages for recvmsg() nvmet-tcp: enable TLS handshake upcall nvmet: Set 'TREQ' to 'required' when TLS is enabled nvmet-tcp: allocate socket file nvmet-tcp: make nvmet_tcp_alloc_queue() a void function nvmet: make TCP sectype settable via configfs nvme-fabrics: parse options 'keyring' and 'tls_key' nvme-tcp: improve icreq/icresp logging nvme-tcp: control message handling for recvmsg() nvme-tcp: enable TLS handshake upcall nvme-tcp: allocate socket file security/keys: export key_lookup() nvme-keyring: implement nvme_tls_psk_default() nvme-tcp: add definitions for TLS cipher suites ...
- Loading branch information
Showing
25 changed files
with
1,090 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (c) 2023 Hannes Reinecke, SUSE Labs | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/seq_file.h> | ||
#include <linux/key.h> | ||
#include <linux/key-type.h> | ||
#include <keys/user-type.h> | ||
#include <linux/nvme.h> | ||
#include <linux/nvme-tcp.h> | ||
#include <linux/nvme-keyring.h> | ||
|
||
static struct key *nvme_keyring; | ||
|
||
key_serial_t nvme_keyring_id(void) | ||
{ | ||
return nvme_keyring->serial; | ||
} | ||
EXPORT_SYMBOL_GPL(nvme_keyring_id); | ||
|
||
static void nvme_tls_psk_describe(const struct key *key, struct seq_file *m) | ||
{ | ||
seq_puts(m, key->description); | ||
seq_printf(m, ": %u", key->datalen); | ||
} | ||
|
||
static bool nvme_tls_psk_match(const struct key *key, | ||
const struct key_match_data *match_data) | ||
{ | ||
const char *match_id; | ||
size_t match_len; | ||
|
||
if (!key->description) { | ||
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; | ||
pr_debug("%s: match '%s' '%s' len %zd\n", | ||
__func__, match_id, key->description, match_len); | ||
return !memcmp(key->description, match_id, match_len); | ||
} | ||
|
||
static int nvme_tls_psk_match_preparse(struct key_match_data *match_data) | ||
{ | ||
match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE; | ||
match_data->cmp = nvme_tls_psk_match; | ||
return 0; | ||
} | ||
|
||
static struct key_type nvme_tls_psk_key_type = { | ||
.name = "psk", | ||
.flags = KEY_TYPE_NET_DOMAIN, | ||
.preparse = user_preparse, | ||
.free_preparse = user_free_preparse, | ||
.match_preparse = nvme_tls_psk_match_preparse, | ||
.instantiate = generic_key_instantiate, | ||
.revoke = user_revoke, | ||
.destroy = user_destroy, | ||
.describe = nvme_tls_psk_describe, | ||
.read = user_read, | ||
}; | ||
|
||
static struct key *nvme_tls_psk_lookup(struct key *keyring, | ||
const char *hostnqn, const char *subnqn, | ||
int hmac, bool generated) | ||
{ | ||
char *identity; | ||
size_t identity_len = (NVMF_NQN_SIZE) * 2 + 11; | ||
key_ref_t keyref; | ||
key_serial_t keyring_id; | ||
|
||
identity = kzalloc(identity_len, GFP_KERNEL); | ||
if (!identity) | ||
return ERR_PTR(-ENOMEM); | ||
|
||
snprintf(identity, identity_len, "NVMe0%c%02d %s %s", | ||
generated ? 'G' : 'R', hmac, hostnqn, subnqn); | ||
|
||
if (!keyring) | ||
keyring = nvme_keyring; | ||
keyring_id = key_serial(keyring); | ||
pr_debug("keyring %x lookup tls psk '%s'\n", | ||
keyring_id, identity); | ||
keyref = keyring_search(make_key_ref(keyring, true), | ||
&nvme_tls_psk_key_type, | ||
identity, false); | ||
if (IS_ERR(keyref)) { | ||
pr_debug("lookup tls psk '%s' failed, error %ld\n", | ||
identity, PTR_ERR(keyref)); | ||
kfree(identity); | ||
return ERR_PTR(-ENOKEY); | ||
} | ||
kfree(identity); | ||
|
||
return key_ref_to_ptr(keyref); | ||
} | ||
|
||
/* | ||
* NVMe PSK priority list | ||
* | ||
* 'Retained' PSKs (ie 'generated == false') | ||
* should be preferred to 'generated' PSKs, | ||
* and SHA-384 should be preferred to SHA-256. | ||
*/ | ||
struct nvme_tls_psk_priority_list { | ||
bool generated; | ||
enum nvme_tcp_tls_cipher cipher; | ||
} nvme_tls_psk_prio[] = { | ||
{ .generated = false, | ||
.cipher = NVME_TCP_TLS_CIPHER_SHA384, }, | ||
{ .generated = false, | ||
.cipher = NVME_TCP_TLS_CIPHER_SHA256, }, | ||
{ .generated = true, | ||
.cipher = NVME_TCP_TLS_CIPHER_SHA384, }, | ||
{ .generated = true, | ||
.cipher = NVME_TCP_TLS_CIPHER_SHA256, }, | ||
}; | ||
|
||
/* | ||
* nvme_tls_psk_default - Return the preferred PSK to use for TLS ClientHello | ||
*/ | ||
key_serial_t nvme_tls_psk_default(struct key *keyring, | ||
const char *hostnqn, const char *subnqn) | ||
{ | ||
struct key *tls_key; | ||
key_serial_t tls_key_id; | ||
int prio; | ||
|
||
for (prio = 0; prio < ARRAY_SIZE(nvme_tls_psk_prio); prio++) { | ||
bool generated = nvme_tls_psk_prio[prio].generated; | ||
enum nvme_tcp_tls_cipher cipher = nvme_tls_psk_prio[prio].cipher; | ||
|
||
tls_key = nvme_tls_psk_lookup(keyring, hostnqn, subnqn, | ||
cipher, generated); | ||
if (!IS_ERR(tls_key)) { | ||
tls_key_id = tls_key->serial; | ||
key_put(tls_key); | ||
return tls_key_id; | ||
} | ||
} | ||
return 0; | ||
} | ||
EXPORT_SYMBOL_GPL(nvme_tls_psk_default); | ||
|
||
int nvme_keyring_init(void) | ||
{ | ||
int err; | ||
|
||
nvme_keyring = keyring_alloc(".nvme", | ||
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, | ||
current_cred(), | ||
(KEY_POS_ALL & ~KEY_POS_SETATTR) | | ||
(KEY_USR_ALL & ~KEY_USR_SETATTR), | ||
KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); | ||
if (IS_ERR(nvme_keyring)) | ||
return PTR_ERR(nvme_keyring); | ||
|
||
err = register_key_type(&nvme_tls_psk_key_type); | ||
if (err) { | ||
key_put(nvme_keyring); | ||
return err; | ||
} | ||
return 0; | ||
} | ||
EXPORT_SYMBOL_GPL(nvme_keyring_init); | ||
|
||
void nvme_keyring_exit(void) | ||
{ | ||
unregister_key_type(&nvme_tls_psk_key_type); | ||
key_revoke(nvme_keyring); | ||
key_put(nvme_keyring); | ||
} | ||
EXPORT_SYMBOL_GPL(nvme_keyring_exit); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.