162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Cryptographic API. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Support for OMAP AES HW ACCELERATOR defines 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2015 Texas Instruments Incorporated 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#ifndef __OMAP_AES_H__ 1062306a36Sopenharmony_ci#define __OMAP_AES_H__ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <crypto/aes.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define DST_MAXBURST 4 1562306a36Sopenharmony_ci#define DMA_MIN (DST_MAXBURST * sizeof(u32)) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define _calc_walked(inout) (dd->inout##_walk.offset - dd->inout##_sg->offset) 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* 2062306a36Sopenharmony_ci * OMAP TRM gives bitfields as start:end, where start is the higher bit 2162306a36Sopenharmony_ci * number. For example 7:0 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) 2462306a36Sopenharmony_ci#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define AES_REG_KEY(dd, x) ((dd)->pdata->key_ofs - \ 2762306a36Sopenharmony_ci (((x) ^ 0x01) * 0x04)) 2862306a36Sopenharmony_ci#define AES_REG_IV(dd, x) ((dd)->pdata->iv_ofs + ((x) * 0x04)) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define AES_REG_CTRL(dd) ((dd)->pdata->ctrl_ofs) 3162306a36Sopenharmony_ci#define AES_REG_CTRL_CONTEXT_READY BIT(31) 3262306a36Sopenharmony_ci#define AES_REG_CTRL_CTR_WIDTH_MASK GENMASK(8, 7) 3362306a36Sopenharmony_ci#define AES_REG_CTRL_CTR_WIDTH_32 0 3462306a36Sopenharmony_ci#define AES_REG_CTRL_CTR_WIDTH_64 BIT(7) 3562306a36Sopenharmony_ci#define AES_REG_CTRL_CTR_WIDTH_96 BIT(8) 3662306a36Sopenharmony_ci#define AES_REG_CTRL_CTR_WIDTH_128 GENMASK(8, 7) 3762306a36Sopenharmony_ci#define AES_REG_CTRL_GCM GENMASK(17, 16) 3862306a36Sopenharmony_ci#define AES_REG_CTRL_CTR BIT(6) 3962306a36Sopenharmony_ci#define AES_REG_CTRL_CBC BIT(5) 4062306a36Sopenharmony_ci#define AES_REG_CTRL_KEY_SIZE GENMASK(4, 3) 4162306a36Sopenharmony_ci#define AES_REG_CTRL_DIRECTION BIT(2) 4262306a36Sopenharmony_ci#define AES_REG_CTRL_INPUT_READY BIT(1) 4362306a36Sopenharmony_ci#define AES_REG_CTRL_OUTPUT_READY BIT(0) 4462306a36Sopenharmony_ci#define AES_REG_CTRL_MASK GENMASK(24, 2) 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define AES_REG_C_LEN_0 0x54 4762306a36Sopenharmony_ci#define AES_REG_C_LEN_1 0x58 4862306a36Sopenharmony_ci#define AES_REG_A_LEN 0x5C 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define AES_REG_DATA_N(dd, x) ((dd)->pdata->data_ofs + ((x) * 0x04)) 5162306a36Sopenharmony_ci#define AES_REG_TAG_N(dd, x) (0x70 + ((x) * 0x04)) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define AES_REG_REV(dd) ((dd)->pdata->rev_ofs) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define AES_REG_MASK(dd) ((dd)->pdata->mask_ofs) 5662306a36Sopenharmony_ci#define AES_REG_MASK_SIDLE BIT(6) 5762306a36Sopenharmony_ci#define AES_REG_MASK_START BIT(5) 5862306a36Sopenharmony_ci#define AES_REG_MASK_DMA_OUT_EN BIT(3) 5962306a36Sopenharmony_ci#define AES_REG_MASK_DMA_IN_EN BIT(2) 6062306a36Sopenharmony_ci#define AES_REG_MASK_SOFTRESET BIT(1) 6162306a36Sopenharmony_ci#define AES_REG_AUTOIDLE BIT(0) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#define AES_REG_LENGTH_N(x) (0x54 + ((x) * 0x04)) 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#define AES_REG_IRQ_STATUS(dd) ((dd)->pdata->irq_status_ofs) 6662306a36Sopenharmony_ci#define AES_REG_IRQ_ENABLE(dd) ((dd)->pdata->irq_enable_ofs) 6762306a36Sopenharmony_ci#define AES_REG_IRQ_DATA_IN BIT(1) 6862306a36Sopenharmony_ci#define AES_REG_IRQ_DATA_OUT BIT(2) 6962306a36Sopenharmony_ci#define DEFAULT_TIMEOUT (5 * HZ) 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci#define DEFAULT_AUTOSUSPEND_DELAY 1000 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define FLAGS_MODE_MASK 0x001f 7462306a36Sopenharmony_ci#define FLAGS_ENCRYPT BIT(0) 7562306a36Sopenharmony_ci#define FLAGS_CBC BIT(1) 7662306a36Sopenharmony_ci#define FLAGS_CTR BIT(2) 7762306a36Sopenharmony_ci#define FLAGS_GCM BIT(3) 7862306a36Sopenharmony_ci#define FLAGS_RFC4106_GCM BIT(4) 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#define FLAGS_INIT BIT(5) 8162306a36Sopenharmony_ci#define FLAGS_FAST BIT(6) 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define FLAGS_IN_DATA_ST_SHIFT 8 8462306a36Sopenharmony_ci#define FLAGS_OUT_DATA_ST_SHIFT 10 8562306a36Sopenharmony_ci#define FLAGS_ASSOC_DATA_ST_SHIFT 12 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#define AES_BLOCK_WORDS (AES_BLOCK_SIZE >> 2) 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistruct omap_aes_gcm_result { 9062306a36Sopenharmony_ci struct completion completion; 9162306a36Sopenharmony_ci int err; 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistruct omap_aes_ctx { 9562306a36Sopenharmony_ci int keylen; 9662306a36Sopenharmony_ci u32 key[AES_KEYSIZE_256 / sizeof(u32)]; 9762306a36Sopenharmony_ci u8 nonce[4]; 9862306a36Sopenharmony_ci struct crypto_skcipher *fallback; 9962306a36Sopenharmony_ci}; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistruct omap_aes_gcm_ctx { 10262306a36Sopenharmony_ci struct omap_aes_ctx octx; 10362306a36Sopenharmony_ci struct crypto_aes_ctx actx; 10462306a36Sopenharmony_ci}; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistruct omap_aes_reqctx { 10762306a36Sopenharmony_ci struct omap_aes_dev *dd; 10862306a36Sopenharmony_ci unsigned long mode; 10962306a36Sopenharmony_ci u8 iv[AES_BLOCK_SIZE]; 11062306a36Sopenharmony_ci u32 auth_tag[AES_BLOCK_SIZE / sizeof(u32)]; 11162306a36Sopenharmony_ci struct skcipher_request fallback_req; // keep at the end 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#define OMAP_AES_QUEUE_LENGTH 1 11562306a36Sopenharmony_ci#define OMAP_AES_CACHE_SIZE 0 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistruct omap_aes_algs_info { 11862306a36Sopenharmony_ci struct skcipher_engine_alg *algs_list; 11962306a36Sopenharmony_ci unsigned int size; 12062306a36Sopenharmony_ci unsigned int registered; 12162306a36Sopenharmony_ci}; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistruct omap_aes_aead_algs { 12462306a36Sopenharmony_ci struct aead_engine_alg *algs_list; 12562306a36Sopenharmony_ci unsigned int size; 12662306a36Sopenharmony_ci unsigned int registered; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistruct omap_aes_pdata { 13062306a36Sopenharmony_ci struct omap_aes_algs_info *algs_info; 13162306a36Sopenharmony_ci unsigned int algs_info_size; 13262306a36Sopenharmony_ci struct omap_aes_aead_algs *aead_algs_info; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci void (*trigger)(struct omap_aes_dev *dd, int length); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci u32 key_ofs; 13762306a36Sopenharmony_ci u32 iv_ofs; 13862306a36Sopenharmony_ci u32 ctrl_ofs; 13962306a36Sopenharmony_ci u32 data_ofs; 14062306a36Sopenharmony_ci u32 rev_ofs; 14162306a36Sopenharmony_ci u32 mask_ofs; 14262306a36Sopenharmony_ci u32 irq_enable_ofs; 14362306a36Sopenharmony_ci u32 irq_status_ofs; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci u32 dma_enable_in; 14662306a36Sopenharmony_ci u32 dma_enable_out; 14762306a36Sopenharmony_ci u32 dma_start; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci u32 major_mask; 15062306a36Sopenharmony_ci u32 major_shift; 15162306a36Sopenharmony_ci u32 minor_mask; 15262306a36Sopenharmony_ci u32 minor_shift; 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistruct omap_aes_dev { 15662306a36Sopenharmony_ci struct list_head list; 15762306a36Sopenharmony_ci unsigned long phys_base; 15862306a36Sopenharmony_ci void __iomem *io_base; 15962306a36Sopenharmony_ci struct omap_aes_ctx *ctx; 16062306a36Sopenharmony_ci struct device *dev; 16162306a36Sopenharmony_ci unsigned long flags; 16262306a36Sopenharmony_ci int err; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci struct tasklet_struct done_task; 16562306a36Sopenharmony_ci struct aead_queue aead_queue; 16662306a36Sopenharmony_ci spinlock_t lock; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci struct skcipher_request *req; 16962306a36Sopenharmony_ci struct aead_request *aead_req; 17062306a36Sopenharmony_ci struct crypto_engine *engine; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* 17362306a36Sopenharmony_ci * total is used by PIO mode for book keeping so introduce 17462306a36Sopenharmony_ci * variable total_save as need it to calc page_order 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_ci size_t total; 17762306a36Sopenharmony_ci size_t total_save; 17862306a36Sopenharmony_ci size_t assoc_len; 17962306a36Sopenharmony_ci size_t authsize; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci struct scatterlist *in_sg; 18262306a36Sopenharmony_ci struct scatterlist *out_sg; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci /* Buffers for copying for unaligned cases */ 18562306a36Sopenharmony_ci struct scatterlist in_sgl[2]; 18662306a36Sopenharmony_ci struct scatterlist out_sgl; 18762306a36Sopenharmony_ci struct scatterlist *orig_out; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci struct scatter_walk in_walk; 19062306a36Sopenharmony_ci struct scatter_walk out_walk; 19162306a36Sopenharmony_ci struct dma_chan *dma_lch_in; 19262306a36Sopenharmony_ci struct dma_chan *dma_lch_out; 19362306a36Sopenharmony_ci int in_sg_len; 19462306a36Sopenharmony_ci int out_sg_len; 19562306a36Sopenharmony_ci int pio_only; 19662306a36Sopenharmony_ci const struct omap_aes_pdata *pdata; 19762306a36Sopenharmony_ci}; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ciu32 omap_aes_read(struct omap_aes_dev *dd, u32 offset); 20062306a36Sopenharmony_civoid omap_aes_write(struct omap_aes_dev *dd, u32 offset, u32 value); 20162306a36Sopenharmony_cistruct omap_aes_dev *omap_aes_find_dev(struct omap_aes_reqctx *rctx); 20262306a36Sopenharmony_ciint omap_aes_gcm_setkey(struct crypto_aead *tfm, const u8 *key, 20362306a36Sopenharmony_ci unsigned int keylen); 20462306a36Sopenharmony_ciint omap_aes_4106gcm_setkey(struct crypto_aead *tfm, const u8 *key, 20562306a36Sopenharmony_ci unsigned int keylen); 20662306a36Sopenharmony_ciint omap_aes_gcm_encrypt(struct aead_request *req); 20762306a36Sopenharmony_ciint omap_aes_gcm_decrypt(struct aead_request *req); 20862306a36Sopenharmony_ciint omap_aes_gcm_setauthsize(struct crypto_aead *tfm, unsigned int authsize); 20962306a36Sopenharmony_ciint omap_aes_4106gcm_encrypt(struct aead_request *req); 21062306a36Sopenharmony_ciint omap_aes_4106gcm_decrypt(struct aead_request *req); 21162306a36Sopenharmony_ciint omap_aes_4106gcm_setauthsize(struct crypto_aead *parent, 21262306a36Sopenharmony_ci unsigned int authsize); 21362306a36Sopenharmony_ciint omap_aes_gcm_cra_init(struct crypto_aead *tfm); 21462306a36Sopenharmony_ciint omap_aes_write_ctrl(struct omap_aes_dev *dd); 21562306a36Sopenharmony_ciint omap_aes_crypt_dma_start(struct omap_aes_dev *dd); 21662306a36Sopenharmony_ciint omap_aes_crypt_dma_stop(struct omap_aes_dev *dd); 21762306a36Sopenharmony_civoid omap_aes_gcm_dma_out_callback(void *data); 21862306a36Sopenharmony_civoid omap_aes_clear_copy_flags(struct omap_aes_dev *dd); 21962306a36Sopenharmony_ciint omap_aes_gcm_crypt_req(struct crypto_engine *engine, void *areq); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci#endif 222