[PATCH 02/13] nvme: add nvme_auth_generate_psk()
hare at kernel.org
hare at kernel.org
Sat Jan 27 01:30:47 PST 2024
From: Hannes Reinecke <hare at suse.de>
Add a function to generate a NVMe PSK from the shared credentials
negotiated by DH-HMAC-CHAP.
Signed-off-by: Hannes Reinecke <hare at suse.de>
---
drivers/nvme/common/auth.c | 76 ++++++++++++++++++++++++++++++++++++++
include/linux/nvme-auth.h | 2 +
2 files changed, 78 insertions(+)
diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
index a23ab5c968b9..9ee459a9400e 100644
--- a/drivers/nvme/common/auth.c
+++ b/drivers/nvme/common/auth.c
@@ -11,6 +11,7 @@
#include <asm/unaligned.h>
#include <crypto/hash.h>
#include <crypto/dh.h>
+#include <crypto/hkdf.h>
#include <linux/nvme.h>
#include <linux/nvme-auth.h>
@@ -471,4 +472,79 @@ int nvme_auth_generate_key(u8 *secret, struct nvme_dhchap_key **ret_key)
}
EXPORT_SYMBOL_GPL(nvme_auth_generate_key);
+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)
+{
+ struct crypto_shash *tfm;
+ struct shash_desc *shash;
+ u8 *psk;
+ const char *hmac_name;
+ int ret, psk_len;
+
+ if (!c1 || !c2) {
+ pr_warn("%s: invalid parameter\n", __func__);
+ 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);
+ }
+
+ tfm = crypto_alloc_shash(hmac_name, 0, 0);
+ if (IS_ERR(tfm))
+ return (u8 *)tfm;
+
+ psk_len = crypto_shash_digestsize(tfm);
+ psk = kzalloc(psk_len, GFP_KERNEL);
+ if (!psk) {
+ 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_psk;
+ }
+
+ shash->tfm = tfm;
+ ret = crypto_shash_setkey(tfm, skey, skey_len);
+ if (ret)
+ goto out_free_shash;
+
+ ret = crypto_shash_init(shash);
+ if (ret)
+ goto out_free_shash;
+
+ ret = crypto_shash_update(shash, c1, hash_len);
+ if (ret)
+ goto out_free_shash;
+
+ ret = crypto_shash_update(shash, c2, hash_len);
+ if (ret)
+ goto out_free_shash;
+
+ ret = crypto_shash_final(shash, psk);
+ if (!ret)
+ *ret_len = psk_len;
+
+out_free_shash:
+ kfree_sensitive(shash);
+out_free_psk:
+ if (ret) {
+ kfree_sensitive(psk);
+ psk = NULL;
+ }
+out_free_tfm:
+ crypto_free_shash(tfm);
+
+ return ret ? ERR_PTR(ret) : psk;
+}
+EXPORT_SYMBOL_GPL(nvme_auth_generate_psk);
+
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/nvme-auth.h b/include/linux/nvme-auth.h
index c1d0bc5d9624..31dc1db2d4d6 100644
--- a/include/linux/nvme-auth.h
+++ b/include/linux/nvme-auth.h
@@ -40,5 +40,7 @@ int nvme_auth_gen_pubkey(struct crypto_kpp *dh_tfm,
int nvme_auth_gen_shared_secret(struct crypto_kpp *dh_tfm,
u8 *ctrl_key, size_t ctrl_key_len,
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);
#endif /* _NVME_AUTH_H */
--
2.35.3
More information about the Linux-nvme
mailing list