[PATCH 13/21] nvme-auth: host: use crypto library in nvme_auth_dhchap_setup_host_response()

Eric Biggers
2026-03-02T08:01:34Z

For the HMAC computation in nvme_auth_dhchap_setup_host_response(), use
the crypto library instead of crypto_shash. This is simpler, faster,
and more reliable.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/nvme/host/auth.c | 59 ++++++++++++++--------------------------
1 file changed, 21 insertions(+), 38 deletions(-)

diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c
index 47a1525e876e0..f22f17ad7e2f4 100644
--- a/drivers/nvme/host/auth.c
+++ b/drivers/nvme/host/auth.c
@@ -432,11 +432,11 @@ static int nvme_auth_set_dhchap_failure2_data(struct nvme_ctrl *ctrl,
}

static int nvme_auth_dhchap_setup_host_response(struct nvme_ctrl *ctrl,
struct nvme_dhchap_queue_context *chap)
{
- SHASH_DESC_ON_STACK(shash, chap->shash_tfm);
+ struct nvme_auth_hmac_ctx hmac;
u8 buf[4], *challenge = chap->c1;
int ret;

dev_dbg(ctrl->device, "%s: qid %d host response seq %u transaction %d\n",
__func__, chap->qid, chap->s1, chap->transaction);
@@ -452,17 +452,15 @@ static int nvme_auth_dhchap_setup_host_response(struct nvme_ctrl *ctrl,
} else {
dev_dbg(ctrl->device, "%s: qid %d re-using host response\n",
__func__, chap->qid);
}

- ret = crypto_shash_setkey(chap->shash_tfm,
- chap->transformed_key->key, chap->transformed_key->len);
- if (ret) {
- dev_warn(ctrl->device, "qid %d: failed to set key, error %d\n",
- chap->qid, ret);
+ ret = nvme_auth_hmac_init(&hmac, chap->hash_id,
+ chap->transformed_key->key,
+ chap->transformed_key->len);
+ if (ret)
goto out;
- }

if (chap->dh_tfm) {
challenge = kmalloc(chap->hash_len, GFP_KERNEL);
if (!challenge) {
ret = -ENOMEM;
@@ -475,48 +473,33 @@ static int nvme_auth_dhchap_setup_host_response(struct nvme_ctrl *ctrl,
chap->hash_len);
if (ret)
goto out;
}

- shash->tfm = chap->shash_tfm;
- ret = crypto_shash_init(shash);
- if (ret)
- goto out;
- ret = crypto_shash_update(shash, challenge, chap->hash_len);
- if (ret)
- goto out;
+ nvme_auth_hmac_update(&hmac, challenge, chap->hash_len);
+
put_unaligned_le32(chap->s1, buf);
- ret = crypto_shash_update(shash, buf, 4);
- if (ret)
- goto out;
+ nvme_auth_hmac_update(&hmac, buf, 4);
+
put_unaligned_le16(chap->transaction, buf);
- ret = crypto_shash_update(shash, buf, 2);
- if (ret)
- goto out;
+ nvme_auth_hmac_update(&hmac, buf, 2);
+
*buf = chap->sc_c;
- ret = crypto_shash_update(shash, buf, 1);
- if (ret)
- goto out;
- ret = crypto_shash_update(shash, "HostHost", 8);
- if (ret)
- goto out;
- ret = crypto_shash_update(shash, ctrl->opts->host->nqn,
- strlen(ctrl->opts->host->nqn));
- if (ret)
- goto out;
+ nvme_auth_hmac_update(&hmac, buf, 1);
+ nvme_auth_hmac_update(&hmac, "HostHost", 8);
+ nvme_auth_hmac_update(&hmac, ctrl->opts->host->nqn,
+ strlen(ctrl->opts->host->nqn));
memset(buf, 0, sizeof(buf));
- ret = crypto_shash_update(shash, buf, 1);
- if (ret)
- goto out;
- ret = crypto_shash_update(shash, ctrl->opts->subsysnqn,
- strlen(ctrl->opts->subsysnqn));
- if (ret)
- goto out;
- ret = crypto_shash_final(shash, chap->response);
+ nvme_auth_hmac_update(&hmac, buf, 1);
+ nvme_auth_hmac_update(&hmac, ctrl->opts->subsysnqn,
+ strlen(ctrl->opts->subsysnqn));
+ nvme_auth_hmac_final(&hmac, chap->response);
+ ret = 0;
out:
if (challenge != chap->c1)
kfree(challenge);
+ memzero_explicit(&hmac, sizeof(hmac));
return ret;
}

static int nvme_auth_dhchap_setup_ctrl_response(struct nvme_ctrl *ctrl,
struct nvme_dhchap_queue_context *chap)
--
2.53.0