crypto: tegra-aes: add support for aes-ofb mode
puneet saxena [Tue, 19 Apr 2011 10:01:40 +0000 (15:01 +0530)]
Bug 787628

Original-Change-Id: I73c3b8f0b3e69f1c4bc13bdaea84b19b14eb73d1
Signed-off-by: Puneet Saxena <puneets@nvidia.com>
Reviewed-on: http://git-master/r/28003
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: Rdf987e66c66135392489bd73ca16429d4d05d636

drivers/crypto/tegra-aes.c
drivers/crypto/tegra-aes.h

index c56d87c..586366f 100644 (file)
 
 #include "tegra-aes.h"
 
-#define FLAGS_MODE_MASK                0x000f
+#define FLAGS_MODE_MASK                0x00ff
 #define FLAGS_ENCRYPT          BIT(0)
-#define FLAGS_CBC              BIT(1)
-#define FLAGS_GIV              BIT(2)
-#define FLAGS_RNG              BIT(3)
-#define FLAGS_NEW_KEY          BIT(4)
-#define FLAGS_NEW_IV           BIT(5)
-#define FLAGS_INIT             BIT(6)
-#define FLAGS_FAST             BIT(7)
-#define FLAGS_BUSY             8
+#define FLAGS_CBC                      BIT(1)
+#define FLAGS_GIV                      BIT(2)
+#define FLAGS_RNG                      BIT(3)
+#define FLAGS_OFB                      BIT(4)
+#define FLAGS_NEW_KEY                  BIT(5)
+#define FLAGS_NEW_IV                   BIT(6)
+#define FLAGS_INIT                     BIT(7)
+#define FLAGS_FAST                     BIT(8)
+#define FLAGS_BUSY                     9
 
 /*
  * Defines AES engine Max process bytes size in one go, which takes 1 msec.
@@ -265,6 +266,7 @@ static int aes_start_crypt(struct tegra_aes_dev *dd, u32 in_addr, u32 out_addr,
        aes_writel(dd, value, CMDQUE_CONTROL);
        dev_dbg(dd->dev, "cmd_q_ctrl=0x%x", value);
 
+       value = 0;
        if (mode & FLAGS_CBC) {
                value = ((0x1 << SECURE_INPUT_ALG_SEL_SHIFT) |
                        ((dd->ctx->keylen * 8) << SECURE_INPUT_KEY_LEN_SHIFT) |
@@ -278,6 +280,17 @@ static int aes_start_crypt(struct tegra_aes_dev *dd, u32 in_addr, u32 out_addr,
                                << SECURE_CORE_SEL_SHIFT |
                        (0 << SECURE_RNG_ENB_SHIFT) |
                        (0 << SECURE_HASH_ENB_SHIFT));
+       } else if (mode & FLAGS_OFB) {
+               value = ((0x1 << SECURE_INPUT_ALG_SEL_SHIFT) |
+                       ((dd->ctx->keylen * 8) << SECURE_INPUT_KEY_LEN_SHIFT) |
+                       ((u32)upd_iv << SECURE_IV_SELECT_SHIFT) |
+                       ((u32)0 << SECURE_IV_SELECT_SHIFT) |
+                       (SECURE_XOR_POS_FIELD) |
+                       (2 << SECURE_INPUT_SEL_SHIFT) |
+                       (0 << SECURE_VCTRAM_SEL_SHIFT) |
+                       (SECURE_CORE_SEL_FIELD) |
+                       (0 << SECURE_RNG_ENB_SHIFT) |
+                       (0 << SECURE_HASH_ENB_SHIFT));
        } else if (mode & FLAGS_RNG){
                value = ((0x1 << SECURE_INPUT_ALG_SEL_SHIFT) |
                        ((dd->ctx->keylen * 8) << SECURE_INPUT_KEY_LEN_SHIFT) |
@@ -497,8 +510,11 @@ static int tegra_aes_handle_req(struct tegra_aes_dev *dd)
                ctx->flags &= ~FLAGS_NEW_KEY;
        }
 
-       if ((dd->flags & FLAGS_CBC) && dd->iv) {
-               /* set iv to the aes hw slot */
+       if (((dd->flags & FLAGS_CBC) || (dd->flags & FLAGS_OFB)) && dd->iv) {
+               /* set iv to the aes hw slot
+                * Hw generates updated iv only after iv is set in slot.
+                * So key and iv is passed asynchronously.
+                */
                memcpy(dd->buf_in, dd->iv, dd->ivlen);
 
                ret = aes_start_crypt(dd, (u32)dd->dma_buf_in,
@@ -678,7 +694,15 @@ static int tegra_aes_cbc_decrypt(struct ablkcipher_request *req)
 {
        return tegra_aes_crypt(req, FLAGS_CBC);
 }
+static int tegra_aes_ofb_encrypt(struct ablkcipher_request *req)
+{
+       return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_OFB);
+}
 
+static int tegra_aes_ofb_decrypt(struct ablkcipher_request *req)
+{
+       return tegra_aes_crypt(req, FLAGS_OFB);
+}
 static int tegra_aes_get_random(struct crypto_rng *tfm, u8 *rdata,
        unsigned int dlen)
 {
@@ -896,6 +920,26 @@ static struct crypto_alg algs[] = {
                        .decrypt = tegra_aes_cbc_decrypt,
                }
        }, {
+               .cra_name = "disabled_ofb(aes)",
+               .cra_driver_name = "ofb-aes-tegra",
+               .cra_priority = 100,
+               .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+               .cra_blocksize = AES_BLOCK_SIZE,
+               .cra_ctxsize  = sizeof(struct tegra_aes_ctx),
+               .cra_alignmask = 3,
+               .cra_type = &crypto_ablkcipher_type,
+               .cra_module = THIS_MODULE,
+               .cra_init = tegra_aes_cra_init,
+               .cra_exit = tegra_aes_cra_exit,
+               .cra_u.ablkcipher = {
+                       .min_keysize = AES_MIN_KEY_SIZE,
+                       .max_keysize = AES_MAX_KEY_SIZE,
+                       .ivsize = AES_MIN_KEY_SIZE,
+                       .setkey = tegra_aes_setkey,
+                       .encrypt = tegra_aes_ofb_encrypt,
+                       .decrypt = tegra_aes_ofb_decrypt,
+               }
+       }, {
                .cra_name = "disabled_ansi_cprng",
                .cra_driver_name = "rng-aes-tegra",
                .cra_priority = 100,
index 83dd6bb..bb311bb 100644 (file)
@@ -71,9 +71,9 @@
 #define CMDQ_CTRL_DST_STM_SEL_SHIFT    5
 #define CMDQ_CTRL_DST_STM_SEL_FIELD    (1 << CMDQ_CTRL_DST_STM_SEL_SHIFT)
 #define CMDQ_CTRL_ICMDQEN_SHIFT                1
-#define CMDQ_CTRL_ICMDQEN_FIELD                (1 << CMDQ_CTRL_SRC_STM_SEL_SHIFT)
+#define CMDQ_CTRL_ICMDQEN_FIELD                (1 << CMDQ_CTRL_ICMDQEN_SHIFT)
 #define CMDQ_CTRL_UCMDQEN_SHIFT                0
-#define CMDQ_CTRL_UCMDQEN_FIELD                (1 << CMDQ_CTRL_DST_STM_SEL_SHIFT)
+#define CMDQ_CTRL_UCMDQEN_FIELD                (1 << CMDQ_CTRL_UCMDQEN_SHIFT)
 
 /* config regsiter masks and shifts */
 #define CONFIG_ENDIAN_ENB_SHIFT                10