diff options
| author | Amit Shah <amit.shah@redhat.com> | 2014-07-10 06:12:34 -0400 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-07-14 08:48:17 -0400 |
| commit | d3cc7996473a7bdd33256029988ea690754e4e2a (patch) | |
| tree | 7219085d965196685ba1185d5a83232d7a47493a /drivers/char/hw_random/core.c | |
| parent | 0378c9a855bfa395f595fbfb049707093e270f69 (diff) | |
hwrng: fetch randomness only after device init
Commit d9e7972619334 "hwrng: add randomness to system from rng sources"
added a call to rng_get_data() from the hwrng_register() function.
However, some rng devices need initialization before data can be read
from them.
This commit makes the call to rng_get_data() depend on no init fn
pointer being registered by the device. If an init function is
registered, this call is made after device init.
CC: Kees Cook <keescook@chromium.org>
CC: Jason Cooper <jason@lakedaemon.net>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: <stable@vger.kernel.org> # For v3.15+
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Reviewed-by: Jason Cooper <jason@lakedaemon.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/char/hw_random/core.c')
| -rw-r--r-- | drivers/char/hw_random/core.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 334601cc81cf..2a451b14b3cc 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c | |||
| @@ -55,16 +55,35 @@ static DEFINE_MUTEX(rng_mutex); | |||
| 55 | static int data_avail; | 55 | static int data_avail; |
| 56 | static u8 *rng_buffer; | 56 | static u8 *rng_buffer; |
| 57 | 57 | ||
| 58 | static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size, | ||
| 59 | int wait); | ||
| 60 | |||
| 58 | static size_t rng_buffer_size(void) | 61 | static size_t rng_buffer_size(void) |
| 59 | { | 62 | { |
| 60 | return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES; | 63 | return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES; |
| 61 | } | 64 | } |
| 62 | 65 | ||
| 66 | static void add_early_randomness(struct hwrng *rng) | ||
| 67 | { | ||
| 68 | unsigned char bytes[16]; | ||
| 69 | int bytes_read; | ||
| 70 | |||
| 71 | bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1); | ||
| 72 | if (bytes_read > 0) | ||
| 73 | add_device_randomness(bytes, bytes_read); | ||
| 74 | } | ||
| 75 | |||
| 63 | static inline int hwrng_init(struct hwrng *rng) | 76 | static inline int hwrng_init(struct hwrng *rng) |
| 64 | { | 77 | { |
| 65 | if (!rng->init) | 78 | if (rng->init) { |
| 66 | return 0; | 79 | int ret; |
| 67 | return rng->init(rng); | 80 | |
| 81 | ret = rng->init(rng); | ||
| 82 | if (ret) | ||
| 83 | return ret; | ||
| 84 | } | ||
| 85 | add_early_randomness(rng); | ||
| 86 | return 0; | ||
| 68 | } | 87 | } |
| 69 | 88 | ||
| 70 | static inline void hwrng_cleanup(struct hwrng *rng) | 89 | static inline void hwrng_cleanup(struct hwrng *rng) |
| @@ -304,8 +323,6 @@ int hwrng_register(struct hwrng *rng) | |||
| 304 | { | 323 | { |
| 305 | int err = -EINVAL; | 324 | int err = -EINVAL; |
| 306 | struct hwrng *old_rng, *tmp; | 325 | struct hwrng *old_rng, *tmp; |
| 307 | unsigned char bytes[16]; | ||
| 308 | int bytes_read; | ||
| 309 | 326 | ||
| 310 | if (rng->name == NULL || | 327 | if (rng->name == NULL || |
| 311 | (rng->data_read == NULL && rng->read == NULL)) | 328 | (rng->data_read == NULL && rng->read == NULL)) |
| @@ -347,9 +364,17 @@ int hwrng_register(struct hwrng *rng) | |||
| 347 | INIT_LIST_HEAD(&rng->list); | 364 | INIT_LIST_HEAD(&rng->list); |
| 348 | list_add_tail(&rng->list, &rng_list); | 365 | list_add_tail(&rng->list, &rng_list); |
| 349 | 366 | ||
| 350 | bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1); | 367 | if (old_rng && !rng->init) { |
| 351 | if (bytes_read > 0) | 368 | /* |
| 352 | add_device_randomness(bytes, bytes_read); | 369 | * Use a new device's input to add some randomness to |
| 370 | * the system. If this rng device isn't going to be | ||
| 371 | * used right away, its init function hasn't been | ||
| 372 | * called yet; so only use the randomness from devices | ||
| 373 | * that don't need an init callback. | ||
| 374 | */ | ||
| 375 | add_early_randomness(rng); | ||
| 376 | } | ||
| 377 | |||
| 353 | out_unlock: | 378 | out_unlock: |
| 354 | mutex_unlock(&rng_mutex); | 379 | mutex_unlock(&rng_mutex); |
| 355 | out: | 380 | out: |
