[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