/*
 * Multi buffer SHA1 algorithm Glue Code
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 *  Copyright(c) 2014 Intel Corporation.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of version 2 of the GNU General Public License as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  Contact Information:
 *	Tim Chen <tim.c.chen@linux.intel.com>
 *
 *  BSD LICENSE
 *
 *  Copyright(c) 2014 Intel Corporation.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in
 *      the documentation and/or other materials provided with the
 *      distribution.
 *    * Neither the name of Intel Corporation nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <crypto/internal/hash.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/cryptohash.h>
#include <linux/types.h>
#include <linux/list.h>
#include <crypto/scatterwalk.h>
#include <crypto/sha.h>
#include <crypto/mcryptd.h>
#include <crypto/crypto_wq.h>
#include <asm/byteorder.h>
#include <linux/hardirq.h>
#include <asm/fpu/api.h>
#include "sha1_mb_ctx.h"

#define FLUSH_INTERVAL 1000 /* in usec */

static struct mcryptd_alg_state sha1_mb_alg_state;

struct sha1_mb_ctx {
	struct mcryptd_ahash *mcryptd_tfm;
};

static inline struct mcryptd_hash_request_ctx
		*cast_hash_to_mcryptd_ctx(struct sha1_hash_ctx *hash_ctx)
{
	struct ahash_request *areq;

	areq = container_of((void *) hash_ctx, struct ahash_request, __ctx);
	return container_of(areq, struct mcryptd_hash_request_ctx, areq);
}

static inline struct ahash_request
		*cast_mcryptd_ctx_to_req(struct mcryptd_hash_request_ctx *ctx)
{
	return container_of((void *) ctx, struct ahash_request, __ctx);
}

static void req_ctx_init(struct mcryptd_hash_request_ctx *rctx,
				struct ahash_request *areq)
{
	rctx->flag = HASH_UPDATE;
}

static asmlinkage void (*sha1_job_mgr_init)(struct sha1_mb_mgr *state);
static asmlinkage struct job_sha1* (*sha1_job_mgr_submit)
			(struct sha1_mb_mgr *state, struct job_sha1 *job);
static asmlinkage struct job_sha1* (*sha1_job_mgr_flush)
						(struct sha1_mb_mgr *state);
static asmlinkage struct job_sha1* (*sha1_job_mgr_get_comp_job)
						(struct sha1_mb_mgr *state);

static inline uint32_t sha1_pad(uint8_t padblock[SHA1_BLOCK_SIZE * 2],
			 uint64_t total_len)
{
	uint32_t i = total_len & (SHA1_BLOCK_SIZE - 1);

	memset(&padblock[i], 0, SHA1_BLOCK_SIZE);
	padblock[i] = 0x80;

	i += ((SHA1_BLOCK_SIZE - 1) &
	      (0 - (total_len + SHA1_PADLENGTHFIELD_SIZE + 1)))
	     + 1 + SHA1_PADLENGTHFIELD_SIZE;

#if SHA1_PADLENGTHFIELD_SIZE == 16
	*((uint64_t *) &padblock[i - 16]) = 0;
#endif

	*((uint64_t *) &padblock[i - 8]) = cpu_to_be64(total_len << 3);

	/* Number of extra blocks to hash */
	return i >> SHA1_LOG2_BLOCK_SIZE;
}

