crypto: rng - Convert low-level crypto_rng to new style
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 21 Apr 2015 02:46:38 +0000 (10:46 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 22 Apr 2015 01:30:14 +0000 (09:30 +0800)
This patch converts the low-level crypto_rng interface to the
"new" style.

This allows existing implementations to be converted over one-
by-one.  Once that is complete we can then remove the old rng
interface.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/rng.c
include/crypto/internal/rng.h
include/crypto/rng.h
include/linux/crypto.h

index f1d64948f6fc8037edd0458eb1bd390d64c717d8..5e0425a246579f490f52b14eb00d5c2a5f5b0c8a 100644 (file)
@@ -36,10 +36,15 @@ static inline struct crypto_rng *__crypto_rng_cast(struct crypto_tfm *tfm)
        return container_of(tfm, struct crypto_rng, base);
 }
 
+static inline struct old_rng_alg *crypto_old_rng_alg(struct crypto_rng *tfm)
+{
+       return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng;
+}
+
 static int generate(struct crypto_rng *tfm, const u8 *src, unsigned int slen,
                    u8 *dst, unsigned int dlen)
 {
-       return crypto_rng_alg(tfm)->rng_make_random(tfm, dst, dlen);
+       return crypto_old_rng_alg(tfm)->rng_make_random(tfm, dst, dlen);
 }
 
 static int rngapi_reset(struct crypto_rng *tfm, const u8 *seed,
@@ -58,7 +63,7 @@ static int rngapi_reset(struct crypto_rng *tfm, const u8 *seed,
                src = buf;
        }
 
-       err = crypto_rng_alg(tfm)->rng_reset(tfm, src, slen);
+       err = crypto_old_rng_alg(tfm)->rng_reset(tfm, src, slen);
 
        kzfree(buf);
        return err;
@@ -88,13 +93,31 @@ EXPORT_SYMBOL_GPL(crypto_rng_reset);
 static int crypto_rng_init_tfm(struct crypto_tfm *tfm)
 {
        struct crypto_rng *rng = __crypto_rng_cast(tfm);
+       struct rng_alg *alg = crypto_rng_alg(rng);
+       struct old_rng_alg *oalg = crypto_old_rng_alg(rng);
+
+       if (oalg->rng_make_random) {
+               rng->generate = generate;
+               rng->seed = rngapi_reset;
+               rng->seedsize = oalg->seedsize;
+               return 0;
+       }
 
-       rng->generate = generate;
-       rng->seed = rngapi_reset;
+       rng->generate = alg->generate;
+       rng->seed = alg->seed;
+       rng->seedsize = alg->seedsize;
 
        return 0;
 }
 
+static unsigned int seedsize(struct crypto_alg *alg)
+{
+       struct rng_alg *ralg = container_of(alg, struct rng_alg, base);
+
+       return alg->cra_rng.rng_make_random ?
+              alg->cra_rng.seedsize : ralg->seedsize;
+}
+
 #ifdef CONFIG_NET
 static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
@@ -102,7 +125,7 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
 
        strncpy(rrng.type, "rng", sizeof(rrng.type));
 
-       rrng.seedsize = alg->cra_rng.seedsize;
+       rrng.seedsize = seedsize(alg);
 
        if (nla_put(skb, CRYPTOCFGA_REPORT_RNG,
                    sizeof(struct crypto_report_rng), &rrng))
@@ -124,7 +147,7 @@ static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
 static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
 {
        seq_printf(m, "type         : rng\n");
-       seq_printf(m, "seedsize     : %u\n", alg->cra_rng.seedsize);
+       seq_printf(m, "seedsize     : %u\n", seedsize(alg));
 }
 
 const struct crypto_type crypto_rng_type = {
@@ -189,5 +212,26 @@ void crypto_put_default_rng(void)
 }
 EXPORT_SYMBOL_GPL(crypto_put_default_rng);
 
+int crypto_register_rng(struct rng_alg *alg)
+{
+       struct crypto_alg *base = &alg->base;
+
+       if (alg->seedsize > PAGE_SIZE / 8)
+               return -EINVAL;
+
+       base->cra_type = &crypto_rng_type;
+       base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+       base->cra_flags |= CRYPTO_ALG_TYPE_RNG;
+
+       return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_rng);
+
+void crypto_unregister_rng(struct rng_alg *alg)
+{
+       crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_rng);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Random Number Generator");
index 896973369573f7f078c519cd562128206129398a..76f3c9519ba5723034bb3a34ca18eb666130c8b3 100644 (file)
@@ -18,6 +18,9 @@
 
 extern const struct crypto_type crypto_rng_type;
 
+int crypto_register_rng(struct rng_alg *alg);
+void crypto_unregister_rng(struct rng_alg *alg);
+
 static inline void *crypto_rng_ctx(struct crypto_rng *tfm)
 {
        return crypto_tfm_ctx(&tfm->base);
index 7fca37144b5905c777c9623f542370f8b6755478..133f0441ad3e0d8c5315061527992f29f4b4b9bb 100644 (file)
 
 #include <linux/crypto.h>
 
+struct crypto_rng;
+
+/**
+ * struct rng_alg - random number generator definition
+ *
+ * @generate:  The function defined by this variable obtains a
+ *             random number. The random number generator transform
+ *             must generate the random number out of the context
+ *             provided with this call, plus any additional data
+ *             if provided to the call.
+ * @seed:      Seed or reseed the random number generator.  With the
+ *             invocation of this function call, the random number
+ *             generator shall become ready fo generation.  If the
+ *             random number generator requires a seed for setting
+ *             up a new state, the seed must be provided by the
+ *             consumer while invoking this function. The required
+ *             size of the seed is defined with @seedsize .
+ * @seedsize:  The seed size required for a random number generator
+ *             initialization defined with this variable. Some
+ *             random number generators does not require a seed
+ *             as the seeding is implemented internally without
+ *             the need of support by the consumer. In this case,
+ *             the seed size is set to zero.
+ * @base:      Common crypto API algorithm data structure.
+ */
+struct rng_alg {
+       int (*generate)(struct crypto_rng *tfm,
+                       const u8 *src, unsigned int slen,
+                       u8 *dst, unsigned int dlen);
+       int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);
+
+       unsigned int seedsize;
+
+       struct crypto_alg base;
+};
+
 struct crypto_rng {
        int (*generate)(struct crypto_rng *tfm,
                        const u8 *src, unsigned int slen,
                        u8 *dst, unsigned int dlen);
        int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);
+       unsigned int seedsize;
        struct crypto_tfm base;
 };
 
