[PATCH 3/4] getentropy: Add test.

Gedare Bloom gedare at rtems.org
Fri Nov 10 16:14:38 UTC 2017


This is a necessary test, but I don't think it is that sufficient to
give a good idea of the quality of the entropy returned. It would be
better instead to calculate an actual entropy (information theoretic)
measure over multiple calls to getentropy(). The program test logic
could be something like....

---
uint8_t entropy_buffers[n][nr_bytes];
/* fill buffers with guard bits */
...

/* read entropy n times */
for ( i = 0; i  < n; i++ ) {
  rv = getentropy(entropy_buffers[i], nr_bytes);
  assert(rv == 0)
}

/* count the occurrence of each byte pattern, 1 per bin */
uint8_t bin_counts[1<<8];
/* init bin_counts to 0 */
...

for ( i = 0; i < n; i++ ) {
  for ( b = 0; b < nr_bytes; b++ ) {
    bin_counts[entropy_buffers[i][b]]++;
  }
}

/* calculate the entropy of the bins */
float entropy = 0.0;
for ( i = 0; i < 1<<8; i++ ) {
  float p = bin_counts[i] / (n * nr_bytes);
  entropy = entropy + p * log(p)/log(8); /* normalize log to bin size
(8 bits) */
}
entropy = 0.0 - entropy;

/* expect entropy ~ 1 for uniformly distributed values */
---