static struct sha1_hash_ctx *sha1_ctx_mgr_resubmit(struct sha1_ctx_mgr *mgr,
						struct sha1_hash_ctx *ctx)
{
	while (ctx) {
		if (ctx->status & HASH_CTX_STS_COMPLETE) {
			/* Clear PROCESSING bit */
			ctx->status = HASH_CTX_STS_COMPLETE;
			return ctx;
		}

		/*
		 * If the extra blocks are empty, begin hashing what remains
		 * in the user's buffer.
		 */
		if (ctx->partial_block_buffer_length == 0 &&
		    ctx->incoming_buffer_length) {

			const void *buffer = ctx->incoming_buffer;
			uint32_t len = ctx->incoming_buffer_length;
			uint32_t copy_len;

			/*
			 * Only entire blocks can be hashed.
			 * Copy remainder to extra blocks buffer.
			 */
			copy_len = len & (SHA1_BLOCK_SIZE-1);

			if (copy_len) {
				len -= copy_len;
				memcpy(ctx->partial_block_buffer,
				       ((const char *) buffer + len),
				       copy_len);
				ctx->partial_block_buffer_length = copy_len;
			}

			ctx->incoming_buffer_length = 0;

			/* len should be a multiple of the block size now */
			assert((len % SHA1_BLOCK_SIZE) == 0);

			/* Set len to the number of blocks to be hashed */
			len >>= SHA1_LOG2_BLOCK_SIZE;

			if (len) {

				ctx->job.buffer = (uint8_t *) buffer;
				ctx->job.len = len;
				ctx = (struct sha1_hash_ctx *)sha1_job_mgr_submit(&mgr->mgr,
										&ctx->job);
				continue;
			}
		}

		/*
		 * If the extra blocks are not empty, then we are
		 * either on the last block(s) or we need more
		 * user input before continuing.
		 */
		if (ctx->status & HASH_CTX_STS_LAST) {

			uint8_t *buf = ctx->partial_block_buffer;
			uint32_t n_extra_blocks =
					sha1_pad(buf, ctx->total_length);

			ctx->status = (HASH_CTX_STS_PROCESSING |
				       HASH_CTX_STS_COMPLETE);
			ctx->job.buffer = buf;
			ctx->job.len = (uint32_t) n_extra_blocks;
			ctx = (struct sha1_hash_ctx *)
				sha1_job_mgr_submit(&mgr->mgr, &ctx->job);
			continue;
		}

		ctx->status = HASH_CTX_STS_IDLE;
		return ctx;
	}

	return NULL;
}

static struct sha1_hash_ctx
			*sha1_ctx_mgr_get_comp_ctx(struct sha1_ctx_mgr *mgr)
{
	/*
	 * If get_comp_job returns NULL, there are no jobs complete.
	 * If get_comp_job returns a job, verify that it is safe to return to
	 * the user.
	 * If it is not ready, resubmit the job to finish processing.
	 * If sha1_ctx_mgr_resubmit returned a job, it is ready to be returned.
	 * Otherwise, all jobs currently being managed by the hash_ctx_mgr
	 * still need processing.
	 */
	struct sha1_hash_ctx *ctx;

	ctx = (struct sha1_hash_ctx *) sha1_job_mgr_get_comp_job(&mgr->mgr);
	return sha1_ctx_mgr_resubmit(mgr, ctx);
}

static void sha1_ctx_mgr_init(struct sha1_ctx_mgr *mgr)
{
	sha1_job_mgr_init(&mgr->mgr);
}

