Skip to content

Commit d3cc799

Browse files
amit3sherbertx
authored andcommitted
hwrng: fetch randomness only after device init
Commit d9e7972 "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 <[email protected]> CC: Jason Cooper <[email protected]> CC: Herbert Xu <[email protected]> CC: <[email protected]> # For v3.15+ Signed-off-by: Amit Shah <[email protected]> Reviewed-by: Jason Cooper <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 0378c9a commit d3cc799

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

drivers/char/hw_random/core.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,35 @@ static DEFINE_MUTEX(rng_mutex);
5555
static int data_avail;
5656
static u8 *rng_buffer;
5757

58+
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
59+
int wait);
60+
5861
static size_t rng_buffer_size(void)
5962
{
6063
return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
6164
}
6265

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+
6376
static inline int hwrng_init(struct hwrng *rng)
6477
{
65-
if (!rng->init)
66-
return 0;
67-
return rng->init(rng);
78+
if (rng->init) {
79+
int ret;
80+
81+
ret = rng->init(rng);
82+
if (ret)
83+
return ret;
84+
}
85+
add_early_randomness(rng);
86+
return 0;
6887
}
6988

7089
static inline void hwrng_cleanup(struct hwrng *rng)
@@ -304,8 +323,6 @@ int hwrng_register(struct hwrng *rng)
304323
{
305324
int err = -EINVAL;
306325
struct hwrng *old_rng, *tmp;
307-
unsigned char bytes[16];
308-
int bytes_read;
309326

310327
if (rng->name == NULL ||
311328
(rng->data_read == NULL && rng->read == NULL))
@@ -347,9 +364,17 @@ int hwrng_register(struct hwrng *rng)
347364
INIT_LIST_HEAD(&rng->list);
348365
list_add_tail(&rng->list, &rng_list);
349366

350-
bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
351-
if (bytes_read > 0)
352-
add_device_randomness(bytes, bytes_read);
367+
if (old_rng && !rng->init) {
368+
/*
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+
353378
out_unlock:
354379
mutex_unlock(&rng_mutex);
355380
out:

0 commit comments

Comments
 (0)