diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-20 22:46:38 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-21 21:30:14 -0400 |
commit | acec27ff35af9caf34d76d16ee17ff3b292e7d83 (patch) | |
tree | cbbadbe7b3b8ed91da58850cd147145c944b359c | |
parent | 3c5d8fa9f56ad0928e7a1f06003e5034f5eedb52 (diff) |
crypto: rng - Convert low-level crypto_rng to new style
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>
-rw-r--r-- | crypto/rng.c | 56 | ||||
-rw-r--r-- | include/crypto/internal/rng.h | 3 | ||||
-rw-r--r-- | include/crypto/rng.h | 42 | ||||
-rw-r--r-- | include/linux/crypto.h | 6 |
4 files changed, 96 insertions, 11 deletions
diff --git a/crypto/rng.c b/crypto/rng.c index f1d64948f6fc..5e0425a24657 100644 --- a/crypto/rng.c +++ b/crypto/rng.c | |||
@@ -36,10 +36,15 @@ static inline struct crypto_rng *__crypto_rng_cast(struct crypto_tfm *tfm) | |||
36 | return container_of(tfm, struct crypto_rng, base); | 36 | return container_of(tfm, struct crypto_rng, base); |
37 | } | 37 | } |
38 | 38 | ||
39 | static inline struct old_rng_alg *crypto_old_rng_alg(struct crypto_rng *tfm) | ||
40 | { | ||
41 | return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng; | ||
42 | } | ||
43 | |||
39 | static int generate(struct crypto_rng *tfm, const u8 *src, unsigned int slen, | 44 | static int generate(struct crypto_rng *tfm, const u8 *src, unsigned int slen, |
40 | u8 *dst, unsigned int dlen) | 45 | u8 *dst, unsigned int dlen) |
41 | { | 46 | { |
42 | return crypto_rng_alg(tfm)->rng_make_random(tfm, dst, dlen); | 47 | return crypto_old_rng_alg(tfm)->rng_make_random(tfm, dst, dlen); |
43 | } | 48 | } |
44 | 49 | ||
45 | static int rngapi_reset(struct crypto_rng *tfm, const u8 *seed, | 50 | 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, | |||
58 | src = buf; | 63 | src = buf; |
59 | } | 64 | } |
60 | 65 | ||
61 | err = crypto_rng_alg(tfm)->rng_reset(tfm, src, slen); | 66 | err = crypto_old_rng_alg(tfm)->rng_reset(tfm, src, slen); |
62 | 67 | ||
63 | kzfree(buf); | 68 | kzfree(buf); |
64 | return err; | 69 | return err; |
@@ -88,13 +93,31 @@ EXPORT_SYMBOL_GPL(crypto_rng_reset); | |||
88 | static int crypto_rng_init_tfm(struct crypto_tfm *tfm) | 93 | static int crypto_rng_init_tfm(struct crypto_tfm *tfm) |
89 | { | 94 | { |
90 | struct crypto_rng *rng = __crypto_rng_cast(tfm); | 95 | struct crypto_rng *rng = __crypto_rng_cast(tfm); |
96 | struct rng_alg *alg = crypto_rng_alg(rng); | ||
97 | struct old_rng_alg *oalg = crypto_old_rng_alg(rng); | ||
98 | |||
99 | if (oalg->rng_make_random) { | ||
100 | rng->generate = generate; | ||
101 | rng->seed = rngapi_reset; | ||
102 | rng->seedsize = oalg->seedsize; | ||
103 | return 0; | ||
104 | } | ||
91 | 105 | ||
92 | rng->generate = generate; | 106 | rng->generate = alg->generate; |
93 | rng->seed = rngapi_reset; | 107 | rng->seed = alg->seed; |
108 | rng->seedsize = alg->seedsize; | ||
94 | 109 | ||
95 | return 0; | 110 | return 0; |
96 | } | 111 | } |
97 | 112 | ||
113 | static unsigned int seedsize(struct crypto_alg *alg) | ||
114 | { | ||
115 | struct rng_alg *ralg = container_of(alg, struct rng_alg, base); | ||
116 | |||
117 | return alg->cra_rng.rng_make_random ? | ||
118 | alg->cra_rng.seedsize : ralg->seedsize; | ||
119 | } | ||
120 | |||
98 | #ifdef CONFIG_NET | 121 | #ifdef CONFIG_NET |
99 | static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) | 122 | static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) |
100 | { | 123 | { |
@@ -102,7 +125,7 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
102 | 125 | ||
103 | strncpy(rrng.type, "rng", sizeof(rrng.type)); | 126 | strncpy(rrng.type, "rng", sizeof(rrng.type)); |
104 | 127 | ||
105 | rrng.seedsize = alg->cra_rng.seedsize; | 128 | rrng.seedsize = seedsize(alg); |
106 | 129 | ||
107 | if (nla_put(skb, CRYPTOCFGA_REPORT_RNG, | 130 | if (nla_put(skb, CRYPTOCFGA_REPORT_RNG, |
108 | sizeof(struct crypto_report_rng), &rrng)) | 131 | sizeof(struct crypto_report_rng), &rrng)) |
@@ -124,7 +147,7 @@ static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) | |||
124 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) | 147 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) |
125 | { | 148 | { |
126 | seq_printf(m, "type : rng\n"); | 149 | seq_printf(m, "type : rng\n"); |
127 | seq_printf(m, "seedsize : %u\n", alg->cra_rng.seedsize); | 150 | seq_printf(m, "seedsize : %u\n", seedsize(alg)); |
128 | } | 151 | } |
129 | 152 | ||
130 | const struct crypto_type crypto_rng_type = { | 153 | const struct crypto_type crypto_rng_type = { |
@@ -189,5 +212,26 @@ void crypto_put_default_rng(void) | |||
189 | } | 212 | } |
190 | EXPORT_SYMBOL_GPL(crypto_put_default_rng); | 213 | EXPORT_SYMBOL_GPL(crypto_put_default_rng); |
191 | 214 | ||
215 | int crypto_register_rng(struct rng_alg *alg) | ||
216 | { | ||
217 | struct crypto_alg *base = &alg->base; | ||
218 | |||
219 | if (alg->seedsize > PAGE_SIZE / 8) | ||
220 | return -EINVAL; | ||
221 | |||
222 | base->cra_type = &crypto_rng_type; | ||
223 | base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; | ||
224 | base->cra_flags |= CRYPTO_ALG_TYPE_RNG; | ||
225 | |||
226 | return crypto_register_alg(base); | ||
227 | } | ||
228 | EXPORT_SYMBOL_GPL(crypto_register_rng); | ||
229 | |||
230 | void crypto_unregister_rng(struct rng_alg *alg) | ||
231 | { | ||
232 | crypto_unregister_alg(&alg->base); | ||
233 | } | ||
234 | EXPORT_SYMBOL_GPL(crypto_unregister_rng); | ||
235 | |||
192 | MODULE_LICENSE("GPL"); | 236 | MODULE_LICENSE("GPL"); |
193 | MODULE_DESCRIPTION("Random Number Generator"); | 237 | MODULE_DESCRIPTION("Random Number Generator"); |
diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h index 896973369573..76f3c9519ba5 100644 --- a/include/crypto/internal/rng.h +++ b/include/crypto/internal/rng.h | |||
@@ -18,6 +18,9 @@ | |||
18 | 18 | ||
19 | extern const struct crypto_type crypto_rng_type; | 19 | extern const struct crypto_type crypto_rng_type; |
20 | 20 | ||
21 | int crypto_register_rng(struct rng_alg *alg); | ||
22 | void crypto_unregister_rng(struct rng_alg *alg); | ||
23 | |||
21 | static inline void *crypto_rng_ctx(struct crypto_rng *tfm) | 24 | static inline void *crypto_rng_ctx(struct crypto_rng *tfm) |
22 | { | 25 | { |
23 | return crypto_tfm_ctx(&tfm->base); | 26 | return crypto_tfm_ctx(&tfm->base); |
diff --git a/include/crypto/rng.h b/include/crypto/rng.h index 7fca37144b59..133f0441ad3e 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h | |||
@@ -15,11 +15,48 @@ | |||
15 | 15 | ||
16 | #include <linux/crypto.h> | 16 | #include <linux/crypto.h> |
17 | 17 | ||
18 | struct crypto_rng; | ||
19 | |||
20 | /** | ||
21 | * struct rng_alg - random number generator definition | ||
22 | * | ||
23 | * @generate: The function defined by this variable obtains a | ||
24 | * random number. The random number generator transform | ||
25 | * must generate the random number out of the context | ||
26 | * provided with this call, plus any additional data | ||
27 | * if provided to the call. | ||
28 | * @seed: Seed or reseed the random number generator. With the | ||
29 | * invocation of this function call, the random number | ||
30 | * generator shall become ready fo generation. If the | ||
31 | * random number generator requires a seed for setting | ||
32 | * up a new state, the seed must be provided by the | ||
33 | * consumer while invoking this function. The required | ||
34 | * size of the seed is defined with @seedsize . | ||
35 | * @seedsize: The seed size required for a random number generator | ||
36 | * initialization defined with this variable. Some | ||
37 | * random number generators does not require a seed | ||
38 | * as the seeding is implemented internally without | ||
39 | * the need of support by the consumer. In this case, | ||
40 | * the seed size is set to zero. | ||
41 | * @base: Common crypto API algorithm data structure. | ||
42 | */ | ||
43 | struct rng_alg { | ||
44 | int (*generate)(struct crypto_rng *tfm, | ||
45 | const u8 *src, unsigned int slen, | ||
46 | u8 *dst, unsigned int dlen); | ||
47 | int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); | ||
48 | |||
49 | unsigned int seedsize; | ||
50 | |||
51 | struct crypto_alg base; | ||
52 | }; | ||
53 | |||
18 | struct crypto_rng { | 54 | struct crypto_rng { |
19 | int (*generate)(struct crypto_rng *tfm, | 55 | int (*generate)(struct crypto_rng *tfm, |
20 | const u8 *src, unsigned int slen, | 56 | const u8 *src, unsigned int slen, |
21 | u8 *dst, unsigned int dlen); | 57 | u8 *dst, unsigned int dlen); |
22 | int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); | 58 | int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); |
59 | unsigned int seedsize; | ||
23 | struct crypto_tfm base; | 60 | struct crypto_tfm base; |
24 | }; | 61 | }; |
25 | 62 | ||
@@ -72,7 +109,8 @@ static inline struct crypto_tfm *crypto_rng_tfm(struct crypto_rng *tfm) | |||
72 | */ | 109 | */ |
73 | static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm) | 110 | static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm) |
74 | { | 111 | { |
75 | return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng; | 112 | return container_of(crypto_rng_tfm(tfm)->__crt_alg, |
113 | struct rng_alg, base); | ||
76 | } | 114 | } |
77 | 115 | ||
78 | /** | 116 | /** |
@@ -156,7 +194,7 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, | |||
156 | */ | 194 | */ |
157 | static inline int crypto_rng_seedsize(struct crypto_rng *tfm) | 195 | static inline int crypto_rng_seedsize(struct crypto_rng *tfm) |
158 | { | 196 | { |
159 | return crypto_rng_alg(tfm)->seedsize; | 197 | return tfm->seedsize; |
160 | } | 198 | } |
161 | 199 | ||
162 | #endif | 200 | #endif |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 781f7d546020..2fa9b05360f7 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -427,7 +427,7 @@ struct compress_alg { | |||
427 | }; | 427 | }; |
428 | 428 | ||
429 | /** | 429 | /** |
430 | * struct rng_alg - random number generator definition | 430 | * struct old_rng_alg - random number generator definition |
431 | * @rng_make_random: The function defined by this variable obtains a random | 431 | * @rng_make_random: The function defined by this variable obtains a random |
432 | * number. The random number generator transform must generate | 432 | * number. The random number generator transform must generate |
433 | * the random number out of the context provided with this | 433 | * the random number out of the context provided with this |
@@ -445,7 +445,7 @@ struct compress_alg { | |||
445 | * seeding is implemented internally without the need of support by | 445 | * seeding is implemented internally without the need of support by |
446 | * the consumer. In this case, the seed size is set to zero. | 446 | * the consumer. In this case, the seed size is set to zero. |
447 | */ | 447 | */ |
448 | struct rng_alg { | 448 | struct old_rng_alg { |
449 | int (*rng_make_random)(struct crypto_rng *tfm, u8 *rdata, | 449 | int (*rng_make_random)(struct crypto_rng *tfm, u8 *rdata, |
450 | unsigned int dlen); | 450 | unsigned int dlen); |
451 | int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); | 451 | int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); |
@@ -559,7 +559,7 @@ struct crypto_alg { | |||
559 | struct blkcipher_alg blkcipher; | 559 | struct blkcipher_alg blkcipher; |
560 | struct cipher_alg cipher; | 560 | struct cipher_alg cipher; |
561 | struct compress_alg compress; | 561 | struct compress_alg compress; |
562 | struct rng_alg rng; | 562 | struct old_rng_alg rng; |
563 | } cra_u; | 563 | } cra_u; |
564 | 564 | ||
565 | int (*cra_init)(struct crypto_tfm *tfm); | 565 | int (*cra_init)(struct crypto_tfm *tfm); |