static struct sha1_hash_ctx *sha1_ctx_mgr_submit(struct sha1_ctx_mgr *mgr,
					  struct sha1_hash_ctx *ctx,
					  const void *buffer,
					  uint32_t len,
					  int flags)
{
	if (flags & ~(HASH_UPDATE | HASH_LAST)) {
		/* User should not pass anything other than UPDATE or LAST */
		ctx->error = HASH_CTX_ERROR_INVALID_FLAGS;
		return ctx;
	}

	if (ctx->status & HASH_CTX_STS_PROCESSING) {
		/* Cannot submit to a currently processing job. */
		ctx->error = HASH_CTX_ERROR_ALREADY_PROCESSING;
		return ctx;
	}

	if (ctx->status & HASH_CTX_STS_COMPLETE) {
		/* Cannot update a finished job. */
		ctx->error = HASH_CTX_ERROR_ALREADY_COMPLETED;
		return ctx;
	}

	/*
	 * If we made it here, there were no errors during this call to
	 * submit
	 */
	ctx->error = HASH_CTX_ERROR_NONE;

	/* Store buffer ptr info from user */
	ctx->incoming_buffer = buffer;
	ctx->incoming_buffer_length = len;

	/*
	 * Store the user's request flags and mark this ctx as currently
	 * being processed.
	 */
	ctx->status = (flags & HASH_LAST) ?
			(HASH_CTX_STS_PROCESSING | HASH_CTX_STS_LAST) :
			HASH_CTX_STS_PROCESSING;

	/* Advance byte counter */
	ctx->total_length += len;

	/*
	 * If there is anything currently buffered in the extra blocks,
	 * append to it until it contains a whole block.
	 * Or if the user's buffer contains less than a whole block,
	 * append as much as possible to the extra block.
	 */
	if (ctx->partial_block_buffer_length || len < SHA1_BLOCK_SIZE) {
		/*
		 * Compute how many bytes to copy from user buffer into
		 * extra block
		 */
		uint32_t copy_len = SHA1_BLOCK_SIZE -
					ctx->partial_block_buffer_length;
		if (len < copy_len)
			copy_len = len;

		if (copy_len) {
			/* Copy and update relevant pointers and counters */
			memcpy(&ctx->partial_block_buffer[ctx->partial_block_buffer_length],
				buffer, copy_len);

			ctx->partial_block_buffer_length += copy_len;
			ctx->incoming_buffer = (const void *)
					((const char *)buffer + copy_len);
			ctx->incoming_buffer_length = len - copy_len;
		}

		/*
		 * The extra block should never contain more than 1 block
		 * here
		 */
		assert(ctx->partial_block_buffer_length <= SHA1_BLOCK_SIZE);

		/*
		 * If the extra block buffer contains exactly 1 block, it can
		 * be hashed.
		 */
		if (ctx->partial_block_buffer_length >= SHA1_BLOCK_SIZE) {
			ctx->partial_block_buffer_length = 0;

			ctx->job.buffer = ctx->partial_block_buffer;
			ctx->job.len = 1;
			ctx = (struct sha1_hash_ctx *)
				sha1_job_mgr_submit(&mgr->mgr, &ctx->job);
		}
	}

	return sha1_ctx_mgr_resubmit(mgr, ctx);
}

static struct sha1_hash_ctx *sha1_ctx_mgr_flush(struct sha1_ctx_mgr *mgr)
{
	struct sha1_hash_ctx *ctx;

	while (1) {
		ctx = (struct sha1_hash_ctx *) sha1_job_mgr_flush(&mgr->mgr);

		/* If flush returned 0, there are no more jobs in flight. */
		if (!ctx)
			return NULL;

		/*
		 * If flush returned a job, resubmit the job to finish
		 * processing.
		 */
		ctx = sha1_ctx_mgr_resubmit(mgr, ctx);

		/*
		 * If sha1_ctx_mgr_resubmit returned a job, it is ready to be
		 * returned. Otherwise, all jobs currently being managed by the
		 * sha1_ctx_mgr still need processing. Loop.
		 */
		if (ctx)
			return ctx;
	}
}

static int sha1_mb_init(struct ahash_request *areq)
{
	struct sha1_hash_ctx *sctx = ahash_request_ctx(areq);

	hash_ctx_init(sctx);
	sctx->job.result_digest[0] = SHA1_H0;
	sctx->job.result_digest[1] = SHA1_H1;
	sctx->job.result_digest[2] = SHA1_H2;
	sctx->job.result_digest[3] = SHA1_H3;
	sctx->job.result_digest[4] = SHA1_H4;
	sctx->total_length = 0;
	sctx->partial_block_buffer_length = 0;
	sctx->status = HASH_CTX_STS_IDLE;

	return 0;
}

static int sha1_mb_set_results(struct mcryptd_hash_request_ctx *rctx)
{
	int	i;
	struct	sha1_hash_ctx *sctx = ahash_request_ctx(&rctx->areq);
	__be32	*dst = (__be32 *) rctx->out;

	for (i = 0; i < 5; ++i)
		dst[i] = cpu_to_be32(sctx->job.result_digest[i]);

	return 0;
}

static int sha_finish_walk(struct mcryptd_hash_request_ctx **ret_rctx,
			struct mcryptd_alg_cstate *cstate, bool flush)
{
	int	flag = HASH_UPDATE;
	int	nbytes, err = 0;
	struct mcryptd_hash_request_ctx *rctx = *ret_rctx;
	struct sha1_hash_ctx *sha_ctx;

