// SPDX-License-Identifier: GPL-2.0
/*
 * NVMe over Fabrics DH-HMAC-CHAP authentication.
 * Copyright (c) 2020 Hannes Reinecke, SUSE Software Solutions.
 * All rights reserved.
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <crypto/hash.h>
#include <linux/crc32.h>
#include <linux/base64.h>
#include <linux/ctype.h>
#include <linux/random.h>
#include <linux/nvme-auth.h>
#include <linux/unaligned.h>

#include "nvmet.h"

int nvmet_auth_set_key(struct nvmet_host *host, const char *secret,
		       bool set_ctrl)
{
	unsigned char key_hash;
	char *dhchap_secret;

	if (!strlen(secret)) {
		if (set_ctrl) {
			kfree(host->dhchap_ctrl_secret);
			host->dhchap_ctrl_secret = NULL;
			host->dhchap_ctrl_key_hash = 0;
		} else {
			kfree(host->dhchap_secret);
			host->dhchap_secret = NULL;
			host->dhchap_key_hash = 0;
		}
		return 0;
	}
	if (sscanf(secret, "DHHC-1:%hhd:%*s", &key_hash) != 1)
		return -EINVAL;
	if (key_hash > 3) {
		pr_warn("Invalid DH-HMAC-CHAP hash id %d\n",
			 key_hash);
		return -EINVAL;
	}
	if (key_hash > 0) {
		/* Validate selected hash algorithm */
		const char *hmac = nvme_auth_hmac_name(key_hash);

		if (!crypto_has_shash(hmac, 0, 0)) {
			pr_err("DH-HMAC-CHAP hash %s unsupported\n", hmac);
			return -ENOTSUPP;
		}
	}
	dhchap_secret = kstrdup(secret, GFP_KERNEL);
	if (!dhchap_secret)
		return -ENOMEM;
	down_write(&nvmet_config_sem);
	if (set_ctrl) {
		kfree(host->dhchap_ctrl_secret);
		host->dhchap_ctrl_secret = strim(dhchap_secret);
		host->dhchap_ctrl_key_hash = key_hash;
	} else {
		kfree(host->dhchap_secret);
		host->dhchap_secret = strim(dhchap_secret);
		host->dhchap_key_hash = key_hash;
	}
	up_write(&nvmet_config_sem);
	return 0;
}

int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id)
{
	const char *dhgroup_kpp;
	int ret = 0;

	pr_debug("%s: ctrl %d selecting dhgroup %d\n",
		 __func__, ctrl->cntlid, dhgroup_id);

	if (ctrl->dh_tfm) {
		if (ctrl->dh_gid == dhgroup_id) {
			pr_debug("%s: ctrl %d reuse existing DH group %d\n",
				 __func__, ctrl->cntlid, dhgroup_id);
			return 0;
		}
		crypto_free_kpp(ctrl->dh_tfm);
		ctrl->dh_tfm = NULL;
		ctrl->dh_gid = 0;
	}

	if (dhgroup_id == NVME_AUTH_DHGROUP_NULL)
		return 0;

	dhgroup_kpp = nvme_auth_dhgroup_kpp(dhgroup_id);
	if (!dhgroup_kpp) {
		pr_debug("%s: ctrl %d invalid DH group %d\n",
			 __func__, ctrl->cntlid, dhgroup_id);
		return -EINVAL;
	}
	ctrl->dh_tfm = crypto_alloc_kpp(dhgroup_kpp, 0, 0);
	if (IS_ERR(ctrl->dh_tfm)) {
		pr_debug("%s: ctrl %d failed to setup DH group %d, err %ld\n",
			 __func__, ctrl->cntlid, dhgroup_id,
			 PTR_ERR(ctrl->dh_tfm));
		ret = PTR_ERR(ctrl->dh_tfm);
		ctrl->dh_tfm = NULL;
		ctrl->dh_gid = 0;
	} else {
		ctrl->dh_gid = dhgroup_id;
		pr_debug("%s: ctrl %d setup DH group %d\n",
			 __func__, ctrl->cntlid, ctrl->dh_gid);
		ret = nvme_auth_gen_privkey(ctrl->dh_tfm, ctrl->dh_gid);
		if (ret < 0) {
			pr_debug("%s: ctrl %d failed to generate private key, err %d\n",
				 __func__, ctrl->cntlid, ret);
			kfree_sensitive(ctrl->dh_key);
			ctrl->dh_key = NULL;
			return ret;
		}
		ctrl->dh_keysize = crypto_kpp_maxsize(ctrl->dh_tfm);
		kfree_sensitive(ctrl->dh_key);
		ctrl->dh_key = kzalloc(ctrl->dh_keysize, GFP_KERNEL);
		if (!ctrl->dh_key) {
			pr_warn("ctrl %d failed to allocate public key\n",
				ctrl->cntlid);
			return -ENOMEM;
		}
		ret = nvme_auth_gen_pubkey(ctrl->dh_tfm, ctrl->dh_key,
					   ctrl->dh_keysize);
		if (ret < 0) {
			pr_warn("ctrl %d failed to generate public key\n",
				ctrl->cntlid);
			kfree(ctrl->dh_key);
			ctrl->dh_key = NULL;
		}
	}

	return ret;
}

