[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