drivers/nvme/target/fabrics-cmd-auth.c

Source file repositories/reference/linux-study-clean/drivers/nvme/target/fabrics-cmd-auth.c

File Facts

System
Linux kernel
Corpus path
drivers/nvme/target/fabrics-cmd-auth.c
Extension
.c
Size
18420 bytes
Lines
593
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (data->sc_c) {
		case NVME_AUTH_SECP_NEWTLSPSK:
			if (nvmet_queue_tls_keyid(req->sq))
				return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH;
			break;
		case NVME_AUTH_SECP_REPLACETLSPSK:
			if (!nvmet_queue_tls_keyid(req->sq))
				return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH;
			break;
		default:
			return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH;
		}
		ctrl->concat = true;
	}

	if (data->napd != 1)
		return NVME_AUTH_DHCHAP_FAILURE_HASH_UNUSABLE;

	if (data->auth_protocol[0].dhchap.authid !=
	    NVME_AUTH_DHCHAP_AUTH_ID)
		return NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD;

	for (i = 0; i < data->auth_protocol[0].dhchap.halen; i++) {
		u8 host_hmac_id = data->auth_protocol[0].dhchap.idlist[i];

		if (!fallback_hash_id && nvme_auth_hmac_hash_len(host_hmac_id))
			fallback_hash_id = host_hmac_id;
		if (ctrl->shash_id != host_hmac_id)
			continue;
		hash_id = ctrl->shash_id;
		break;
	}
	if (hash_id == 0) {
		if (fallback_hash_id == 0) {
			pr_debug("%s: ctrl %d qid %d: no usable hash found\n",
				 __func__, ctrl->cntlid, req->sq->qid);
			return NVME_AUTH_DHCHAP_FAILURE_HASH_UNUSABLE;
		}
		pr_debug("%s: ctrl %d qid %d: no usable hash found, falling back to %s\n",
			 __func__, ctrl->cntlid, req->sq->qid,
			 nvme_auth_hmac_name(fallback_hash_id));
		ctrl->shash_id = fallback_hash_id;
	}

	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 != 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) {
		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;
		}
		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;
	}
	if (ctrl->dh_gid == NVME_AUTH_DHGROUP_NULL && ctrl->concat) {
		pr_debug("%s: ctrl %d qid %d: NULL DH group invalid "
			 "for secure channel concatenation\n", __func__,
			 ctrl->cntlid, req->sq->qid);
		return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH;
	}
	pr_debug("%s: ctrl %d qid %d: selected DH group %s (%d)\n",
		 __func__, ctrl->cntlid, req->sq->qid,
		 nvme_auth_dhgroup_name(ctrl->dh_gid), ctrl->dh_gid);
	return 0;
}

static u8 nvmet_auth_reply(struct nvmet_req *req, void *d, u32 tl)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvmf_auth_dhchap_reply_data *data = d;
	u16 dhvlen;
	u8 *response;

Annotation

Implementation Notes