You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/05/04 09:52:25 UTC

[GitHub] andrzej-kaczmarek closed pull request #1037: hw/drivers/trng: Add driver for True Random Number Generator (TRNG)

andrzej-kaczmarek closed pull request #1037: hw/drivers/trng: Add driver for True Random Number Generator (TRNG)
URL: https://github.com/apache/mynewt-core/pull/1037
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/apps/trng_test/pkg.yml b/apps/trng_test/pkg.yml
new file mode 100644
index 000000000..61b8e9246
--- /dev/null
+++ b/apps/trng_test/pkg.yml
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+pkg.name: apps/trng_test
+pkg.type: app
+pkg.description: 
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - kernel/os
+    - sys/console/full
+    - hw/drivers/trng
diff --git a/apps/trng_test/src/main.c b/apps/trng_test/src/main.c
new file mode 100755
index 000000000..55939b38b
--- /dev/null
+++ b/apps/trng_test/src/main.c
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "sysinit/sysinit.h"
+#include "os/os.h"
+#include "console/console.h"
+#include "trng/trng.h"
+
+static uint8_t buf[128];
+
+static void
+print_buffer(void *ptr, size_t size)
+{
+    while (size) {
+        console_printf("%02x", *((uint8_t *) ptr));
+
+        size--;
+        ptr++;
+    }
+
+    console_printf("\n");
+}
+
+int
+main(void)
+{
+    struct trng_dev *trng;
+
+    sysinit();
+
+    trng = (struct trng_dev *) os_dev_open(MYNEWT_VAL(APP_TRNG_DEV),
+                                           OS_TIMEOUT_NEVER, NULL);
+    assert(trng);
+
+    os_time_delay(OS_TICKS_PER_SEC);
+
+    trng_read(trng, buf, sizeof(buf));
+    console_printf("%d bytes from os_dev:\n", sizeof(buf));
+    print_buffer(buf, sizeof(buf));
+
+    while (1) {
+        console_printf("os_dev -> %08x\n", (unsigned) trng_get_u32(trng));
+
+        os_time_delay(OS_TICKS_PER_SEC / 4);
+    }
+
+    return 0;
+}
diff --git a/apps/trng_test/syscfg.yml b/apps/trng_test/syscfg.yml
new file mode 100644
index 000000000..945e48ef4
--- /dev/null
+++ b/apps/trng_test/syscfg.yml
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    APP_TRNG_DEV:
+        description: TRNG device name
+        value: '"trng"'
+
+syscfg.vals:
+    TRNG: 1
diff --git a/hw/bsp/nrf52840pdk/pkg.yml b/hw/bsp/nrf52840pdk/pkg.yml
index 75689c1f4..09268619f 100644
--- a/hw/bsp/nrf52840pdk/pkg.yml
+++ b/hw/bsp/nrf52840pdk/pkg.yml
@@ -40,6 +40,9 @@ pkg.deps:
 pkg.deps.BLE_DEVICE:
     - hw/drivers/nimble/nrf52
 
+pkg.deps.TRNG:
+    - hw/drivers/trng/trng_nrf52
+
 pkg.deps.UART_0:
     - hw/drivers/uart/uart_hal
 
diff --git a/hw/bsp/nrf52840pdk/src/hal_bsp.c b/hw/bsp/nrf52840pdk/src/hal_bsp.c
index 8996dd5d9..e3ae8a04d 100644
--- a/hw/bsp/nrf52840pdk/src/hal_bsp.c
+++ b/hw/bsp/nrf52840pdk/src/hal_bsp.c
@@ -30,6 +30,11 @@
 #include "hal/hal_watchdog.h"
 #include "hal/hal_i2c.h"
 #include "mcu/nrf52_hal.h"
+
+#if MYNEWT_VAL(TRNG)
+#include "trng/trng.h"
+#include "trng_nrf52/trng_nrf52.h"
+#endif
 #if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
 #include "uart/uart.h"
 #endif
@@ -51,6 +56,10 @@
 #include <soft_pwm/soft_pwm.h>
 #endif
 
