[PATCH 05/17] nvme: add nvme_auth_generate_digest()

Sagi Grimberg sagi at grimberg.me
Sun Apr 7 14:02:07 PDT 2024



On 18/03/2024 17:03, Hannes Reinecke wrote:
> From: Hannes Reinecke <hare at suse.de>
>
> Add a function to calculate the PSK digest as specified in TP8018.
>
> Signed-off-by: Hannes Reinecke <hare at suse.de>
> Reviewed-by: Sagi Grimberg <sagi at grimberg.me>
> ---
>   drivers/nvme/common/auth.c | 105 +++++++++++++++++++++++++++++++++++++
>   include/linux/nvme-auth.h  |   2 +
>   2 files changed, 107 insertions(+)
>
> diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
> index 7a4b6589351d..f56f08a4461e 100644
> --- a/drivers/nvme/common/auth.c
> +++ b/drivers/nvme/common/auth.c
> @@ -547,5 +547,110 @@ u8 *nvme_auth_generate_psk(u8 hmac_id, u8 *skey, size_t skey_len,
>   }
>   EXPORT_SYMBOL_GPL(nvme_auth_generate_psk);
>   
> +u8 *nvme_auth_generate_digest(u8 hmac_id, u8 *psk, size_t psk_len,
> +			      char *subsysnqn, char *hostnqn)

Same comment here.

> +{
> +	struct crypto_shash *tfm;
> +	struct shash_desc *shash;
> +	u8 *digest, *hmac;
> +	const char *hmac_name;
> +	size_t digest_len, hmac_len;
> +	int ret;
> +
> +	if (WARN_ON(!subsysnqn || !hostnqn))
> +		return ERR_PTR(-EINVAL);
> +
> +	hmac_name = nvme_auth_hmac_name(hmac_id);
> +	if (!hmac_name) {
> +		pr_warn("%s: invalid hash algoritm %d\n",
> +			__func__, hmac_id);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	switch (nvme_auth_hmac_hash_len(hmac_id)) {
> +	case 32:
> +		hmac_len = 44;
> +		break;
> +	case 48:
> +		hmac_len = 64;
> +		break;
> +	default:
> +		pr_warn("%s: invalid hash algorithm '%s'\n",
> +			__func__, hmac_name);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	hmac = kzalloc(hmac_len + 1, GFP_KERNEL);
> +	if (!hmac)
> +		return ERR_PTR(-ENOMEM);
> +
> +	tfm = crypto_alloc_shash(hmac_name, 0, 0);
> +	if (IS_ERR(tfm))
> +		goto out_free_hmac;
> +
> +	digest_len = crypto_shash_digestsize(tfm);
> +	digest = kzalloc(digest_len, GFP_KERNEL);
> +	if (!digest) {
> +		ret = -ENOMEM;
> +		goto out_free_tfm;
> +	}
> +
> +	shash = kmalloc(sizeof(struct shash_desc) +
> +			crypto_shash_descsize(tfm),
> +			GFP_KERNEL);
> +	if (!shash) {
> +		ret = -ENOMEM;
> +		goto out_free_digest;
> +	}
> +
> +	shash->tfm = tfm;
> +	ret = crypto_shash_setkey(tfm, psk, psk_len);
> +	if (ret)
> +		goto out_free_shash;
> +
> +	ret = crypto_shash_init(shash);
> +	if (ret)
> +		goto out_free_shash;
> +
> +	ret = crypto_shash_update(shash, hostnqn, strlen(hostnqn));
> +	if (ret)
> +		goto out_free_shash;
> +
> +	ret = crypto_shash_update(shash, " ", 1);
> +	if (ret)
> +		goto out_free_shash;
> +
> +	ret = crypto_shash_update(shash, subsysnqn, strlen(subsysnqn));
> +	if (ret)
> +		goto out_free_shash;
> +
> +	ret = crypto_shash_update(shash, " NVMe-over-Fabrics", 18);
> +	if (ret)
> +		goto out_free_shash;
> +
> +	ret = crypto_shash_final(shash, digest);
> +	if (ret)
> +		goto out_free_shash;
> +
> +	ret = base64_encode(digest, digest_len, hmac);
> +	if (ret < hmac_len)
> +		ret = -ENOKEY;
> +	ret = 0;
> +
> +out_free_shash:
> +	kfree_sensitive(shash);
> +out_free_digest:
> +	kfree_sensitive(digest);
> +out_free_tfm:
> +	crypto_free_shash(tfm);
> +out_free_hmac:
> +	if (ret) {
> +		kfree_sensitive(hmac);
> +		hmac = NULL;
> +	}
> +	return ret ? ERR_PTR(ret) : hmac;
> +}
> +EXPORT_SYMBOL_GPL(nvme_auth_generate_digest);
> +
>   MODULE_DESCRIPTION("NVMe Authentication framework");
>   MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/nvme-auth.h b/include/linux/nvme-auth.h
> index 31dc1db2d4d6..2cbb9249a8b3 100644
> --- a/include/linux/nvme-auth.h
> +++ b/include/linux/nvme-auth.h
> @@ -42,5 +42,7 @@ int nvme_auth_gen_shared_secret(struct crypto_kpp *dh_tfm,
>   				u8 *sess_key, size_t sess_key_len);
>   u8 *nvme_auth_generate_psk(u8 hmac_id, u8 *skey, size_t skey_len,
>   			   u8 *c1, u8 *c2, size_t hash_len, size_t *ret_len);
> +u8 *nvme_auth_generate_digest(u8 hmac_id, u8 *psk, size_t psk_len,
> +			      char *subsysnqn, char *hostnqn);
>   
>   #endif /* _NVME_AUTH_H */




More information about the Linux-nvme mailing list