X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=crypto%2Fapi.c;h=959c4e5f264f42ed831720149b3627d9a9e6300c;hb=5acd57936c3224fd86e838201e528e0169373e9b;hp=0b583d24f7fa3765701184fae2f4252636e51eb5;hpb=176c3652c544b6f8d4bb1984c58c10080f45dbf0;p=linux-2.6 diff --git a/crypto/api.c b/crypto/api.c index 0b583d24f7..959c4e5f26 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -13,6 +13,8 @@ * any later version. * */ + +#include #include #include #include @@ -64,7 +66,8 @@ static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) { - tfm->crt_flags = 0; + tfm->crt_flags = flags & CRYPTO_TFM_REQ_MASK; + flags &= ~CRYPTO_TFM_REQ_MASK; switch (crypto_tfm_alg_type(tfm)) { case CRYPTO_ALG_TYPE_CIPHER: @@ -125,20 +128,46 @@ static void crypto_exit_ops(struct crypto_tfm *tfm) } } +static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags) +{ + unsigned int len; + + switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { + default: + BUG(); + + case CRYPTO_ALG_TYPE_CIPHER: + len = crypto_cipher_ctxsize(alg, flags); + break; + + case CRYPTO_ALG_TYPE_DIGEST: + len = crypto_digest_ctxsize(alg, flags); + break; + + case CRYPTO_ALG_TYPE_COMPRESS: + len = crypto_compress_ctxsize(alg, flags); + break; + } + + return len + alg->cra_alignmask; +} + struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) { struct crypto_tfm *tfm = NULL; struct crypto_alg *alg; + unsigned int tfm_size; alg = crypto_alg_mod_lookup(name); if (alg == NULL) goto out; - - tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); + + tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); + tfm = kmalloc(tfm_size, GFP_KERNEL); if (tfm == NULL) goto out_put; - memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); + memset(tfm, 0, tfm_size); tfm->__crt_alg = alg; @@ -163,8 +192,14 @@ out: void crypto_free_tfm(struct crypto_tfm *tfm) { - struct crypto_alg *alg = tfm->__crt_alg; - int size = sizeof(*tfm) + alg->cra_ctxsize; + struct crypto_alg *alg; + int size; + + if (unlikely(!tfm)) + return; + + alg = tfm->__crt_alg; + size = sizeof(*tfm) + alg->cra_ctxsize; crypto_exit_ops(tfm); crypto_alg_put(alg);