+#if MYNEWT_VAL(TRNG)
+static struct trng_dev os_bsp_trng;
+#endif
+
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev os_bsp_uart0;
 static const struct nrf52_uart_cfg os_bsp_uart0_cfg = {
@@ -202,6 +211,13 @@ hal_bsp_init(void)
     /* Make sure system clocks have started */
     hal_system_clock_start();
 
+#if MYNEWT_VAL(TRNG)
+    rc = os_dev_create(&os_bsp_trng.dev, "trng",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       nrf52_trng_dev_init, NULL);
+    assert(rc == 0);
+#endif
+
 #if MYNEWT_VAL(TIMER_0)
     rc = hal_timer_init(0, NULL);
     assert(rc == 0);
diff --git a/hw/drivers/trng/include/trng/trng.h b/hw/drivers/trng/include/trng/trng.h
new file mode 100644
index 000000000..df75e646a
--- /dev/null
+++ b/hw/drivers/trng/include/trng/trng.h
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __TRNG_H__
+#define __TRNG_H__
+
+#include <inttypes.h>
+#include <stddef.h>
+#include "os/mynewt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct trng_dev;
+
+typedef uint32_t (* trng_get_u32_func_t)(struct trng_dev *trng);
+typedef size_t (* trng_read_func_t)(struct trng_dev *trng, void *ptr,
+                                    size_t size);
+
+struct trng_interface {
+    trng_get_u32_func_t get_u32;
+    trng_read_func_t read;
+};
+
+struct trng_dev {
+    struct os_dev dev;
+    struct trng_interface interface;
+};
+
+/**
+ * Get 32-bit random value from TRNG
+ *
+ * This function will block until data is available in TRNG.
+ *
+ * @param trng  OS device
+ *
+ * @return  random value
+ */
+uint32_t trng_get_u32(struct trng_dev *trng);
+
+/**
+ * Fill buffer with random values from TRNG
+ *
+ * This function will read no more than \p size bytes from TRNG into target
+ * buffer (up to amount of data available in TRNG for immediate read).
+ *
+ * @param trng  OS device
+ * @param ptr   target buffer pointer
+ * @param size  target buffer size (in bytes)
+ *
+ * @return  number of bytes read from TRNG
+ */
+size_t trng_read(struct trng_dev *trng, void *ptr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TRNG_H__ */
diff --git a/hw/drivers/trng/pkg.yml b/hw/drivers/trng/pkg.yml
new file mode 100644
index 000000000..0cb0551b9
--- /dev/null
+++ b/hw/drivers/trng/pkg.yml
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/drivers/trng
+pkg.description: True Random Number Generator (TRNG) driver interfaces
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+pkg.req_apis:
+    - TRNG_HW_IMPL
diff --git a/hw/drivers/trng/src/trng.c b/hw/drivers/trng/src/trng.c
new file mode 100644
index 000000000..c028a8235
--- /dev/null
+++ b/hw/drivers/trng/src/trng.c
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "trng/trng.h"
+
+uint32_t
+trng_get_u32(struct trng_dev *trng)
+{
+    assert(trng->interface.get_u32);
+
+    return trng->interface.get_u32(trng);
+}
+
+size_t
+trng_read(struct trng_dev *trng, void *ptr, size_t size)
+{
+    assert(trng->interface.read);
+
+    return trng->interface.read(trng, ptr, size);
+}
diff --git a/hw/drivers/trng/trng_nrf52/include/trng_nrf52/trng_nrf52.h b/hw/drivers/trng/trng_nrf52/include/trng_nrf52/trng_nrf52.h
new file mode 100644
index 000000000..ce955b9ee
--- /dev/null
+++ b/hw/drivers/trng/trng_nrf52/include/trng_nrf52/trng_nrf52.h
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __TRNG_NRF52_H__
+#define __TRNG_NRF52_H__
+
+#include "trng/trng.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int nrf52_trng_dev_init(struct os_dev *dev, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TRNG_NRF52_H__ */
diff --git a/hw/drivers/trng/trng_nrf52/pkg.yml b/hw/drivers/trng/trng_nrf52/pkg.yml
new file mode 100644
index 000000000..9d9dc048d
--- /dev/null
+++ b/hw/drivers/trng/trng_nrf52/pkg.yml
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/drivers/trng/trng_nrf52
+pkg.description: TRNG driver for nRF52xxx
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.apis:
+    - TRNG_HW_IMPL
+
+pkg.deps:
+   - hw/drivers/trng
diff --git a/hw/drivers/trng/trng_nrf52/src/trng_nrf52.c b/hw/drivers/trng/trng_nrf52/src/trng_nrf52.c
new file mode 100644
index 000000000..9fe2b455f
--- /dev/null
+++ b/hw/drivers/trng/trng_nrf52/src/trng_nrf52.c
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string.h>
+#include "mcu/cmsis_nvic.h"
+#include "trng/trng.h"
+#include "trng_nrf52/trng_nrf52.h"
+
+static uint8_t rng_cache[ MYNEWT_VAL(NRF52_TRNG_CACHE_LEN) ];
+static uint16_t rng_cache_out;
+static uint16_t rng_cache_in;
+
+static void
+nrf52_rng_start(void)
+{
+    os_sr_t sr;
+
+    OS_ENTER_CRITICAL(sr);
+
+    NRF_RNG->EVENTS_VALRDY = 0;
+    NRF_RNG->INTENSET = 1;
+    NRF_RNG->TASKS_START = 1;
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static void
+nrf52_rng_stop(void)
+{
+    os_sr_t sr;
+
+    OS_ENTER_CRITICAL(sr);
+
+    NRF_RNG->INTENCLR = 1;
+    NRF_RNG->TASKS_STOP = 1;
+    NRF_RNG->EVENTS_VALRDY = 0;
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static void
+nrf52_rng_irq_handler(void)
+{
+    if (NRF_RNG->EVENTS_VALRDY) {
+        NRF_RNG->EVENTS_VALRDY = 0;
+        rng_cache[rng_cache_in] = NRF_RNG->VALUE;
+        rng_cache_in++;
+        if (rng_cache_in >= sizeof(rng_cache)) {
+            rng_cache_in = 0;
+        }
+    }
+
+    if ((rng_cache_in + 1) % sizeof(rng_cache) == rng_cache_out) {
+        nrf52_rng_stop();
+    }
+}
+
+static size_t
+nrf52_trng_read(struct trng_dev *trng, void *ptr, size_t size)
+{
+    os_sr_t sr;
+    size_t num_read;
+
+    OS_ENTER_CRITICAL(sr);
+
+    if (rng_cache_out <= rng_cache_in) {
+        /* Can read from head to tail */
+        size = min(size, rng_cache_in - rng_cache_out);
+        memcpy(ptr, &rng_cache[rng_cache_out], size);
+
+        num_read = size;
+    } else if (rng_cache_out + size <= sizeof(rng_cache)) {
+        /* Can read from head to end of queue */
+        memcpy(ptr, &rng_cache[rng_cache_out], size);
+
+        num_read = size;
+    } else {
+        /* Can read from head until end of queue */
+        num_read = sizeof(rng_cache) - rng_cache_out;
+        memcpy(ptr, &rng_cache[rng_cache_out], num_read);
+
+        size -= num_read;
+        ptr += num_read;
+
+        /* Can read from start of queue to tail */
+        size = min(size, rng_cache_in);
+        memcpy(ptr, rng_cache, size);
+
+        num_read += size;
+    }
+
+    rng_cache_out += num_read;
+    rng_cache_out %= sizeof(rng_cache);
+
+    if (num_read > 0) {
+        nrf52_rng_start();
+    }
+
+    OS_EXIT_CRITICAL(sr);
+
+    return num_read;
+}
+
+static uint32_t
+nrf52_trng_get_u32(struct trng_dev *trng)
+{
+    union {
+        uint32_t v32;
+        uint8_t v8[4];
+    } val;
+    size_t num;
+
+    num = nrf52_trng_read(trng, &val.v8, sizeof(val.v8));
+    while (num < sizeof(val.v8)) {
+        os_sched(NULL);
+        num += nrf52_trng_read(trng, &val.v8[num], sizeof(val.v8) - num);
+    }
+
+    return val.v32;
+}
+
+static int
+nrf52_trng_dev_open(struct os_dev *dev, uint32_t wait, void *arg)
+{
+    struct trng_dev *trng;
+
+    trng = (struct trng_dev *)dev;
+    assert(trng);
+
+    if (!(dev->od_flags & OS_DEV_F_STATUS_OPEN)) {
+        rng_cache_out = 0;
+        rng_cache_in = 0;
+
+        NRF_RNG->CONFIG = 1;
+
+        NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
+        NVIC_SetVector(RNG_IRQn, (uint32_t)nrf52_rng_irq_handler);
+        NVIC_EnableIRQ(RNG_IRQn);
+
+        nrf52_rng_start();
+    }
+
+    return OS_OK;
+}
+
+int
+nrf52_trng_dev_init(struct os_dev *dev, void *arg)
+{
+    struct trng_dev *trng;
+
+    trng = (struct trng_dev *)dev;
+    assert(trng);
+
+    OS_DEV_SETHANDLERS(dev, nrf52_trng_dev_open, NULL);
+
+    trng->interface.get_u32 = nrf52_trng_get_u32;
+    trng->interface.read = nrf52_trng_read;
+
+    return 0;
+}
diff --git a/hw/drivers/trng/trng_nrf52/syscfg.yml b/hw/drivers/trng/trng_nrf52/syscfg.yml
new file mode 100644
index 000000000..8467c71ef
--- /dev/null
+++ b/hw/drivers/trng/trng_nrf52/syscfg.yml
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Package: hw/drivers/trng/trng_nrf52
+
+syscfg.defs:
+    NRF52_TRNG_CACHE_LEN:
+        description: 'Internal cache length, shall be power of 2'
+        value: 32
diff --git a/hw/mcu/nordic/nrf52xxx/syscfg.yml b/hw/mcu/nordic/nrf52xxx/syscfg.yml
index ecabe5663..bbf2ad3a0 100644
--- a/hw/mcu/nordic/nrf52xxx/syscfg.yml
+++ b/hw/mcu/nordic/nrf52xxx/syscfg.yml
@@ -106,6 +106,10 @@ syscfg.defs:
         description: 'SOFT PWM'
         value: 0
 
+    TRNG:
+        description: 'True Random Number Generator (RNG)'
+        value: 0
+
     QSPI_ENABLE:
         description: 'NRF52 QSPI'
         value: 0


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services