aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/hw_random/core.c41
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);
55static int data_avail; 55static int data_avail;
56static u8 *rng_buffer; 56static u8 *rng_buffer;
57 57
58static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
59 int wait);
60
58static size_t rng_buffer_size(void) 61static 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
66static 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
63static inline int hwrng_init(struct hwrng *rng) 76static 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
70static inline void hwrng_cleanup(struct hwrng *rng) 89static 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
353out_unlock: 378out_unlock:
354 mutex_unlock(&rng_mutex); 379 mutex_unlock(&rng_mutex);
355out: 380out: