All H/W RNG Drivers: Can now be configured to register as /dev/random and/or /dev/urandom

This commit is contained in:
Gregory Nutt 2016-07-18 11:10:37 -06:00
parent 1660329d06
commit 078bbe5e5c
4 changed files with 208 additions and 39 deletions

View File

@ -59,6 +59,9 @@
#include "sam_periphclks.h" #include "sam_periphclks.h"
#include "sam_trng.h" #include "sam_trng.h"
#if defined(CONFIG_SAMA5_TRNG)
#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
@ -325,14 +328,10 @@ errout:
} }
/**************************************************************************** /****************************************************************************
* Public Functions * Name: sam_rng_initialize
****************************************************************************/
/****************************************************************************
* Name: devrandom_register
* *
* Description: * Description:
* Initialize the TRNG hardware and register the /dev/random driver. * Initialize the TRNG hardware.
* *
* Input Parameters: * Input Parameters:
* None * None
@ -342,7 +341,7 @@ errout:
* *
****************************************************************************/ ****************************************************************************/
int devrandom_register(void) static int sam_rng_initialize(void)
{ {
int ret; int ret;
@ -375,17 +374,78 @@ int devrandom_register(void)
putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR);
/* Register the character driver */
ret = register_driver("/dev/random", &g_trngops, 0644, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to register /dev/random\n");
return ret;
}
/* Enable the TRNG interrupt at the AIC */ /* Enable the TRNG interrupt at the AIC */
up_enable_irq(SAM_IRQ_TRNG); up_enable_irq(SAM_IRQ_TRNG);
return OK; return OK;
} }
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: devrandom_register
*
* Description:
* Initialize the TRNG hardware and register the /dev/random driver.
* Must be called BEFORE devurandom_register.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_DEV_RANDOM
int devrandom_register(void)
{
int ret;
ret = sam_rng_initialize();
if (ret >= 0)
{
ret = register_driver("/dev/random", &g_trngops, 0644, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to register /dev/random\n");
}
}
return ret;
}
#endif
/****************************************************************************
* Name: devurandom_register
*
* Description:
* Register /dev/urandom
*
****************************************************************************/
#ifdef CONFIG_DEV_URANDOM_ARCH
int devurandom_register(void)
{
int ret;
#ifndef CONFIG_DEV_RANDOM
ret = sam_rng_initialize();
if (ret >= 0)
#endif
{
ret = register_driver("/dev/urandom", &g_trngops, 0644, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to register /dev/urandom\n");
}
}
return ret;
}
#endif
#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */
#endif /* CONFIG_SAMA5_TRNG */

View File

@ -60,6 +60,9 @@
#include "sam_periphclks.h" #include "sam_periphclks.h"
#include "sam_trng.h" #include "sam_trng.h"
#if defined(CONFIG_SAMV7_TRNG)
#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
@ -326,14 +329,10 @@ errout:
} }
/**************************************************************************** /****************************************************************************
* Public Functions * Name: sam_rng_initialize
****************************************************************************/
/****************************************************************************
* Name: devrandom_register
* *
* Description: * Description:
* Initialize the TRNG hardware and register the /dev/random driver. * Initialize the TRNG hardware.
* *
* Input Parameters: * Input Parameters:
* None * None
@ -343,7 +342,7 @@ errout:
* *
****************************************************************************/ ****************************************************************************/
int devrandom_register(void) static int sam_rng_initialize(void)
{ {
int ret; int ret;
@ -376,17 +375,77 @@ int devrandom_register(void)
putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR);
/* Register the character driver */
ret = register_driver("/dev/random", &g_trngops, 0644, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to register /dev/random\n");
return ret;
}
/* Enable the TRNG interrupt at the AIC */ /* Enable the TRNG interrupt at the AIC */
up_enable_irq(SAM_IRQ_TRNG); up_enable_irq(SAM_IRQ_TRNG);
return OK; return OK;
} }
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: devrandom_register
*
* Description:
* Initialize the TRNG hardware and register the /dev/random driver.
* Must be called BEFORE devurandom_register.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_DEV_RANDOM
int devrandom_register(void)
{
int ret;
ret = sam_rng_initialize();
if (ret >= 0)
{
ret = register_driver("/dev/random", &g_trngops, 0644, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to register /dev/random\n");
}
}
return ret;
}
#endif
/****************************************************************************
* Name: devurandom_register
*
* Description:
* Register /dev/urandom
*
****************************************************************************/
#ifdef CONFIG_DEV_URANDOM_ARCH
int devurandom_register(void)
{
int ret;
#ifndef CONFIG_DEV_RANDOM
ret = sam_rng_initialize();
if (ret >= 0)
#endif
{
ret = register_driver("/dev/urandom", &g_trngops, 0644, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to register /dev/urandom\n");
}
}
return ret;
}
#endif
#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */

