[PATCH 10/12] nvmet: Implement basic In-Band Authentication
Sagi Grimberg
sagi at grimberg.me
Sun Sep 26 15:51:56 PDT 2021
> +void nvmet_execute_auth_send(struct nvmet_req *req)
> +{
> + struct nvmet_ctrl *ctrl = req->sq->ctrl;
> + struct nvmf_auth_dhchap_success2_data *data;
> + void *d;
> + u32 tl;
> + u16 status = 0;
> +
> + if (req->cmd->auth_send.secp != NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER) {
> + status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
> + req->error_loc =
> + offsetof(struct nvmf_auth_send_command, secp);
> + goto done;
> + }
> + if (req->cmd->auth_send.spsp0 != 0x01) {
> + status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
> + req->error_loc =
> + offsetof(struct nvmf_auth_send_command, spsp0);
> + goto done;
> + }
> + if (req->cmd->auth_send.spsp1 != 0x01) {
> + status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
> + req->error_loc =
> + offsetof(struct nvmf_auth_send_command, spsp1);
> + goto done;
> + }
> + tl = le32_to_cpu(req->cmd->auth_send.tl);
> + if (!tl) {
> + status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
> + req->error_loc =
> + offsetof(struct nvmf_auth_send_command, tl);
> + goto done;
> + }
> + if (!nvmet_check_transfer_len(req, tl)) {
> + pr_debug("%s: transfer length mismatch (%u)\n", __func__, tl);
> + return;
> + }
> +
> + d = kmalloc(tl, GFP_KERNEL);
> + if (!d) {
> + status = NVME_SC_INTERNAL;
> + goto done;
> + }
> +
> + status = nvmet_copy_from_sgl(req, 0, d, tl);
> + if (status) {
> + kfree(d);
> + goto done;
> + }
> +
> + data = d;
> + pr_debug("%s: ctrl %d qid %d type %d id %d step %x\n", __func__,
> + ctrl->cntlid, req->sq->qid, data->auth_type, data->auth_id,
> + req->sq->dhchap_step);
> + if (data->auth_type != NVME_AUTH_COMMON_MESSAGES &&
> + data->auth_type != NVME_AUTH_DHCHAP_MESSAGES)
> + goto done_failure1;
> + if (data->auth_type == NVME_AUTH_COMMON_MESSAGES) {
> + if (data->auth_id == NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE) {
> + /* Restart negotiation */
> + pr_debug("%s: ctrl %d qid %d reset negotiation\n", __func__,
> + ctrl->cntlid, req->sq->qid);
This is the point where you need to reset also auth config as this may
have changed and the host will not create a new controller but rather
re-authenticate on the existing controller.
i.e.
+ if (!req->sq->qid) {
+ nvmet_destroy_auth(ctrl);
+ if (nvmet_setup_auth(ctrl) < 0) {
+ pr_err("Failed to setup
re-authentication\n");
+ goto done_failure1;
+ }
+ }
> + req->sq->dhchap_step = NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE;
> + } else if (data->auth_id != req->sq->dhchap_step)
> + goto done_failure1;
> + /* Validate negotiation parameters */
> + status = nvmet_auth_negotiate(req, d);/
More information about the Linux-nvme
mailing list