diff options
Diffstat (limited to 'security/keys/dh.c')
-rw-r--r-- | security/keys/dh.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/security/keys/dh.c b/security/keys/dh.c index e603bd912e4c..9b6e6b3ecccb 100644 --- a/security/keys/dh.c +++ b/security/keys/dh.c @@ -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) @@ -120,14 +130,6 @@ static void kdf_dealloc(struct kdf_sdesc *sdesc) kzfree(sdesc); } -/* convert 32 bit integer into its string representation */ -static inline void crypto_kw_cpu_to_be32(u32 val, u8 *buf) -{ - __be32 *a = (__be32 *)buf; - - *a = cpu_to_be32(val); -} - /* * Implementation of the KDF in counter mode according to SP800-108 section 5.1 * as well as SP800-56A section 5.8.1 (Single-step KDF). @@ -144,16 +146,14 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, unsigned int h = crypto_shash_digestsize(desc->tfm); int err = 0; u8 *dst_orig = dst; - u32 i = 1; - u8 iteration[sizeof(u32)]; + __be32 counter = cpu_to_be32(1); while (dlen) { err = crypto_shash_init(desc); if (err) goto err; - crypto_kw_cpu_to_be32(i, iteration); - err = crypto_shash_update(desc, iteration, sizeof(u32)); + err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32)); if (err) goto err; @@ -179,7 +179,7 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, dlen -= h; dst += h; - i++; + counter = cpu_to_be32(be32_to_cpu(counter) + 1); } } @@ -296,7 +296,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, } /* allocate space for DH shared secret and SP800-56A otherinfo */ - kbuf = kmalloc(kdfcopy ? (resultlen + kdfcopy->otherinfolen) : resultlen, + kbuf = kzalloc(kdfcopy ? (resultlen + kdfcopy->otherinfolen) : resultlen, GFP_KERNEL); if (!kbuf) { ret = -ENOMEM; @@ -307,7 +307,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, * Concatenate SP800-56A otherinfo past DH shared secret -- the * input to the KDF is (DH shared secret || otherinfo) */ - if (kdfcopy && kdfcopy->otherinfo && + if (kdfcopy && copy_from_user(kbuf + resultlen, kdfcopy->otherinfo, kdfcopy->otherinfolen) != 0) { ret = -EFAULT; @@ -318,7 +318,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, if (ret) goto error5; - ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL); + ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL, false); if (ret != 0) goto error5; |