Merge branch 'fix/hda' into topic/hda
[safe/jmp/linux-2.6] / crypto / cryptd.c
index fbd26f9..ef71318 100644 (file)
@@ -31,7 +31,7 @@ struct cryptd_cpu_queue {
 };
 
 struct cryptd_queue {
-       struct cryptd_cpu_queue *cpu_queue;
+       struct cryptd_cpu_queue __percpu *cpu_queue;
 };
 
 struct cryptd_instance_ctx {
@@ -99,7 +99,7 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue,
        struct cryptd_cpu_queue *cpu_queue;
 
        cpu = get_cpu();
-       cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+       cpu_queue = this_cpu_ptr(queue->cpu_queue);
        err = crypto_enqueue_request(&cpu_queue->queue, request);
        queue_work_on(cpu, kcrypto_wq, &cpu_queue->work);
        put_cpu();
@@ -478,6 +478,29 @@ static int cryptd_hash_final_enqueue(struct ahash_request *req)
        return cryptd_hash_enqueue(req, cryptd_hash_final);
 }
 
+static void cryptd_hash_finup(struct crypto_async_request *req_async, int err)
+{
+       struct ahash_request *req = ahash_request_cast(req_async);
+       struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+
+       if (unlikely(err == -EINPROGRESS))
+               goto out;
+
+       err = shash_ahash_finup(req, &rctx->desc);
+
+       req->base.complete = rctx->complete;
+
+out:
+       local_bh_disable();
+       rctx->complete(&req->base, err);
+       local_bh_enable();
+}
+
+static int cryptd_hash_finup_enqueue(struct ahash_request *req)
+{
+       return cryptd_hash_enqueue(req, cryptd_hash_finup);
+}
+
 static void cryptd_hash_digest(struct crypto_async_request *req_async, int err)
 {
        struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm);
@@ -507,6 +530,20 @@ static int cryptd_hash_digest_enqueue(struct ahash_request *req)
        return cryptd_hash_enqueue(req, cryptd_hash_digest);
 }
 
+static int cryptd_hash_export(struct ahash_request *req, void *out)
+{
+       struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+
+       return crypto_shash_export(&rctx->desc, out);
+}
+
+static int cryptd_hash_import(struct ahash_request *req, const void *in)
+{
+       struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+
+       return crypto_shash_import(&rctx->desc, in);
+}
+
 static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
                              struct cryptd_queue *queue)
 {
@@ -546,6 +583,9 @@ static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
        inst->alg.init   = cryptd_hash_init_enqueue;
        inst->alg.update = cryptd_hash_update_enqueue;
        inst->alg.final  = cryptd_hash_final_enqueue;
+       inst->alg.finup  = cryptd_hash_finup_enqueue;
+       inst->alg.export = cryptd_hash_export;
+       inst->alg.import = cryptd_hash_import;
        inst->alg.setkey = cryptd_hash_setkey;
        inst->alg.digest = cryptd_hash_digest_enqueue;
 
@@ -642,6 +682,48 @@ void cryptd_free_ablkcipher(struct cryptd_ablkcipher *tfm)
 }
 EXPORT_SYMBOL_GPL(cryptd_free_ablkcipher);
 
+struct cryptd_ahash *cryptd_alloc_ahash(const char *alg_name,
+                                       u32 type, u32 mask)
+{
+       char cryptd_alg_name[CRYPTO_MAX_ALG_NAME];
+       struct crypto_ahash *tfm;
+
+       if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME,
+                    "cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME)
+               return ERR_PTR(-EINVAL);
+       tfm = crypto_alloc_ahash(cryptd_alg_name, type, mask);
+       if (IS_ERR(tfm))
+               return ERR_CAST(tfm);
+       if (tfm->base.__crt_alg->cra_module != THIS_MODULE) {
+               crypto_free_ahash(tfm);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return __cryptd_ahash_cast(tfm);
+}
+EXPORT_SYMBOL_GPL(cryptd_alloc_ahash);
+
+struct crypto_shash *cryptd_ahash_child(struct cryptd_ahash *tfm)
+{
+       struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(&tfm->base);
+
+       return ctx->child;
+}
+EXPORT_SYMBOL_GPL(cryptd_ahash_child);
+
+struct shash_desc *cryptd_shash_desc(struct ahash_request *req)
+{
+       struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+       return &rctx->desc;
+}
+EXPORT_SYMBOL_GPL(cryptd_shash_desc);
+
+void cryptd_free_ahash(struct cryptd_ahash *tfm)
+{
+       crypto_free_ahash(&tfm->base);
+}
+EXPORT_SYMBOL_GPL(cryptd_free_ahash);
+
 static int __init cryptd_init(void)
 {
        int err;