u8 nvmet_setup_auth(struct nvmet_ctrl *ctrl)
{
	int ret = 0;
	struct nvmet_host_link *p;
	struct nvmet_host *host = NULL;

	down_read(&nvmet_config_sem);
	if (nvmet_is_disc_subsys(ctrl->subsys))
		goto out_unlock;

	if (ctrl->subsys->allow_any_host)
		goto out_unlock;

	list_for_each_entry(p, &ctrl->subsys->hosts, entry) {
		pr_debug("check %s\n", nvmet_host_name(p->host));
		if (strcmp(nvmet_host_name(p->host), ctrl->hostnqn))
			continue;
		host = p->host;
		break;
	}
	if (!host) {
		pr_debug("host %s not found\n", ctrl->hostnqn);
		ret = NVME_AUTH_DHCHAP_FAILURE_FAILED;
		goto out_unlock;
	}

	ret = nvmet_setup_dhgroup(ctrl, host->dhchap_dhgroup_id);
	if (ret < 0) {
		pr_warn("Failed to setup DH group");
		ret = NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE;
		goto out_unlock;
	}

	if (!host->dhchap_secret) {
		pr_debug("No authentication provided\n");
		goto out_unlock;
	}

	if (host->dhchap_hash_id == ctrl->shash_id) {
		pr_debug("Re-use existing hash ID %d\n",
			 ctrl->shash_id);
	} else {
		ctrl->shash_id = host->dhchap_hash_id;
	}

	/* Skip the 'DHHC-1:XX:' prefix */
	nvme_auth_free_key(ctrl->host_key);
	ctrl->host_key = nvme_auth_extract_key(host->dhchap_secret + 10,
					       host->dhchap_key_hash);
	if (IS_ERR(ctrl->host_key)) {
		ret = NVME_AUTH_DHCHAP_FAILURE_NOT_USABLE;
		ctrl->host_key = NULL;
		goto out_free_hash;
	}
	pr_debug("%s: using hash %s key %*ph\n", __func__,
		 ctrl->host_key->hash > 0 ?
		 nvme_auth_hmac_name(ctrl->host_key->hash) : "none",
		 (int)ctrl->host_key->len, ctrl->host_key->key);

	nvme_auth_free_key(ctrl->ctrl_key);
	if (!host->dhchap_ctrl_secret) {
		ctrl->ctrl_key = NULL;
		goto out_unlock;
	}

	ctrl->ctrl_key = nvme_auth_extract_key(host->dhchap_ctrl_secret + 10,
					       host->dhchap_ctrl_key_hash);
	if (IS_ERR(ctrl->ctrl_key)) {
		ret = NVME_AUTH_DHCHAP_FAILURE_NOT_USABLE;
		ctrl->ctrl_key = NULL;
		goto out_free_hash;
	}
	pr_debug("%s: using ctrl hash %s key %*ph\n", __func__,
		 ctrl->ctrl_key->hash > 0 ?
		 nvme_auth_hmac_name(ctrl->ctrl_key->hash) : "none",
		 (int)ctrl->ctrl_key->len, ctrl->ctrl_key->key);

out_free_hash:
	if (ret) {
		if (ctrl->host_key) {
			nvme_auth_free_key(ctrl->host_key);
			ctrl->host_key = NULL;
		}
		ctrl->shash_id = 0;
	}
out_unlock:
	up_read(&nvmet_config_sem);

	return ret;
}

void nvmet_auth_sq_free(struct nvmet_sq *sq)
{
	cancel_delayed_work(&sq->auth_expired_work);
	kfree(sq->dhchap_c1);
	sq->dhchap_c1 = NULL;
	kfree(sq->dhchap_c2);
	sq->dhchap_c2 = NULL;
	kfree(sq->dhchap_skey);
	sq->dhchap_skey = NULL;
}