@@ -72,7 +109,8 @@ static inline struct crypto_tfm *crypto_rng_tfm(struct crypto_rng *tfm)
  */
 static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm)
 {
-       return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng;
+       return container_of(crypto_rng_tfm(tfm)->__crt_alg,
+                           struct rng_alg, base);
 }
 
 /**
@@ -156,7 +194,7 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed,
  */
 static inline int crypto_rng_seedsize(struct crypto_rng *tfm)
 {
-       return crypto_rng_alg(tfm)->seedsize;
+       return tfm->seedsize;
 }
 
 #endif
index 781f7d54602081665ebd955403f902368bf42dc3..2fa9b05360f7b39c03309cc89950fa602051ae0c 100644 (file)
@@ -427,7 +427,7 @@ struct compress_alg {
 };
 
 /**
- * struct rng_alg - random number generator definition
+ * struct old_rng_alg - random number generator definition
  * @rng_make_random: The function defined by this variable obtains a random
  *                  number. The random number generator transform must generate
  *                  the random number out of the context provided with this
@@ -445,7 +445,7 @@ struct compress_alg {
  *           seeding is implemented internally without the need of support by
  *           the consumer. In this case, the seed size is set to zero.
  */
-struct rng_alg {
+struct old_rng_alg {
        int (*rng_make_random)(struct crypto_rng *tfm, u8 *rdata,
                               unsigned int dlen);
        int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen);
@@ -559,7 +559,7 @@ struct crypto_alg {
                struct blkcipher_alg blkcipher;
                struct cipher_alg cipher;
                struct compress_alg compress;
-               struct rng_alg rng;
+               struct old_rng_alg rng;
        } cra_u;
 
        int (*cra_init)(struct crypto_tfm *tfm);