	/* more work ? */
	while (!(rctx->flag & HASH_DONE)) {
		nbytes = crypto_ahash_walk_done(&rctx->walk, 0);
		if (nbytes < 0) {
			err = nbytes;
			goto out;
		}
		/* check if the walk is done */
		if (crypto_ahash_walk_last(&rctx->walk)) {
			rctx->flag |= HASH_DONE;
			if (rctx->flag & HASH_FINAL)
				flag |= HASH_LAST;

		}
		sha_ctx = (struct sha1_hash_ctx *)
						ahash_request_ctx(&rctx->areq);
		kernel_fpu_begin();
		sha_ctx = sha1_ctx_mgr_submit(cstate->mgr, sha_ctx,
						rctx->walk.data, nbytes, flag);
		if (!sha_ctx) {
			if (flush)
				sha_ctx = sha1_ctx_mgr_flush(cstate->mgr);
		}
		kernel_fpu_end();
		if (sha_ctx)
			rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
		else {
			rctx = NULL;
			goto out;
		}
	}

	/* copy the results */
	if (rctx->flag & HASH_FINAL)
		sha1_mb_set_results(rctx);

out:
	*ret_rctx = rctx;
	return err;
}

static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx,
			    struct mcryptd_alg_cstate *cstate,
			    int err)
{
	struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
	struct sha1_hash_ctx *sha_ctx;
	struct mcryptd_hash_request_ctx *req_ctx;
	int ret;

	/* remove from work list */
	spin_lock(&cstate->work_lock);
	list_del(&rctx->waiter);
	spin_unlock(&cstate->work_lock);

	if (irqs_disabled())
		rctx->complete(&req->base, err);
	else {
		local_bh_disable();
		rctx->complete(&req->base, err);
		local_bh_enable();
	}

	/* check to see if there are other jobs that are done */
	sha_ctx = sha1_ctx_mgr_get_comp_ctx(cstate->mgr);
	while (sha_ctx) {
		req_ctx = cast_hash_to_mcryptd_ctx(sha_ctx);
		ret = sha_finish_walk(&req_ctx, cstate, false);
		if (req_ctx) {
			spin_lock(&cstate->work_lock);
			list_del(&req_ctx->waiter);
			spin_unlock(&cstate->work_lock);

			req = cast_mcryptd_ctx_to_req(req_ctx);
			if (irqs_disabled())
				req_ctx->complete(&req->base, ret);
			else {
				local_bh_disable();
				req_ctx->complete(&req->base, ret);
				local_bh_enable();
			}
		}
		sha_ctx = sha1_ctx_mgr_get_comp_ctx(cstate->mgr);
	}

	return 0;
}

static void sha1_mb_add_list(struct mcryptd_hash_request_ctx *rctx,
			     struct mcryptd_alg_cstate *cstate)
{
	unsigned long next_flush;
	unsigned long delay = usecs_to_jiffies(FLUSH_INTERVAL);

	/* initialize tag */
	rctx->tag.arrival = jiffies;    /* tag the arrival time */
	rctx->tag.seq_num = cstate->next_seq_num++;
	next_flush = rctx->tag.arrival + delay;
	rctx->tag.expire = next_flush;

	spin_lock(&cstate->work_lock);
	list_add_tail(&rctx->waiter, &cstate->work_list);
	spin_unlock(&cstate->work_lock);

	mcryptd_arm_flusher(cstate, delay);
}

