aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/apm821xx/patches-4.14/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch
diff options
context:
space:
mode:
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