crypto: cryptd - Switch to new style ahash
[pandora-kernel.git] / crypto / cryptd.c
index ef5720c..5dabb7d 100644 (file)
@@ -255,17 +255,18 @@ static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm)
        crypto_free_blkcipher(ctx->child);
 }
 
-static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg,
-                                                    unsigned int tail)
+static void *cryptd_alloc_instance(struct crypto_alg *alg, unsigned int head,
+                                  unsigned int tail)
 {
+       char *p;
        struct crypto_instance *inst;
        int err;
 
-       inst = kzalloc(sizeof(*inst) + tail, GFP_KERNEL);
-       if (!inst) {
-               inst = ERR_PTR(-ENOMEM);
-               goto out;
-       }
+       p = kzalloc(head + sizeof(*inst) + tail, GFP_KERNEL);
+       if (!p)
+               return ERR_PTR(-ENOMEM);
+
+       inst = (void *)(p + head);
 
        err = -ENAMETOOLONG;
        if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
@@ -279,16 +280,17 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg,
        inst->alg.cra_alignmask = alg->cra_alignmask;
 
 out:
-       return inst;
+       return p;
 
 out_free_inst:
-       kfree(inst);
-       inst = ERR_PTR(err);
+       kfree(p);
+       p = ERR_PTR(err);
        goto out;
 }
 
-static struct crypto_instance *cryptd_alloc_blkcipher(
-       struct rtattr **tb, struct cryptd_queue *queue)
+static int cryptd_create_blkcipher(struct crypto_template *tmpl,
+                                  struct rtattr **tb,
+                                  struct cryptd_queue *queue)
 {
        struct cryptd_instance_ctx *ctx;
        struct crypto_instance *inst;
@@ -298,9 +300,9 @@ static struct crypto_instance *cryptd_alloc_blkcipher(
        alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_BLKCIPHER,
                                  CRYPTO_ALG_TYPE_MASK);
        if (IS_ERR(alg))
-               return ERR_CAST(alg);
+               return PTR_ERR(alg);
 
-       inst = cryptd_alloc_instance(alg, sizeof(*ctx));
+       inst = cryptd_alloc_instance(alg, 0, sizeof(*ctx));
        if (IS_ERR(inst))
                goto out_put_alg;
 
@@ -330,14 +332,16 @@ static struct crypto_instance *cryptd_alloc_blkcipher(
        inst->alg.cra_ablkcipher.encrypt = cryptd_blkcipher_encrypt_enqueue;
        inst->alg.cra_ablkcipher.decrypt = cryptd_blkcipher_decrypt_enqueue;
 
+       err = crypto_register_instance(tmpl, inst);
+       if (err) {
+               crypto_drop_spawn(&ctx->spawn);
+out_free_inst:
+               kfree(inst);
+       }
+
 out_put_alg:
        crypto_mod_put(alg);
-       return inst;
-
-out_free_inst:
-       kfree(inst);
-       inst = ERR_PTR(err);
-       goto out_put_alg;
+       return err;
 }
 
 static int cryptd_hash_init_tfm(struct crypto_tfm *tfm)
@@ -353,8 +357,9 @@ static int cryptd_hash_init_tfm(struct crypto_tfm *tfm)
                return PTR_ERR(hash);
 
        ctx->child = hash;
-       tfm->crt_ahash.reqsize = sizeof(struct cryptd_hash_request_ctx) +
-                                crypto_shash_descsize(hash);
+       crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+                                sizeof(struct cryptd_hash_request_ctx) +
+                                crypto_shash_descsize(hash));
        return 0;
 }
 
@@ -501,79 +506,90 @@ static int cryptd_hash_digest_enqueue(struct ahash_request *req)
        return cryptd_hash_enqueue(req, cryptd_hash_digest);
 }
 