static int sha1_mb_update(struct ahash_request *areq)
{
	struct mcryptd_hash_request_ctx *rctx =
		container_of(areq, struct mcryptd_hash_request_ctx, areq);
	struct mcryptd_alg_cstate *cstate =
				this_cpu_ptr(sha1_mb_alg_state.alg_cstate);

	struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
	struct sha1_hash_ctx *sha_ctx;
	int ret = 0, nbytes;


	/* sanity check */
	if (rctx->tag.cpu != smp_processor_id()) {
		pr_err("mcryptd error: cpu clash\n");
		goto done;
	}

	/* need to init context */
	req_ctx_init(rctx, areq);

	nbytes = crypto_ahash_walk_first(req, &rctx->walk);

	if (nbytes < 0) {
		ret = nbytes;
		goto done;
	}

	if (crypto_ahash_walk_last(&rctx->walk))
		rctx->flag |= HASH_DONE;

	/* submit */
	sha_ctx = (struct sha1_hash_ctx *) ahash_request_ctx(areq);
	sha1_mb_add_list(rctx, cstate);
	kernel_fpu_begin();
	sha_ctx = sha1_ctx_mgr_submit(cstate->mgr, sha_ctx, rctx->walk.data,
							nbytes, HASH_UPDATE);
	kernel_fpu_end();

	/* check if anything is returned */
	if (!sha_ctx)
		return -EINPROGRESS;

	if (sha_ctx->error) {
		ret = sha_ctx->error;
		rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
		goto done;
	}

	rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
	ret = sha_finish_walk(&rctx, cstate, false);

	if (!rctx)
		return -EINPROGRESS;
done:
	sha_complete_job(rctx, cstate, ret);
	return ret;
}

static int sha1_mb_finup(struct ahash_request *areq)
{
	struct mcryptd_hash_request_ctx *rctx =
		container_of(areq, struct mcryptd_hash_request_ctx, areq);
	struct mcryptd_alg_cstate *cstate =
				this_cpu_ptr(sha1_mb_alg_state.alg_cstate);

	struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
	struct sha1_hash_ctx *sha_ctx;
	int ret = 0, flag = HASH_UPDATE, nbytes;

	/* sanity check */
	if (rctx->tag.cpu != smp_processor_id()) {
		pr_err("mcryptd error: cpu clash\n");
		goto done;
	}

	/* need to init context */
	req_ctx_init(rctx, areq);

	nbytes = crypto_ahash_walk_first(req, &rctx->walk);

	if (nbytes < 0) {
		ret = nbytes;
		goto done;
	}

	if (crypto_ahash_walk_last(&rctx->walk)) {
		rctx->flag |= HASH_DONE;
		flag = HASH_LAST;
	}

	/* submit */
	rctx->flag |= HASH_FINAL;
	sha_ctx = (struct sha1_hash_ctx *) ahash_request_ctx(areq);
	sha1_mb_add_list(rctx, cstate);

	kernel_fpu_begin();
	sha_ctx = sha1_ctx_mgr_submit(cstate->mgr, sha_ctx, rctx->walk.data,
								nbytes, flag);
	kernel_fpu_end();

	/* check if anything is returned */
	if (!sha_ctx)
		return -EINPROGRESS;

	if (sha_ctx->error) {
		ret = sha_ctx->error;
		goto done;
	}

	rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
	ret = sha_finish_walk(&rctx, cstate, false);
	if (!rctx)
		return -EINPROGRESS;
done:
	sha_complete_job(rctx, cstate, ret);
	return ret;
}

static int sha1_mb_final(struct ahash_request *areq)
{
	struct mcryptd_hash_request_ctx *rctx =
		container_of(areq, struct mcryptd_hash_request_ctx, areq);
	struct mcryptd_alg_cstate *cstate =
				this_cpu_ptr(sha1_mb_alg_state.alg_cstate);

	struct sha1_hash_ctx *sha_ctx;
	int ret = 0;
	u8 data;

	/* sanity check */
	if (rctx->tag.cpu != smp_processor_id()) {
		pr_err("mcryptd error: cpu clash\n");
		goto done;
	}

	/* need to init context */
	req_ctx_init(rctx, areq);

	rctx->flag |= HASH_DONE | HASH_FINAL;

	sha_ctx = (struct sha1_hash_ctx *) ahash_request_ctx(areq);
	/* flag HASH_FINAL and 0 data size */
	sha1_mb_add_list(rctx, cstate);
	kernel_fpu_begin();
	sha_ctx = sha1_ctx_mgr_submit(cstate->mgr, sha_ctx, &data, 0,
								HASH_LAST);
	kernel_fpu_end();

	/* check if anything is returned */
	if (!sha_ctx)
		return -EINPROGRESS;

	if (sha_ctx->error) {
		ret = sha_ctx->error;
		rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
		goto done;
	}

	rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
	ret = sha_finish_walk(&rctx, cstate, false);
	if (!rctx)
		return -EINPROGRESS;
done:
	sha_complete_job(rctx, cstate, ret);
	return ret;
}

