lkml.org 
[lkml]   [2019]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v24 03/12] LRNG - /proc interface
    Date
    The LRNG /proc interface provides the same files as the legacy
    /dev/random. These files behave identically. Yet, all files are
    documented at [1].

    In addition, it provides the file lrng_type which provides details about
    the LRNG:

    - is the TRNG present

    - the name of the DRNG that produces the random numbers for /dev/random,
    /dev/urandom, getrandom(2)

    - the hash used to produce random numbers from the entropy pool

    - the number of secondary DRNG instances

    - indicator whether the LRNG operates SP800-90B compliant

    - indicator whether a high-resolution timer is identified - only with a
    high-resolution timer the interrupt noise source will deliver sufficient
    entropy

    - indicator whether the LRNG has been minimally seeded (i.e. is the
    secondary DRNG seeded with at least 128 bits of of entropy)

    - indicator whether the LRNG has been fully seeded (i.e. is the
    secondary DRNG seeded with at least 256 bits of entropy)

    [1] https://www.chronox.de/lrng.html

    CC: "Eric W. Biederman" <ebiederm@xmission.com>
    CC: "Alexander E. Patrakov" <patrakov@gmail.com>
    CC: "Ahmed S. Darwish" <darwish.07@gmail.com>
    CC: "Theodore Y. Ts'o" <tytso@mit.edu>
    CC: Willy Tarreau <w@1wt.eu>
    CC: Matthew Garrett <mjg59@srcf.ucam.org>
    CC: Vito Caputo <vcaputo@pengaru.com>
    CC: Andreas Dilger <adilger.kernel@dilger.ca>
    CC: Jan Kara <jack@suse.cz>
    CC: Ray Strode <rstrode@redhat.com>
    CC: William Jon McCann <mccann@jhu.edu>
    CC: zhangjs <zachary@baishancloud.com>
    CC: Andy Lutomirski <luto@kernel.org>
    CC: Florian Weimer <fweimer@redhat.com>
    CC: Lennart Poettering <mzxreary@0pointer.de>
    CC: Nicolai Stange <nstange@suse.de>
    Reviewed-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
    Reviewed-by: Roman Drahtmueller <draht@schaltsekun.de>
    Tested-by: Roman Drahtmüller <draht@schaltsekun.de>
    Tested-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
    Tested-by: Neil Horman <nhorman@redhat.com>
    Signed-off-by: Stephan Mueller <smueller@chronox.de>
    ---
    drivers/char/lrng/Makefile | 1 +
    drivers/char/lrng/lrng_interfaces.c | 1 -
    drivers/char/lrng/lrng_internal.h | 4 +
    drivers/char/lrng/lrng_proc.c | 192 ++++++++++++++++++++++++++++
    4 files changed, 197 insertions(+), 1 deletion(-)
    create mode 100644 drivers/char/lrng/lrng_proc.c

    diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
    index a00cddb45773..b6240b73e33d 100644
    --- a/drivers/char/lrng/Makefile
    +++ b/drivers/char/lrng/Makefile
    @@ -9,3 +9,4 @@ obj-y += lrng_pool.o lrng_aux.o \
    lrng_interfaces.o \

    obj-$(CONFIG_NUMA) += lrng_numa.o
    +obj-$(CONFIG_SYSCTL) += lrng_proc.o
    diff --git a/drivers/char/lrng/lrng_interfaces.c b/drivers/char/lrng/lrng_interfaces.c
    index e652849a1bdb..1c9517c6df4a 100644
    --- a/drivers/char/lrng/lrng_interfaces.c
    +++ b/drivers/char/lrng/lrng_interfaces.c
    @@ -56,7 +56,6 @@ static DECLARE_WAIT_QUEUE_HEAD(lrng_write_wait);
    static DECLARE_WAIT_QUEUE_HEAD(lrng_init_wait);
    static struct fasync_struct *fasync;

    -struct ctl_table random_table[];
    /********************************** Helper ***********************************/

    /* Is the primary DRNG seed level too low? */
    diff --git a/drivers/char/lrng/lrng_internal.h b/drivers/char/lrng/lrng_internal.h
    index e6ac2c527378..8528c2e8de88 100644
    --- a/drivers/char/lrng/lrng_internal.h
    +++ b/drivers/char/lrng/lrng_internal.h
    @@ -116,7 +116,11 @@ void lrng_cc20_init_state(struct chacha20_state *state);

    /********************************** /proc *************************************/

    +#ifdef CONFIG_SYSCTL
    +void lrng_pool_inc_numa_node(void);
    +#else
    static inline void lrng_pool_inc_numa_node(void) { }
    +#endif

    /****************************** LRNG interfaces *******************************/

    diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
    new file mode 100644
    index 000000000000..0e67dd4e5901
    --- /dev/null
    +++ b/drivers/char/lrng/lrng_proc.c
    @@ -0,0 +1,192 @@
    +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
    +/*
    + * LRNG proc interfaces
    + *
    + * Copyright (C) 2016 - 2019, Stephan Mueller <smueller@chronox.de>
    + *
    + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
    + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
    + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
    + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
    + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
    + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
    + * DAMAGE.
    + */
    +
    +#include <linux/lrng.h>
    +#include <linux/sysctl.h>
    +#include <linux/uuid.h>
    +
    +#include "lrng_internal.h"
    +
    +/* Number of online DRNGs */
    +static u32 numa_drngs = 1;
    +
    +void lrng_pool_inc_numa_node(void)
    +{
    + numa_drngs++;
    +}
    +
    +/*
    + * This function is used to return both the bootid UUID, and random
    + * UUID. The difference is in whether table->data is NULL; if it is,
    + * then a new UUID is generated and returned to the user.
    + *
    + * If the user accesses this via the proc interface, the UUID will be
    + * returned as an ASCII string in the standard UUID format; if via the
    + * sysctl system call, as 16 bytes of binary data.
    + */
    +static int lrng_proc_do_uuid(struct ctl_table *table, int write,
    + void __user *buffer, size_t *lenp, loff_t *ppos)
    +{
    + struct ctl_table fake_table;
    + unsigned char buf[64], tmp_uuid[16], *uuid;
    +
    + uuid = table->data;
    + if (!uuid) {
    + uuid = tmp_uuid;
    + generate_random_uuid(uuid);
    + } else {
    + static DEFINE_SPINLOCK(bootid_spinlock);
    +
    + spin_lock(&bootid_spinlock);
    + if (!uuid[8])
    + generate_random_uuid(uuid);
    + spin_unlock(&bootid_spinlock);
    + }
    +
    + sprintf(buf, "%pU", uuid);
    +
    + fake_table.data = buf;
    + fake_table.maxlen = sizeof(buf);
    +
    + return proc_dostring(&fake_table, write, buffer, lenp, ppos);
    +}
    +
    +static int lrng_proc_do_type(struct ctl_table *table, int write,
    + void __user *buffer, size_t *lenp, loff_t *ppos)
    +{
    + struct lrng_sdrng *lrng_sdrng_init = lrng_sdrng_init_instance();
    + struct ctl_table fake_table;
    + unsigned long flags = 0;
    + unsigned char buf[300];
    +
    + lrng_sdrng_lock(lrng_sdrng_init, &flags);
    + snprintf(buf, sizeof(buf),
    +#ifdef CONFIG_LRNG_TRNG_SUPPORT
    + "TRNG present: true\n"
    +#else
    + "TRNG present: false\n"
    +#endif
    + "DRNG name: %s\n"
    + "Hash for reading entropy pool: %s\n"
    + "DRNG security strength: %d bits\n"
    + "number of secondary DRNG instances: %u\n"
    + "SP800-90B compliance: %s\n"
    + "High-resolution timer: %s\n"
    + "LRNG minimally seeded: %s\n"
    + "LRNG fully seeded: %s",
    + lrng_sdrng_init->crypto_cb->lrng_drng_name(),
    + lrng_sdrng_init->crypto_cb->lrng_hash_name(),
    + LRNG_DRNG_SECURITY_STRENGTH_BITS, numa_drngs,
    + lrng_sp80090b_compliant() ? "true" : "false",
    + lrng_pool_highres_timer() ? "true" : "false",
    + lrng_state_min_seeded() ? "true" : "false",
    + lrng_state_fully_seeded() ? "true" : "false");
    + lrng_sdrng_unlock(lrng_sdrng_init, &flags);
    +
    + fake_table.data = buf;
    + fake_table.maxlen = sizeof(buf);
    +
    + return proc_dostring(&fake_table, write, buffer, lenp, ppos);
    +}
    +
    +static int lrng_proc_do_entropy(struct ctl_table *table, int write,
    + void __user *buffer, size_t *lenp, loff_t *ppos)
    +{
    + struct ctl_table fake_table;
    + int entropy_count;
    +
    + entropy_count = lrng_avail_entropy();
    +
    + fake_table.data = &entropy_count;
    + fake_table.maxlen = sizeof(entropy_count);
    +
    + return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
    +}
    +
    +static int lrng_sysctl_poolsize = LRNG_POOL_SIZE_BITS;
    +static int lrng_min_read_thresh = LRNG_POOL_WORD_BITS;
    +static int lrng_min_write_thresh;
    +static int lrng_max_read_thresh = LRNG_POOL_SIZE_BITS;
    +static int lrng_max_write_thresh = LRNG_POOL_SIZE_BITS;
    +static char lrng_sysctl_bootid[16];
    +static int lrng_sdrng_reseed_max_min;
    +
    +extern struct ctl_table random_table[];
    +struct ctl_table random_table[] = {
    + {
    + .procname = "poolsize",
    + .data = &lrng_sysctl_poolsize,
    + .maxlen = sizeof(int),
    + .mode = 0444,
    + .proc_handler = proc_dointvec,
    + },
    + {
    + .procname = "entropy_avail",
    + .maxlen = sizeof(int),
    + .mode = 0444,
    + .proc_handler = lrng_proc_do_entropy,
    + },
    + {
    + .procname = "read_wakeup_threshold",
    + .data = &lrng_read_wakeup_bits,
    + .maxlen = sizeof(int),
    + .mode = 0644,
    + .proc_handler = proc_dointvec_minmax,
    + .extra1 = &lrng_min_read_thresh,
    + .extra2 = &lrng_max_read_thresh,
    + },
    + {
    + .procname = "write_wakeup_threshold",
    + .data = &lrng_write_wakeup_bits,
    + .maxlen = sizeof(int),
    + .mode = 0644,
    + .proc_handler = proc_dointvec_minmax,
    + .extra1 = &lrng_min_write_thresh,
    + .extra2 = &lrng_max_write_thresh,
    + },
    + {
    + .procname = "boot_id",
    + .data = &lrng_sysctl_bootid,
    + .maxlen = 16,
    + .mode = 0444,
    + .proc_handler = lrng_proc_do_uuid,
    + },
    + {
    + .procname = "uuid",
    + .maxlen = 16,
    + .mode = 0444,
    + .proc_handler = lrng_proc_do_uuid,
    + },
    + {
    + .procname = "urandom_min_reseed_secs",
    + .data = &lrng_sdrng_reseed_max_time,
    + .maxlen = sizeof(int),
    + .mode = 0644,
    + .proc_handler = proc_dointvec,
    + .extra1 = &lrng_sdrng_reseed_max_min,
    + },
    + {
    + .procname = "lrng_type",
    + .maxlen = 30,
    + .mode = 0444,
    + .proc_handler = lrng_proc_do_type,
    + },
    + { }
    +};
    --
    2.23.0



    \
     
     \ /
      Last update: 2019-11-11 20:15    [W:4.495 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site