View File

@ -51,11 +51,14 @@
#include "chip/stm32_rng.h" #include "chip/stm32_rng.h"
#include "up_internal.h" #include "up_internal.h"
#if defined(CONFIG_STM32_RNG)
#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
static int stm32_rnginitialize(void); static int stm32_rng_initialize(void);
static int stm32_interrupt(int irq, void *context); static int stm32_interrupt(int irq, void *context);
static void stm32_enable(void); static void stm32_enable(void);
static void stm32_disable(void); static void stm32_disable(void);
@ -98,7 +101,7 @@ static const struct file_operations g_rngops =
* Private functions * Private functions
****************************************************************************/ ****************************************************************************/
static int stm32_rnginitialize() static int stm32_rng_initialize()
{ {
uint32_t regval; uint32_t regval;
@ -263,6 +266,7 @@ static ssize_t stm32_read(struct file *filep, char *buffer, size_t buflen)
* *
* Description: * Description:
* Initialize the RNG hardware and register the /dev/random driver. * Initialize the RNG hardware and register the /dev/random driver.
* Must be called BEFORE devurandom_register.
* *
* Input Parameters: * Input Parameters:
* None * None
@ -272,8 +276,31 @@ static ssize_t stm32_read(struct file *filep, char *buffer, size_t buflen)
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_DEV_RANDOM
int devrandom_register(void) int devrandom_register(void)
{ {
stm32_rnginitialize(); stm32_rng_initialize();
return register_driver("/dev/random", &g_rngops, 0444, NULL); return register_driver("/dev/random", &g_rngops, 0444, NULL);
} }
#endif
/****************************************************************************
* Name: devurandom_register
*
* Description:
* Register /dev/urandom
*
****************************************************************************/
#ifdef CONFIG_DEV_URANDOM_ARCH
int devurandom_register(void)
{
#ifndef CONFIG_DEV_RANDOM
stm32l4_rnginitialize();
#endif
return register_driver("/dev/urandom", &g_rngops, 0444, NULL);
}
#endif
#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */
#endif /* CONFIG_STM32_RNG */

View File

@ -52,13 +52,14 @@
#include "chip/stm32l4_rng.h" #include "chip/stm32l4_rng.h"
#include "up_internal.h" #include "up_internal.h"
#ifdef CONFIG_STM32L4_RNG #if defined(CONFIG_STM32L4_RNG)
#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
static int stm32l4_rnginitialize(void); static int stm32l4_rng_initialize(void);
static int stm32l4_rnginterrupt(int irq, void *context); static int stm32l4_rnginterrupt(int irq, void *context);
static void stm32l4_rngenable(void); static void stm32l4_rngenable(void);
static void stm32l4_rngdisable(void); static void stm32l4_rngdisable(void);
@ -105,7 +106,7 @@ static const struct file_operations g_rngops =
* Private functions * Private functions
****************************************************************************/ ****************************************************************************/
static int stm32l4_rnginitialize(void) static int stm32l4_rng_initialize(void)
{ {
_info("Initializing RNG\n"); _info("Initializing RNG\n");
@ -294,6 +295,7 @@ static ssize_t stm32l4_rngread(struct file *filep, char *buffer, size_t buflen)
* *
* Description: * Description:
* Initialize the RNG hardware and register the /dev/random driver. * Initialize the RNG hardware and register the /dev/random driver.
* Must be called BEFORE devurandom_register.
* *
* Input Parameters: * Input Parameters:
* None * None
@ -303,10 +305,31 @@ static ssize_t stm32l4_rngread(struct file *filep, char *buffer, size_t buflen)
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_DEV_RANDOM
int devrandom_register(void) int devrandom_register(void)
{ {
stm32l4_rnginitialize(); stm32l4_rng_initialize();
return register_driver("/dev/random", &g_rngops, 0444, NULL); return register_driver("/dev/random", &g_rngops, 0444, NULL);
} }
#endif
/****************************************************************************
* Name: devurandom_register
*
* Description:
* Register /dev/urandom
*
****************************************************************************/
#ifdef CONFIG_DEV_URANDOM_ARCH
int devurandom_register(void)
{
#ifndef CONFIG_DEV_RANDOM
stm32l4_rng_initialize();
#endif
return register_driver("/dev/urandom", &g_rngops, 0444, NULL);
}
#endif
#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */
#endif /* CONFIG_STM32L4_RNG */ #endif /* CONFIG_STM32L4_RNG */