static int sha1_mb_export(struct ahash_request *areq, void *out)
{
	struct sha1_hash_ctx *sctx = ahash_request_ctx(areq);

	memcpy(out, sctx, sizeof(*sctx));

	return 0;
}

static int sha1_mb_import(struct ahash_request *areq, const void *in)
{
	struct sha1_hash_ctx *sctx = ahash_request_ctx(areq);

	memcpy(sctx, in, sizeof(*sctx));

	return 0;
}

static int sha1_mb_async_init_tfm(struct crypto_tfm *tfm)
{
	struct mcryptd_ahash *mcryptd_tfm;
	struct sha1_mb_ctx *ctx = crypto_tfm_ctx(tfm);
	struct mcryptd_hash_ctx *mctx;

	mcryptd_tfm = mcryptd_alloc_ahash("__intel_sha1-mb",
						CRYPTO_ALG_INTERNAL,
						CRYPTO_ALG_INTERNAL);
	if (IS_ERR(mcryptd_tfm))
		return PTR_ERR(mcryptd_tfm);
	mctx = crypto_ahash_ctx(&mcryptd_tfm->base);
	mctx->alg_state = &sha1_mb_alg_state;
	ctx->mcryptd_tfm = mcryptd_tfm;
	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
				sizeof(struct ahash_request) +
				crypto_ahash_reqsize(&mcryptd_tfm->base));

	return 0;
}

static void sha1_mb_async_exit_tfm(struct crypto_tfm *tfm)
{
	struct sha1_mb_ctx *ctx = crypto_tfm_ctx(tfm);

	mcryptd_free_ahash(ctx->mcryptd_tfm);
}

static int sha1_mb_areq_init_tfm(struct crypto_tfm *tfm)
{
	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
				sizeof(struct ahash_request) +
				sizeof(struct sha1_hash_ctx));

	return 0;
}

static void sha1_mb_areq_exit_tfm(struct crypto_tfm *tfm)
{
	struct sha1_mb_ctx *ctx = crypto_tfm_ctx(tfm);

	mcryptd_free_ahash(ctx->mcryptd_tfm);
}

static struct ahash_alg sha1_mb_areq_alg = {
	.init		=	sha1_mb_init,
	.update		=	sha1_mb_update,
	.final		=	sha1_mb_final,
	.finup		=	sha1_mb_finup,
	.export		=	sha1_mb_export,
	.import		=	sha1_mb_import,
	.halg		=	{
		.digestsize	=	SHA1_DIGEST_SIZE,
		.statesize	=	sizeof(struct sha1_hash_ctx),
		.base		=	{
			.cra_name	 = "__sha1-mb",
			.cra_driver_name = "__intel_sha1-mb",
			.cra_priority	 = 100,
			/*
			 * use ASYNC flag as some buffers in multi-buffer
			 * algo may not have completed before hashing thread
			 * sleep
			 */
			.cra_flags	= CRYPTO_ALG_ASYNC |
					  CRYPTO_ALG_INTERNAL,
			.cra_blocksize	= SHA1_BLOCK_SIZE,
			.cra_module	= THIS_MODULE,
			.cra_list	= LIST_HEAD_INIT
					(sha1_mb_areq_alg.halg.base.cra_list),
			.cra_init	= sha1_mb_areq_init_tfm,
			.cra_exit	= sha1_mb_areq_exit_tfm,
			.cra_ctxsize	= sizeof(struct sha1_hash_ctx),
		}
	}
};

static int sha1_mb_async_init(struct ahash_request *req)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
	struct ahash_request *mcryptd_req = ahash_request_ctx(req);
	struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;

	memcpy(mcryptd_req, req, sizeof(*req));
	ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
	return crypto_ahash_init(mcryptd_req);
}

