crypto4xx: add prng crypto support
PATCH 1/1 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 <[email protected]>
--- 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(+)
drivers/crypto/amcc/crypto4xx_core.c +87 -0
@@ -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 crypto4xx_device *sec_dev, 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(struct crypto4xx_device *sec_dev)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_interrupt_handler_revb(int irq, void *data) 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 crypto4xx_alg[] = { .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 platform_device *ofdev) 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 platform_device *ofdev)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);
drivers/crypto/amcc/crypto4xx_core.h +4 -0
@@ -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; };
drivers/crypto/amcc/crypto4xx_reg_def.h +1 -0
@@ -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
Signature · 1 line
2.20.1
Herbert Xu
maintainerQuoted 6 lines · Christian Lamparter
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.
Quoted 6 lines
Signed-off-by Christian Lamparter <[email protected]>--- 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(+)
Patch applied. Thanks.
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt