[PATCH 06/17] nvme: add nvme_auth_derive_tls_psk()

Sagi Grimberg sagi at grimberg.me
Sun Apr 7 14:04:27 PDT 2024



On 18/03/2024 17:03, Hannes Reinecke wrote:
> From: Hannes Reinecke <hare at suse.de>
>
> Add a function to derive the TLS PSK as specified TP8018.
>
> Signed-off-by: Hannes Reinecke <hare at suse.de>
> ---
>   drivers/nvme/common/auth.c | 71 ++++++++++++++++++++++++++++++++++++++
>   include/linux/nvme-auth.h  |  1 +
>   2 files changed, 72 insertions(+)
>
> diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
> index f56f08a4461e..90d525afc240 100644
> --- a/drivers/nvme/common/auth.c
> +++ b/drivers/nvme/common/auth.c
> @@ -652,5 +652,76 @@ u8 *nvme_auth_generate_digest(u8 hmac_id, u8 *psk, size_t psk_len,
>   }
>   EXPORT_SYMBOL_GPL(nvme_auth_generate_digest);
>   
> +u8 *nvme_auth_derive_tls_psk(int hmac_id, u8 *psk, size_t psk_len, u8 *psk_digest)
> +{

Same comment here.
Can you please add a description of the derivation process in a function 
comment?
It is not trivial for me to follow.

> +	struct crypto_shash *hmac_tfm;
> +	const char *hmac_name;
> +	const char *psk_prefix = "tls13 nvme-tls-psk";
> +	size_t info_len, prk_len;
> +	char *info;
> +	unsigned char *prk, *tls_key;
> +	int ret;
> +
> +	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);
> +	}
> +	if (hmac_id == NVME_AUTH_HASH_SHA512) {
> +		pr_warn("%s: unsupported hash algorithm %s\n",
> +			__func__, hmac_name);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	hmac_tfm = crypto_alloc_shash(hmac_name, 0, 0);
> +	if (IS_ERR(hmac_tfm))
> +		return (u8 *)hmac_tfm;
> +
> +	prk_len = crypto_shash_digestsize(hmac_tfm);
> +	prk = kzalloc(prk_len, GFP_KERNEL);

What does prk stand for?

> +	if (!prk) {
> +		ret = -ENOMEM;
> +		goto out_free_shash;
> +	}
> +
> +	ret = hkdf_extract(hmac_tfm, psk, psk_len, prk);
> +	if (ret)
> +		goto out_free_prk;
> +
> +	ret = crypto_shash_setkey(hmac_tfm, prk, prk_len);
> +	if (ret)
> +		goto out_free_prk;
> +
> +	info_len = strlen(psk_digest) + strlen(psk_prefix) + 1;
> +	info = kzalloc(info_len, GFP_KERNEL);
> +	if (!info)
> +		goto out_free_prk;
> +
> +	memcpy(info, psk_prefix, strlen(psk_prefix));
> +	memcpy(info + strlen(psk_prefix), psk_digest, strlen(psk_digest));
> +
> +	tls_key = kzalloc(psk_len, GFP_KERNEL);
> +	if (!tls_key) {
> +		ret = -ENOMEM;
> +		goto out_free_info;
> +	}
> +	ret = hkdf_expand(hmac_tfm, info, strlen(info), tls_key, psk_len);
> +	if (ret)
> +		goto out_free_key;
> +
> +out_free_key:
> +	kfree(tls_key);
> +out_free_info:
> +	kfree(info);
> +out_free_prk:
> +	kfree(prk);
> +out_free_shash:
> +	crypto_free_shash(hmac_tfm);
> +
> +	return ret ? ERR_PTR(ret) : tls_key;
> +}
> +EXPORT_SYMBOL_GPL(nvme_auth_derive_tls_psk);
> +
>   MODULE_DESCRIPTION("NVMe Authentication framework");
>   MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/nvme-auth.h b/include/linux/nvme-auth.h
> index 2cbb9249a8b3..335236fb2b73 100644
> --- a/include/linux/nvme-auth.h
> +++ b/include/linux/nvme-auth.h
> @@ -44,5 +44,6 @@ 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);
> +u8 *nvme_auth_derive_tls_psk(int hmac_id, u8 *psk, size_t psk_len, u8 *psk_digest);
>   
>   #endif /* _NVME_AUTH_H */




More information about the Linux-nvme mailing list