Patch for BBB: >From a6b3b58a38a6925bf26b6573f36fc652708f9f32 Mon Sep 17 00:00:00 2001 From: Udit agarwal <dev.mada...@gmail.com> Date: Fri, 16 Mar 2018 15:37:05 +0530 Subject: [PATCH] arm/beagle: add TRNG based getentropy implementation
--- bsps/arm/include/libcpu/am335x.h | 33 ++++++ c/src/lib/libbsp/arm/beagle/Makefile.am | 4 +- c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c | 130 +++++++++++++++++++++++ 3 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c diff --git a/bsps/arm/include/libcpu/am335x.h b/bsps/arm/include/libcpu/am335x.h index 367e97c..a6fb8b8 100644 --- a/bsps/arm/include/libcpu/am335x.h +++ b/bsps/arm/include/libcpu/am335x.h @@ -14,11 +14,17 @@ * Modified by Ben Gras <b...@shrike-systems.com> to add lots * of beagleboard/beaglebone definitions, delete lpc32xx specific * ones, and merge with some other header files. + * + * Modified by Udit agarwal <dev.mada...@gmail.com> to add true random + * number generating module definitions and TRNG register structure. */ #if !defined(_AM335X_H_) #define _AM335X_H_ +/* For TRNG register definition */ +#include <stdint.h> + /* Interrupt controller memory map */ #define OMAP3_DM37XX_INTR_BASE 0x48200000 /* INTCPS physical address */ @@ -701,4 +707,31 @@ #define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK (0x00000020u) #define AM335X_I2C_INT_STOP_CONDITION AM335X_I2C_IRQSTATUS_BF +/* TRNG Registers */ +/* TRNG base address */ +#define TRNG_BASE 0x48310000 +/* Mask bits for trng clock status */ +#define AM335X_CLK_TRNG_BIT_MASK (0x30000) +/* Mask bits for output ready flag */ +#define TRNG_STATUS_RDY (1u << 0) +/* Mask bits for FRO related error */ +#define TRNG_STATUS_ERR (1u << 1) +/* Mask bits for clock status */ +#define TRNG_STATUS_CLK (1u << 31) +/* enable module */ +#define AM335X_TRNG_ENABLE (1 << 10) + +/* TRNG module clock register */ +#define CM_PER_TRNG_CLKCTRL (AM335X_CM_PER_ADDR | (9 << 4)) + +/* TRNG register structure */ +typedef struct { + uint64_t output; /* 00 */ + uint32_t status; /* 08 */ + uint32_t irq_en; /* 0c */ + uint32_t status_clr; /* 10 */ + uint32_t control; /* 14 */ + uint32_t config; /* 18 */ +} am335x_trng_register; + #endif diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am index 8251660..c483dc4 100644 --- a/c/src/lib/libbsp/arm/beagle/Makefile.am +++ b/c/src/lib/libbsp/arm/beagle/Makefile.am @@ -40,7 +40,6 @@ libbsp_a_LIBADD = # Shared libbsp_a_SOURCES += ../../shared/bootcard.c -libbsp_a_SOURCES += ../../shared/getentropy-cpucounter.c libbsp_a_SOURCES += ../../shared/src/bsp-fdt.c libbsp_a_SOURCES += ../../shared/bspclean.c libbsp_a_SOURCES += ../../shared/bspgetworkarea.c @@ -88,6 +87,9 @@ libbsp_a_SOURCES += gpio/bbb-gpio.c #pwm libbsp_a_SOURCES += pwm/pwm.c +#getentropy +libbsp_a_SOURCES += dev/bbb_getentropy.c + #RTC libbsp_a_SOURCES += rtc.c libbsp_a_SOURCES += ../../shared/tod.c diff --git a/c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c b/c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c new file mode 100644 index 0000000..b3ea681 --- /dev/null +++ b/c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c @@ -0,0 +1,130 @@ +/** +* @file +* +* @ingroup arm_beagle +* +* @brief Getentropy implementation on BeagleBone Black BSP +*/ + +/* +* Copyright (c) 2018 Udit agarwal <dev.madaari at gmail.com> +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +#include <libcpu/am335x.h> +#include <unistd.h> +#include <string.h> +#include <rtems/sysinit.h> +#include <rtems/thread.h> +#include <stdint.h> + +/* max refill 34 * 256 cycles */ +#define AM335X_TRNG_MAX_REFILL (34 << 16) +/* min refill 33 * 64 cycles */ +#define AM335X_TRNG_MIN_REFILL (33 << 0) +/* startup 33 * 256 cycles */ +#define AM335X_TRNG_STARTUP_CYCLES (33 << 16) + +static rtems_mutex am335x_trng_mutex = + RTEMS_MUTEX_INITIALIZER("am335x_trng"); + +/* maximun and minimum refill cycle sets the number of samples to be taken + * from FRO to generate random number */ +static void am335x_trng_enable(volatile am335x_trng_register *trng) +{ + trng->control = trng->config = 0; + trng->config |= AM335X_TRNG_MIN_REFILL | AM335X_TRNG_MAX_REFILL ; + trng->control |= AM335X_TRNG_STARTUP_CYCLES | AM335X_TRNG_ENABLE ; +} + +static void am335x_trng_clock_enable(void) +{ + volatile am335x_trng_register *trng = (am335x_trng_register*) TRNG_BASE; + *(volatile uint8_t *) CM_PER_TRNG_CLKCTRL = 2; + while( + *(volatile uint32_t *) CM_PER_TRNG_CLKCTRL & + AM335X_CLK_TRNG_BIT_MASK + ) { + /* wait */ + } + am335x_trng_enable(trng); +} + +static uint64_t trng_getranddata(volatile am335x_trng_register *trng) +{ + uint64_t output = trng->output; + return output; +} + +int getentropy(void *ptr, size_t n) +{ + volatile am335x_trng_register *trng = + (am335x_trng_register*) TRNG_BASE; + + /* for mutual exclusion synchronization between multiple + * access to TRNG register in different contexts */ + rtems_mutex_lock(&am335x_trng_mutex); + + while ( n > 0 ) + { + uint64_t random; + size_t copy; + + /* wait untill TRNG becomes ready with next set of random data */ + while ( ( trng->status & TRNG_STATUS_RDY ) == 0 ) + { + /* wait */ + } + + random = trng_getranddata(trng); + + /* clear the status flag after reading to generate new random + * value */ + trng->status_clr = TRNG_STATUS_RDY; + + /* checking for error by masking all bits other then error bit in + * status register */ + if ( ((trng->status & TRNG_STATUS_ERR) >> 1) == 1 ) + { + copy = sizeof(random); + if ( n < copy ) + { + copy = n; + } + memcpy(ptr, &random, copy); + n -= copy; + ptr = (char*)ptr + copy; + } + + } + + rtems_mutex_unlock(&am335x_trng_mutex); + return 0; +} + +RTEMS_SYSINIT_ITEM( + am335x_trng_clock_enable, + RTEMS_SYSINIT_DEVICE_DRIVERS, + RTEMS_SYSINIT_ORDER_LAST +); -- 1.9.1 On Fri, Mar 16, 2018 at 3:01 PM, Udit agarwal <dev.mada...@gmail.com> wrote: > Thanks for pointing that out, I have rectified the indentation errors. > > Here's the patch for atsam: > From 8e5e17525a76e68bc4d869d0af9700aaa5628483 Mon Sep 17 00:00:00 2001 > From: Udit agarwal <dev.mada...@gmail.com> > Date: Fri, 16 Mar 2018 14:54:53 +0530 > Subject: [PATCH] arm/atsam: protect TRNG_GetRandData with mutex > > --- > c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c > b/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c > index 11e24dc..54a1cef 100644 > --- a/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c > +++ b/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c > @@ -17,6 +17,9 @@ > #include <string.h> > #include <rtems/sysinit.h> > > +static rtems_mutex atsam_trng_mutex = > + RTEMS_MUTEX_INITIALIZER("atsam_trng"); > + > static void atsam_trng_enable(void) > { > PMC_EnablePeripheral(ID_TRNG); > @@ -25,6 +28,8 @@ static void atsam_trng_enable(void) > > int getentropy(void *ptr, size_t n) > { > + rtems_mutex_lock(&atsam_trng_mutex); > + > while (n > 0) { > uint32_t random; > size_t copy; > @@ -50,7 +55,7 @@ int getentropy(void *ptr, size_t n) > n -= copy; > ptr += copy; > } > - > + rtems_mutex_unlock(&atsam_trng_mutex); > return 0; > } > > -- > 1.9.1 > > On Thu, Mar 15, 2018 at 7:52 PM, Gedare Bloom <ged...@rtems.org> wrote: > >> On Thu, Mar 15, 2018 at 7:00 AM, Udit agarwal <dev.mada...@gmail.com> >> wrote: >> > >> > >> > On Thu, Mar 15, 2018 at 2:38 PM, Sebastian Huber >> > <sebastian.hu...@embedded-brains.de> wrote: >> >> >> >> On 15/03/18 09:20, Udit agarwal wrote: >> >>> >> >>> Also, will it be ok to keep atsam_trng_mutex even after user has >> finished >> >>> using getentropy() i.e when we don't use destroy(&atsam_trng_mutex) >> at all? >> >> >> >> >> >> Why do you want to destroy the mutex? >> > >> > Just trying to reduce redundancy, but then i don't think that's a good >> idea. >> > BTW, here's atsam patch, please have a look: >> > >> > From 35313002ea19715c5914c5983a24471b0763aa68 Mon Sep 17 00:00:00 2001 >> > From: Udit agarwal <dev.mada...@gmail.com> >> > Date: Thu, 15 Mar 2018 16:21:51 +0530 >> > Subject: [PATCH] Added mutex across TRNG_GetRandData >> >> In the commit message, identify the rtems subsystem. I guess we don't >> have detailed advice on the wiki for this, but here I guess we usually >> would have something like "arm/atsam: protect TRNG_GetRandData with >> mutex" >> >> > >> > --- >> > c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c | 7 +++++++ >> > 1 file changed, 7 insertions(+) >> > >> > diff --git a/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c >> > b/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c >> > index 11e24dc..2789970 100644 >> > --- a/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c >> > +++ b/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c >> > @@ -16,6 +16,9 @@ >> > #include <unistd.h> >> > #include <string.h> >> > #include <rtems/sysinit.h> >> > +#include <rtems/thread.h> >> > + >> > +static rtems_mutex atsam_trng_mutex = >> > RTEMS_MUTEX_INITIALIZER("atsam_trng"); >> > >> The second line should be indented 2 more levels (4 spaces). >> https://devel.rtems.org/wiki/Developer/Coding/80_characters_per_line >> >> > static void atsam_trng_enable(void) >> > { >> > @@ -25,6 +28,9 @@ static void atsam_trng_enable(void) >> > >> > int getentropy(void *ptr, size_t n) >> > { >> > + >> > + rtems_mutex_lock(&atsam_trng_mutex); >> The number of indent spaces here look wrong to me. It should be 2. >> >> > + >> > while (n > 0) { >> > uint32_t random; >> > size_t copy; >> > @@ -51,6 +57,7 @@ int getentropy(void *ptr, size_t n) >> > ptr += copy; >> > } >> > >> > + rtems_mutex_unlock(&atsam_trng_mutex); >> ditto. >> >> > return 0; >> > } >> > >> > -- >> > 1.9.1 >> > >> > >> >> >> >> >> >> >> >> -- >> >> Sebastian Huber, embedded brains GmbH >> >> >> >> Address : Dornierstr. 4, D-82178 Puchheim, Germany >> >> Phone : +49 89 189 47 41-16 >> >> Fax : +49 89 189 47 41-09 >> >> E-Mail : sebastian.hu...@embedded-brains.de >> >> PGP : Public key available on request. >> >> >> >> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. >> >> >> > >> > >> > _______________________________________________ >> > devel mailing list >> > devel@rtems.org >> > http://lists.rtems.org/mailman/listinfo/devel >> > >
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel