aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorJames Morris <jmorris@intercode.com.au>2002-11-14 21:43:43 -0800
committerDavid S. Miller <davem@nuts.ninka.net>2002-11-14 21:43:43 -0800
commitfdd30fe27d07461d201a3ce41a2c49b1041451d9 (patch)
tree39967f8209a451bec30d0080a76b3032d4107582 /crypto
parent28b9daad2aee31d2a8ee5cbca796f136933befe6 (diff)
downloadhistory-fdd30fe27d07461d201a3ce41a2c49b1041451d9.tar.gz
[CRYPTO] kstack cleanup (v0.28)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/api.c37
-rw-r--r--crypto/cipher.c30
-rw-r--r--crypto/compress.c6
-rw-r--r--crypto/digest.c17
-rw-r--r--crypto/hmac.c34
-rw-r--r--crypto/internal.h23
6 files changed, 115 insertions, 32 deletions
diff --git a/crypto/api.c b/crypto/api.c
index 833481f4e2c810..2db42767229d1e 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -74,19 +74,39 @@ static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
return -EINVAL;
}
-static void crypto_init_ops(struct crypto_tfm *tfm)
+static int crypto_init_ops(struct crypto_tfm *tfm)
{
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
- crypto_init_cipher_ops(tfm);
+ return crypto_init_cipher_ops(tfm);
+
+ case CRYPTO_ALG_TYPE_DIGEST:
+ return crypto_init_digest_ops(tfm);
+
+ case CRYPTO_ALG_TYPE_COMP:
+ return crypto_init_compress_ops(tfm);
+
+ default:
+ break;
+ }
+
+ BUG();
+ return -EINVAL;
+}
+
+static void crypto_exit_ops(struct crypto_tfm *tfm)
+{
+ switch (crypto_tfm_alg_type(tfm)) {
+ case CRYPTO_ALG_TYPE_CIPHER:
+ crypto_exit_cipher_ops(tfm);
break;
case CRYPTO_ALG_TYPE_DIGEST:
- crypto_init_digest_ops(tfm);
+ crypto_exit_digest_ops(tfm);
break;
case CRYPTO_ALG_TYPE_COMP:
- crypto_init_compress_ops(tfm);
+ crypto_exit_compress_ops(tfm);
break;
default:
@@ -110,6 +130,8 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
memset(tfm, 0, sizeof(*tfm));
+ memset(tfm, 0, sizeof(*tfm));
+
if (alg->cra_ctxsize) {
tfm->crt_ctx = kmalloc(alg->cra_ctxsize, GFP_KERNEL);
if (tfm->crt_ctx == NULL)
@@ -128,8 +150,11 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
if (crypto_init_flags(tfm, flags))
goto out_free_work_block;
- crypto_init_ops(tfm);
-
+ if (crypto_init_ops(tfm)) {
+ crypto_exit_ops(tfm);
+ goto out_free_ctx;
+ }
+
goto out;
out_free_work_block:
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 87882e24fe411d..04d27e10ed2604 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -234,27 +234,19 @@ static int nocrypt(struct crypto_tfm *tfm,
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
{
- struct crypto_alg *alg = tfm->__crt_alg;
u32 mode = flags & CRYPTO_TFM_MODE_MASK;
tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
-
- if (alg->cra_cipher.cia_ivsize && mode != CRYPTO_TFM_MODE_ECB) {
- tfm->crt_cipher.cit_iv =
- kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL);
- if (tfm->crt_cipher.cit_iv == NULL)
- return -ENOMEM;
- } else
- tfm->crt_cipher.cit_iv = NULL;
-
if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
return 0;
}
-void crypto_init_cipher_ops(struct crypto_tfm *tfm)
+int crypto_init_cipher_ops(struct crypto_tfm *tfm)
{
+ int ret = 0;
+ struct crypto_alg *alg = tfm->__crt_alg;
struct cipher_tfm *ops = &tfm->crt_cipher;
ops->cit_setkey = setkey;
@@ -283,4 +275,20 @@ void crypto_init_cipher_ops(struct crypto_tfm *tfm)
default:
BUG();
}
+
+ if (alg->cra_cipher.cia_ivsize &&
+ ops->cit_mode != CRYPTO_TFM_MODE_ECB) {
+
+ ops->cit_iv = kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL);
+ if (ops->cit_iv == NULL)
+ ret = -ENOMEM;
+ }
+
+ return ret;
+}
+
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
+{
+ if (tfm->crt_cipher.cit_iv)
+ kfree(tfm->crt_cipher.cit_iv);
}
diff --git a/crypto/compress.c b/crypto/compress.c
index f599a4e37954c2..773fc576405017 100644
--- a/crypto/compress.c
+++ b/crypto/compress.c
@@ -33,10 +33,14 @@ int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
return crypto_cipher_flags(flags) ? -EINVAL : 0;
}
-void crypto_init_compress_ops(struct crypto_tfm *tfm)
+int crypto_init_compress_ops(struct crypto_tfm *tfm)
{
struct compress_tfm *ops = &tfm->crt_compress;
ops->cot_compress = crypto_compress;
ops->cot_decompress = crypto_decompress;
+ return 0;
}
+
+void crypto_exit_compress_ops(struct crypto_tfm *tfm)
+{ }
diff --git a/crypto/digest.c b/crypto/digest.c
index 83aae1d9eaf7fc..4db5f88ef38dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -63,12 +63,19 @@ int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
return crypto_cipher_flags(flags) ? -EINVAL : 0;
}
-void crypto_init_digest_ops(struct crypto_tfm *tfm)
+int crypto_init_digest_ops(struct crypto_tfm *tfm)
{
struct digest_tfm *ops = &tfm->crt_digest;
- ops->dit_init = init;
- ops->dit_update = update;
- ops->dit_final = final;
- ops->dit_digest = digest;
+ ops->dit_init = init;
+ ops->dit_update = update;
+ ops->dit_final = final;
+ ops->dit_digest = digest;
+
+ return crypto_alloc_hmac_block(tfm);
+}
+
+void crypto_exit_digest_ops(struct crypto_tfm *tfm)
+{
+ crypto_free_hmac_block(tfm);
}
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 5a70ad66bc9d93..31cd7799c5d802 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -17,6 +17,7 @@
#include <linux/crypto.h>
#include <linux/mm.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <asm/scatterlist.h>
#include "internal.h"
@@ -31,18 +32,39 @@ static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
}
+int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
+{
+ int ret = 0;
+
+ BUG_ON(!crypto_tfm_alg_blocksize(tfm));
+
+ tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
+ GFP_KERNEL);
+ if (tfm->crt_digest.dit_hmac_block == NULL)
+ ret = -ENOMEM;
+
+ return ret;
+
+}
+
+void crypto_free_hmac_block(struct crypto_tfm *tfm)
+{
+ if (tfm->crt_digest.dit_hmac_block)
+ kfree(tfm->crt_digest.dit_hmac_block);
+}
+
void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
{
unsigned int i;
struct scatterlist tmp;
- char *ipad = tfm->crt_work_block;
-
+ char *ipad = tfm->crt_digest.dit_hmac_block;
+
if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen);
*keylen = crypto_tfm_alg_digestsize(tfm);
}
- memset(ipad, 0, crypto_tfm_alg_blocksize(tfm) + 1);
+ memset(ipad, 0, crypto_tfm_alg_blocksize(tfm));
memcpy(ipad, key, *keylen);
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
@@ -67,8 +89,8 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
{
unsigned int i;
struct scatterlist tmp;
- char *opad = tfm->crt_work_block;
-
+ char *opad = tfm->crt_digest.dit_hmac_block;
+
if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen);
*keylen = crypto_tfm_alg_digestsize(tfm);
@@ -76,7 +98,7 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
crypto_digest_final(tfm, out);
- memset(opad, 0, crypto_tfm_alg_blocksize(tfm) + 1);
+ memset(opad, 0, crypto_tfm_alg_blocksize(tfm));
memcpy(opad, key, *keylen);
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
diff --git a/crypto/internal.h b/crypto/internal.h
index a75326211f1e87..408bc1bb5b0c6a 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -52,13 +52,30 @@ static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
}
#endif
+#ifdef CONFIG_CRYPTO_HMAC
+int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
+void crypto_free_hmac_block(struct crypto_tfm *tfm);
+#else
+static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
+{
+ return 0;
+}
+
+static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
+{ }
+#endif
+
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
-void crypto_init_digest_ops(struct crypto_tfm *tfm);
-void crypto_init_cipher_ops(struct crypto_tfm *tfm);
-void crypto_init_compress_ops(struct crypto_tfm *tfm);
+int crypto_init_digest_ops(struct crypto_tfm *tfm);
+int crypto_init_cipher_ops(struct crypto_tfm *tfm);
+int crypto_init_compress_ops(struct crypto_tfm *tfm);
+
+void crypto_exit_digest_ops(struct crypto_tfm *tfm);
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
+void crypto_exit_compress_ops(struct crypto_tfm *tfm);
#endif /* _CRYPTO_INTERNAL_H */