void nvmet_destroy_auth(struct nvmet_ctrl *ctrl)
{
	ctrl->shash_id = 0;

	if (ctrl->dh_tfm) {
		crypto_free_kpp(ctrl->dh_tfm);
		ctrl->dh_tfm = NULL;
		ctrl->dh_gid = 0;
	}
	kfree_sensitive(ctrl->dh_key);
	ctrl->dh_key = NULL;

	if (ctrl->host_key) {
		nvme_auth_free_key(ctrl->host_key);
		ctrl->host_key = NULL;
	}
	if (ctrl->ctrl_key) {
		nvme_auth_free_key(ctrl->ctrl_key);
		ctrl->ctrl_key = NULL;
	}
}

bool nvmet_check_auth_status(struct nvmet_req *req)
{
	if (req->sq->ctrl->host_key &&
	    !req->sq->authenticated)
		return false;
	return true;
}

int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response,
			 unsigned int shash_len)
{
	struct crypto_shash *shash_tfm;
	struct shash_desc *shash;
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	const char *hash_name;
	u8 *challenge = req->sq->dhchap_c1;
	struct nvme_dhchap_key *transformed_key;
	u8 buf[4];
	int ret;

	hash_name = nvme_auth_hmac_name(ctrl->shash_id);
	if (!hash_name) {
		pr_warn("Hash ID %d invalid\n", ctrl->shash_id);
		return -EINVAL;
	}

	shash_tfm = crypto_alloc_shash(hash_name, 0, 0);
	if (IS_ERR(shash_tfm)) {
		pr_err("failed to allocate shash %s\n", hash_name);
		return PTR_ERR(shash_tfm);
	}

	if (shash_len != crypto_shash_digestsize(shash_tfm)) {
		pr_err("%s: hash len mismatch (len %d digest %d)\n",
			__func__, shash_len,
			crypto_shash_digestsize(shash_tfm));
		ret = -EINVAL;
		goto out_free_tfm;
	}

	transformed_key = nvme_auth_transform_key(ctrl->host_key,
						  ctrl->hostnqn);
	if (IS_ERR(transformed_key)) {
		ret = PTR_ERR(transformed_key);
		goto out_free_tfm;
	}

	ret = crypto_shash_setkey(shash_tfm, transformed_key->key,
				  transformed_key->len);
	if (ret)
		goto out_free_response;

	if (ctrl->dh_gid != NVME_AUTH_DHGROUP_NULL) {
		challenge = kmalloc(shash_len, GFP_KERNEL);
		if (!challenge) {
			ret = -ENOMEM;
			goto out_free_response;
		}
		ret = nvme_auth_augmented_challenge(ctrl->shash_id,
						    req->sq->dhchap_skey,
						    req->sq->dhchap_skey_len,
						    req->sq->dhchap_c1,
						    challenge, shash_len);
		if (ret)
			goto out_free_challenge;
	}

	pr_debug("ctrl %d qid %d host response seq %u transaction %d\n",
		 ctrl->cntlid, req->sq->qid, req->sq->dhchap_s1,
		 req->sq->dhchap_tid);

	shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(shash_tfm),
			GFP_KERNEL);
	if (!shash) {
		ret = -ENOMEM;
		goto out_free_challenge;
	}
	shash->tfm = shash_tfm;
	ret = crypto_shash_init(shash);
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, challenge, shash_len);
	if (ret)
		goto out;
	put_unaligned_le32(req->sq->dhchap_s1, buf);
	ret = crypto_shash_update(shash, buf, 4);
	if (ret)
		goto out;
	put_unaligned_le16(req->sq->dhchap_tid, buf);
	ret = crypto_shash_update(shash, buf, 2);
	if (ret)
		goto out;
	memset(buf, 0, 4);
	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->hostnqn, strlen(ctrl->hostnqn));
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, buf, 1);
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, ctrl->subsysnqn,
				  strlen(ctrl->subsysnqn));
	if (ret)
		goto out;
	ret = crypto_shash_final(shash, response);
out:
	kfree(shash);
out_free_challenge:
	if (challenge != req->sq->dhchap_c1)
		kfree(challenge);
out_free_response:
	nvme_auth_free_key(transformed_key);
out_free_tfm:
	crypto_free_shash(shash_tfm);
	return ret;
}

