KEYS: DH: forbid using digest_null as the KDF hash
authorEric Biggers <ebiggers@google.com>
Thu, 8 Jun 2017 13:49:34 +0000 (14:49 +0100)
committerJames Morris <james.l.morris@oracle.com>
Fri, 9 Jun 2017 03:29:49 +0000 (13:29 +1000)
Requesting "digest_null" in the keyctl_kdf_params caused an infinite
loop in kdf_ctr() because the "null" hash has a digest size of 0.  Fix
it by rejecting hash algorithms with a digest size of 0.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: James Morris <james.l.morris@oracle.com>
security/keys/dh.c

index e603bd912e4c2300287e98248449a55b2e0b4ea4..8abc70ebe22dfbff556a8e675c4832f9cf3f60ff 100644 (file)
@@ -89,6 +89,7 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname)
        struct crypto_shash *tfm;
        struct kdf_sdesc *sdesc;
        int size;
+       int err;
 
        /* allocate synchronous hash */
        tfm = crypto_alloc_shash(hashname, 0, 0);
@@ -97,16 +98,25 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname)
                return PTR_ERR(tfm);
        }
 
+       err = -EINVAL;
+       if (crypto_shash_digestsize(tfm) == 0)
+               goto out_free_tfm;
+
+       err = -ENOMEM;
        size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm);
        sdesc = kmalloc(size, GFP_KERNEL);
        if (!sdesc)
-               return -ENOMEM;
+               goto out_free_tfm;
        sdesc->shash.tfm = tfm;
        sdesc->shash.flags = 0x0;
 
        *sdesc_ret = sdesc;
 
        return 0;
+
+out_free_tfm:
+       crypto_free_shash(tfm);
+       return err;
 }
 
 static void kdf_dealloc(struct kdf_sdesc *sdesc)