Introduce public APIs for random number generation

Convert the existing non-public random number generation APIs
into public APIs (i.e. sys_rand32_init and sys_rand32_get).

Change-Id: Id93e81e351a66d02c08cf3f5d2dd54a3b4b213c5
Signed-off-by: Dmitriy Korovkin <dmitriy.korovkin@windriver.com>
This commit is contained in:
Dmitriy Korovkin 2015-05-25 12:22:44 -04:00 committed by Anas Nashif
parent e2fa00be6e
commit ec8a461bfb
6 changed files with 45 additions and 23 deletions

View file

@ -1,4 +1,4 @@
/* rand32.c - non-random number generator */ /* non-random number generator based on x86 CPU timestamp */
/* /*
* Copyright (c) 2013-2014 Wind River Systems, Inc. * Copyright (c) 2013-2014 Wind River Systems, Inc.
@ -32,10 +32,10 @@
/* /*
DESCRIPTION DESCRIPTION
This module provides a non-random implementation of _Rand32Get(), which is not This module provides a non-random implementation of sys_rand32_get(), which is
meant to be used in a final product as a truly random number generator. It not meant to be used in a final product as a truly random number generator. It
was provided to allow testing of kernel stack canaries on a BSP that does not was provided to allow testing on a BSP that does not (yet) provide a random
(yet) provide a random number generator. number generator.
*/ */
#include <nanokernel.h> #include <nanokernel.h>
@ -44,20 +44,21 @@ was provided to allow testing of kernel stack canaries on a BSP that does not
/******************************************************************************* /*******************************************************************************
* *
* _Rand32Init - initialize the random number generator * sys_rand32_init - initialize the random number generator
* *
* The non-random number generator does not require any initialization. * The non-random number generator does not require any initialization.
* Routine is automatically invoked by the kernel during system startup.
* *
* RETURNS: N/A * RETURNS: N/A
*/ */
void _Rand32Init(void) void sys_rand32_init(void)
{ {
} }
/******************************************************************************* /*******************************************************************************
* *
* _Rand32Get - get a 32 bit random number * sys_rand32_get - get a 32 bit random number
* *
* The non-random number generator returns values that are based off the * The non-random number generator returns values that are based off the
* CPU's timestamp counter, which means that successive calls will normally * CPU's timestamp counter, which means that successive calls will normally
@ -66,7 +67,7 @@ void _Rand32Init(void)
* RETURNS: a 32-bit number * RETURNS: a 32-bit number
*/ */
uint32_t _Rand32Get(void) uint32_t sys_rand32_get(void)
{ {
return _do_read_cpu_timestamp32(); return _do_read_cpu_timestamp32();
} }

View file

@ -1,4 +1,4 @@
/* rand32.c - random number generator */ /* non-random number generator based on system timer */
/* /*
* Copyright (c) 2013-2015 Wind River Systems, Inc. * Copyright (c) 2013-2015 Wind River Systems, Inc.
@ -32,10 +32,10 @@
/* /*
DESCRIPTION DESCRIPTION
This module provides a non-random implementation of _Rand32Get(), which is not This module provides a non-random implementation of sys_rand32_get(), which is
meant to be used in a final product as a truly random number generator. It not meant to be used in a final product as a truly random number generator. It
was provided to allow testing of kernel stack canaries on a BSP that does not was provided to allow testing on a BSP that does not (yet) provide a random
(yet) provide a random number generator. number generator.
*/ */
#include <drivers/rand32.h> #include <drivers/rand32.h>
@ -54,21 +54,23 @@ static atomic_val_t _rand32_counter = 0;
/******************************************************************************* /*******************************************************************************
* *
* _Rand32Init - initialize the random number generator * sys_rand32_init - initialize the random number generator
* *
* The non-random number generator does not require any initialization. * The non-random number generator does not require any initialization.
* This routine is automatically invoked by the kernel during system
* initialization.
* *
* RETURNS: N/A * RETURNS: N/A
*/ */
void _Rand32Init(void) void sys_rand32_init(void)
{ {
} }
/******************************************************************************* /*******************************************************************************
* *
* _Rand32Get - get a 32 bit random number * sys_rand32_get - get a 32 bit random number
* *
* The non-random number generator returns values that are based off the * The non-random number generator returns values that are based off the
* target's clock counter, which means that successive calls will return * target's clock counter, which means that successive calls will return
@ -77,7 +79,7 @@ void _Rand32Init(void)
* RETURNS: a 32-bit number * RETURNS: a 32-bit number
*/ */
uint32_t _Rand32Get(void) uint32_t sys_rand32_get(void)
{ {
return timer_read() + atomic_add(&_rand32_counter, _RAND32_INC); return timer_read() + atomic_add(&_rand32_counter, _RAND32_INC);
} }

