Commit fdd30fe2 authored by James Morris's avatar James Morris Committed by David S. Miller

[CRYPTO] kstack cleanup (v0.28)

parent 28b9daad
...@@ -74,19 +74,39 @@ static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) ...@@ -74,19 +74,39 @@ static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
return -EINVAL; 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)) { switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER: 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; break;
case CRYPTO_ALG_TYPE_DIGEST: case CRYPTO_ALG_TYPE_DIGEST:
crypto_init_digest_ops(tfm); crypto_exit_digest_ops(tfm);
break; break;
case CRYPTO_ALG_TYPE_COMP: case CRYPTO_ALG_TYPE_COMP:
crypto_init_compress_ops(tfm); crypto_exit_compress_ops(tfm);
break; break;
default: default:
...@@ -110,6 +130,8 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) ...@@ -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));
memset(tfm, 0, sizeof(*tfm));
if (alg->cra_ctxsize) { if (alg->cra_ctxsize) {
tfm->crt_ctx = kmalloc(alg->cra_ctxsize, GFP_KERNEL); tfm->crt_ctx = kmalloc(alg->cra_ctxsize, GFP_KERNEL);
if (tfm->crt_ctx == NULL) if (tfm->crt_ctx == NULL)
...@@ -128,7 +150,10 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) ...@@ -128,7 +150,10 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
if (crypto_init_flags(tfm, flags)) if (crypto_init_flags(tfm, flags))
goto out_free_work_block; goto out_free_work_block;
crypto_init_ops(tfm); if (crypto_init_ops(tfm)) {
crypto_exit_ops(tfm);
goto out_free_ctx;
}
goto out; goto out;
......
...@@ -234,27 +234,19 @@ static int nocrypt(struct crypto_tfm *tfm, ...@@ -234,27 +234,19 @@ static int nocrypt(struct crypto_tfm *tfm,
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags) 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; u32 mode = flags & CRYPTO_TFM_MODE_MASK;
tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB; 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) if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY; tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
return 0; 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; struct cipher_tfm *ops = &tfm->crt_cipher;
ops->cit_setkey = setkey; ops->cit_setkey = setkey;
...@@ -283,4 +275,20 @@ void crypto_init_cipher_ops(struct crypto_tfm *tfm) ...@@ -283,4 +275,20 @@ void crypto_init_cipher_ops(struct crypto_tfm *tfm)
default: default:
BUG(); 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);
} }
...@@ -33,10 +33,14 @@ int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags) ...@@ -33,10 +33,14 @@ int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
return crypto_cipher_flags(flags) ? -EINVAL : 0; 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; struct compress_tfm *ops = &tfm->crt_compress;
ops->cot_compress = crypto_compress; ops->cot_compress = crypto_compress;
ops->cot_decompress = crypto_decompress; ops->cot_decompress = crypto_decompress;
return 0;
} }
void crypto_exit_compress_ops(struct crypto_tfm *tfm)
{ }
...@@ -63,7 +63,7 @@ int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) ...@@ -63,7 +63,7 @@ int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
return crypto_cipher_flags(flags) ? -EINVAL : 0; 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; struct digest_tfm *ops = &tfm->crt_digest;
...@@ -71,4 +71,11 @@ void crypto_init_digest_ops(struct crypto_tfm *tfm) ...@@ -71,4 +71,11 @@ void crypto_init_digest_ops(struct crypto_tfm *tfm)
ops->dit_update = update; ops->dit_update = update;
ops->dit_final = final; ops->dit_final = final;
ops->dit_digest = digest; ops->dit_digest = digest;
return crypto_alloc_hmac_block(tfm);
}
void crypto_exit_digest_ops(struct crypto_tfm *tfm)
{
crypto_free_hmac_block(tfm);
} }
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/crypto.h> #include <linux/crypto.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/slab.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include "internal.h" #include "internal.h"
...@@ -31,18 +32,39 @@ static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen) ...@@ -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) void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
{ {
unsigned int i; unsigned int i;
struct scatterlist tmp; struct scatterlist tmp;
char *ipad = tfm->crt_work_block; char *ipad = tfm->crt_digest.dit_hmac_block;
if (*keylen > crypto_tfm_alg_blocksize(tfm)) { if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen); hash_key(tfm, key, *keylen);
*keylen = crypto_tfm_alg_digestsize(tfm); *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); memcpy(ipad, key, *keylen);
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++) for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
...@@ -67,7 +89,7 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, ...@@ -67,7 +89,7 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
{ {
unsigned int i; unsigned int i;
struct scatterlist tmp; struct scatterlist tmp;
char *opad = tfm->crt_work_block; char *opad = tfm->crt_digest.dit_hmac_block;
if (*keylen > crypto_tfm_alg_blocksize(tfm)) { if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen); hash_key(tfm, key, *keylen);
...@@ -76,7 +98,7 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, ...@@ -76,7 +98,7 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
crypto_digest_final(tfm, out); 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); memcpy(opad, key, *keylen);
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++) for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
......
...@@ -52,13 +52,30 @@ static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) ...@@ -52,13 +52,30 @@ static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
} }
#endif #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_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_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); int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
void crypto_init_digest_ops(struct crypto_tfm *tfm); int crypto_init_digest_ops(struct crypto_tfm *tfm);
void crypto_init_cipher_ops(struct crypto_tfm *tfm); int crypto_init_cipher_ops(struct crypto_tfm *tfm);
void crypto_init_compress_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 */ #endif /* _CRYPTO_INTERNAL_H */
...@@ -144,6 +144,9 @@ struct digest_tfm { ...@@ -144,6 +144,9 @@ struct digest_tfm {
void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
unsigned int nsg, u8 *out); unsigned int nsg, u8 *out);
#ifdef CONFIG_CRYPTO_HMAC
void *dit_hmac_block;
#endif
}; };
struct compress_tfm { struct compress_tfm {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment