mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
nvmet-tcp: support secure channel concatenation
Evaluate the SC_C flag during DH-CHAP-HMAC negotiation to check if secure concatenation as specified in the NVMe Base Specification v2.1, section 8.3.4.3: "Secure Channel Concatenationand" is requested. If requested the generated PSK is inserted into the keyring once negotiation has finished allowing for an encrypted connection once the admin queue is restarted. Signed-off-by: Hannes Reinecke <hare@kernel.org> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
committed by
Keith Busch
parent
5032167264
commit
fa2e0f8bbc
@@ -15,6 +15,7 @@
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/nvme-auth.h>
|
||||
#include <linux/nvme-keyring.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include "nvmet.h"
|
||||
@@ -165,6 +166,11 @@ u8 nvmet_setup_auth(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (nvmet_queue_tls_keyid(sq)) {
|
||||
pr_debug("host %s tls enabled\n", ctrl->hostnqn);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = nvmet_setup_dhgroup(ctrl, host->dhchap_dhgroup_id);
|
||||
if (ret < 0) {
|
||||
pr_warn("Failed to setup DH group");
|
||||
@@ -233,6 +239,9 @@ out_unlock:
|
||||
void nvmet_auth_sq_free(struct nvmet_sq *sq)
|
||||
{
|
||||
cancel_delayed_work(&sq->auth_expired_work);
|
||||
#ifdef CONFIG_NVME_TARGET_TCP_TLS
|
||||
sq->tls_key = 0;
|
||||
#endif
|
||||
kfree(sq->dhchap_c1);
|
||||
sq->dhchap_c1 = NULL;
|
||||
kfree(sq->dhchap_c2);
|
||||
@@ -261,6 +270,12 @@ void nvmet_destroy_auth(struct nvmet_ctrl *ctrl)
|
||||
nvme_auth_free_key(ctrl->ctrl_key);
|
||||
ctrl->ctrl_key = NULL;
|
||||
}
|
||||
#ifdef CONFIG_NVME_TARGET_TCP_TLS
|
||||
if (ctrl->tls_key) {
|
||||
key_put(ctrl->tls_key);
|
||||
ctrl->tls_key = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool nvmet_check_auth_status(struct nvmet_req *req)
|
||||
@@ -542,3 +557,58 @@ int nvmet_auth_ctrl_sesskey(struct nvmet_req *req,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nvmet_auth_insert_psk(struct nvmet_sq *sq)
|
||||
{
|
||||
int hash_len = nvme_auth_hmac_hash_len(sq->ctrl->shash_id);
|
||||
u8 *psk, *digest, *tls_psk;
|
||||
size_t psk_len;
|
||||
int ret;
|
||||
#ifdef CONFIG_NVME_TARGET_TCP_TLS
|
||||
struct key *tls_key = NULL;
|
||||
#endif
|
||||
|
||||
ret = nvme_auth_generate_psk(sq->ctrl->shash_id,
|
||||
sq->dhchap_skey,
|
||||
sq->dhchap_skey_len,
|
||||
sq->dhchap_c1, sq->dhchap_c2,
|
||||
hash_len, &psk, &psk_len);
|
||||
if (ret) {
|
||||
pr_warn("%s: ctrl %d qid %d failed to generate PSK, error %d\n",
|
||||
__func__, sq->ctrl->cntlid, sq->qid, ret);
|
||||
return;
|
||||
}
|
||||
ret = nvme_auth_generate_digest(sq->ctrl->shash_id, psk, psk_len,
|
||||
sq->ctrl->subsysnqn,
|
||||
sq->ctrl->hostnqn, &digest);
|
||||
if (ret) {
|
||||
pr_warn("%s: ctrl %d qid %d failed to generate digest, error %d\n",
|
||||
__func__, sq->ctrl->cntlid, sq->qid, ret);
|
||||
goto out_free_psk;
|
||||
}
|
||||
ret = nvme_auth_derive_tls_psk(sq->ctrl->shash_id, psk, psk_len,
|
||||
digest, &tls_psk);
|
||||
if (ret) {
|
||||
pr_warn("%s: ctrl %d qid %d failed to derive TLS PSK, error %d\n",
|
||||
__func__, sq->ctrl->cntlid, sq->qid, ret);
|
||||
goto out_free_digest;
|
||||
}
|
||||
#ifdef CONFIG_NVME_TARGET_TCP_TLS
|
||||
tls_key = nvme_tls_psk_refresh(NULL, sq->ctrl->hostnqn, sq->ctrl->subsysnqn,
|
||||
sq->ctrl->shash_id, tls_psk, psk_len, digest);
|
||||
if (IS_ERR(tls_key)) {
|
||||
pr_warn("%s: ctrl %d qid %d failed to refresh key, error %ld\n",
|
||||
__func__, sq->ctrl->cntlid, sq->qid, PTR_ERR(tls_key));
|
||||
tls_key = NULL;
|
||||
kfree_sensitive(tls_psk);
|
||||
}
|
||||
if (sq->ctrl->tls_key)
|
||||
key_put(sq->ctrl->tls_key);
|
||||
sq->ctrl->tls_key = tls_key;
|
||||
#endif
|
||||
|
||||
out_free_digest:
|
||||
kfree_sensitive(digest);
|
||||
out_free_psk:
|
||||
kfree_sensitive(psk);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user