// 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 <linux/crc32.h>
#include <linux/base64.h>
#include <linux/ctype.h>
#include <linux/random.h>
#include <linux/nvme-auth.h>
#include <linux/nvme-keyring.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;
	}
	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, struct nvmet_sq *sq, bool reset)
{
	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) {
		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;
	}

	if (!reset && nvmet_queue_tls_keyid(sq)) {
		pr_debug("host %s tls enabled\n", ctrl->hostnqn);
		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;
	}
#ifdef CONFIG_NVME_TARGET_AUTH_DEBUG
	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);
#endif
	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;
	}
#ifdef CONFIG_NVME_TARGET_AUTH_DEBUG
	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);
#endif
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;
	}
#ifdef CONFIG_NVME_TARGET_TCP_TLS
	if (ctrl->tls_key) {
		key_put(ctrl->tls_key);
		ctrl->tls_key = NULL;
	}
#endif
}

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

int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response,
			 unsigned int shash_len)
{
	struct nvme_auth_hmac_ctx hmac;
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	u8 *challenge = req->sq->dhchap_c1;
	struct nvme_dhchap_key *transformed_key;
	u8 buf[4];
	int ret;

	transformed_key = nvme_auth_transform_key(ctrl->host_key,
						  ctrl->hostnqn);
	if (IS_ERR(transformed_key))
		return PTR_ERR(transformed_key);

	ret = nvme_auth_hmac_init(&hmac, ctrl->shash_id, transformed_key->key,
				  transformed_key->len);
	if (ret)
		goto out_free_response;

	if (shash_len != nvme_auth_hmac_hash_len(ctrl->shash_id)) {
		pr_err("%s: hash len mismatch (len %u digest %zu)\n", __func__,
		       shash_len, nvme_auth_hmac_hash_len(ctrl->shash_id));
		ret = -EINVAL;
		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);

	nvme_auth_hmac_update(&hmac, challenge, shash_len);

	put_unaligned_le32(req->sq->dhchap_s1, buf);
	nvme_auth_hmac_update(&hmac, buf, 4);

	put_unaligned_le16(req->sq->dhchap_tid, buf);
	nvme_auth_hmac_update(&hmac, buf, 2);

	*buf = req->sq->sc_c;
	nvme_auth_hmac_update(&hmac, buf, 1);
	nvme_auth_hmac_update(&hmac, "HostHost", 8);
	memset(buf, 0, 4);
	nvme_auth_hmac_update(&hmac, ctrl->hostnqn, strlen(ctrl->hostnqn));
	nvme_auth_hmac_update(&hmac, buf, 1);
	nvme_auth_hmac_update(&hmac, ctrl->subsys->subsysnqn,
			      strlen(ctrl->subsys->subsysnqn));
	nvme_auth_hmac_final(&hmac, response);
	ret = 0;
out_free_challenge:
	if (challenge != req->sq->dhchap_c1)
		kfree(challenge);
out_free_response:
	memzero_explicit(&hmac, sizeof(hmac));
	nvme_auth_free_key(transformed_key);
	return ret;
}

int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response,
			 unsigned int shash_len)
{
	struct nvme_auth_hmac_ctx hmac;
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	u8 *challenge = req->sq->dhchap_c2;
	struct nvme_dhchap_key *transformed_key;
	u8 buf[4];
	int ret;

	transformed_key = nvme_auth_transform_key(ctrl->ctrl_key,
						ctrl->subsys->subsysnqn);
	if (IS_ERR(transformed_key))
		return PTR_ERR(transformed_key);

	ret = nvme_auth_hmac_init(&hmac, ctrl->shash_id, transformed_key->key,
				  transformed_key->len);
	if (ret)
		goto out_free_response;

	if (shash_len != nvme_auth_hmac_hash_len(ctrl->shash_id)) {
		pr_err("%s: hash len mismatch (len %u digest %zu)\n", __func__,
		       shash_len, nvme_auth_hmac_hash_len(ctrl->shash_id));
		ret = -EINVAL;
		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;
	}

	nvme_auth_hmac_update(&hmac, challenge, shash_len);

	put_unaligned_le32(req->sq->dhchap_s2, buf);
	nvme_auth_hmac_update(&hmac, buf, 4);

	put_unaligned_le16(req->sq->dhchap_tid, buf);
	nvme_auth_hmac_update(&hmac, buf, 2);

	*buf = req->sq->sc_c;
	nvme_auth_hmac_update(&hmac, buf, 1);
	nvme_auth_hmac_update(&hmac, "Controller", 10);
	nvme_auth_hmac_update(&hmac, ctrl->subsys->subsysnqn,
			      strlen(ctrl->subsys->subsysnqn));
	memset(buf, 0, 4);
	nvme_auth_hmac_update(&hmac, buf, 1);
	nvme_auth_hmac_update(&hmac, ctrl->hostnqn, strlen(ctrl->hostnqn));
	nvme_auth_hmac_final(&hmac, response);
	ret = 0;
out_free_challenge:
	if (challenge != req->sq->dhchap_c2)
		kfree(challenge);
out_free_response:
	memzero_explicit(&hmac, sizeof(hmac));
	nvme_auth_free_key(transformed_key);
	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);
