aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@gmail.com>2019-05-31 19:30:00 +0200
committerChristian Lamparter <chunkeey@gmail.com>2019-06-01 19:47:14 +0200
commitb2b1265a1d6cd12d7945b6faad91e4a214ef1bd7 (patch)
tree2a8757e6880a88f3beeae57c9ade0153c6baffe3 /target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch
parent67619619195aa57b2d3169b659e677cd8b879e2a (diff)
downloadupstream-b2b1265a1d6cd12d7945b6faad91e4a214ef1bd7.tar.gz
upstream-b2b1265a1d6cd12d7945b6faad91e4a214ef1bd7.tar.bz2
upstream-b2b1265a1d6cd12d7945b6faad91e4a214ef1bd7.zip
apm821xx: backport accepted linux-crypto patches
Rather than wait until the patches hit vanilla and get backported via the stable kernel, this patch patches the crypto4xx driver with the latest fixes from the upstream linux-crypto tree. Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Diffstat (limited to 'target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch')
-rw-r--r--target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch199
1 files changed, 199 insertions, 0 deletions
diff --git a/target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch b/target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch
new file mode 100644
index 0000000000..b20049c83e
--- /dev/null
+++ b/target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch
@@ -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"
+@@ -1035,6 +1037,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;
+@@ -1064,6 +1070,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);
+ }
+@@ -1122,6 +1132,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
+ */
+@@ -1291,6 +1364,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,
++ } },
+ };
+
+ /**
+@@ -1360,6 +1445,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);
+@@ -1439,6 +1525,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