nvme-auth: use crypto_memneq for DH-HMAC-CHAP response comparison

DH-HMAC-CHAP authentication compares HMAC response digests with memcmp().
Standard memcmp() may stop at the first differing byte, which can leak
timing information to a remote attacker and allow incremental recovery
of the expected digest.

Use crypto_memneq() for constant-time comparison on both the host path
that validates the controller Success1 response and the target path that
validates the host Reply digest.  Other memcmp() uses in the NVMe auth
code (e.g. fixed string prefix checks) are not security-sensitive and
are left unchanged.

Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
Xixin Liu 2026-07-01 14:30:00 +08:00 committed by Keith Busch
parent dd516cd762
commit 3a6d89836a
2 changed files with 4 additions and 2 deletions

View File

@ -8,6 +8,7 @@
#include <linux/prandom.h>
#include <linux/unaligned.h>
#include <crypto/dh.h>
#include <crypto/utils.h>
#include "nvme.h"
#include "fabrics.h"
#include <linux/nvme-auth.h>
@ -361,7 +362,7 @@ static int nvme_auth_process_dhchap_success1(struct nvme_ctrl *ctrl,
return 0;
/* Validate controller response */
if (memcmp(chap->response, data->rval, data->hl)) {
if (crypto_memneq(chap->response, data->rval, data->hl)) {
dev_dbg(ctrl->device, "%s: qid %d ctrl response %*ph\n",
__func__, chap->qid, (int)chap->hash_len, data->rval);
dev_dbg(ctrl->device, "%s: qid %d host response %*ph\n",

View File

@ -9,6 +9,7 @@
#include <linux/random.h>
#include <linux/nvme-auth.h>
#include <crypto/kpp.h>
#include <crypto/utils.h>
#include "nvmet.h"
static void nvmet_auth_expired_work(struct work_struct *work)
@ -177,7 +178,7 @@ static u8 nvmet_auth_reply(struct nvmet_req *req, void *d, u32 tl)
return NVME_AUTH_DHCHAP_FAILURE_FAILED;
}
if (memcmp(data->rval, response, data->hl)) {
if (crypto_memneq(data->rval, response, data->hl)) {
pr_info("ctrl %d qid %d host response mismatch\n",
ctrl->cntlid, req->sq->qid);
pr_debug("ctrl %d qid %d rval %*ph\n",