#ifdef CONFIG_NVME_TARGET_AUTH_DEBUG
		pr_debug("%s: ctrl %d public key %*ph\n", __func__,
			 ctrl->cntlid, (int)buf_size, buf);
#endif
	}

	return ret;
}

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

	req->sq->dhchap_skey_len = nvme_auth_hmac_hash_len(ctrl->shash_id);
	req->sq->dhchap_skey = kzalloc(req->sq->dhchap_skey_len, GFP_KERNEL);
	if (!req->sq->dhchap_skey)
		return -ENOMEM;
	ret = nvme_auth_gen_session_key(ctrl->dh_tfm,
					pkey, pkey_size,
					req->sq->dhchap_skey,
					req->sq->dhchap_skey_len,
					ctrl->shash_id);
	if (ret)
		pr_debug("failed to compute session key, err %d\n", ret);
#ifdef CONFIG_NVME_TARGET_AUTH_DEBUG
	else
		pr_debug("%s: session key %*ph\n", __func__,
			 (int)req->sq->dhchap_skey_len,
			 req->sq->dhchap_skey);
#endif
	return ret;
}

void nvmet_auth_insert_psk(struct nvmet_sq *sq)
{
	int hash_len = nvme_auth_hmac_hash_len(sq->ctrl->shash_id);
	u8 *psk, *tls_psk;
	char *digest;
	size_t psk_len;
	int ret;
#ifdef CONFIG_NVME_TARGET_TCP_TLS
	struct key *tls_key = NULL;
#endif

	ret = nvme_auth_generate_psk(sq->ctrl->shash_id,
				     sq->dhchap_skey,
				     sq->dhchap_skey_len,
				     sq->dhchap_c1, sq->dhchap_c2,
				     hash_len, &psk, &psk_len);
	if (ret) {
		pr_warn("%s: ctrl %d qid %d failed to generate PSK, error %d\n",
			__func__, sq->ctrl->cntlid, sq->qid, ret);
		return;
	}
	ret = nvme_auth_generate_digest(sq->ctrl->shash_id, psk, psk_len,
					sq->ctrl->subsys->subsysnqn,
					sq->ctrl->hostnqn, &digest);
	if (ret) {
		pr_warn("%s: ctrl %d qid %d failed to generate digest, error %d\n",
			__func__, sq->ctrl->cntlid, sq->qid, ret);
		goto out_free_psk;
	}
	ret = nvme_auth_derive_tls_psk(sq->ctrl->shash_id, psk, psk_len,
				       digest, &tls_psk);
	if (ret) {
		pr_warn("%s: ctrl %d qid %d failed to derive TLS PSK, error %d\n",
			__func__, sq->ctrl->cntlid, sq->qid, ret);
		goto out_free_digest;
	}
#ifdef CONFIG_NVME_TARGET_TCP_TLS
	tls_key = nvme_tls_psk_refresh(NULL, sq->ctrl->hostnqn,
				       sq->ctrl->subsys->subsysnqn,
				       sq->ctrl->shash_id, tls_psk, psk_len,
				       digest);
	if (IS_ERR(tls_key)) {
		pr_warn("%s: ctrl %d qid %d failed to refresh key, error %ld\n",
			__func__, sq->ctrl->cntlid, sq->qid, PTR_ERR(tls_key));
		tls_key = NULL;
	}
	if (sq->ctrl->tls_key)
		key_put(sq->ctrl->tls_key);
	sq->ctrl->tls_key = tls_key;
#endif
	kfree_sensitive(tls_psk);
out_free_digest:
	kfree_sensitive(digest);
out_free_psk:
	kfree_sensitive(psk);
}