-static struct crypto_instance *cryptd_alloc_hash(
-       struct rtattr **tb, struct cryptd_queue *queue)
+static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
+                             struct cryptd_queue *queue)
 {
        struct hashd_instance_ctx *ctx;
-       struct crypto_instance *inst;
+       struct ahash_instance *inst;
        struct shash_alg *salg;
        struct crypto_alg *alg;
        int err;
 
        salg = shash_attr_alg(tb[1], 0, 0);
        if (IS_ERR(salg))
-               return ERR_CAST(salg);
+               return PTR_ERR(salg);
 
        alg = &salg->base;
-       inst = cryptd_alloc_instance(alg, sizeof(*ctx));
+       inst = cryptd_alloc_instance(alg, ahash_instance_headroom(),
+                                    sizeof(*ctx));
        if (IS_ERR(inst))
                goto out_put_alg;
 
-       ctx = crypto_instance_ctx(inst);
+       ctx = ahash_instance_ctx(inst);
        ctx->queue = queue;
 
-       err = crypto_init_shash_spawn(&ctx->spawn, salg, inst);
+       err = crypto_init_shash_spawn(&ctx->spawn, salg,
+                                     ahash_crypto_instance(inst));
        if (err)
                goto out_free_inst;
 
-       inst->alg.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC;
-       inst->alg.cra_type = &crypto_ahash_type;
+       inst->alg.halg.base.cra_flags = CRYPTO_ALG_ASYNC;
+
+       inst->alg.halg.digestsize = salg->digestsize;
+       inst->alg.halg.base.cra_ctxsize = sizeof(struct cryptd_hash_ctx);
 
-       inst->alg.cra_ahash.digestsize = salg->digestsize;
-       inst->alg.cra_ctxsize = sizeof(struct cryptd_hash_ctx);
+       inst->alg.halg.base.cra_init = cryptd_hash_init_tfm;
+       inst->alg.halg.base.cra_exit = cryptd_hash_exit_tfm;
 
-       inst->alg.cra_init = cryptd_hash_init_tfm;
-       inst->alg.cra_exit = cryptd_hash_exit_tfm;
+       inst->alg.init   = cryptd_hash_init_enqueue;
+       inst->alg.update = cryptd_hash_update_enqueue;
+       inst->alg.final  = cryptd_hash_final_enqueue;
+       inst->alg.setkey = cryptd_hash_setkey;
+       inst->alg.digest = cryptd_hash_digest_enqueue;
 
-       inst->alg.cra_ahash.init   = cryptd_hash_init_enqueue;
-       inst->alg.cra_ahash.update = cryptd_hash_update_enqueue;
-       inst->alg.cra_ahash.final  = cryptd_hash_final_enqueue;
-       inst->alg.cra_ahash.setkey = cryptd_hash_setkey;
-       inst->alg.cra_ahash.digest = cryptd_hash_digest_enqueue;
+       err = ahash_register_instance(tmpl, inst);
+       if (err) {
+               crypto_drop_shash(&ctx->spawn);
+out_free_inst:
+               kfree(inst);
+       }
 
 out_put_alg:
        crypto_mod_put(alg);
-       return inst;
-
-out_free_inst:
-       kfree(inst);
-       inst = ERR_PTR(err);
-       goto out_put_alg;
+       return err;
 }
 
 static struct cryptd_queue queue;
 
-static struct crypto_instance *cryptd_alloc(struct rtattr **tb)
+static int cryptd_create(struct crypto_template *tmpl, struct rtattr **tb)
 {
        struct crypto_attr_type *algt;
 
        algt = crypto_get_attr_type(tb);
        if (IS_ERR(algt))
-               return ERR_CAST(algt);
+               return PTR_ERR(algt);
 
        switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) {
        case CRYPTO_ALG_TYPE_BLKCIPHER:
-               return cryptd_alloc_blkcipher(tb, &queue);
+               return cryptd_create_blkcipher(tmpl, tb, &queue);
        case CRYPTO_ALG_TYPE_DIGEST:
-               return cryptd_alloc_hash(tb, &queue);
+               return cryptd_create_hash(tmpl, tb, &queue);
        }
 
-       return ERR_PTR(-EINVAL);
+       return -EINVAL;
 }
 
 static void cryptd_free(struct crypto_instance *inst)
 {
        struct cryptd_instance_ctx *ctx = crypto_instance_ctx(inst);
+       struct hashd_instance_ctx *hctx = crypto_instance_ctx(inst);
+
+       switch (inst->alg.cra_flags & CRYPTO_ALG_TYPE_MASK) {
+       case CRYPTO_ALG_TYPE_AHASH:
+               crypto_drop_shash(&hctx->spawn);
+               kfree(ahash_instance(inst));
+               return;
+       }
 
        crypto_drop_spawn(&ctx->spawn);
        kfree(inst);
@@ -581,7 +597,7 @@ static void cryptd_free(struct crypto_instance *inst)
 
 static struct crypto_template cryptd_tmpl = {
        .name = "cryptd",
-       .alloc = cryptd_alloc,
+       .create = cryptd_create,
        .free = cryptd_free,
        .module = THIS_MODULE,
 };