static int sha1_mb_async_update(struct ahash_request *req)
{
	struct ahash_request *mcryptd_req = ahash_request_ctx(req);

	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
	struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;

	memcpy(mcryptd_req, req, sizeof(*req));
	ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
	return crypto_ahash_update(mcryptd_req);
}

static int sha1_mb_async_finup(struct ahash_request *req)
{
	struct ahash_request *mcryptd_req = ahash_request_ctx(req);

	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
	struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;

	memcpy(mcryptd_req, req, sizeof(*req));
	ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
	return crypto_ahash_finup(mcryptd_req);
}

static int sha1_mb_async_final(struct ahash_request *req)
{
	struct ahash_request *mcryptd_req = ahash_request_ctx(req);

	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
	struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;

	memcpy(mcryptd_req, req, sizeof(*req));
	ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
	return crypto_ahash_final(mcryptd_req);
}

static int sha1_mb_async_digest(struct ahash_request *req)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
	struct ahash_request *mcryptd_req = ahash_request_ctx(req);
	struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;

	memcpy(mcryptd_req, req, sizeof(*req));
	ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
	return crypto_ahash_digest(mcryptd_req);
}

static int sha1_mb_async_export(struct ahash_request *req, void *out)
{
	struct ahash_request *mcryptd_req = ahash_request_ctx(req);
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
	struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;

	memcpy(mcryptd_req, req, sizeof(*req));
	ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
	return crypto_ahash_export(mcryptd_req, out);
}

static int sha1_mb_async_import(struct ahash_request *req, const void *in)
{
	struct ahash_request *mcryptd_req = ahash_request_ctx(req);
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
	struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
	struct crypto_ahash *child = mcryptd_ahash_child(mcryptd_tfm);
	struct mcryptd_hash_request_ctx *rctx;
	struct ahash_request *areq;

	memcpy(mcryptd_req, req, sizeof(*req));
	ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
	rctx = ahash_request_ctx(mcryptd_req);
	areq = &rctx->areq;

	ahash_request_set_tfm(areq, child);
	ahash_request_set_callback(areq, CRYPTO_TFM_REQ_MAY_SLEEP,
					rctx->complete, req);

	return crypto_ahash_import(mcryptd_req, in);
}

static struct ahash_alg sha1_mb_async_alg = {
	.init           = sha1_mb_async_init,
	.update         = sha1_mb_async_update,
	.final          = sha1_mb_async_final,
	.finup          = sha1_mb_async_finup,
	.digest         = sha1_mb_async_digest,
	.export		= sha1_mb_async_export,
	.import		= sha1_mb_async_import,
	.halg = {
		.digestsize     = SHA1_DIGEST_SIZE,
		.statesize	= sizeof(struct sha1_hash_ctx),
		.base = {
			.cra_name               = "sha1",
			.cra_driver_name        = "sha1_mb",
			/*
			 * Low priority, since with few concurrent hash requests
			 * this is extremely slow due to the flush delay.  Users
			 * whose workloads would benefit from this can request
			 * it explicitly by driver name, or can increase its
			 * priority at runtime using NETLINK_CRYPTO.
			 */
			.cra_priority           = 50,
			.cra_flags              = CRYPTO_ALG_ASYNC,
			.cra_blocksize          = SHA1_BLOCK_SIZE,
			.cra_module             = THIS_MODULE,
			.cra_list               = LIST_HEAD_INIT(sha1_mb_async_alg.halg.base.cra_list),
			.cra_init               = sha1_mb_async_init_tfm,
			.cra_exit               = sha1_mb_async_exit_tfm,
			.cra_ctxsize		= sizeof(struct sha1_mb_ctx),
			.cra_alignmask		= 0,
		},
	},
};

