mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
nvmet-auth: Diffie-Hellman key exchange support
Implement Diffie-Hellman key exchange using FFDHE groups for NVMe In-Band Authentication. This patch adds a new host configfs attribute 'dhchap_dhgroup' to select the FFDHE group to use. Signed-off-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
db1312dd95
commit
7a277c37d3
@@ -27,7 +27,7 @@ static u16 nvmet_auth_negotiate(struct nvmet_req *req, void *d)
|
||||
{
|
||||
struct nvmet_ctrl *ctrl = req->sq->ctrl;
|
||||
struct nvmf_auth_dhchap_negotiate_data *data = d;
|
||||
int i, hash_id = 0, fallback_hash_id = 0, dhgid;
|
||||
int i, hash_id = 0, fallback_hash_id = 0, dhgid, fallback_dhgid;
|
||||
|
||||
pr_debug("%s: ctrl %d qid %d: data sc_d %d napd %d authid %d halen %d dhlen %d\n",
|
||||
__func__, ctrl->cntlid, req->sq->qid,
|
||||
@@ -69,22 +69,35 @@ static u16 nvmet_auth_negotiate(struct nvmet_req *req, void *d)
|
||||
}
|
||||
|
||||
dhgid = -1;
|
||||
fallback_dhgid = -1;
|
||||
for (i = 0; i < data->auth_protocol[0].dhchap.dhlen; i++) {
|
||||
int tmp_dhgid = data->auth_protocol[0].dhchap.idlist[i + 30];
|
||||
|
||||
if (tmp_dhgid == NVME_AUTH_DHGROUP_NULL) {
|
||||
if (tmp_dhgid != ctrl->dh_gid) {
|
||||
dhgid = tmp_dhgid;
|
||||
break;
|
||||
}
|
||||
if (fallback_dhgid < 0) {
|
||||
const char *kpp = nvme_auth_dhgroup_kpp(tmp_dhgid);
|
||||
|
||||
if (crypto_has_kpp(kpp, 0, 0))
|
||||
fallback_dhgid = tmp_dhgid;
|
||||
}
|
||||
}
|
||||
if (dhgid < 0) {
|
||||
pr_debug("%s: ctrl %d qid %d: no usable DH group found\n",
|
||||
if (fallback_dhgid < 0) {
|
||||
pr_debug("%s: ctrl %d qid %d: no usable DH group found\n",
|
||||
__func__, ctrl->cntlid, req->sq->qid);
|
||||
return NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE;
|
||||
return NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE;
|
||||
}
|
||||
pr_debug("%s: ctrl %d qid %d: configured DH group %s not found\n",
|
||||
__func__, ctrl->cntlid, req->sq->qid,
|
||||
nvme_auth_dhgroup_name(fallback_dhgid));
|
||||
ctrl->dh_gid = fallback_dhgid;
|
||||
}
|
||||
pr_debug("%s: ctrl %d qid %d: selected DH group %s (%d)\n",
|
||||
__func__, ctrl->cntlid, req->sq->qid,
|
||||
nvme_auth_dhgroup_name(dhgid), dhgid);
|
||||
nvme_auth_dhgroup_name(ctrl->dh_gid), ctrl->dh_gid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -100,7 +113,11 @@ static u16 nvmet_auth_reply(struct nvmet_req *req, void *d)
|
||||
data->hl, data->cvalid, dhvlen);
|
||||
|
||||
if (dhvlen) {
|
||||
return NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD;
|
||||
if (!ctrl->dh_tfm)
|
||||
return NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD;
|
||||
if (nvmet_auth_ctrl_sesskey(req, data->rval + 2 * data->hl,
|
||||
dhvlen) < 0)
|
||||
return NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE;
|
||||
}
|
||||
|
||||
response = kmalloc(data->hl, GFP_KERNEL);
|
||||
@@ -332,6 +349,8 @@ static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al)
|
||||
int hash_len = nvme_auth_hmac_hash_len(ctrl->shash_id);
|
||||
int data_size = sizeof(*d) + hash_len;
|
||||
|
||||
if (ctrl->dh_tfm)
|
||||
data_size += ctrl->dh_keysize;
|
||||
if (al < data_size) {
|
||||
pr_debug("%s: buffer too small (al %d need %d)\n", __func__,
|
||||
al, data_size);
|
||||
@@ -350,9 +369,15 @@ static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al)
|
||||
return -ENOMEM;
|
||||
get_random_bytes(req->sq->dhchap_c1, data->hl);
|
||||
memcpy(data->cval, req->sq->dhchap_c1, data->hl);
|
||||
pr_debug("%s: ctrl %d qid %d seq %u transaction %d hl %d dhvlen %u\n",
|
||||
if (ctrl->dh_tfm) {
|
||||
data->dhgid = ctrl->dh_gid;
|
||||
data->dhvlen = cpu_to_le16(ctrl->dh_keysize);
|
||||
ret = nvmet_auth_ctrl_exponential(req, data->cval + data->hl,
|
||||
ctrl->dh_keysize);
|
||||
}
|
||||
pr_debug("%s: ctrl %d qid %d seq %d transaction %d hl %d dhvlen %zu\n",
|
||||
__func__, ctrl->cntlid, req->sq->qid, req->sq->dhchap_s1,
|
||||
req->sq->dhchap_tid, data->hl, 0);
|
||||
req->sq->dhchap_tid, data->hl, ctrl->dh_keysize);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user