On Thu, Nov 9, 2017 at 8:23 AM, Christian Mauderer
<christian.mauderer at embedded-brains.de> wrote:
> From: Christian Mauderer <Christian.Mauderer at embedded-brains.de>
>
> ---
>  testsuites/libtests/Makefile.am           |   1 +
>  testsuites/libtests/configure.ac          |   1 +
>  testsuites/libtests/random01/Makefile.am  |  19 ++++++
>  testsuites/libtests/random01/init.c       | 105 ++++++++++++++++++++++++++++++
>  testsuites/libtests/random01/random01.doc |  12 ++++
>  testsuites/libtests/random01/random01.scn |   2 +
>  6 files changed, 140 insertions(+)
>  create mode 100644 testsuites/libtests/random01/Makefile.am
>  create mode 100644 testsuites/libtests/random01/init.c
>  create mode 100644 testsuites/libtests/random01/random01.doc
>  create mode 100644 testsuites/libtests/random01/random01.scn
>
> diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am
> index e72ca1bbaa..c9017301ce 100644
> --- a/testsuites/libtests/Makefile.am
> +++ b/testsuites/libtests/Makefile.am
> @@ -54,6 +54,7 @@ _SUBDIRS += newlib01
>  _SUBDIRS += putenvtest
>  _SUBDIRS += pwdgrp01
>  _SUBDIRS += pwdgrp02
> +_SUBDIRS += random01
>  _SUBDIRS += rbheap01
>  _SUBDIRS += rtmonuse
>  _SUBDIRS += sha
> diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac
> index bbdf4df9d1..1a5e215f3b 100644
> --- a/testsuites/libtests/configure.ac
> +++ b/testsuites/libtests/configure.ac
> @@ -155,6 +155,7 @@ newlib01/Makefile
>  putenvtest/Makefile
>  pwdgrp01/Makefile
>  pwdgrp02/Makefile
> +random01/Makefile
>  rbheap01/Makefile
>  rtmonuse/Makefile
>  sha/Makefile
> diff --git a/testsuites/libtests/random01/Makefile.am b/testsuites/libtests/random01/Makefile.am
> new file mode 100644
> index 0000000000..7c81fc1865
> --- /dev/null
> +++ b/testsuites/libtests/random01/Makefile.am
> @@ -0,0 +1,19 @@
> +rtems_tests_PROGRAMS = random01
> +random01_SOURCES = init.c
> +
> +dist_rtems_tests_DATA = random01.scn random01.doc
> +
> +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
> +include $(top_srcdir)/../automake/compile.am
> +include $(top_srcdir)/../automake/leaf.am
> +
> +AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> +
> +LINK_OBJS = $(random01_OBJECTS)
> +LINK_LIBS = $(random01_LDLIBS)
> +
> +random01$(EXEEXT): $(random01_OBJECTS) $(random01_DEPENDENCIES)
> +       @rm -f random01$(EXEEXT)
> +       $(make-exe)
> +
> +include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/libtests/random01/init.c b/testsuites/libtests/random01/init.c
> new file mode 100644
> index 0000000000..b874a497ee
> --- /dev/null
> +++ b/testsuites/libtests/random01/init.c
> @@ -0,0 +1,105 @@
> +/*
> + * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
> + *
> + *  embedded brains GmbH
> + *  Dornierstr. 4
> + *  82178 Puchheim
> + *  Germany
> + *  <rtems at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include "tmacros.h"
> +
> +#include <rtems.h>
> +#include <unistd.h>
> +#include <assert.h>
> +
> +const char rtems_test_name[] = "RANDOM 1";
> +
> +/* forward declarations to avoid warnings */
> +static rtems_task Init(rtems_task_argument argument);
> +
> +#define TEST_MAX_BYTES 32
> +#define TEST_GUARD_BYTES 32
> +#define TEST_GUARD 0xA5
> +
> +static char entropy_buffer1 [TEST_MAX_BYTES + TEST_GUARD_BYTES];
> +static char entropy_buffer2 [TEST_MAX_BYTES + TEST_GUARD_BYTES];
> +static char guard_buffer [TEST_MAX_BYTES + TEST_GUARD_BYTES];
> +
> +static void test_getentropy(size_t nr_bytes)
> +{
> +  int rv;
> +  size_t try = 1;
> +
> +  /*
> +   * For very small patterns, the probability that two random patterns are the
> +   * same is quite high. Therefore retry the test for these a few times.
> +   */
> +  if (nr_bytes < 4) {
> +    try = 4;
> +  }
> +
> +  do {
> +    --try;
> +
> +    /* Fill buffers with guard pattern */
> +    memset(entropy_buffer1, TEST_GUARD, sizeof(entropy_buffer1));
> +    memset(entropy_buffer2, TEST_GUARD, sizeof(entropy_buffer2));
> +    memset(guard_buffer, TEST_GUARD, sizeof(entropy_buffer2));
> +
> +    /* Get entropy with the given size */
> +    rv = getentropy(entropy_buffer1, nr_bytes);
> +    assert(rv == 0);
> +    rv = getentropy(entropy_buffer2, nr_bytes);
> +    assert(rv == 0);
> +
> +    /* Check guard pattern */
> +    rv = memcmp(entropy_buffer1 + nr_bytes, guard_buffer + nr_bytes,
> +        sizeof(entropy_buffer1) - nr_bytes);
> +    assert(rv == 0);
> +    rv = memcmp(entropy_buffer2 + nr_bytes, guard_buffer + nr_bytes,
> +        sizeof(entropy_buffer2) - nr_bytes);
> +    assert(rv == 0);
> +
> +    /* Make sure that buffers are not the same */
> +    rv = memcmp(entropy_buffer1, entropy_buffer2, sizeof(entropy_buffer1));
> +  } while (try > 0 && rv == 0);
> +  assert(rv != 0);
> +}
> +
> +static void Init(rtems_task_argument arg)
> +{
> +  volatile size_t i;
> +
> +  TEST_BEGIN();
> +
> +  for (i=1; i <= TEST_MAX_BYTES; ++i) {
> +    test_getentropy(i);
> +  }
> +
> +  TEST_END();
> +
> +  rtems_test_exit(0);
> +}
> +
> +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
> +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> +
> +#define CONFIGURE_MAXIMUM_TASKS 1
> +
> +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
> +
> +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
> +
> +#define CONFIGURE_INIT
> +
> +#include <rtems/confdefs.h>
> diff --git a/testsuites/libtests/random01/random01.doc b/testsuites/libtests/random01/random01.doc
> new file mode 100644
> index 0000000000..957da9a680
> --- /dev/null
> +++ b/testsuites/libtests/random01/random01.doc
> @@ -0,0 +1,12 @@
> +This file describes the directives and concepts tested by this test set.
> +
> +test set name: random01
> +
> +directives:
> +
> +  getentropy
> +
> +concepts:
> +
> +  Ensure that getentropy() works with different sizes of arrays and delivers
> +  different values on multiple calls.
> diff --git a/testsuites/libtests/random01/random01.scn b/testsuites/libtests/random01/random01.scn
> new file mode 100644
> index 0000000000..f8cd99f18b
> --- /dev/null
> +++ b/testsuites/libtests/random01/random01.scn
> @@ -0,0 +1,2 @@
> +*** TEST RANDOM 1 ***
> +*** END OF TEST RANDOM 1 ***
> --
> 2.12.3
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list