/*
 * Multi buffer SHA256 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) 2016 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:
 *	Megha Dey <megha.dey@linux.intel.com>
 *
 *  BSD LICENSE
 *
 *  Copyright(c) 2016 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 "sha256_mb_ctx.h"

#define FLUSH_INTERVAL 1000 /* in usec */

static struct mcryptd_alg_state sha256_mb_alg_state;

struct sha256_mb_ctx {
	struct mcryptd_ahash *mcryptd_tfm;
};

static inline struct mcryptd_hash_request_ctx
		*cast_hash_to_mcryptd_ctx(struct sha256_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 (*sha256_job_mgr_init)(struct sha256_mb_mgr *state);
static asmlinkage struct job_sha256* (*sha256_job_mgr_submit)
			(struct sha256_mb_mgr *state, struct job_sha256 *job);
static asmlinkage struct job_sha256* (*sha256_job_mgr_flush)
			(struct sha256_mb_mgr *state);
static asmlinkage struct job_sha256* (*sha256_job_mgr_get_comp_job)
			(struct sha256_mb_mgr *state);

inline void sha256_init_digest(uint32_t *digest)
{
	static const uint32_t initial_digest[SHA256_DIGEST_LENGTH] = {
				SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
				SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7};
	memcpy(digest, initial_digest, sizeof(initial_digest));
}

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

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

	i += ((SHA256_BLOCK_SIZE - 1) &
	      (0 - (total_len + SHA256_PADLENGTHFIELD_SIZE + 1)))
	     + 1 + SHA256_PADLENGTHFIELD_SIZE;

#if SHA256_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 >> SHA256_LOG2_BLOCK_SIZE;
}

static struct sha256_hash_ctx
		*sha256_ctx_mgr_resubmit(struct sha256_ctx_mgr *mgr,
					struct sha256_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 & (SHA256_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 % SHA256_BLOCK_SIZE) == 0);

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

			if (len) {

				ctx->job.buffer = (uint8_t *) buffer;
				ctx->job.len = len;
				ctx = (struct sha256_hash_ctx *)
				sha256_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 =
				sha256_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 sha256_hash_ctx *)
				sha256_job_mgr_submit(&mgr->mgr, &ctx->job);
			continue;
		}

		ctx->status = HASH_CTX_STS_IDLE;
		return ctx;
	}

	return NULL;
}

static struct sha256_hash_ctx
		*sha256_ctx_mgr_get_comp_ctx(struct sha256_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 sha256_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 sha256_hash_ctx *ctx;

	ctx = (struct sha256_hash_ctx *) sha256_job_mgr_get_comp_job(&mgr->mgr);
	return sha256_ctx_mgr_resubmit(mgr, ctx);
}

static void sha256_ctx_mgr_init(struct sha256_ctx_mgr *mgr)
{
	sha256_job_mgr_init(&mgr->mgr);
}

static struct sha256_hash_ctx *sha256_ctx_mgr_submit(struct sha256_ctx_mgr *mgr,
					  struct sha256_hash_ctx *ctx,
					  const void *buffer,
					  uint32_t len,
					  int flags)
{
	if (flags & (~HASH_ENTIRE)) {
		/* User should not pass anything other than FIRST, 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) && !(flags & HASH_FIRST)) {
		/* Cannot update a finished job. */
		ctx->error = HASH_CTX_ERROR_ALREADY_COMPLETED;
		return ctx;
	}

	if (flags & HASH_FIRST) {
		/* Init digest */
		sha256_init_digest(ctx->job.result_digest);

		/* Reset byte counter */
		ctx->total_length = 0;

		/* Clear extra blocks */
		ctx->partial_block_buffer_length = 0;
	}

	/* If we made it here, there was no error 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 < SHA256_BLOCK_SIZE) {
		/*
		 * Compute how many bytes to copy from user buffer into
		 * extra block
		 */
		uint32_t copy_len = SHA256_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 */
		assert(ctx->partial_block_buffer_length <= SHA256_BLOCK_SIZE);

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

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

	return sha256_ctx_mgr_resubmit(mgr, ctx);
}

static struct sha256_hash_ctx *sha256_ctx_mgr_flush(struct sha256_ctx_mgr *mgr)
{
	struct sha256_hash_ctx *ctx;

