1 From d072bfa4885354fff86aa1fb1dbc4f1533c9e0bf Mon Sep 17 00:00:00 2001
2 From: Christian Lamparter <chunkeey@gmail.com>
3 Date: Sun, 23 Dec 2018 02:16:13 +0100
4 Subject: [PATCH 06/15] crypto: crypto4xx - add prng crypto support
6 This patch adds support for crypto4xx's ANSI X9.17 Annex C compliant
7 pseudo random number generator which provides a pseudo random source
8 for the purpose of generating Initialization Vectors (IV's) for AES
9 algorithms to the Packet Engine and other pseudo random number
12 Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
13 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
15 drivers/crypto/amcc/crypto4xx_core.c | 87 +++++++++++++++++++++++++
16 drivers/crypto/amcc/crypto4xx_core.h | 4 ++
17 drivers/crypto/amcc/crypto4xx_reg_def.h | 1 +
18 3 files changed, 92 insertions(+)
20 --- a/drivers/crypto/amcc/crypto4xx_core.c
21 +++ b/drivers/crypto/amcc/crypto4xx_core.c
23 #include <crypto/ctr.h>
24 #include <crypto/gcm.h>
25 #include <crypto/sha.h>
26 +#include <crypto/rng.h>
27 #include <crypto/scatterwalk.h>
28 #include <crypto/skcipher.h>
29 #include <crypto/internal/aead.h>
30 +#include <crypto/internal/rng.h>
31 #include <crypto/internal/skcipher.h>
32 #include "crypto4xx_reg_def.h"
33 #include "crypto4xx_core.h"
34 @@ -1031,6 +1033,10 @@ static int crypto4xx_register_alg(struct
35 rc = crypto_register_ahash(&alg->alg.u.hash);
38 + case CRYPTO_ALG_TYPE_RNG:
39 + rc = crypto_register_rng(&alg->alg.u.rng);
43 rc = crypto_register_skcipher(&alg->alg.u.cipher);
45 @@ -1060,6 +1066,10 @@ static void crypto4xx_unregister_alg(str
46 crypto_unregister_aead(&alg->alg.u.aead);
49 + case CRYPTO_ALG_TYPE_RNG:
50 + crypto_unregister_rng(&alg->alg.u.rng);
54 crypto_unregister_skcipher(&alg->alg.u.cipher);
56 @@ -1118,6 +1128,69 @@ static irqreturn_t crypto4xx_ce_interrup
60 +static int ppc4xx_prng_data_read(struct crypto4xx_device *dev,
61 + u8 *data, unsigned int max)
63 + unsigned int i, curr = 0;
67 + /* trigger PRN generation */
68 + writel(PPC4XX_PRNG_CTRL_AUTO_EN,
69 + dev->ce_base + CRYPTO4XX_PRNG_CTRL);
71 + for (i = 0; i < 1024; i++) {
72 + /* usually 19 iterations are enough */
73 + if ((readl(dev->ce_base + CRYPTO4XX_PRNG_STAT) &
74 + CRYPTO4XX_PRNG_STAT_BUSY))
77 + val[0] = readl_be(dev->ce_base + CRYPTO4XX_PRNG_RES_0);
78 + val[1] = readl_be(dev->ce_base + CRYPTO4XX_PRNG_RES_1);
84 + if ((max - curr) >= 8) {
85 + memcpy(data, &val, 8);
89 + /* copy only remaining bytes */
90 + memcpy(data, &val, max - curr);
93 + } while (curr < max);
98 +static int crypto4xx_prng_generate(struct crypto_rng *tfm,
99 + const u8 *src, unsigned int slen,
100 + u8 *dstn, unsigned int dlen)
102 + struct rng_alg *alg = crypto_rng_alg(tfm);
103 + struct crypto4xx_alg *amcc_alg;
104 + struct crypto4xx_device *dev;
107 + amcc_alg = container_of(alg, struct crypto4xx_alg, alg.u.rng);
108 + dev = amcc_alg->dev;
110 + mutex_lock(&dev->core_dev->rng_lock);
111 + ret = ppc4xx_prng_data_read(dev, dstn, dlen);
112 + mutex_unlock(&dev->core_dev->rng_lock);
117 +static int crypto4xx_prng_seed(struct crypto_rng *tfm, const u8 *seed,
124 * Supported Crypto Algorithms
126 @@ -1287,6 +1360,18 @@ static struct crypto4xx_alg_common crypt
127 .cra_module = THIS_MODULE,
130 + { .type = CRYPTO_ALG_TYPE_RNG, .u.rng = {
132 + .cra_name = "stdrng",
133 + .cra_driver_name = "crypto4xx_rng",
134 + .cra_priority = 300,
136 + .cra_module = THIS_MODULE,
138 + .generate = crypto4xx_prng_generate,
139 + .seed = crypto4xx_prng_seed,
145 @@ -1356,6 +1441,7 @@ static int crypto4xx_probe(struct platfo
146 core_dev->dev->core_dev = core_dev;
147 core_dev->dev->is_revb = is_revb;
148 core_dev->device = dev;
149 + mutex_init(&core_dev->rng_lock);
150 spin_lock_init(&core_dev->lock);
151 INIT_LIST_HEAD(&core_dev->dev->alg_list);
152 ratelimit_default_init(&core_dev->dev->aead_ratelimit);
153 @@ -1435,6 +1521,7 @@ static int crypto4xx_remove(struct platf
154 tasklet_kill(&core_dev->tasklet);
155 /* Un-register with Linux CryptoAPI */
156 crypto4xx_unregister_alg(core_dev->dev);
157 + mutex_destroy(&core_dev->rng_lock);
158 /* Free all allocated memory */
159 crypto4xx_stop_all(core_dev);
161 --- a/drivers/crypto/amcc/crypto4xx_core.h
162 +++ b/drivers/crypto/amcc/crypto4xx_core.h
164 #define __CRYPTO4XX_CORE_H__
166 #include <linux/ratelimit.h>
167 +#include <linux/mutex.h>
168 #include <crypto/internal/hash.h>
169 #include <crypto/internal/aead.h>
170 +#include <crypto/internal/rng.h>
171 #include <crypto/internal/skcipher.h>
172 #include "crypto4xx_reg_def.h"
173 #include "crypto4xx_sa.h"
174 @@ -119,6 +121,7 @@ struct crypto4xx_core_device {
176 struct tasklet_struct tasklet;
178 + struct mutex rng_lock;
181 struct crypto4xx_ctx {
182 @@ -143,6 +146,7 @@ struct crypto4xx_alg_common {
183 struct skcipher_alg cipher;
184 struct ahash_alg hash;
185 struct aead_alg aead;
186 + struct rng_alg rng;
190 --- a/drivers/crypto/amcc/crypto4xx_reg_def.h
191 +++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
193 #define CRYPTO4XX_ENDIAN_CFG 0x000600d8
195 #define CRYPTO4XX_PRNG_STAT 0x00070000
196 +#define CRYPTO4XX_PRNG_STAT_BUSY 0x1
197 #define CRYPTO4XX_PRNG_CTRL 0x00070004
198 #define CRYPTO4XX_PRNG_SEED_L 0x00070008
199 #define CRYPTO4XX_PRNG_SEED_H 0x0007000c