[PATCH 09/10] crypto: omap-aes: gcm: Add support for PIO mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support for PIO mode for GCM mode.

Signed-off-by: Lokesh Vutla <lokeshvutla@xxxxxx>
---
 drivers/crypto/omap-aes-gcm.c |   10 ++++++----
 drivers/crypto/omap-aes.c     |   24 ++++++++++++++++++------
 drivers/crypto/omap-aes.h     |    3 ++-
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
index 9c68ff0..370891b 100644
--- a/drivers/crypto/omap-aes-gcm.c
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -52,8 +52,8 @@ static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
 	u8 *tag;
 	int pages, alen, clen, i, ret = 0, nsg;
 
-	alen = ALIGN(dd->assoc_len, AES_BLOCK_SIZE);
-	clen = ALIGN(dd->total, AES_BLOCK_SIZE);
+	alen = ALIGN(dd->assoc_len_save, AES_BLOCK_SIZE);
+	clen = ALIGN(dd->total_save, AES_BLOCK_SIZE);
 
 	nsg = 1 + !!(dd->assoc_len && dd->total);
 
@@ -161,7 +161,9 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,
 
 	dd->in_sg = dd->in_sgl;
 	dd->total = cryptlen;
+	dd->total_save = cryptlen;
 	dd->assoc_len = req->assoclen;
+	dd->assoc_len_save = req->assoclen;
 	dd->authsize = authlen;
 
 	if (omap_aes_check_aligned(req->dst, cryptlen)) {
@@ -248,14 +250,14 @@ static int do_encrypt_iv(struct aead_request *req, u32 *tag)
 	return ret;
 }
 
-void omap_aes_gcm_dma_out_callback(void *data)
+void omap_aes_gcm_process_auth_tag(void *data)
 {
 	struct omap_aes_dev *dd = data;
 	int i, val;
 	u32 *auth_tag, tag[4];
 
 	if (!(dd->flags & FLAGS_ENCRYPT))
-		scatterwalk_map_and_copy(tag, dd->aead_req->src, dd->total,
+		scatterwalk_map_and_copy(tag, dd->aead_req->src, dd->total_save,
 					 dd->authsize, 0);
 
 	auth_tag = dd->ctx->auth_tag;
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 11f3850..8aeb913 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -340,7 +340,7 @@ static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
 	}
 
 	if (dd->flags & FLAGS_GCM)
-		tx_out->callback = omap_aes_gcm_dma_out_callback;
+		tx_out->callback = omap_aes_gcm_process_auth_tag;
 	else
 		tx_out->callback = omap_aes_dma_out_callback;
 	tx_out->callback_param = dd;
@@ -927,8 +927,15 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id)
 		status &= ~AES_REG_IRQ_DATA_IN;
 		omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
 
-		/* Enable DATA_OUT interrupt */
-		omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4);
+		/*
+		 * if GCM mode enable DATA_IN till assoc data is copied
+		 * else Enable DATA_OUT interrupt
+		 * */
+		if ((dd->flags & FLAGS_GCM) && dd->assoc_len)
+			dd->assoc_len -= min((size_t)AES_BLOCK_SIZE,
+					     dd->assoc_len);
+		else
+			omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4);
 
 	} else if (status & AES_REG_IRQ_DATA_OUT) {
 		omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x0);
@@ -961,12 +968,17 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id)
 		status &= ~AES_REG_IRQ_DATA_OUT;
 		omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
 
-		if (!dd->total)
+		if (!dd->total) {
 			/* All bytes read! */
-			tasklet_schedule(&dd->done_task);
-		else
+			if (dd->flags & FLAGS_GCM)
+				/* Process auth tag and call done_task */
+				omap_aes_gcm_process_auth_tag(dd);
+			else
+				tasklet_schedule(&dd->done_task);
+		} else {
 			/* Enable DATA_IN interrupt for next block */
 			omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x2);
+		}
 	}
 
 	return IRQ_HANDLED;
diff --git a/drivers/crypto/omap-aes.h b/drivers/crypto/omap-aes.h
index 0863874..e0621dd 100644
--- a/drivers/crypto/omap-aes.h
+++ b/drivers/crypto/omap-aes.h
@@ -164,6 +164,7 @@ struct omap_aes_dev {
 	size_t				total;
 	size_t				total_save;
 	size_t				assoc_len;
+	size_t				assoc_len_save;
 	size_t				authsize;
 
 	struct scatterlist		*in_sg;
@@ -199,7 +200,7 @@ int omap_aes_gcm_decrypt(struct aead_request *req);
 int omap_aes_write_ctrl(struct omap_aes_dev *dd);
 int omap_aes_check_aligned(struct scatterlist *sg, int total);
 int omap_aes_crypt_dma_start(struct omap_aes_dev *dd);
-void omap_aes_gcm_dma_out_callback(void *data);
+void omap_aes_gcm_process_auth_tag(void *data);
 int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd);
 
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux