11e65b81a90df50bf450193065cc9073b706b8ddaTim Chen/*
21e65b81a90df50bf450193065cc9073b706b8ddaTim Chen * Software async multibuffer crypto daemon headers
31e65b81a90df50bf450193065cc9073b706b8ddaTim Chen *
41e65b81a90df50bf450193065cc9073b706b8ddaTim Chen *    Author:
51e65b81a90df50bf450193065cc9073b706b8ddaTim Chen *             Tim Chen <tim.c.chen@linux.intel.com>
61e65b81a90df50bf450193065cc9073b706b8ddaTim Chen *
71e65b81a90df50bf450193065cc9073b706b8ddaTim Chen *    Copyright (c) 2014, Intel Corporation.
81e65b81a90df50bf450193065cc9073b706b8ddaTim Chen */
91e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
101e65b81a90df50bf450193065cc9073b706b8ddaTim Chen#ifndef _CRYPTO_MCRYPT_H
111e65b81a90df50bf450193065cc9073b706b8ddaTim Chen#define _CRYPTO_MCRYPT_H
121e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
131e65b81a90df50bf450193065cc9073b706b8ddaTim Chen#include <linux/crypto.h>
141e65b81a90df50bf450193065cc9073b706b8ddaTim Chen#include <linux/kernel.h>
151e65b81a90df50bf450193065cc9073b706b8ddaTim Chen#include <crypto/hash.h>
161e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
171e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_ahash {
181e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct crypto_ahash base;
191e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
201e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
211e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstatic inline struct mcryptd_ahash *__mcryptd_ahash_cast(
221e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct crypto_ahash *tfm)
231e65b81a90df50bf450193065cc9073b706b8ddaTim Chen{
241e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	return (struct mcryptd_ahash *)tfm;
251e65b81a90df50bf450193065cc9073b706b8ddaTim Chen}
261e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
271e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_cpu_queue {
281e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct crypto_queue queue;
291e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct work_struct work;
301e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
311e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
321e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_queue {
331e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct mcryptd_cpu_queue __percpu *cpu_queue;
341e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
351e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
361e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_instance_ctx {
371e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct crypto_spawn spawn;
381e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct mcryptd_queue *queue;
391e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
401e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
411e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_hash_ctx {
421e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct crypto_shash *child;
431e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct mcryptd_alg_state *alg_state;
441e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
451e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
461e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_tag {
471e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	/* seq number of request */
481e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	unsigned seq_num;
491e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	/* arrival time of request */
501e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	unsigned long arrival;
511e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	unsigned long expire;
521e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	int	cpu;
531e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
541e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
551e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_hash_request_ctx {
561e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct list_head waiter;
571e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	crypto_completion_t complete;
581e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct mcryptd_tag tag;
591e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct crypto_hash_walk walk;
601e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	u8 *out;
611e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	int flag;
621e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct shash_desc desc;
631e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
641e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
651e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_ahash *mcryptd_alloc_ahash(const char *alg_name,
661e65b81a90df50bf450193065cc9073b706b8ddaTim Chen					u32 type, u32 mask);
671e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct crypto_shash *mcryptd_ahash_child(struct mcryptd_ahash *tfm);
681e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct shash_desc *mcryptd_shash_desc(struct ahash_request *req);
691e65b81a90df50bf450193065cc9073b706b8ddaTim Chenvoid mcryptd_free_ahash(struct mcryptd_ahash *tfm);
701e65b81a90df50bf450193065cc9073b706b8ddaTim Chenvoid mcryptd_flusher(struct work_struct *work);
711e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
721e65b81a90df50bf450193065cc9073b706b8ddaTim Chenenum mcryptd_req_type {
731e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	MCRYPTD_NONE,
741e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	MCRYPTD_UPDATE,
751e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	MCRYPTD_FINUP,
761e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	MCRYPTD_DIGEST,
771e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	MCRYPTD_FINAL
781e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
791e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
801e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_alg_cstate {
811e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	unsigned long next_flush;
821e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	unsigned next_seq_num;
831e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	bool	flusher_engaged;
841e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct  delayed_work flush;
851e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	int	cpu;
861e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct  mcryptd_alg_state *alg_state;
871e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	void	*mgr;
881e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	spinlock_t work_lock;
891e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct list_head work_list;
901e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct list_head flush_list;
911e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
921e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
931e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstruct mcryptd_alg_state {
941e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	struct mcryptd_alg_cstate __percpu *alg_cstate;
951e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	unsigned long (*flusher)(struct mcryptd_alg_cstate *cstate);
961e65b81a90df50bf450193065cc9073b706b8ddaTim Chen};
971e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
981e65b81a90df50bf450193065cc9073b706b8ddaTim Chen/* return delay in jiffies from current time */
991e65b81a90df50bf450193065cc9073b706b8ddaTim Chenstatic inline unsigned long get_delay(unsigned long t)
1001e65b81a90df50bf450193065cc9073b706b8ddaTim Chen{
1011e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	long delay;
1021e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
1031e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	delay = (long) t - (long) jiffies;
1041e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	if (delay <= 0)
1051e65b81a90df50bf450193065cc9073b706b8ddaTim Chen		return 0;
1061e65b81a90df50bf450193065cc9073b706b8ddaTim Chen	else
1071e65b81a90df50bf450193065cc9073b706b8ddaTim Chen		return (unsigned long) delay;
1081e65b81a90df50bf450193065cc9073b706b8ddaTim Chen}
1091e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
1101e65b81a90df50bf450193065cc9073b706b8ddaTim Chenvoid mcryptd_arm_flusher(struct mcryptd_alg_cstate *cstate, unsigned long delay);
1111e65b81a90df50bf450193065cc9073b706b8ddaTim Chen
1121e65b81a90df50bf450193065cc9073b706b8ddaTim Chen#endif
113