apm821xx: backport accepted linux-crypto patches to 4.19
authorChristian Lamparter <chunkeey@gmail.com>
Fri, 31 May 2019 18:13:55 +0000 (20:13 +0200)
committerChristian Lamparter <chunkeey@gmail.com>
Sun, 2 Jun 2019 09:08:38 +0000 (11:08 +0200)
This patch brings the crypto4xx driver up to the latest
upstream changes.

Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
target/linux/apm821xx/patches-4.19/023-0003-crypto-drop-mask-CRYPTO_ALG_ASYNC-from-cipher-tfm-al.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0004-crypto4xx_core-don-t-abuse-__dma_sync_page.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0005-cross-tree-phase-out-dma_zalloc_coherent.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0007-crypto-crypto4xx-Fix-wrong-ppc4xx_trng_probe-ppc4xx_.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0012-crypto-crypto4xx-get-rid-of-redundant-using_sd-varia.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0013-crypto-crypto4xx-fix-AES-CTR-blocksize-value.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0014-crypto-crypto4xx-fix-blocksize-for-cfb-and-ofb.patch [new file with mode: 0644]
target/linux/apm821xx/patches-4.19/023-0015-crypto-crypto4xx-block-ciphers-should-only-accept-co.patch [new file with mode: 0644]

diff --git a/target/linux/apm821xx/patches-4.19/023-0003-crypto-drop-mask-CRYPTO_ALG_ASYNC-from-cipher-tfm-al.patch b/target/linux/apm821xx/patches-4.19/023-0003-crypto-drop-mask-CRYPTO_ALG_ASYNC-from-cipher-tfm-al.patch
new file mode 100644 (file)
index 0000000..bb1f406
--- /dev/null
@@ -0,0 +1,34 @@
+From 1ad0f1603a6b2afb62a1c065409aaa4e43ca7627 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 14 Nov 2018 12:19:39 -0800
+Subject: [PATCH 03/15] crypto: drop mask=CRYPTO_ALG_ASYNC from 'cipher' tfm
+ allocations
+
+'cipher' algorithms (single block ciphers) are always synchronous, so
+passing CRYPTO_ALG_ASYNC in the mask to crypto_alloc_cipher() has no
+effect.  Many users therefore already don't pass it, but some still do.
+This inconsistency can cause confusion, especially since the way the
+'mask' argument works is somewhat counterintuitive.
+
+Thus, just remove the unneeded CRYPTO_ALG_ASYNC flags.
+
+This patch shouldn't change any actual behavior.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_alg.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_alg.c
++++ b/drivers/crypto/amcc/crypto4xx_alg.c
+@@ -526,8 +526,7 @@ static int crypto4xx_compute_gcm_hash_ke
+       uint8_t src[16] = { 0 };
+       int rc = 0;
+-      aes_tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC |
+-                                    CRYPTO_ALG_NEED_FALLBACK);
++      aes_tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_NEED_FALLBACK);
+       if (IS_ERR(aes_tfm)) {
+               rc = PTR_ERR(aes_tfm);
+               pr_warn("could not load aes cipher driver: %d\n", rc);
diff --git a/target/linux/apm821xx/patches-4.19/023-0004-crypto4xx_core-don-t-abuse-__dma_sync_page.patch b/target/linux/apm821xx/patches-4.19/023-0004-crypto4xx_core-don-t-abuse-__dma_sync_page.patch
new file mode 100644 (file)
index 0000000..635ab00
--- /dev/null
@@ -0,0 +1,30 @@
+From 67d8208fba1324fa0198f9fc58a9edbe09596947 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Sun, 16 Dec 2018 18:19:46 +0100
+Subject: [PATCH 04/15] crypto4xx_core: don't abuse __dma_sync_page
+
+This function is internal to the DMA API implementation. Instead use
+the DMA API to properly unmap. Note that the DMA API usage in this
+driver is a disaster and urgently needs some work - it is missing all
+the unmaps, seems to do a secondary map where it looks like it should
+to a unmap in one place to work around cache coherency and the
+directions passed in seem to be partially wrong.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Tested-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+---
+ drivers/crypto/amcc/crypto4xx_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -596,7 +596,7 @@ static void crypto4xx_aead_done(struct c
+                                         pd->pd_ctl_len.bf.pkt_len,
+                                         dst);
+       } else {
+-              __dma_sync_page(sg_page(dst), dst->offset, dst->length,
++              dma_unmap_page(dev->core_dev->device, pd->dest, dst->length,
+                               DMA_FROM_DEVICE);
+       }
diff --git a/target/linux/apm821xx/patches-4.19/023-0005-cross-tree-phase-out-dma_zalloc_coherent.patch b/target/linux/apm821xx/patches-4.19/023-0005-cross-tree-phase-out-dma_zalloc_coherent.patch
new file mode 100644 (file)
index 0000000..857578b
--- /dev/null
@@ -0,0 +1,40 @@
+From 750afb08ca71310fcf0c4e2cb1565c63b8235b60 Mon Sep 17 00:00:00 2001
+From: Luis Chamberlain <mcgrof@kernel.org>
+Date: Fri, 4 Jan 2019 09:23:09 +0100
+Subject: [PATCH 05/15] cross-tree: phase out dma_zalloc_coherent()
+
+We already need to zero out memory for dma_alloc_coherent(), as such
+using dma_zalloc_coherent() is superflous. Phase it out.
+
+This change was generated with the following Coccinelle SmPL patch:
+
+@ replace_dma_zalloc_coherent @
+expression dev, size, data, handle, flags;
+@@
+
+-dma_zalloc_coherent(dev, size, handle, flags)
++dma_alloc_coherent(dev, size, handle, flags)
+
+Suggested-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
+[hch: re-ran the script on the latest tree]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ drivers/crypto/amcc/crypto4xx_core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -283,9 +283,9 @@ static u32 crypto4xx_put_pd_to_pdr(struc
+  */
+ static u32 crypto4xx_build_gdr(struct crypto4xx_device *dev)
+ {
+-      dev->gdr = dma_zalloc_coherent(dev->core_dev->device,
+-                                     sizeof(struct ce_gd) * PPC4XX_NUM_GD,
+-                                     &dev->gdr_pa, GFP_ATOMIC);
++      dev->gdr = dma_alloc_coherent(dev->core_dev->device,
++                                    sizeof(struct ce_gd) * PPC4XX_NUM_GD,
++                                    &dev->gdr_pa, GFP_ATOMIC);
+       if (!dev->gdr)
+               return -ENOMEM;
diff --git a/target/linux/apm821xx/patches-4.19/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch b/target/linux/apm821xx/patches-4.19/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch
new file mode 100644 (file)
index 0000000..ba44197
--- /dev/null
@@ -0,0 +1,199 @@
+From d072bfa4885354fff86aa1fb1dbc4f1533c9e0bf Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Sun, 23 Dec 2018 02:16:13 +0100
+Subject: [PATCH 06/15] crypto: crypto4xx - add prng crypto support
+
+This patch adds support for crypto4xx's ANSI X9.17 Annex C compliant
+pseudo random number generator which provides a pseudo random source
+for the purpose of generating  Initialization Vectors (IV's) for AES
+algorithms to the Packet Engine and other pseudo random number
+requirements.
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_core.c    | 87 +++++++++++++++++++++++++
+ drivers/crypto/amcc/crypto4xx_core.h    |  4 ++
+ drivers/crypto/amcc/crypto4xx_reg_def.h |  1 +
+ 3 files changed, 92 insertions(+)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -40,9 +40,11 @@
+ #include <crypto/ctr.h>
+ #include <crypto/gcm.h>
+ #include <crypto/sha.h>
++#include <crypto/rng.h>
+ #include <crypto/scatterwalk.h>
+ #include <crypto/skcipher.h>
+ #include <crypto/internal/aead.h>
++#include <crypto/internal/rng.h>
+ #include <crypto/internal/skcipher.h>
+ #include "crypto4xx_reg_def.h"
+ #include "crypto4xx_core.h"
+@@ -1046,6 +1048,10 @@ static int crypto4xx_register_alg(struct
+                       rc = crypto_register_ahash(&alg->alg.u.hash);
+                       break;
++              case CRYPTO_ALG_TYPE_RNG:
++                      rc = crypto_register_rng(&alg->alg.u.rng);
++                      break;
++
+               default:
+                       rc = crypto_register_skcipher(&alg->alg.u.cipher);
+                       break;
+@@ -1075,6 +1081,10 @@ static void crypto4xx_unregister_alg(str
+                       crypto_unregister_aead(&alg->alg.u.aead);
+                       break;
++              case CRYPTO_ALG_TYPE_RNG:
++                      crypto_unregister_rng(&alg->alg.u.rng);
++                      break;
++
+               default:
+                       crypto_unregister_skcipher(&alg->alg.u.cipher);
+               }
+@@ -1133,6 +1143,69 @@ static irqreturn_t crypto4xx_ce_interrup
+               PPC4XX_TMO_ERR_INT);
+ }
++static int ppc4xx_prng_data_read(struct crypto4xx_device *dev,
++                               u8 *data, unsigned int max)
++{
++      unsigned int i, curr = 0;
++      u32 val[2];
++
++      do {
++              /* trigger PRN generation */
++              writel(PPC4XX_PRNG_CTRL_AUTO_EN,
++                     dev->ce_base + CRYPTO4XX_PRNG_CTRL);
++
++              for (i = 0; i < 1024; i++) {
++                      /* usually 19 iterations are enough */
++                      if ((readl(dev->ce_base + CRYPTO4XX_PRNG_STAT) &
++                           CRYPTO4XX_PRNG_STAT_BUSY))
++                              continue;
++
++                      val[0] = readl_be(dev->ce_base + CRYPTO4XX_PRNG_RES_0);
++                      val[1] = readl_be(dev->ce_base + CRYPTO4XX_PRNG_RES_1);
++                      break;
++              }
++              if (i == 1024)
++                      return -ETIMEDOUT;
++
++              if ((max - curr) >= 8) {
++                      memcpy(data, &val, 8);
++                      data += 8;
++                      curr += 8;
++              } else {
++                      /* copy only remaining bytes */
++                      memcpy(data, &val, max - curr);
++                      break;
++              }
++      } while (curr < max);
++
++      return curr;
++}
++
++static int crypto4xx_prng_generate(struct crypto_rng *tfm,
++                                 const u8 *src, unsigned int slen,
++                                 u8 *dstn, unsigned int dlen)
++{
++      struct rng_alg *alg = crypto_rng_alg(tfm);
++      struct crypto4xx_alg *amcc_alg;
++      struct crypto4xx_device *dev;
++      int ret;
++
++      amcc_alg = container_of(alg, struct crypto4xx_alg, alg.u.rng);
++      dev = amcc_alg->dev;
++
++      mutex_lock(&dev->core_dev->rng_lock);
++      ret = ppc4xx_prng_data_read(dev, dstn, dlen);
++      mutex_unlock(&dev->core_dev->rng_lock);
++      return ret;
++}
++
++
++static int crypto4xx_prng_seed(struct crypto_rng *tfm, const u8 *seed,
++                      unsigned int slen)
++{
++      return 0;
++}
++
+ /**
+  * Supported Crypto Algorithms
+  */
+@@ -1302,6 +1375,18 @@ static struct crypto4xx_alg_common crypt
+                       .cra_module     = THIS_MODULE,
+               },
+       } },
++      { .type = CRYPTO_ALG_TYPE_RNG, .u.rng = {
++              .base = {
++                      .cra_name               = "stdrng",
++                      .cra_driver_name        = "crypto4xx_rng",
++                      .cra_priority           = 300,
++                      .cra_ctxsize            = 0,
++                      .cra_module             = THIS_MODULE,
++              },
++              .generate               = crypto4xx_prng_generate,
++              .seed                   = crypto4xx_prng_seed,
++              .seedsize               = 0,
++      } },
+ };
+ /**
+@@ -1371,6 +1456,7 @@ static int crypto4xx_probe(struct platfo
+       core_dev->dev->core_dev = core_dev;
+       core_dev->dev->is_revb = is_revb;
+       core_dev->device = dev;
++      mutex_init(&core_dev->rng_lock);
+       spin_lock_init(&core_dev->lock);
+       INIT_LIST_HEAD(&core_dev->dev->alg_list);
+       ratelimit_default_init(&core_dev->dev->aead_ratelimit);
+@@ -1450,6 +1536,7 @@ static int crypto4xx_remove(struct platf
+       tasklet_kill(&core_dev->tasklet);
+       /* Un-register with Linux CryptoAPI */
+       crypto4xx_unregister_alg(core_dev->dev);
++      mutex_destroy(&core_dev->rng_lock);
+       /* Free all allocated memory */
+       crypto4xx_stop_all(core_dev);
+--- a/drivers/crypto/amcc/crypto4xx_core.h
++++ b/drivers/crypto/amcc/crypto4xx_core.h
+@@ -23,8 +23,10 @@
+ #define __CRYPTO4XX_CORE_H__
+ #include <linux/ratelimit.h>
++#include <linux/mutex.h>
+ #include <crypto/internal/hash.h>
+ #include <crypto/internal/aead.h>
++#include <crypto/internal/rng.h>
+ #include <crypto/internal/skcipher.h>
+ #include "crypto4xx_reg_def.h"
+ #include "crypto4xx_sa.h"
+@@ -119,6 +121,7 @@ struct crypto4xx_core_device {
+       u32 irq;
+       struct tasklet_struct tasklet;
+       spinlock_t lock;
++      struct mutex rng_lock;
+ };
+ struct crypto4xx_ctx {
+@@ -143,6 +146,7 @@ struct crypto4xx_alg_common {
+               struct skcipher_alg cipher;
+               struct ahash_alg hash;
+               struct aead_alg aead;
++              struct rng_alg rng;
+       } u;
+ };
+--- a/drivers/crypto/amcc/crypto4xx_reg_def.h
++++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
+@@ -100,6 +100,7 @@
+ #define CRYPTO4XX_ENDIAN_CFG                  0x000600d8
+ #define CRYPTO4XX_PRNG_STAT                   0x00070000
++#define CRYPTO4XX_PRNG_STAT_BUSY              0x1
+ #define CRYPTO4XX_PRNG_CTRL                   0x00070004
+ #define CRYPTO4XX_PRNG_SEED_L                 0x00070008
+ #define CRYPTO4XX_PRNG_SEED_H                 0x0007000c
diff --git a/target/linux/apm821xx/patches-4.19/023-0007-crypto-crypto4xx-Fix-wrong-ppc4xx_trng_probe-ppc4xx_.patch b/target/linux/apm821xx/patches-4.19/023-0007-crypto-crypto4xx-Fix-wrong-ppc4xx_trng_probe-ppc4xx_.patch
new file mode 100644 (file)
index 0000000..d2c3848
--- /dev/null
@@ -0,0 +1,39 @@
+From 6e88098ca43a3d80ae86908f7badba683c8a0d84 Mon Sep 17 00:00:00 2001
+From: Corentin Labbe <clabbe@baylibre.com>
+Date: Wed, 23 Jan 2019 11:24:18 +0000
+Subject: [PATCH 07/15] crypto: crypto4xx - Fix wrong
+ ppc4xx_trng_probe()/ppc4xx_trng_remove() arguments
+
+When building without CONFIG_HW_RANDOM_PPC4XX, I hit the following build failure:
+drivers/crypto/amcc/crypto4xx_core.c: In function 'crypto4xx_probe':
+drivers/crypto/amcc/crypto4xx_core.c:1407:20: error: passing argument 1 of 'ppc4xx_trng_probe' from incompatible pointer type [-Werror=incompatible-pointer-types]
+In file included from drivers/crypto/amcc/crypto4xx_core.c:50:0:
+drivers/crypto/amcc/crypto4xx_trng.h:28:20: note: expected 'struct crypto4xx_device *' but argument is of type 'struct crypto4xx_core_device *'
+drivers/crypto/amcc/crypto4xx_core.c: In function 'crypto4xx_remove':
+drivers/crypto/amcc/crypto4xx_core.c:1434:21: error: passing argument 1 of 'ppc4xx_trng_remove' from incompatible pointer type [-Werror=incompatible-pointer-types]
+In file included from drivers/crypto/amcc/crypto4xx_core.c:50:0:
+drivers/crypto/amcc/crypto4xx_trng.h:30:20: note: expected 'struct crypto4xx_device *' but argument is of type 'struct crypto4xx_core_device *'
+
+This patch fix the needed argument of ppc4xx_trng_probe()/ppc4xx_trng_remove() in that case.
+
+Fixes: 5343e674f32f ("crypto4xx: integrate ppc4xx-rng into crypto4xx")
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_trng.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_trng.h
++++ b/drivers/crypto/amcc/crypto4xx_trng.h
+@@ -26,9 +26,9 @@ void ppc4xx_trng_probe(struct crypto4xx_
+ void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev);
+ #else
+ static inline void ppc4xx_trng_probe(
+-      struct crypto4xx_device *dev __maybe_unused) { }
++      struct crypto4xx_core_device *dev __maybe_unused) { }
+ static inline void ppc4xx_trng_remove(
+-      struct crypto4xx_device *dev __maybe_unused) { }
++      struct crypto4xx_core_device *dev __maybe_unused) { }
+ #endif
+ #endif
diff --git a/target/linux/apm821xx/patches-4.19/023-0012-crypto-crypto4xx-get-rid-of-redundant-using_sd-varia.patch b/target/linux/apm821xx/patches-4.19/023-0012-crypto-crypto4xx-get-rid-of-redundant-using_sd-varia.patch
new file mode 100644 (file)
index 0000000..4b246a7
--- /dev/null
@@ -0,0 +1,63 @@
+From 38cf5533d7a876f75088bacc1277046f30005f28 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Mon, 22 Apr 2019 13:26:01 +0200
+Subject: [PATCH 12/15] crypto: crypto4xx - get rid of redundant using_sd
+ variable
+
+using_sd is used as a stand-in for sa_command_0.bf.scatter
+that we need to set anyway, so we might as well just prevent
+double-accounting.
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_core.c | 6 ++----
+ drivers/crypto/amcc/crypto4xx_core.h | 1 -
+ 2 files changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -539,7 +539,7 @@ static void crypto4xx_cipher_done(struct
+       req = skcipher_request_cast(pd_uinfo->async_req);
+-      if (pd_uinfo->using_sd) {
++      if (pd_uinfo->sa_va->sa_command_0.bf.scatter) {
+               crypto4xx_copy_pkt_to_dst(dev, pd, pd_uinfo,
+                                         req->cryptlen, req->dst);
+       } else {
+@@ -593,7 +593,7 @@ static void crypto4xx_aead_done(struct c
+       u32 icv[AES_BLOCK_SIZE];
+       int err = 0;
+-      if (pd_uinfo->using_sd) {
++      if (pd_uinfo->sa_va->sa_command_0.bf.scatter) {
+               crypto4xx_copy_pkt_to_dst(dev, pd, pd_uinfo,
+                                         pd->pd_ctl_len.bf.pkt_len,
+                                         dst);
+@@ -887,7 +887,6 @@ int crypto4xx_build_pd(struct crypto_asy
+                * we know application give us dst a whole piece of memory
+                * no need to use scatter ring.
+                */
+-              pd_uinfo->using_sd = 0;
+               pd_uinfo->first_sd = 0xffffffff;
+               sa->sa_command_0.bf.scatter = 0;
+               pd->dest = (u32)dma_map_page(dev->core_dev->device,
+@@ -901,7 +900,6 @@ int crypto4xx_build_pd(struct crypto_asy
+               u32 sd_idx = fst_sd;
+               nbytes = datalen;
+               sa->sa_command_0.bf.scatter = 1;
+-              pd_uinfo->using_sd = 1;
+               pd_uinfo->first_sd = fst_sd;
+               sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx);
+               pd->dest = sd_dma;
+--- a/drivers/crypto/amcc/crypto4xx_core.h
++++ b/drivers/crypto/amcc/crypto4xx_core.h
+@@ -64,7 +64,6 @@ union shadow_sa_buf {
+ struct pd_uinfo {
+       struct crypto4xx_device *dev;
+       u32   state;
+-      u32 using_sd;
+       u32 first_gd;           /* first gather discriptor
+                               used by this packet */
+       u32 num_gd;             /* number of gather discriptor
diff --git a/target/linux/apm821xx/patches-4.19/023-0013-crypto-crypto4xx-fix-AES-CTR-blocksize-value.patch b/target/linux/apm821xx/patches-4.19/023-0013-crypto-crypto4xx-fix-AES-CTR-blocksize-value.patch
new file mode 100644 (file)
index 0000000..a6fa84d
--- /dev/null
@@ -0,0 +1,60 @@
+From bfa2ba7d9e6b20aca82b99e6842fe18842ae3a0f Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Fri, 17 May 2019 23:15:57 +0200
+Subject: [PATCH 13/15] crypto: crypto4xx - fix AES CTR blocksize value
+
+This patch fixes a issue with crypto4xx's ctr(aes) that was
+discovered by libcapi's kcapi-enc-test.sh test.
+
+The some of the ctr(aes) encryptions test were failing on the
+non-power-of-two test:
+
+kcapi-enc - Error: encryption failed with error 0
+kcapi-enc - Error: decryption failed with error 0
+[FAILED: 32-bit - 5.1.0-rc1+] 15 bytes: STDIN / STDOUT enc test (128 bits):
+original file (1d100e..cc96184c) and generated file (e3b0c442..1b7852b855)
+[FAILED: 32-bit - 5.1.0-rc1+] 15 bytes: STDIN / STDOUT enc test (128 bits)
+(openssl generated CT): original file (e3b0..5) and generated file (3..8e)
+[PASSED: 32-bit - 5.1.0-rc1+] 15 bytes: STDIN / STDOUT enc test (128 bits)
+(openssl generated PT)
+[FAILED: 32-bit - 5.1.0-rc1+] 15 bytes: STDIN / STDOUT enc test (password):
+original file (1d1..84c) and generated file (e3b..852b855)
+
+But the 16, 32, 512, 65536 tests always worked.
+
+Thankfully, this isn't a hidden hardware problem like previously,
+instead this turned out to be a copy and paste issue.
+
+With this patch, all the tests are passing with and
+kcapi-enc-test.sh gives crypto4xx's a clean bill of health:
+ "Number of failures: 0" :).
+
+Cc: stable@vger.kernel.org
+Fixes: 98e87e3d933b ("crypto: crypto4xx - add aes-ctr support")
+Fixes: f2a13e7cba9e ("crypto: crypto4xx - enable AES RFC3686, ECB, CFB and OFB offloads")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -1257,7 +1257,7 @@ static struct crypto4xx_alg_common crypt
+                       .cra_flags = CRYPTO_ALG_NEED_FALLBACK |
+                               CRYPTO_ALG_ASYNC |
+                               CRYPTO_ALG_KERN_DRIVER_ONLY,
+-                      .cra_blocksize = AES_BLOCK_SIZE,
++                      .cra_blocksize = 1,
+                       .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+                       .cra_module = THIS_MODULE,
+               },
+@@ -1277,7 +1277,7 @@ static struct crypto4xx_alg_common crypt
+                       .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
+                       .cra_flags = CRYPTO_ALG_ASYNC |
+                               CRYPTO_ALG_KERN_DRIVER_ONLY,
+-                      .cra_blocksize = AES_BLOCK_SIZE,
++                      .cra_blocksize = 1,
+                       .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+                       .cra_module = THIS_MODULE,
+               },
diff --git a/target/linux/apm821xx/patches-4.19/023-0014-crypto-crypto4xx-fix-blocksize-for-cfb-and-ofb.patch b/target/linux/apm821xx/patches-4.19/023-0014-crypto-crypto4xx-fix-blocksize-for-cfb-and-ofb.patch
new file mode 100644 (file)
index 0000000..16f5af2
--- /dev/null
@@ -0,0 +1,44 @@
+From 70c4997f34b6c6888b3ac157adec49e01d0df2d5 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Sat, 18 May 2019 23:28:11 +0200
+Subject: [PATCH 14/15] crypto: crypto4xx - fix blocksize for cfb and ofb
+
+While the hardware consider them to be blockciphers, the
+reference implementation defines them as streamciphers.
+
+Do the right thing and set the blocksize to 1. This
+was found by CONFIG_CRYPTO_MANAGER_EXTRA_TESTS.
+
+This fixes the following issues:
+skcipher: blocksize for ofb-aes-ppc4xx (16) doesn't match generic impl (1)
+skcipher: blocksize for cfb-aes-ppc4xx (16) doesn't match generic impl (1)
+
+Cc: Eric Biggers <ebiggers@kernel.org>
+Cc: stable@vger.kernel.org
+Fixes: f2a13e7cba9e ("crypto: crypto4xx - enable AES RFC3686, ECB, CFB and OFB offloads")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -1236,7 +1236,7 @@ static struct crypto4xx_alg_common crypt
+                       .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
+                       .cra_flags = CRYPTO_ALG_ASYNC |
+                               CRYPTO_ALG_KERN_DRIVER_ONLY,
+-                      .cra_blocksize = AES_BLOCK_SIZE,
++                      .cra_blocksize = 1,
+                       .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+                       .cra_module = THIS_MODULE,
+               },
+@@ -1316,7 +1316,7 @@ static struct crypto4xx_alg_common crypt
+                       .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
+                       .cra_flags = CRYPTO_ALG_ASYNC |
+                               CRYPTO_ALG_KERN_DRIVER_ONLY,
+-                      .cra_blocksize = AES_BLOCK_SIZE,
++                      .cra_blocksize = 1,
+                       .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+                       .cra_module = THIS_MODULE,
+               },
diff --git a/target/linux/apm821xx/patches-4.19/023-0015-crypto-crypto4xx-block-ciphers-should-only-accept-co.patch b/target/linux/apm821xx/patches-4.19/023-0015-crypto-crypto4xx-block-ciphers-should-only-accept-co.patch
new file mode 100644 (file)
index 0000000..2706042
--- /dev/null
@@ -0,0 +1,172 @@
+From 0f7a81374060828280fcfdfbaa162cb559017f9f Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Sat, 18 May 2019 23:28:12 +0200
+Subject: [PATCH 15/15] crypto: crypto4xx - block ciphers should only accept
+ complete blocks
+
+The hardware automatically zero pads incomplete block ciphers
+blocks without raising any errors. This is a screw-up. This
+was noticed by CONFIG_CRYPTO_MANAGER_EXTRA_TESTS tests that
+sent a incomplete blocks and expect them to fail.
+
+This fixes:
+cbc-aes-ppc4xx encryption unexpectedly succeeded on test vector
+"random: len=2409 klen=32"; expected_error=-22, cfg="random:
+may_sleep use_digest src_divs=[96.90%@+2295, 2.34%@+4066,
+0.32%@alignmask+12, 0.34%@+4087, 0.9%@alignmask+1787, 0.1%@+3767]
+iv_offset=6"
+
+ecb-aes-ppc4xx encryption unexpectedly succeeded on test vector
+"random: len=1011 klen=32"; expected_error=-22, cfg="random:
+may_sleep use_digest src_divs=[100.0%@alignmask+20]
+dst_divs=[3.12%@+3001, 96.88%@+4070]"
+
+Cc: Eric Biggers <ebiggers@kernel.org>
+Cc: stable@vger.kernel.org [4.19, 5.0 and 5.1]
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_alg.c  | 36 +++++++++++++++++++---------
+ drivers/crypto/amcc/crypto4xx_core.c | 16 ++++++-------
+ drivers/crypto/amcc/crypto4xx_core.h | 10 ++++----
+ 3 files changed, 39 insertions(+), 23 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_alg.c
++++ b/drivers/crypto/amcc/crypto4xx_alg.c
+@@ -76,12 +76,16 @@ static void set_dynamic_sa_command_1(str
+ }
+ static inline int crypto4xx_crypt(struct skcipher_request *req,
+-                                const unsigned int ivlen, bool decrypt)
++                                const unsigned int ivlen, bool decrypt,
++                                bool check_blocksize)
+ {
+       struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
+       struct crypto4xx_ctx *ctx = crypto_skcipher_ctx(cipher);
+       __le32 iv[AES_IV_SIZE];
++      if (check_blocksize && !IS_ALIGNED(req->cryptlen, AES_BLOCK_SIZE))
++              return -EINVAL;
++
+       if (ivlen)
+               crypto4xx_memcpy_to_le32(iv, req->iv, ivlen);
+@@ -90,24 +94,34 @@ static inline int crypto4xx_crypt(struct
+               ctx->sa_len, 0, NULL);
+ }
+-int crypto4xx_encrypt_noiv(struct skcipher_request *req)
++int crypto4xx_encrypt_noiv_block(struct skcipher_request *req)
++{
++      return crypto4xx_crypt(req, 0, false, true);
++}
++
++int crypto4xx_encrypt_iv_stream(struct skcipher_request *req)
++{
++      return crypto4xx_crypt(req, AES_IV_SIZE, false, false);
++}
++
++int crypto4xx_decrypt_noiv_block(struct skcipher_request *req)
+ {
+-      return crypto4xx_crypt(req, 0, false);
++      return crypto4xx_crypt(req, 0, true, true);
+ }
+-int crypto4xx_encrypt_iv(struct skcipher_request *req)
++int crypto4xx_decrypt_iv_stream(struct skcipher_request *req)
+ {
+-      return crypto4xx_crypt(req, AES_IV_SIZE, false);
++      return crypto4xx_crypt(req, AES_IV_SIZE, true, false);
+ }
+-int crypto4xx_decrypt_noiv(struct skcipher_request *req)
++int crypto4xx_encrypt_iv_block(struct skcipher_request *req)
+ {
+-      return crypto4xx_crypt(req, 0, true);
++      return crypto4xx_crypt(req, AES_IV_SIZE, false, true);
+ }
+-int crypto4xx_decrypt_iv(struct skcipher_request *req)
++int crypto4xx_decrypt_iv_block(struct skcipher_request *req)
+ {
+-      return crypto4xx_crypt(req, AES_IV_SIZE, true);
++      return crypto4xx_crypt(req, AES_IV_SIZE, true, true);
+ }
+ /**
+@@ -278,8 +292,8 @@ crypto4xx_ctr_crypt(struct skcipher_requ
+               return ret;
+       }
+-      return encrypt ? crypto4xx_encrypt_iv(req)
+-                     : crypto4xx_decrypt_iv(req);
++      return encrypt ? crypto4xx_encrypt_iv_stream(req)
++                     : crypto4xx_decrypt_iv_stream(req);
+ }
+ static int crypto4xx_sk_setup_fallback(struct crypto4xx_ctx *ctx,
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -1224,8 +1224,8 @@ static struct crypto4xx_alg_common crypt
+               .max_keysize = AES_MAX_KEY_SIZE,
+               .ivsize = AES_IV_SIZE,
+               .setkey = crypto4xx_setkey_aes_cbc,
+-              .encrypt = crypto4xx_encrypt_iv,
+-              .decrypt = crypto4xx_decrypt_iv,
++              .encrypt = crypto4xx_encrypt_iv_block,
++              .decrypt = crypto4xx_decrypt_iv_block,
+               .init = crypto4xx_sk_init,
+               .exit = crypto4xx_sk_exit,
+       } },
+@@ -1244,8 +1244,8 @@ static struct crypto4xx_alg_common crypt
+               .max_keysize = AES_MAX_KEY_SIZE,
+               .ivsize = AES_IV_SIZE,
+               .setkey = crypto4xx_setkey_aes_cfb,
+-              .encrypt = crypto4xx_encrypt_iv,
+-              .decrypt = crypto4xx_decrypt_iv,
++              .encrypt = crypto4xx_encrypt_iv_stream,
++              .decrypt = crypto4xx_decrypt_iv_stream,
+               .init = crypto4xx_sk_init,
+               .exit = crypto4xx_sk_exit,
+       } },
+@@ -1304,8 +1304,8 @@ static struct crypto4xx_alg_common crypt
+               .min_keysize = AES_MIN_KEY_SIZE,
+               .max_keysize = AES_MAX_KEY_SIZE,
+               .setkey = crypto4xx_setkey_aes_ecb,
+-              .encrypt = crypto4xx_encrypt_noiv,
+-              .decrypt = crypto4xx_decrypt_noiv,
++              .encrypt = crypto4xx_encrypt_noiv_block,
++              .decrypt = crypto4xx_decrypt_noiv_block,
+               .init = crypto4xx_sk_init,
+               .exit = crypto4xx_sk_exit,
+       } },
+@@ -1324,8 +1324,8 @@ static struct crypto4xx_alg_common crypt
+               .max_keysize = AES_MAX_KEY_SIZE,
+               .ivsize = AES_IV_SIZE,
+               .setkey = crypto4xx_setkey_aes_ofb,
+-              .encrypt = crypto4xx_encrypt_iv,
+-              .decrypt = crypto4xx_decrypt_iv,
++              .encrypt = crypto4xx_encrypt_iv_stream,
++              .decrypt = crypto4xx_decrypt_iv_stream,
+               .init = crypto4xx_sk_init,
+               .exit = crypto4xx_sk_exit,
+       } },
+--- a/drivers/crypto/amcc/crypto4xx_core.h
++++ b/drivers/crypto/amcc/crypto4xx_core.h
+@@ -182,10 +182,12 @@ int crypto4xx_setkey_rfc3686(struct cryp
+                            const u8 *key, unsigned int keylen);
+ int crypto4xx_encrypt_ctr(struct skcipher_request *req);
+ int crypto4xx_decrypt_ctr(struct skcipher_request *req);
+-int crypto4xx_encrypt_iv(struct skcipher_request *req);
+-int crypto4xx_decrypt_iv(struct skcipher_request *req);
+-int crypto4xx_encrypt_noiv(struct skcipher_request *req);
+-int crypto4xx_decrypt_noiv(struct skcipher_request *req);
++int crypto4xx_encrypt_iv_stream(struct skcipher_request *req);
++int crypto4xx_decrypt_iv_stream(struct skcipher_request *req);
++int crypto4xx_encrypt_iv_block(struct skcipher_request *req);
++int crypto4xx_decrypt_iv_block(struct skcipher_request *req);
++int crypto4xx_encrypt_noiv_block(struct skcipher_request *req);
++int crypto4xx_decrypt_noiv_block(struct skcipher_request *req);
+ int crypto4xx_rfc3686_encrypt(struct skcipher_request *req);
+ int crypto4xx_rfc3686_decrypt(struct skcipher_request *req);
+ int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm);