diff options
author | Tero Kristo <t-kristo@ti.com> | 2017-05-24 10:35:31 +0300 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-06-10 12:04:19 +0800 |
commit | ad18cc9d0f911928704cdc37f4d126853daa9e4e (patch) | |
tree | 1a16791b6ee2b5fdbe468743c529869c81bb15bc /drivers/crypto/omap-aes.h | |
parent | d695bfd6f02adf362511a6d0139e7f7e6342d3e8 (diff) | |
download | linux-stable-ad18cc9d0f911928704cdc37f4d126853daa9e4e.tar.gz linux-stable-ad18cc9d0f911928704cdc37f4d126853daa9e4e.tar.bz2 linux-stable-ad18cc9d0f911928704cdc37f4d126853daa9e4e.zip |
crypto: omap-aes - Add support for GCM mode
OMAP AES hw supports AES-GCM mode. This patch adds support for GCM and
RFC4106 GCM mode in omap-aes driver. The GCM implementation is mostly
written into its own source file, which gets built into the same driver
binary as the existing AES support.
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
[t-kristo@ti.com: forward port to latest upstream kernel, conversion to use
omap-crypto lib and some additional fixes]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/omap-aes.h')
-rw-r--r-- | drivers/crypto/omap-aes.h | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/drivers/crypto/omap-aes.h b/drivers/crypto/omap-aes.h index 11e1784cc4a5..8906342e2b9a 100644 --- a/drivers/crypto/omap-aes.h +++ b/drivers/crypto/omap-aes.h @@ -30,11 +30,13 @@ #define AES_REG_IV(dd, x) ((dd)->pdata->iv_ofs + ((x) * 0x04)) #define AES_REG_CTRL(dd) ((dd)->pdata->ctrl_ofs) +#define AES_REG_CTRL_CONTEXT_READY BIT(31) #define AES_REG_CTRL_CTR_WIDTH_MASK GENMASK(8, 7) #define AES_REG_CTRL_CTR_WIDTH_32 0 #define AES_REG_CTRL_CTR_WIDTH_64 BIT(7) #define AES_REG_CTRL_CTR_WIDTH_96 BIT(8) #define AES_REG_CTRL_CTR_WIDTH_128 GENMASK(8, 7) +#define AES_REG_CTRL_GCM GENMASK(17, 16) #define AES_REG_CTRL_CTR BIT(6) #define AES_REG_CTRL_CBC BIT(5) #define AES_REG_CTRL_KEY_SIZE GENMASK(4, 3) @@ -43,7 +45,12 @@ #define AES_REG_CTRL_OUTPUT_READY BIT(0) #define AES_REG_CTRL_MASK GENMASK(24, 2) +#define AES_REG_C_LEN_0 0x54 +#define AES_REG_C_LEN_1 0x58 +#define AES_REG_A_LEN 0x5C + #define AES_REG_DATA_N(dd, x) ((dd)->pdata->data_ofs + ((x) * 0x04)) +#define AES_REG_TAG_N(dd, x) (0x70 + ((x) * 0x04)) #define AES_REG_REV(dd) ((dd)->pdata->rev_ofs) @@ -65,30 +72,41 @@ #define DEFAULT_AUTOSUSPEND_DELAY 1000 -#define FLAGS_MODE_MASK 0x000f +#define FLAGS_MODE_MASK 0x001f #define FLAGS_ENCRYPT BIT(0) #define FLAGS_CBC BIT(1) -#define FLAGS_GIV BIT(2) -#define FLAGS_CTR BIT(3) +#define FLAGS_CTR BIT(2) +#define FLAGS_GCM BIT(3) +#define FLAGS_RFC4106_GCM BIT(4) -#define FLAGS_INIT BIT(4) -#define FLAGS_FAST BIT(5) -#define FLAGS_BUSY BIT(6) +#define FLAGS_INIT BIT(5) +#define FLAGS_FAST BIT(6) +#define FLAGS_BUSY BIT(7) #define FLAGS_IN_DATA_ST_SHIFT 8 #define FLAGS_OUT_DATA_ST_SHIFT 10 +#define FLAGS_ASSOC_DATA_ST_SHIFT 12 #define AES_BLOCK_WORDS (AES_BLOCK_SIZE >> 2) +struct omap_aes_gcm_result { + struct completion completion; + int err; +}; + struct omap_aes_ctx { int keylen; u32 key[AES_KEYSIZE_256 / sizeof(u32)]; + u8 nonce[4]; struct crypto_skcipher *fallback; + struct crypto_skcipher *ctr; }; struct omap_aes_reqctx { struct omap_aes_dev *dd; unsigned long mode; + u8 iv[AES_BLOCK_SIZE]; + u32 auth_tag[AES_BLOCK_SIZE / sizeof(u32)]; }; #define OMAP_AES_QUEUE_LENGTH 1 @@ -100,9 +118,16 @@ struct omap_aes_algs_info { unsigned int registered; }; +struct omap_aes_aead_algs { + struct aead_alg *algs_list; + unsigned int size; + unsigned int registered; +}; + struct omap_aes_pdata { struct omap_aes_algs_info *algs_info; unsigned int algs_info_size; + struct omap_aes_aead_algs *aead_algs_info; void (*trigger)(struct omap_aes_dev *dd, int length); @@ -135,8 +160,11 @@ struct omap_aes_dev { int err; struct tasklet_struct done_task; + struct aead_queue aead_queue; + spinlock_t lock; struct ablkcipher_request *req; + struct aead_request *aead_req; struct crypto_engine *engine; /* @@ -145,12 +173,14 @@ struct omap_aes_dev { */ size_t total; size_t total_save; + size_t assoc_len; + size_t authsize; struct scatterlist *in_sg; struct scatterlist *out_sg; /* Buffers for copying for unaligned cases */ - struct scatterlist in_sgl; + struct scatterlist in_sgl[2]; struct scatterlist out_sgl; struct scatterlist *orig_out; @@ -167,8 +197,18 @@ struct omap_aes_dev { u32 omap_aes_read(struct omap_aes_dev *dd, u32 offset); void omap_aes_write(struct omap_aes_dev *dd, u32 offset, u32 value); struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_reqctx *rctx); +int omap_aes_gcm_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen); +int omap_aes_4106gcm_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen); +int omap_aes_gcm_encrypt(struct aead_request *req); +int omap_aes_gcm_decrypt(struct aead_request *req); +int omap_aes_4106gcm_encrypt(struct aead_request *req); +int omap_aes_4106gcm_decrypt(struct aead_request *req); int omap_aes_write_ctrl(struct omap_aes_dev *dd); int omap_aes_crypt_dma_start(struct omap_aes_dev *dd); int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd); +void omap_aes_gcm_dma_out_callback(void *data); +void omap_aes_clear_copy_flags(struct omap_aes_dev *dd); #endif |