	while (1) {
		ctx = (struct sha256_hash_ctx *)
					sha256_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 = sha256_ctx_mgr_resubmit(mgr, ctx);

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

static int sha256_mb_init(struct ahash_request *areq)
{
	struct sha256_hash_ctx *sctx = ahash_request_ctx(areq);

	hash_ctx_init(sctx);
	sctx->job.result_digest[0] = SHA256_H0;
	sctx->job.result_digest[1] = SHA256_H1;
	sctx->job.result_digest[2] = SHA256_H2;
	sctx->job.result_digest[3] = SHA256_H3;
	sctx->job.result_digest[4] = SHA256_H4;
	sctx->job.result_digest[5] = SHA256_H5;
	sctx->job.result_digest[6] = SHA256_H6;
	sctx->job.result_digest[7] = SHA256_H7;
	sctx->total_length = 0;
	sctx->partial_block_buffer_length = 0;
	sctx->status = HASH_CTX_STS_IDLE;

	return 0;
}

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

	for (i = 0; i < 8; ++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 sha256_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 sha256_hash_ctx *)
						ahash_request_ctx(&rctx->areq);
		kernel_fpu_begin();
		sha_ctx = sha256_ctx_mgr_submit(cstate->mgr, sha_ctx,
						rctx->walk.data, nbytes, flag);
		if (!sha_ctx) {
			if (flush)
				sha_ctx = sha256_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)
		sha256_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 sha256_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 = sha256_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 = sha256_ctx_mgr_get_comp_ctx(cstate->mgr);
	}

	return 0;
}

static void sha256_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 sha256_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(sha256_mb_alg_state.alg_cstate);

	struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
	struct sha256_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 sha256_hash_ctx *) ahash_request_ctx(areq);
	sha256_mb_add_list(rctx, cstate);
	kernel_fpu_begin();
	sha_ctx = sha256_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 sha256_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(sha256_mb_alg_state.alg_cstate);

	struct ahash_request *req = cast_mcryptd_ctx_to_req(rctx);
	struct sha256_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 sha256_hash_ctx *) ahash_request_ctx(areq);
	sha256_mb_add_list(rctx, cstate);

	kernel_fpu_begin();
	sha_ctx = sha256_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 sha256_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(sha256_mb_alg_state.alg_cstate);

	struct sha256_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 sha256_hash_ctx *) ahash_request_ctx(areq);
	/* flag HASH_FINAL and 0 data size */
	sha256_mb_add_list(rctx, cstate);
	kernel_fpu_begin();
	sha_ctx = sha256_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 sha256_mb_export(struct ahash_request *areq, void *out)
{
	struct sha256_hash_ctx *sctx = ahash_request_ctx(areq);

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

	return 0;
}

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

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

	return 0;
}

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

	mcryptd_tfm = mcryptd_alloc_ahash("__intel_sha256-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 = &sha256_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 sha256_mb_async_exit_tfm(struct crypto_tfm *tfm)
{
	struct sha256_mb_ctx *ctx = crypto_tfm_ctx(tfm);

	mcryptd_free_ahash(ctx->mcryptd_tfm);
}

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

	return 0;
}

static void sha256_mb_areq_exit_tfm(struct crypto_tfm *tfm)
{
	struct sha256_mb_ctx *ctx = crypto_tfm_ctx(tfm);

	mcryptd_free_ahash(ctx->mcryptd_tfm);
}

static struct ahash_alg sha256_mb_areq_alg = {
	.init		=	sha256_mb_init,
	.update		=	sha256_mb_update,
	.final		=	sha256_mb_final,
	.finup		=	sha256_mb_finup,
	.export		=	sha256_mb_export,
	.import		=	sha256_mb_import,
	.halg		=	{
	.digestsize	=	SHA256_DIGEST_SIZE,
	.statesize	=	sizeof(struct sha256_hash_ctx),
		.base		=	{
			.cra_name	 = "__sha256-mb",
			.cra_driver_name = "__intel_sha256-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_TYPE_AHASH |
						CRYPTO_ALG_ASYNC |
						CRYPTO_ALG_INTERNAL,
			.cra_blocksize	= SHA256_BLOCK_SIZE,
			.cra_module	= THIS_MODULE,
			.cra_list	= LIST_HEAD_INIT
					(sha256_mb_areq_alg.halg.base.cra_list),
			.cra_init	= sha256_mb_areq_init_tfm,
			.cra_exit	= sha256_mb_areq_exit_tfm,
			.cra_ctxsize	= sizeof(struct sha256_hash_ctx),
		}
	}
};

