blob: 42dea66c74bfced5fce3d6b034e6d9b3f6f1327a [file] [log] [blame]
#ifndef ASR_SHA_H
#define ASR_SHA_H
#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <crypto/sha.h>
#include <crypto/hash.h>
#include <crypto/internal/hash.h>
#define ASR_SHA_BUFFER_ORDER 2
#define ASR_SHA_BUFFER_SIZE (PAGE_SIZE << ASR_SHA_BUFFER_ORDER)
/* SHA flags */
#define SHA_FLAGS_BUSY BIT(0)
#define SHA_FLAGS_INIT BIT(1)
#define SHA_FLAGS_FINAL BIT(2)
#define SHA_FLAGS_FINUP BIT(3)
#define SHA_FLAGS_OUTPUT_READY BIT(4)
#define SHA_FLAGS_ALGO_MASK GENMASK(10, 5)
#define SHA_FLAGS_SHA1 BIT(5)
#define SHA_FLAGS_SHA224 BIT(6)
#define SHA_FLAGS_SHA256 BIT(7)
#define SHA_FLAGS_HMAC BIT(8)
#define SHA_FLAGS_PAD BIT(9)
#define SHA_FLAGS_ERROR BIT(10)
#define SHA_OP_INIT 1
#define SHA_OP_UPDATE 2
#define SHA_OP_FINAL 3
#define HASH_BUF_LEN 64
typedef enum {
HASH_SHA1 = 0x0,
HASH_SHA224 = 0X2,
HASH_SHA256 = 0x3,
} HASH_ALGO_T;
struct asr_te200_sha;
typedef int (*asr_sha_fn_t)(struct asr_te200_sha *);
typedef irqreturn_t (*asr_sha_irq_t)(void *);
struct asr_te200_sha {
unsigned long phys_base;
struct device *dev;
struct clk *iclk;
int irq;
void __iomem *io_base;
spinlock_t lock;
struct mutex sha_lock;
int err;
struct tasklet_struct done_task;
struct tasklet_struct queue_task;
unsigned long flags;
struct crypto_queue queue;
struct ahash_request *req;
bool is_async;
bool force_complete;
asr_sha_fn_t resume;
int alg;
};
typedef struct te200_hash_context {
volatile uint32_t count; /* Used to store the extra data count */
unsigned char extra_data[HASH_BUF_LEN]; /* Buffer to store the extra data*/
volatile uint64_t total_bits_num; /* Total process data bits number */
unsigned char
hash_temp[64 / 2]; /* Buffer to store hash temp value */
int alg;
uint32_t hash_temp_valid;
uint32_t finish_flag; /* This flag indicates if the context need to finish.
* 0 not, 1 need to do. */
} te200_hash_context_t;
/*
* .statesize = sizeof(struct asr_sha_reqctx) must be <= PAGE_SIZE / 8 as
* tested by the ahash_prepare_alg() function.
*/
struct asr_sha_reqctx {
struct asr_te200_sha *dd;
unsigned long op;
u8 digest[SHA512_DIGEST_SIZE] __aligned(sizeof(u32));
u64 digcnt[2];
void *buffer;
size_t bufcnt;
size_t buflen;
/* walk state */
struct scatterlist *sg;
unsigned int offset; /* offset in current sg */
unsigned int total; /* total request */
int alg;
unsigned long flags;
te200_hash_context_t hash_ctx;
};
struct asr_sha_ctx {
struct asr_te200_sha *dd;
asr_sha_fn_t start;
unsigned long flags;
};
#define ASR_SHA_QUEUE_LENGTH 50
int asr_te200_hash_init(struct asr_sha_reqctx *reqctx, int alg);
int asr_te200_hash_proc(struct asr_sha_reqctx *reqctx, const uint8_t *src, size_t size);
int asr_te200_hash_finish(struct asr_sha_reqctx *reqctx, uint8_t *out, uint32_t out_size);
#endif