diff options
Diffstat (limited to 'drivers/crypto/omap-aes.c')
| -rw-r--r-- | drivers/crypto/omap-aes.c | 86 | 
1 files changed, 41 insertions, 45 deletions
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 9a28b7e07c71..eba23147c0ee 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -52,29 +52,30 @@  #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_CTR_WIDTH_MASK	(3 << 7) -#define AES_REG_CTRL_CTR_WIDTH_32		(0 << 7) -#define AES_REG_CTRL_CTR_WIDTH_64		(1 << 7) -#define AES_REG_CTRL_CTR_WIDTH_96		(2 << 7) -#define AES_REG_CTRL_CTR_WIDTH_128		(3 << 7) -#define AES_REG_CTRL_CTR		(1 << 6) -#define AES_REG_CTRL_CBC		(1 << 5) -#define AES_REG_CTRL_KEY_SIZE		(3 << 3) -#define AES_REG_CTRL_DIRECTION		(1 << 2) -#define AES_REG_CTRL_INPUT_READY	(1 << 1) -#define AES_REG_CTRL_OUTPUT_READY	(1 << 0) +#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_CTR		BIT(6) +#define AES_REG_CTRL_CBC		BIT(5) +#define AES_REG_CTRL_KEY_SIZE		GENMASK(4, 3) +#define AES_REG_CTRL_DIRECTION		BIT(2) +#define AES_REG_CTRL_INPUT_READY	BIT(1) +#define AES_REG_CTRL_OUTPUT_READY	BIT(0) +#define AES_REG_CTRL_MASK		GENMASK(24, 2)  #define AES_REG_DATA_N(dd, x)		((dd)->pdata->data_ofs + ((x) * 0x04))  #define AES_REG_REV(dd)			((dd)->pdata->rev_ofs)  #define AES_REG_MASK(dd)		((dd)->pdata->mask_ofs) -#define AES_REG_MASK_SIDLE		(1 << 6) -#define AES_REG_MASK_START		(1 << 5) -#define AES_REG_MASK_DMA_OUT_EN		(1 << 3) -#define AES_REG_MASK_DMA_IN_EN		(1 << 2) -#define AES_REG_MASK_SOFTRESET		(1 << 1) -#define AES_REG_AUTOIDLE		(1 << 0) +#define AES_REG_MASK_SIDLE		BIT(6) +#define AES_REG_MASK_START		BIT(5) +#define AES_REG_MASK_DMA_OUT_EN		BIT(3) +#define AES_REG_MASK_DMA_IN_EN		BIT(2) +#define AES_REG_MASK_SOFTRESET		BIT(1) +#define AES_REG_AUTOIDLE		BIT(0)  #define AES_REG_LENGTH_N(x)		(0x54 + ((x) * 0x04)) @@ -254,7 +255,7 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)  {  	unsigned int key32;  	int i, err; -	u32 val, mask = 0; +	u32 val;  	err = omap_aes_hw_init(dd);  	if (err) @@ -274,17 +275,13 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)  	val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);  	if (dd->flags & FLAGS_CBC)  		val |= AES_REG_CTRL_CBC; -	if (dd->flags & FLAGS_CTR) { +	if (dd->flags & FLAGS_CTR)  		val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128; -		mask = AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_MASK; -	} +  	if (dd->flags & FLAGS_ENCRYPT)  		val |= AES_REG_CTRL_DIRECTION; -	mask |= AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION | -			AES_REG_CTRL_KEY_SIZE; - -	omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, mask); +	omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, AES_REG_CTRL_MASK);  	return 0;  } @@ -558,6 +555,9 @@ static int omap_aes_check_aligned(struct scatterlist *sg, int total)  {  	int len = 0; +	if (!IS_ALIGNED(total, AES_BLOCK_SIZE)) +		return -EINVAL; +  	while (sg) {  		if (!IS_ALIGNED(sg->offset, 4))  			return -1; @@ -577,9 +577,10 @@ static int omap_aes_check_aligned(struct scatterlist *sg, int total)  static int omap_aes_copy_sgs(struct omap_aes_dev *dd)  {  	void *buf_in, *buf_out; -	int pages; +	int pages, total; -	pages = get_order(dd->total); +	total = ALIGN(dd->total, AES_BLOCK_SIZE); +	pages = get_order(total);  	buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);  	buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); @@ -594,11 +595,11 @@ static int omap_aes_copy_sgs(struct omap_aes_dev *dd)  	sg_copy_buf(buf_in, dd->in_sg, 0, dd->total, 0);  	sg_init_table(&dd->in_sgl, 1); -	sg_set_buf(&dd->in_sgl, buf_in, dd->total); +	sg_set_buf(&dd->in_sgl, buf_in, total);  	dd->in_sg = &dd->in_sgl;  	sg_init_table(&dd->out_sgl, 1); -	sg_set_buf(&dd->out_sgl, buf_out, dd->total); +	sg_set_buf(&dd->out_sgl, buf_out, total);  	dd->out_sg = &dd->out_sgl;  	return 0; @@ -611,7 +612,7 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,  	struct omap_aes_ctx *ctx;  	struct omap_aes_reqctx *rctx;  	unsigned long flags; -	int err, ret = 0; +	int err, ret = 0, len;  	spin_lock_irqsave(&dd->lock, flags);  	if (req) @@ -650,8 +651,9 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,  		dd->sgs_copied = 0;  	} -	dd->in_sg_len = scatterwalk_bytes_sglen(dd->in_sg, dd->total); -	dd->out_sg_len = scatterwalk_bytes_sglen(dd->out_sg, dd->total); +	len = ALIGN(dd->total, AES_BLOCK_SIZE); +	dd->in_sg_len = scatterwalk_bytes_sglen(dd->in_sg, len); +	dd->out_sg_len = scatterwalk_bytes_sglen(dd->out_sg, len);  	BUG_ON(dd->in_sg_len < 0 || dd->out_sg_len < 0);  	rctx = ablkcipher_request_ctx(req); @@ -678,7 +680,7 @@ static void omap_aes_done_task(unsigned long data)  {  	struct omap_aes_dev *dd = (struct omap_aes_dev *)data;  	void *buf_in, *buf_out; -	int pages; +	int pages, len;  	pr_debug("enter done_task\n"); @@ -697,7 +699,8 @@ static void omap_aes_done_task(unsigned long data)  		sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1); -		pages = get_order(dd->total_save); +		len = ALIGN(dd->total_save, AES_BLOCK_SIZE); +		pages = get_order(len);  		free_pages((unsigned long)buf_in, pages);  		free_pages((unsigned long)buf_out, pages);  	} @@ -726,11 +729,6 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)  		  !!(mode & FLAGS_ENCRYPT),  		  !!(mode & FLAGS_CBC)); -	if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { -		pr_err("request size is not exact amount of AES blocks\n"); -		return -EINVAL; -	} -  	dd = omap_aes_find_dev(ctx);  	if (!dd)  		return -ENODEV; @@ -833,7 +831,7 @@ static struct crypto_alg algs_ecb_cbc[] = {  {  	.cra_name		= "ecb(aes)",  	.cra_driver_name	= "ecb-aes-omap", -	.cra_priority		= 100, +	.cra_priority		= 300,  	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |  				  CRYPTO_ALG_KERN_DRIVER_ONLY |  				  CRYPTO_ALG_ASYNC, @@ -855,7 +853,7 @@ static struct crypto_alg algs_ecb_cbc[] = {  {  	.cra_name		= "cbc(aes)",  	.cra_driver_name	= "cbc-aes-omap", -	.cra_priority		= 100, +	.cra_priority		= 300,  	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |  				  CRYPTO_ALG_KERN_DRIVER_ONLY |  				  CRYPTO_ALG_ASYNC, @@ -881,7 +879,7 @@ static struct crypto_alg algs_ctr[] = {  {  	.cra_name		= "ctr(aes)",  	.cra_driver_name	= "ctr-aes-omap", -	.cra_priority		= 100, +	.cra_priority		= 300,  	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |  				  CRYPTO_ALG_KERN_DRIVER_ONLY |  				  CRYPTO_ALG_ASYNC, @@ -1046,9 +1044,7 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id)  			}  		} -		dd->total -= AES_BLOCK_SIZE; - -		BUG_ON(dd->total < 0); +		dd->total -= min_t(size_t, AES_BLOCK_SIZE, dd->total);  		/* Clear IRQ status */  		status &= ~AES_REG_IRQ_DATA_OUT;  |