OMAP AES hw supports AES-GCM mode.
Adding support for GCM and RFC4106 GCM mode in omap-aes driver.
Signed-off-by: Lokesh Vutla
---
Tested on BeagleBone-Black: http://pastebin.ubuntu.com/12417512/
Changes since v1:
- Addressed comments by Herbert.
Previously posted here:
https://www.mail-archive.com/linux-omap@vger.kernel.org/msg117573.html
drivers/crypto/Kconfig| 1 +
drivers/crypto/Makefile | 3 +-
drivers/crypto/omap-aes-gcm.c | 434 ++
drivers/crypto/omap-aes.c | 335
drivers/crypto/omap-aes.h | 219 +
5 files changed, 818 insertions(+), 174 deletions(-)
create mode 100644 drivers/crypto/omap-aes-gcm.c
create mode 100644 drivers/crypto/omap-aes.h
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index d234719..bc78c91 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -293,6 +293,7 @@ config CRYPTO_DEV_OMAP_AES
depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP2PLUS
select CRYPTO_AES
select CRYPTO_BLKCIPHER
+ select CRYPTO_AEAD
help
OMAP processors have AES module accelerator. Select this if you
want to use the OMAP module for AES algorithms.
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index c3ced6f..d7a3181 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o
obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o
n2_crypto-y := n2_core.o n2_asm.o
obj-$(CONFIG_CRYPTO_DEV_NX) += nx/
-obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
+obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes-driver.o
+omap-aes-driver-objs := omap-aes.o omap-aes-gcm.o
obj-$(CONFIG_CRYPTO_DEV_OMAP_DES) += omap-des.o
obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
new file mode 100644
index 000..8fbab23
--- /dev/null
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -0,0 +1,434 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for OMAP AES GCM HW acceleration.
+ *
+ * Copyright (c) 2015 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "omap-aes.h"
+
+static int omap_aes_gcm_handle_queue(struct omap_aes_dev *dd,
+struct aead_request *req);
+
+static void omap_aes_gcm_finish_req(struct omap_aes_dev *dd, int ret)
+{
+ struct aead_request *req = dd->aead_req;
+
+ dd->flags &= ~FLAGS_BUSY;
+ dd->in_sg = NULL;
+ dd->out_sg = NULL;
+
+ req->base.complete(>base, ret);
+}
+
+static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
+{
+ void *buf;
+ u8 *tag;
+ int pages, alen, clen, i, ret = 0, nsg;
+ struct omap_aes_reqctx *rctx;
+
+ alen = ALIGN(dd->assoc_len, AES_BLOCK_SIZE);
+ clen = ALIGN(dd->total, AES_BLOCK_SIZE);
+ rctx = aead_request_ctx(dd->aead_req);
+
+ nsg = !!(dd->assoc_len && dd->total);
+
+ dma_sync_sg_for_device(dd->dev, dd->out_sg, dd->out_sg_len,
+ DMA_FROM_DEVICE);
+ dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
+ dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, DMA_FROM_DEVICE);
+ omap_aes_crypt_dma_stop(dd);
+
+ if (dd->sgs_copied & AES_OUT_DATA_COPIED) {
+ buf = sg_virt(>out_sgl);
+ scatterwalk_map_and_copy(buf, dd->orig_out,
+dd->aead_req->assoclen, dd->total, 1);
+
+ pages = get_order(clen);
+ free_pages((unsigned long)buf, pages);
+ }
+
+ if (dd->flags & FLAGS_ENCRYPT)
+ scatterwalk_map_and_copy(rctx->auth_tag,
+dd->aead_req->dst,
+dd->total + dd->aead_req->assoclen,
+dd->authsize, 1);
+
+ if (dd->sgs_copied & AES_ASSOC_DATA_COPIED) {
+ buf = sg_virt(>in_sgl[0]);
+ pages = get_order(alen);
+ free_pages((unsigned long)buf, pages);
+ }
+ if (dd->sgs_copied & AES_IN_DATA_COPIED) {
+ buf = sg_virt(>in_sgl[nsg]);
+ pages = get_order(clen);
+ free_pages((unsigned long)buf, pages);
+ }
+
+ if (!(dd->flags & FLAGS_ENCRYPT)) {
+ tag = (u8 *)rctx->auth_tag;
+ for (i = 0; i < dd->authsize; i++) {
+ if (tag[i]) {
+ dev_err(dd->dev, "GCM decryption: Tag Message
is