int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response,
			 unsigned int shash_len)
{
	struct crypto_shash *shash_tfm;
	struct shash_desc *shash;
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	const char *hash_name;
	u8 *challenge = req->sq->dhchap_c2;
	struct nvme_dhchap_key *transformed_key;
	u8 buf[4];
	int ret;

	hash_name = nvme_auth_hmac_name(ctrl->shash_id);
	if (!hash_name) {
		pr_warn("Hash ID %d invalid\n", ctrl->shash_id);
		return -EINVAL;
	}

	shash_tfm = crypto_alloc_shash(hash_name, 0, 0);
	if (IS_ERR(shash_tfm)) {
		pr_err("failed to allocate shash %s\n", hash_name);
		return PTR_ERR(shash_tfm);
	}

	if (shash_len != crypto_shash_digestsize(shash_tfm)) {
		pr_debug("%s: hash len mismatch (len %d digest %d)\n",
			 __func__, shash_len,
			 crypto_shash_digestsize(shash_tfm));
		ret = -EINVAL;
		goto out_free_tfm;
	}

	transformed_key = nvme_auth_transform_key(ctrl->ctrl_key,
						ctrl->subsysnqn);
	if (IS_ERR(transformed_key)) {
		ret = PTR_ERR(transformed_key);
		goto out_free_tfm;
	}

	ret = crypto_shash_setkey(shash_tfm, transformed_key->key,
				  transformed_key->len);
	if (ret)
		goto out_free_response;

	if (ctrl->dh_gid != NVME_AUTH_DHGROUP_NULL) {
		challenge = kmalloc(shash_len, GFP_KERNEL);
		if (!challenge) {
			ret = -ENOMEM;
			goto out_free_response;
		}
		ret = nvme_auth_augmented_challenge(ctrl->shash_id,
						    req->sq->dhchap_skey,
						    req->sq->dhchap_skey_len,
						    req->sq->dhchap_c2,
						    challenge, shash_len);
		if (ret)
			goto out_free_challenge;
	}

	shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(shash_tfm),
			GFP_KERNEL);
	if (!shash) {
		ret = -ENOMEM;
		goto out_free_challenge;
	}
	shash->tfm = shash_tfm;

	ret = crypto_shash_init(shash);
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, challenge, shash_len);
	if (ret)
		goto out;
	put_unaligned_le32(req->sq->dhchap_s2, buf);
	ret = crypto_shash_update(shash, buf, 4);
	if (ret)
		goto out;
	put_unaligned_le16(req->sq->dhchap_tid, buf);
	ret = crypto_shash_update(shash, buf, 2);
	if (ret)
		goto out;
	memset(buf, 0, 4);
	ret = crypto_shash_update(shash, buf, 1);
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, "Controller", 10);
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, ctrl->subsysnqn,
			    strlen(ctrl->subsysnqn));
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, buf, 1);
	if (ret)
		goto out;
	ret = crypto_shash_update(shash, ctrl->hostnqn, strlen(ctrl->hostnqn));
	if (ret)
		goto out;
	ret = crypto_shash_final(shash, response);
out:
	kfree(shash);
out_free_challenge:
	if (challenge != req->sq->dhchap_c2)
		kfree(challenge);
out_free_response:
	nvme_auth_free_key(transformed_key);
out_free_tfm:
	crypto_free_shash(shash_tfm);
	return ret;
}

int nvmet_auth_ctrl_exponential(struct nvmet_req *req,
				u8 *buf, int buf_size)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	int ret = 0;

	if (!ctrl->dh_key) {
		pr_warn("ctrl %d no DH public key!\n", ctrl->cntlid);
		return -ENOKEY;
	}
	if (buf_size != ctrl->dh_keysize) {
		pr_warn("ctrl %d DH public key size mismatch, need %zu is %d\n",
			ctrl->cntlid, ctrl->dh_keysize, buf_size);
		ret = -EINVAL;
	} else {
		memcpy(buf, ctrl->dh_key, buf_size);
		pr_debug("%s: ctrl %d public key %*ph\n", __func__,
			 ctrl->cntlid, (int)buf_size, buf);
	}

	return ret;
}

int nvmet_auth_ctrl_sesskey(struct nvmet_req *req,
			    u8 *pkey, int pkey_size)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	int ret;

	req->sq->dhchap_skey_len = ctrl->dh_keysize;
	req->sq->dhchap_skey = kzalloc(req->sq->dhchap_skey_len, GFP_KERNEL);
	if (!req->sq->dhchap_skey)
		return -ENOMEM;
	ret = nvme_auth_gen_shared_secret(ctrl->dh_tfm,
					  pkey, pkey_size,
					  req->sq->dhchap_skey,
					  req->sq->dhchap_skey_len);
	if (ret)
		pr_debug("failed to compute shared secret, err %d\n", ret);
	else
		pr_debug("%s: shared secret %*ph\n", __func__,
			 (int)req->sq->dhchap_skey_len,
			 req->sq->dhchap_skey);

	return ret;
}
