Re: [PATCH 1/3] crypto: hwrng use rng source with best quality

2017-07-04 Thread PrasannaKumar Muralidharan
On 3 July 2017 at 15:33, Harald Freudenberger  wrote:
> This patch rewoks the hwrng to always use the
> rng source with best entropy quality.
>
> On registation and unregistration the hwrng now
> tries to choose the best (= highest quality value)
> rng source. The handling of the internal list
> of registered rng sources is now always sorted
> by quality and the top most rng chosen.
>
> Signed-off-by: Harald Freudenberger 
> ---
>  drivers/char/hw_random/core.c | 25 +++--
>  1 file changed, 19 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
> index 503a41d..e9dda16 100644
> --- a/drivers/char/hw_random/core.c
> +++ b/drivers/char/hw_random/core.c
> @@ -29,6 +29,7 @@
>
>  static struct hwrng *current_rng;
>  static struct task_struct *hwrng_fill;
> +/* list of registered rngs, sorted decending by quality */
>  static LIST_HEAD(rng_list);
>  /* Protects rng_list and current_rng */
>  static DEFINE_MUTEX(rng_mutex);
> @@ -417,6 +418,7 @@ int hwrng_register(struct hwrng *rng)
>  {
> int err = -EINVAL;
> struct hwrng *old_rng, *tmp;
> +   struct list_head *rng_list_ptr;
>
> if (!rng->name || (!rng->data_read && !rng->read))
> goto out;
> @@ -432,14 +434,25 @@ int hwrng_register(struct hwrng *rng)
> init_completion(>cleanup_done);
> complete(>cleanup_done);
>
> +   /* rng_list is sorted by decreasing quality */
> +   list_for_each(rng_list_ptr, _list) {
> +   tmp = list_entry(rng_list_ptr, struct hwrng, list);
> +   if (tmp->quality < rng->quality)
> +   break;
> +   }
> +   list_add_tail(>list, rng_list_ptr);
> +
> old_rng = current_rng;
> err = 0;
> -   if (!old_rng) {
> +   if (!old_rng || (rng->quality > old_rng->quality)) {
> +   /*
> +* Set new rng as current as the new rng source
> +* provides better entropy quality.
> +*/
> err = set_current_rng(rng);
> if (err)
> goto out_unlock;
> }
> -   list_add_tail(>list, _list);
>
> if (old_rng && !rng->init) {
> /*
> @@ -466,12 +479,12 @@ void hwrng_unregister(struct hwrng *rng)
> list_del(>list);
> if (current_rng == rng) {
> drop_current_rng();
> +   /* rng_list is sorted by quality, use the best (=first) one */
> if (!list_empty(_list)) {
> -   struct hwrng *tail;
> -
> -   tail = list_entry(rng_list.prev, struct hwrng, list);
> +   struct hwrng *new_rng;
>
> -   set_current_rng(tail);
> +   new_rng = list_entry(rng_list.next, struct hwrng, 
> list);
> +   set_current_rng(new_rng);
> }
> }
>
> --
> 2.7.4
>

Looks good to me.
Reviewed-by: PrasannaKumar Muralidharan .

Regards,
PrasannaKumar


[PATCH 1/3] crypto: hwrng use rng source with best quality

2017-07-03 Thread Harald Freudenberger
This patch rewoks the hwrng to always use the
rng source with best entropy quality.

On registation and unregistration the hwrng now
tries to choose the best (= highest quality value)
rng source. The handling of the internal list
of registered rng sources is now always sorted
by quality and the top most rng chosen.

Signed-off-by: Harald Freudenberger 
---
 drivers/char/hw_random/core.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 503a41d..e9dda16 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -29,6 +29,7 @@
 
 static struct hwrng *current_rng;
 static struct task_struct *hwrng_fill;
+/* list of registered rngs, sorted decending by quality */
 static LIST_HEAD(rng_list);
 /* Protects rng_list and current_rng */
 static DEFINE_MUTEX(rng_mutex);
@@ -417,6 +418,7 @@ int hwrng_register(struct hwrng *rng)
 {
int err = -EINVAL;
struct hwrng *old_rng, *tmp;
+   struct list_head *rng_list_ptr;
 
if (!rng->name || (!rng->data_read && !rng->read))
goto out;
@@ -432,14 +434,25 @@ int hwrng_register(struct hwrng *rng)
init_completion(>cleanup_done);
complete(>cleanup_done);
 
+   /* rng_list is sorted by decreasing quality */
+   list_for_each(rng_list_ptr, _list) {
+   tmp = list_entry(rng_list_ptr, struct hwrng, list);
+   if (tmp->quality < rng->quality)
+   break;
+   }
+   list_add_tail(>list, rng_list_ptr);
+
old_rng = current_rng;
err = 0;
-   if (!old_rng) {
+   if (!old_rng || (rng->quality > old_rng->quality)) {
+   /*
+* Set new rng as current as the new rng source
+* provides better entropy quality.
+*/
err = set_current_rng(rng);
if (err)
goto out_unlock;
}
-   list_add_tail(>list, _list);
 
if (old_rng && !rng->init) {
/*
@@ -466,12 +479,12 @@ void hwrng_unregister(struct hwrng *rng)
list_del(>list);
if (current_rng == rng) {
drop_current_rng();
+   /* rng_list is sorted by quality, use the best (=first) one */
if (!list_empty(_list)) {
-   struct hwrng *tail;
-
-   tail = list_entry(rng_list.prev, struct hwrng, list);
+   struct hwrng *new_rng;
 
-   set_current_rng(tail);
+   new_rng = list_entry(rng_list.next, struct hwrng, list);
+   set_current_rng(new_rng);
}
}
 
-- 
2.7.4