diff options
Diffstat (limited to 'target/linux/apm821xx/patches-4.19/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch')
-rw-r--r-- | target/linux/apm821xx/patches-4.19/023-0006-crypto-crypto4xx-add-prng-crypto-support.patch | 199 |
1 files changed, 199 insertions, 0 deletions
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 index 0000000000..ba4419787c --- /dev/null +++ b/target/linux/apm821xx/patches-4.19/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" +@@ -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 |