static int sha256_mb_async_init(struct ahash_request *req)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha256_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 sha256_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 sha256_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 sha256_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 sha256_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 sha256_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 sha256_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 sha256_mb_async_digest(struct ahash_request *req)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sha256_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 sha256_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 sha256_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 sha256_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 sha256_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 sha256_mb_async_alg = {
	.init           = sha256_mb_async_init,
	.update         = sha256_mb_async_update,
	.final          = sha256_mb_async_final,
	.finup          = sha256_mb_async_finup,
	.export         = sha256_mb_async_export,
	.import         = sha256_mb_async_import,
	.digest         = sha256_mb_async_digest,
	.halg = {
		.digestsize     = SHA256_DIGEST_SIZE,
		.statesize      = sizeof(struct sha256_hash_ctx),
		.base = {
			.cra_name               = "sha256",
			.cra_driver_name        = "sha256_mb",
			.cra_priority           = 200,
			.cra_flags              = CRYPTO_ALG_TYPE_AHASH |
							CRYPTO_ALG_ASYNC,
			.cra_blocksize          = SHA256_BLOCK_SIZE,
			.cra_type               = &crypto_ahash_type,
			.cra_module             = THIS_MODULE,
			.cra_list               = LIST_HEAD_INIT
				(sha256_mb_async_alg.halg.base.cra_list),
			.cra_init               = sha256_mb_async_init_tfm,
			.cra_exit               = sha256_mb_async_exit_tfm,
			.cra_ctxsize		= sizeof(struct sha256_mb_ctx),
			.cra_alignmask		= 0,
		},
	},
};

static unsigned long sha256_mb_flusher(struct mcryptd_alg_cstate *cstate)
{
	struct mcryptd_hash_request_ctx *rctx;
	unsigned long cur_time;
	unsigned long next_flush = 0;
	struct sha256_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 sha256_hash_ctx *)
					sha256_ctx_mgr_flush(cstate->mgr);
		kernel_fpu_end();
		if (!sha_ctx) {
			pr_err("sha256_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 sha256_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 */
	sha256_mb_alg_state.alg_cstate = alloc_percpu
						(struct mcryptd_alg_cstate);

	sha256_job_mgr_init = sha256_mb_mgr_init_avx2;
	sha256_job_mgr_submit = sha256_mb_mgr_submit_avx2;
	sha256_job_mgr_flush = sha256_mb_mgr_flush_avx2;
	sha256_job_mgr_get_comp_job = sha256_mb_mgr_get_comp_job_avx2;

	if (!sha256_mb_alg_state.alg_cstate)
		return -ENOMEM;
	for_each_possible_cpu(cpu) {
		cpu_state = per_cpu_ptr(sha256_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 = &sha256_mb_alg_state;
		cpu_state->mgr = kzalloc(sizeof(struct sha256_ctx_mgr),
					GFP_KERNEL);
		if (!cpu_state->mgr)
			goto err2;
		sha256_ctx_mgr_init(cpu_state->mgr);
		INIT_LIST_HEAD(&cpu_state->work_list);
		spin_lock_init(&cpu_state->work_lock);
	}
	sha256_mb_alg_state.flusher = &sha256_mb_flusher;

	err = crypto_register_ahash(&sha256_mb_areq_alg);
	if (err)
		goto err2;
	err = crypto_register_ahash(&sha256_mb_async_alg);
	if (err)
		goto err1;


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

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

	crypto_unregister_ahash(&sha256_mb_async_alg);
	crypto_unregister_ahash(&sha256_mb_areq_alg);
	for_each_possible_cpu(cpu) {
		cpu_state = per_cpu_ptr(sha256_mb_alg_state.alg_cstate, cpu);
		kfree(cpu_state->mgr);
	}
	free_percpu(sha256_mb_alg_state.alg_cstate);
}

module_init(sha256_mb_mod_init);
module_exit(sha256_mb_mod_fini);

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

MODULE_ALIAS_CRYPTO("sha256");
