nvme-auth: alloc nvme_dhchap_key as single buffer
authorMark O'Donovan <shiftee@posteo.net>
Tue, 17 Oct 2023 17:09:17 +0000 (17:09 +0000)
committerKeith Busch <kbusch@kernel.org>
Tue, 17 Oct 2023 20:57:54 +0000 (13:57 -0700)
Co-developed-by: Akash Appaiah <Akash.Appaiah@dell.com>
Signed-off-by: Akash Appaiah <Akash.Appaiah@dell.com>
Signed-off-by: Mark O'Donovan <shiftee@posteo.net>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/common/auth.c
include/linux/nvme-auth.h

index d90e4f0c08b7b90201e745663d658afd61b21d57..16a071448d5401cbdf4efeb6c1b6f8b69ff579d2 100644 (file)
@@ -150,6 +150,14 @@ size_t nvme_auth_hmac_hash_len(u8 hmac_id)
 }
 EXPORT_SYMBOL_GPL(nvme_auth_hmac_hash_len);
 
+u32 nvme_auth_key_struct_size(u32 key_len)
+{
+       struct nvme_dhchap_key key;
+
+       return struct_size(&key, key, key_len);
+}
+EXPORT_SYMBOL_GPL(nvme_auth_key_struct_size);
+
 struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
                                              u8 key_hash)
 {
@@ -163,14 +171,9 @@ struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
        p = strrchr(secret, ':');
        if (p)
                allocated_len = p - secret;
-       key = kzalloc(sizeof(*key), GFP_KERNEL);
+       key = nvme_auth_alloc_key(allocated_len, 0);
        if (!key)
                return ERR_PTR(-ENOMEM);
-       key->key = kzalloc(allocated_len, GFP_KERNEL);
-       if (!key->key) {
-               ret = -ENOMEM;
-               goto out_free_key;
-       }
 
        key_len = base64_decode(secret, allocated_len, key->key);
        if (key_len < 0) {
@@ -213,19 +216,29 @@ struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
        key->hash = key_hash;
        return key;
 out_free_secret:
-       kfree_sensitive(key->key);
-out_free_key:
-       kfree(key);
+       nvme_auth_free_key(key);
        return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(nvme_auth_extract_key);
 
+struct nvme_dhchap_key *nvme_auth_alloc_key(u32 len, u8 hash)
+{
+       u32 num_bytes = nvme_auth_key_struct_size(len);
+       struct nvme_dhchap_key *key = kzalloc(num_bytes, GFP_KERNEL);
+
+       if (key) {
+               key->len = len;
+               key->hash = hash;
+       }
+       return key;
+}
+EXPORT_SYMBOL_GPL(nvme_auth_alloc_key);
+
 void nvme_auth_free_key(struct nvme_dhchap_key *key)
 {
        if (!key)
                return;
-       kfree_sensitive(key->key);
-       kfree(key);
+       kfree_sensitive(key);
 }
 EXPORT_SYMBOL_GPL(nvme_auth_free_key);
 
@@ -237,7 +250,7 @@ u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn)
        u8 *transformed_key;
        int ret;
 
-       if (!key || !key->key) {
+       if (!key) {
                pr_warn("No key specified\n");
                return ERR_PTR(-ENOKEY);
        }
index dcb8030062ddaf0100f2daf6af4cae910e6b9025..a5ae9abe1ef6b5d6ad911ced3a8e96d07d9da542 100644 (file)
@@ -9,9 +9,9 @@
 #include <crypto/kpp.h>
 
 struct nvme_dhchap_key {
-       u8 *key;
        size_t len;
        u8 hash;
+       u8 key[];
 };
 
 u32 nvme_auth_get_seqnum(void);
@@ -24,9 +24,11 @@ const char *nvme_auth_digest_name(u8 hmac_id);
 size_t nvme_auth_hmac_hash_len(u8 hmac_id);
 u8 nvme_auth_hmac_id(const char *hmac_name);
 
+u32 nvme_auth_key_struct_size(u32 key_len);
 struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
                                              u8 key_hash);
 void nvme_auth_free_key(struct nvme_dhchap_key *key);
+struct nvme_dhchap_key *nvme_auth_alloc_key(u32 len, u8 hash);
 u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn);
 int nvme_auth_generate_key(u8 *secret, struct nvme_dhchap_key **ret_key);
 int nvme_auth_augmented_challenge(u8 hmac_id, u8 *skey, size_t skey_len,