lkml.org 
[lkml]   [2022]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 006/264] random: convert get_random_int/long into get_random_u32/u64
    Date
    From: "Jason A. Donenfeld" <Jason@zx2c4.com>

    commit c440408cf6901eeb2c09563397e24a9097907078 upstream.

    Many times, when a user wants a random number, he wants a random number
    of a guaranteed size. So, thinking of get_random_int and get_random_long
    in terms of get_random_u32 and get_random_u64 makes it much easier to
    achieve this. It also makes the code simpler.

    On 32-bit platforms, get_random_int and get_random_long are both aliased
    to get_random_u32. On 64-bit platforms, int->u32 and long->u64.

    Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Theodore Ts'o <tytso@mit.edu>
    Signed-off-by: Theodore Ts'o <tytso@mit.edu>
    Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/char/random.c | 63 ++++++++++++++++++++++++++-----------------------
    include/linux/random.h | 17 +++++++++++--
    2 files changed, 49 insertions(+), 31 deletions(-)

    --- a/drivers/char/random.c
    +++ b/drivers/char/random.c
    @@ -2089,57 +2089,62 @@ struct ctl_table random_table[] = {

    struct batched_entropy {
    union {
    - unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)];
    - unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)];
    + u64 entropy_u64[CHACHA20_BLOCK_SIZE / sizeof(u64)];
    + u32 entropy_u32[CHACHA20_BLOCK_SIZE / sizeof(u32)];
    };
    unsigned int position;
    };

    /*
    * Get a random word for internal kernel use only. The quality of the random
    - * number is good as /dev/urandom, but there is no backtrack protection, with
    - * the goal of being quite fast and not depleting entropy.
    + * number is either as good as RDRAND or as good as /dev/urandom, with the
    + * goal of being quite fast and not depleting entropy.
    */
    -static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long);
    -unsigned long get_random_long(void)
    +static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
    +u64 get_random_u64(void)
    {
    - unsigned long ret;
    + u64 ret;
    struct batched_entropy *batch;

    - batch = &get_cpu_var(batched_entropy_long);
    - if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) {
    - extract_crng((u8 *)batch->entropy_long);
    +#if BITS_PER_LONG == 64
    + if (arch_get_random_long((unsigned long *)&ret))
    + return ret;
    +#else
    + if (arch_get_random_long((unsigned long *)&ret) &&
    + arch_get_random_long((unsigned long *)&ret + 1))
    + return ret;
    +#endif
    +
    + batch = &get_cpu_var(batched_entropy_u64);
    + if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
    + extract_crng((u8 *)batch->entropy_u64);
    batch->position = 0;
    }
    - ret = batch->entropy_long[batch->position++];
    - put_cpu_var(batched_entropy_long);
    + ret = batch->entropy_u64[batch->position++];
    + put_cpu_var(batched_entropy_u64);
    return ret;
    }
    -EXPORT_SYMBOL(get_random_long);
    +EXPORT_SYMBOL(get_random_u64);

    -#if BITS_PER_LONG == 32
    -unsigned int get_random_int(void)
    -{
    - return get_random_long();
    -}
    -#else
    -static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int);
    -unsigned int get_random_int(void)
    +static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
    +u32 get_random_u32(void)
    {
    - unsigned int ret;
    + u32 ret;
    struct batched_entropy *batch;

    - batch = &get_cpu_var(batched_entropy_int);
    - if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) {
    - extract_crng((u8 *)batch->entropy_int);
    + if (arch_get_random_int(&ret))
    + return ret;
    +
    + batch = &get_cpu_var(batched_entropy_u32);
    + if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
    + extract_crng((u8 *)batch->entropy_u32);
    batch->position = 0;
    }
    - ret = batch->entropy_int[batch->position++];
    - put_cpu_var(batched_entropy_int);
    + ret = batch->entropy_u32[batch->position++];
    + put_cpu_var(batched_entropy_u32);
    return ret;
    }
    -#endif
    -EXPORT_SYMBOL(get_random_int);
    +EXPORT_SYMBOL(get_random_u32);

    /**
    * randomize_page - Generate a random, page aligned address
    --- a/include/linux/random.h
    +++ b/include/linux/random.h
    @@ -42,8 +42,21 @@ extern void get_random_bytes_arch(void *
    extern const struct file_operations random_fops, urandom_fops;
    #endif

    -unsigned int get_random_int(void);
    -unsigned long get_random_long(void);
    +u32 get_random_u32(void);
    +u64 get_random_u64(void);
    +static inline unsigned int get_random_int(void)
    +{
    + return get_random_u32();
    +}
    +static inline unsigned long get_random_long(void)
    +{
    +#if BITS_PER_LONG == 64
    + return get_random_u64();
    +#else
    + return get_random_u32();
    +#endif
    +}
    +
    unsigned long randomize_page(unsigned long start, unsigned long range);

    /*

    \
     
     \ /
      Last update: 2022-06-23 18:53    [W:4.196 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site