[v3,1/3] nvme-auth: alloc nvme_dhchap_key as single buffer

Message ID 20231016225857.3085234-2-shiftee@posteo.net
State New
Headers
Series Remove secret-size restrictions for hashes |

Commit Message

Mark O'Donovan Oct. 16, 2023, 10:58 p.m. UTC
  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>
---
 drivers/nvme/common/auth.c | 26 +++++++++++++++-----------
 include/linux/nvme-auth.h  |  3 ++-
 2 files changed, 17 insertions(+), 12 deletions(-)
  

Comments

Hannes Reinecke Oct. 17, 2023, 6:05 a.m. UTC | #1
On 10/17/23 00:58, Mark O'Donovan wrote:
> 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>
> ---
>   drivers/nvme/common/auth.c | 26 +++++++++++++++-----------
>   include/linux/nvme-auth.h  |  3 ++-
>   2 files changed, 17 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
> index d90e4f0c08b7..225fc474e34a 100644
> --- a/drivers/nvme/common/auth.c
> +++ b/drivers/nvme/common/auth.c
> @@ -163,14 +163,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 +208,28 @@ 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)
> +{
> +	struct nvme_dhchap_key *key = kzalloc(len + sizeof(*key), 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);
>   
> diff --git a/include/linux/nvme-auth.h b/include/linux/nvme-auth.h
> index dcb8030062dd..df96940be930 100644
> --- a/include/linux/nvme-auth.h
> +++ b/include/linux/nvme-auth.h
> @@ -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);
> @@ -27,6 +27,7 @@ u8 nvme_auth_hmac_id(const char *hmac_name);
>   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,
Good idea.

Reviewed-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
  
Christoph Hellwig Oct. 17, 2023, 6:09 a.m. UTC | #2
> +struct nvme_dhchap_key *nvme_auth_alloc_key(u32 len, u8 hash)
> +{
> +	struct nvme_dhchap_key *key = kzalloc(len + sizeof(*key), GFP_KERNEL);

This should use the struct_size() helper:

	key = kzalloc(struct_size(key, key, len), GFP_KERNEL);

Otherwise the change looks good.
  

Patch

diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
index d90e4f0c08b7..225fc474e34a 100644
--- a/drivers/nvme/common/auth.c
+++ b/drivers/nvme/common/auth.c
@@ -163,14 +163,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 +208,28 @@  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)
+{
+	struct nvme_dhchap_key *key = kzalloc(len + sizeof(*key), 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);
 
diff --git a/include/linux/nvme-auth.h b/include/linux/nvme-auth.h
index dcb8030062dd..df96940be930 100644
--- a/include/linux/nvme-auth.h
+++ b/include/linux/nvme-auth.h
@@ -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);
@@ -27,6 +27,7 @@  u8 nvme_auth_hmac_id(const char *hmac_name);
 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,