Sorry about the typo in the patch subject. Obviously should be
API-NEXT. I'll correct in v7 if that's needed.

On Mon, Dec 5, 2016 at 3:28 PM, Bill Fischofer
<bill.fischo...@linaro.org> wrote:
> Rework the odp_random_data() API to replace the use_entropy with an
> explicit odp_random_kind parameter that controls the type of random
> desired. Two new APIs are also introduced:
>
> - odp_random_max_kind() returns the maximum kind of random data available
>
> - odp_random_repeatable_data() permits applications to generate repeatable
>   random sequences for testing purposes
>
> Because the type signature of odp_random_data() is changed, the
> implementation and validation tests are included here for bisectability.
>
> Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org>
> ---
> Changes in v6:
> - Add odp_random_max_kind() API instead of adding this to the
>   odp_crypto_capability() API.
> - Rename odp_random_seeded_data() to odp_random_repeatable_data()
> - Merge API defs, implementation, and validation to preserve bisectability
>
> Changes in v5:
> - Change return type from int to int32_t for random APIs
>
> Changes in v4:
> - Normalize random API signatures with other ODP APIs
> - Add new odp_random_seeded_data() API for repeatable random data generation
> - Add additional tests for new odp_random_seeded_data() API
> - Break out crypto section of User Guide to its own sub-document
> - Add User Guide docuemntation for ODP random data API.
>
> Changes in v3:
> - Address commments by Petri
> - Rename ODP_RAND_NORMAL to ODP_RANDOM_BASIC to avoid confusion with the
> mathematical term "normal"
>
>  include/odp/api/spec/random.h                   | 58 
> +++++++++++++++++++++++--
>  platform/linux-generic/odp_crypto.c             | 50 ++++++++++++++++++---
>  test/common_plat/validation/api/random/random.c | 54 ++++++++++++++++++++++-
>  test/common_plat/validation/api/random/random.h |  2 +
>  4 files changed, 154 insertions(+), 10 deletions(-)
>
> diff --git a/include/odp/api/spec/random.h b/include/odp/api/spec/random.h
> index 00fa15b..bc130f5 100644
> --- a/include/odp/api/spec/random.h
> +++ b/include/odp/api/spec/random.h
> @@ -24,18 +24,68 @@ extern "C" {
>   */
>
>  /**
> + * Random kind selector
> + */
> +typedef enum {
> +       /** Basic random, presumably pseudo-random generated by SW */
> +       ODP_RANDOM_BASIC,
> +       /** Cryptographic quality random */
> +       ODP_RANDOM_CRYPTO,
> +       /** True random, generated from a HW entropy source */
> +       ODP_RANDOM_TRUE,
> +} odp_random_kind_t;
> +
> +/**
> + * Query random max kind
> + *
> + * @return kind The maximum odp_random_kind_t supported by this 
> implementation
> + */
> +odp_random_kind_t odp_random_max_kind(void);
> +
> +/**
>   * Generate random byte data
>   *
> + * The intent in supporting different kinds of random data is to allow
> + * tradeoffs between performance and the quality of random data needed. The
> + * assumption is that basic random is cheap while true random is relatively
> + * expensive in terms of time to generate, with cryptographic random being
> + * something in between. Implementations that support highly efficient true
> + * random are free to use this for all requested kinds. So it is always
> + * permissible to "upgrade" a random data request, but never to "downgrade"
> + * such requests.
> + *
>   * @param[out]    buf   Output buffer
> - * @param         size  Size of output buffer
> - * @param use_entropy   Use entropy
> + * @param         len   Length of output buffer in bytes
> + * @param         kind  Specifies the type of random data required. Request
> + *                      is expected to fail if the implementation is unable 
> to
> + *                      provide the requested type.
> + *
> + * @return Number of bytes written
> + * @retval <0 on failure
> + */
> +int32_t odp_random_data(uint8_t *buf, uint32_t len, odp_random_kind_t kind);
> +
> +/**
> + * Generate repeatable random byte data
> + *
> + * For testing purposes it is often useful to generate "random" sequences
> + * that are repeatable. This is accomplished by supplying a seed value that
> + * is used for pseudo-random data generation. The caller provides
>   *
> - * @todo Define the implication of the use_entropy parameter
> + * @param[out]    buf  Output buffer
> + * @param         len  Length of output buffer in bytes
> + * @param         kind Specifies the type of random data required. Request
> + *                     will fail if the implementation is unable to provide
> + *                     repeatable random of the requested type. This is
> + *                     always true for true random and may be true for
> + *                     cryptographic random.
> + * @param[in,out] seed Seed value to use
>   *
>   * @return Number of bytes written
>   * @retval <0 on failure
>   */
> -int32_t odp_random_data(uint8_t *buf, int32_t size, odp_bool_t use_entropy);
> +int32_t odp_random_repeatable_data(uint8_t *buf, uint32_t len,
> +                                  odp_random_kind_t kind, uint32_t *seed);
>
>  /**
>   * @}
> diff --git a/platform/linux-generic/odp_crypto.c 
> b/platform/linux-generic/odp_crypto.c
> index 7e686ff..a731528 100644
> --- a/platform/linux-generic/odp_crypto.c
> +++ b/platform/linux-generic/odp_crypto.c
> @@ -4,6 +4,7 @@
>   * SPDX-License-Identifier:     BSD-3-Clause
>   */
>
> +#include <odp_posix_extensions.h>
>  #include <odp/api/crypto.h>
>  #include <odp_internal.h>
>  #include <odp/api/atomic.h>
> @@ -19,6 +20,7 @@
>  #include <odp_packet_internal.h>
>
>  #include <string.h>
> +#include <stdlib.h>
>
>  #include <openssl/des.h>
>  #include <openssl/rand.h>
> @@ -877,12 +879,50 @@ int odp_crypto_term_global(void)
>         return rc;
>  }
>
> -int32_t
> -odp_random_data(uint8_t *buf, int32_t len, odp_bool_t use_entropy ODP_UNUSED)
> +odp_random_kind_t odp_random_max_kind(void)
>  {
> -       int32_t rc;
> -       rc = RAND_bytes(buf, len);
> -       return (1 == rc) ? len /*success*/: -1 /*failure*/;
> +       return ODP_RANDOM_CRYPTO;
> +}
> +
> +int32_t odp_random_data(uint8_t *buf, uint32_t len, odp_random_kind_t kind)
> +{
> +       int rc;
> +
> +       switch (kind) {
> +       case ODP_RANDOM_BASIC:
> +               RAND_pseudo_bytes(buf, len);
> +               return len;
> +
> +       case ODP_RANDOM_CRYPTO:
> +               rc = RAND_bytes(buf, len);
> +               return (1 == rc) ? (int)len /*success*/: -1 /*failure*/;
> +
> +       case ODP_RANDOM_TRUE:
> +       default:
> +               return -1;
> +       }
> +}
> +
> +int32_t odp_random_repeatable_data(uint8_t *buf, uint32_t len,
> +                                  odp_random_kind_t kind, uint32_t *seed)
> +{
> +       union {
> +               uint32_t rand_word;
> +               uint8_t rand_byte[4];
> +       } u;
> +       uint32_t i = 0, j;
> +
> +       if (kind != ODP_RANDOM_BASIC)
> +               return -1;
> +
> +       while (i < len) {
> +               u.rand_word = rand_r(seed);
> +
> +               for (j = 0; j < 4 && i < len; j++, i++)
> +                       *buf++ = u.rand_byte[j];
> +       }
> +
> +       return len;
>  }
>
>  odp_crypto_compl_t odp_crypto_compl_from_event(odp_event_t ev)
> diff --git a/test/common_plat/validation/api/random/random.c 
> b/test/common_plat/validation/api/random/random.c
> index 7572366..3537b2a 100644
> --- a/test/common_plat/validation/api/random/random.c
> +++ b/test/common_plat/validation/api/random/random.c
> @@ -13,12 +13,64 @@ void random_test_get_size(void)
>         int32_t ret;
>         uint8_t buf[32];
>
> -       ret = odp_random_data(buf, sizeof(buf), false);
> +       ret = odp_random_data(buf, sizeof(buf), ODP_RANDOM_BASIC);
>         CU_ASSERT(ret == sizeof(buf));
>  }
>
> +void random_test_kind(void)
> +{
> +       int32_t rc;
> +       uint8_t buf[4096];
> +       uint32_t buf_size = sizeof(buf);
> +       odp_random_kind_t max_kind = odp_random_max_kind();
> +
> +       rc = odp_random_data(buf, buf_size, max_kind);
> +       CU_ASSERT(rc > 0);
> +
> +       switch (max_kind) {
> +       case ODP_RANDOM_BASIC:
> +               rc = odp_random_data(buf, 4, ODP_RANDOM_CRYPTO);
> +               CU_ASSERT(rc < 0);
> +               /* Fall through */
> +
> +       case ODP_RANDOM_CRYPTO:
> +               rc = odp_random_data(buf, 4, ODP_RANDOM_TRUE);
> +               CU_ASSERT(rc < 0);
> +               break;
> +
> +       default:
> +               break;
> +       }
> +}
> +
> +void random_test_repeat(void)
> +{
> +       uint8_t buf1[1024];
> +       uint8_t buf2[1024];
> +       int32_t rc;
> +       uint32_t seed1 = 12345897;
> +       uint32_t seed2 = seed1;
> +
> +       rc = odp_random_repeatable_data(buf1, sizeof(buf1),
> +                                       ODP_RANDOM_BASIC, &seed1);
> +       CU_ASSERT(rc == sizeof(buf1));
> +
> +       rc = odp_random_repeatable_data(buf2, sizeof(buf2),
> +                                       ODP_RANDOM_BASIC, &seed2);
> +
> +       CU_ASSERT(rc == sizeof(buf2));
> +       CU_ASSERT(seed1 == seed2);
> +       CU_ASSERT(memcmp(buf1, buf2, sizeof(buf1)) == 0);
> +
> +       rc = odp_random_repeatable_data(buf1, sizeof(buf1),
> +                                       ODP_RANDOM_TRUE, &seed1);
> +       CU_ASSERT(rc < 0);
> +}
> +
>  odp_testinfo_t random_suite[] = {
>         ODP_TEST_INFO(random_test_get_size),
> +       ODP_TEST_INFO(random_test_kind),
> +       ODP_TEST_INFO(random_test_repeat),
>         ODP_TEST_INFO_NULL,
>  };
>
> diff --git a/test/common_plat/validation/api/random/random.h 
> b/test/common_plat/validation/api/random/random.h
> index 26202cc..c4bca78 100644
> --- a/test/common_plat/validation/api/random/random.h
> +++ b/test/common_plat/validation/api/random/random.h
> @@ -11,6 +11,8 @@
>
>  /* test functions: */
>  void random_test_get_size(void);
> +void random_test_kind(void);
> +void random_test_repeat(void);
>
>  /* test arrays: */
>  extern odp_testinfo_t random_suite[];
> --
> 2.7.4
>

Reply via email to