View file

@ -36,7 +36,8 @@ This header file declares prototypes for the kernel's random number generator
APIs. APIs.
Typically a BSP should enable the hidden CUSTOM_RANDOM_GENERATOR configuration Typically a BSP should enable the hidden CUSTOM_RANDOM_GENERATOR configuration
option and provide its the implementations for _Rand32Init() and _Rand32Get(). option and provide its the implementations for sys_rand32_init() and
sys_rand32_get().
However, if it does not do so a project requiring random numbers must implement However, if it does not do so a project requiring random numbers must implement
these routines, or (for testing purposes only) enable the TEST_RANDOM_GENERATOR these routines, or (for testing purposes only) enable the TEST_RANDOM_GENERATOR
configuration option. configuration option.
@ -47,7 +48,7 @@ configuration option.
#include <stdint.h> #include <stdint.h>
extern void _Rand32Init(void); extern void sys_rand32_init(void);
extern uint32_t _Rand32Get(void); extern uint32_t sys_rand32_get(void);
#endif /* __INCrand32h */ #endif /* __INCrand32h */

View file

@ -38,6 +38,7 @@
#include <cputype.h> #include <cputype.h>
#include <microkernel/k_types.h> #include <microkernel/k_types.h>
#include <clock_vars.h> #include <clock_vars.h>
#include <drivers/rand32.h>
#include <microkernel/task.h> #include <microkernel/task.h>
#include <microkernel/ticks.h> #include <microkernel/ticks.h>

View file

@ -39,6 +39,7 @@
#include <nanokernel/private.h> #include <nanokernel/private.h>
#include <kernel_version.h> #include <kernel_version.h>
#include <clock_vars.h> #include <clock_vars.h>
#include <drivers/rand32.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View file

@ -69,6 +69,14 @@ const char * const build_timestamp = BUILD_TIMESTAMP;
#define PRINT_BOOT_BANNER() printk(BOOT_BANNER " %s\n", build_timestamp) #define PRINT_BOOT_BANNER() printk(BOOT_BANNER " %s\n", build_timestamp)
#endif #endif
/* random number generator items */
#if defined(CONFIG_TEST_RANDOM_GENERATOR) || \
defined(CONFIG_CUSTOM_RANDOM_GENERATOR)
#define RAND32_INIT() sys_rand32_init()
#else
#define RAND32_INIT()
#endif
/* stack space for the background (or idle) task context */ /* stack space for the background (or idle) task context */
static char __noinit main_task_stack[CONFIG_MAIN_STACK_SIZE]; static char __noinit main_task_stack[CONFIG_MAIN_STACK_SIZE];
@ -201,8 +209,7 @@ extern void *__stack_chk_guard;
#define STACK_CANARY_INIT() \ #define STACK_CANARY_INIT() \
do { \ do { \
register void *tmp; \ register void *tmp; \
_Rand32Init(); \ tmp = (void *)sys_rand32_get(); \
tmp = (void *)_Rand32Get(); \
__asm__ volatile(_MOVE_INSTR "%1, %0;\n\t" \ __asm__ volatile(_MOVE_INSTR "%1, %0;\n\t" \
: "=m"(__stack_chk_guard) \ : "=m"(__stack_chk_guard) \
: "r"(tmp)); \ : "r"(tmp)); \
@ -241,6 +248,15 @@ FUNC_NORETURN void _Cstart(void)
_InitHardware(); _InitHardware();
/*
* Initialize random number generator
* As a platform may implement it in hardware, it has to be
* initialized after rest of hardware initialization and
* before stack canaries that use it
*/
RAND32_INIT();
/* initialize stack canaries */ /* initialize stack canaries */
STACK_CANARY_INIT(); STACK_CANARY_INIT();