diff options
author | James Morris <jmorris@intercode.com.au> | 2002-11-14 21:43:43 -0800 |
---|---|---|
committer | David S. Miller <davem@nuts.ninka.net> | 2002-11-14 21:43:43 -0800 |
commit | fdd30fe27d07461d201a3ce41a2c49b1041451d9 (patch) | |
tree | 39967f8209a451bec30d0080a76b3032d4107582 /crypto | |
parent | 28b9daad2aee31d2a8ee5cbca796f136933befe6 (diff) | |
download | history-fdd30fe27d07461d201a3ce41a2c49b1041451d9.tar.gz |
[CRYPTO] kstack cleanup (v0.28)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/api.c | 37 | ||||
-rw-r--r-- | crypto/cipher.c | 30 | ||||
-rw-r--r-- | crypto/compress.c | 6 | ||||
-rw-r--r-- | crypto/digest.c | 17 | ||||
-rw-r--r-- | crypto/hmac.c | 34 | ||||
-rw-r--r-- | crypto/internal.h | 23 |
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 */ |