static unsigned long sha1_mb_flusher(struct mcryptd_alg_cstate *cstate)
{
	struct mcryptd_hash_request_ctx *rctx;
	unsigned long cur_time;
	unsigned long next_flush = 0;
	struct sha1_hash_ctx *sha_ctx;


	cur_time = jiffies;

	while (!list_empty(&cstate->work_list)) {
		rctx = list_entry(cstate->work_list.next,
				struct mcryptd_hash_request_ctx, waiter);
		if (time_before(cur_time, rctx->tag.expire))
			break;
		kernel_fpu_begin();
		sha_ctx = (struct sha1_hash_ctx *)
					sha1_ctx_mgr_flush(cstate->mgr);
		kernel_fpu_end();
		if (!sha_ctx) {
			pr_err("sha1_mb error: nothing got flushed for non-empty list\n");
			break;
		}
		rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
		sha_finish_walk(&rctx, cstate, true);
		sha_complete_job(rctx, cstate, 0);
	}

	if (!list_empty(&cstate->work_list)) {
		rctx = list_entry(cstate->work_list.next,
				struct mcryptd_hash_request_ctx, waiter);
		/* get the hash context and then flush time */
		next_flush = rctx->tag.expire;
		mcryptd_arm_flusher(cstate, get_delay(next_flush));
	}
	return next_flush;
}

static int __init sha1_mb_mod_init(void)
{

	int cpu;
	int err;
	struct mcryptd_alg_cstate *cpu_state;

	/* check for dependent cpu features */
	if (!boot_cpu_has(X86_FEATURE_AVX2) ||
	    !boot_cpu_has(X86_FEATURE_BMI2))
		return -ENODEV;

	/* initialize multibuffer structures */
	sha1_mb_alg_state.alg_cstate = alloc_percpu(struct mcryptd_alg_cstate);

	sha1_job_mgr_init = sha1_mb_mgr_init_avx2;
	sha1_job_mgr_submit = sha1_mb_mgr_submit_avx2;
	sha1_job_mgr_flush = sha1_mb_mgr_flush_avx2;
	sha1_job_mgr_get_comp_job = sha1_mb_mgr_get_comp_job_avx2;

	if (!sha1_mb_alg_state.alg_cstate)
		return -ENOMEM;
	for_each_possible_cpu(cpu) {
		cpu_state = per_cpu_ptr(sha1_mb_alg_state.alg_cstate, cpu);
		cpu_state->next_flush = 0;
		cpu_state->next_seq_num = 0;
		cpu_state->flusher_engaged = false;
		INIT_DELAYED_WORK(&cpu_state->flush, mcryptd_flusher);
		cpu_state->cpu = cpu;
		cpu_state->alg_state = &sha1_mb_alg_state;
		cpu_state->mgr = kzalloc(sizeof(struct sha1_ctx_mgr),
					GFP_KERNEL);
		if (!cpu_state->mgr)
			goto err2;
		sha1_ctx_mgr_init(cpu_state->mgr);
		INIT_LIST_HEAD(&cpu_state->work_list);
		spin_lock_init(&cpu_state->work_lock);
	}
	sha1_mb_alg_state.flusher = &sha1_mb_flusher;

	err = crypto_register_ahash(&sha1_mb_areq_alg);
	if (err)
		goto err2;
	err = crypto_register_ahash(&sha1_mb_async_alg);
	if (err)
		goto err1;


	return 0;
err1:
	crypto_unregister_ahash(&sha1_mb_areq_alg);
err2:
	for_each_possible_cpu(cpu) {
		cpu_state = per_cpu_ptr(sha1_mb_alg_state.alg_cstate, cpu);
		kfree(cpu_state->mgr);
	}
	free_percpu(sha1_mb_alg_state.alg_cstate);
	return -ENODEV;
}

static void __exit sha1_mb_mod_fini(void)
{
	int cpu;
	struct mcryptd_alg_cstate *cpu_state;

	crypto_unregister_ahash(&sha1_mb_async_alg);
	crypto_unregister_ahash(&sha1_mb_areq_alg);
	for_each_possible_cpu(cpu) {
		cpu_state = per_cpu_ptr(sha1_mb_alg_state.alg_cstate, cpu);
		kfree(cpu_state->mgr);
	}
	free_percpu(sha1_mb_alg_state.alg_cstate);
}

module_init(sha1_mb_mod_init);
module_exit(sha1_mb_mod_fini);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, multi buffer accelerated");

MODULE_ALIAS_CRYPTO("sha1");
