mynewt-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From w...@apache.org
Subject incubator-mynewt-core git commit: MYNEWT-99: add random number genration/support for LE encryption
Date Mon, 28 Mar 2016 16:05:50 GMT
Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop ea3ff1802 -> f936daef1


MYNEWT-99: add random number genration/support for LE encryption


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/f936daef
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/f936daef
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/f936daef

Branch: refs/heads/develop
Commit: f936daef15fb3cf9da66aebdc3224ba6c9842c26
Parents: ea3ff18
Author: wes3 <will@micosa.io>
Authored: Mon Mar 28 09:04:22 2016 -0700
Committer: wes3 <will@micosa.io>
Committed: Mon Mar 28 09:04:22 2016 -0700

----------------------------------------------------------------------
 apps/bletest/src/main.c                         |   5 +
 .../controller/include/controller/ble_hw.h      |  25 ++++
 .../controller/include/controller/ble_ll.h      |  17 ++-
 net/nimble/controller/src/ble_ll.c              |  19 ++-
 net/nimble/controller/src/ble_ll_ctrl.c         |  80 ++++++-----
 net/nimble/controller/src/ble_ll_hci.c          |  27 ++++
 net/nimble/controller/src/ble_ll_rand.c         | 136 +++++++++++++++++++
 net/nimble/controller/src/ble_ll_rng.c          |  60 ++++++++
 net/nimble/controller/src/ble_ll_supp_cmd.c     |  11 +-
 net/nimble/drivers/native/src/ble_hw.c          |  48 +++++++
 net/nimble/drivers/nrf51/src/ble_hw.c           | 122 +++++++++++++++++
 net/nimble/drivers/nrf52/src/ble_hw.c           | 122 +++++++++++++++++
 net/nimble/host/include/host/host_hci.h         |   1 +
 net/nimble/host/src/host_dbg.c                  |   6 +
 net/nimble/host/src/host_hci_cmd.c              |  28 +++-
 net/nimble/include/nimble/hci_common.h          |   3 +
 net/nimble/include/nimble/nimble_opt.h          |  13 +-
 net/nimble/src/hci_common.c                     |   2 +-
 18 files changed, 668 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/apps/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c
index 0961bb0..1a230c1 100755
--- a/apps/bletest/src/main.c
+++ b/apps/bletest/src/main.c
@@ -847,6 +847,11 @@ bletest_task_handler(void *arg)
     assert(rc == 0);
     host_hci_outstanding_opcode = 0;
 
+    /* Get a random number */
+    rc = host_hci_cmd_le_rand();
+    assert(rc == 0);
+    host_hci_outstanding_opcode = 0;
+
     /* Wait some time before starting */
     os_time_delay(OS_TICKS_PER_SEC);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/include/controller/ble_hw.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_hw.h b/net/nimble/controller/include/controller/ble_hw.h
index a0f69e7..6166e58 100644
--- a/net/nimble/controller/include/controller/ble_hw.h
+++ b/net/nimble/controller/include/controller/ble_hw.h
@@ -51,4 +51,29 @@ int ble_hw_whitelist_match(void);
 struct ble_encryption_block;
 int ble_hw_encrypt_block(struct ble_encryption_block *ecb);
 
+/* Random number generation */
+typedef void (*ble_rng_isr_cb_t)(uint8_t rnum);
+int ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias);
+
+/**
+ * Start the random number generator
+ * 
+ * @return int 
+ */
+int ble_hw_rng_start(void);
+
+/**
+ * Stop the random generator
+ * 
+ * @return int 
+ */
+int ble_hw_rng_stop(void);
+
+/**
+ * Read the random number generator.
+ * 
+ * @return uint8_t 
+ */
+uint8_t ble_hw_rng_read(void);
+
 #endif /* H_BLE_HW_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/include/controller/ble_ll.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
index bd4a325..503380a 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -22,7 +22,16 @@
 
 #include "stats/stats.h"
 #include "hal/hal_cputime.h"
-#include "ble_hw.h"
+
+/* Configuration for supported features */
+#define  BLE_LL_CFG_FEAT_LE_ENCRYPTION
+#define BLE_LL_CFG_FEAT_CONN_PARAM_REQ
+#undef  BLE_LL_CFG_FEAT_EXT_REJECT_IND
+#define BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG
+#undef  BLE_LL_CFG_FEAT_LE_PING
+#define BLE_LL_CFG_FEAT_DATA_LEN_EXT
+#undef  BLE_LL_CFG_FEAT_LL_PRIVACY
+#undef  BLE_LL_CFG_FEAT_EXT_SCAN_FILT
 
 /* Controller revision. */
 #define BLE_LL_SUB_VERS_NR      (0x0000)
@@ -342,6 +351,12 @@ uint8_t ble_ll_read_supp_features(void);
 /* Read set of states supported by the Link Layer */
 uint64_t ble_ll_read_supp_states(void);
 
+/* Random numbers */
+int ble_ll_rand_init(void);
+void ble_ll_rand_sample(uint8_t rnum);
+int ble_ll_rand_data_get(uint8_t *buf, uint8_t len);
+int ble_ll_rand_start(void);
+
 /* 
  * XXX: temporary LL debug log. Will get removed once we transition to real
  * log

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index 0081311..a0e06c9 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -26,6 +26,7 @@
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
+#include "controller/ble_hw.h"
 #include "controller/ble_phy.h"
 #include "controller/ble_ll.h"
 #include "controller/ble_ll_adv.h"
@@ -47,16 +48,6 @@
  * right thing to do.
  */
 
-/* Configuration for supported features */
-#undef  BLE_LL_CFG_FEAT_LE_ENCRYPTION
-#define BLE_LL_CFG_FEAT_CONN_PARAM_REQ
-#undef  BLE_LL_CFG_FEAT_EXT_REJECT_IND
-#define BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG
-#undef  BLE_LL_CFG_FEAT_LE_PING
-#define BLE_LL_CFG_FEAT_DATA_LEN_EXT
-#undef  BLE_LL_CFG_FEAT_LL_PRIVACY
-#undef  BLE_LL_CFG_FEAT_EXT_SCAN_FILT
-
 /* Supported states */
 #define BLE_LL_S_NCA                    (0x00000000001)
 #define BLE_LL_S_SA                     (0x00000000002)
@@ -838,6 +829,10 @@ ble_ll_task(void *arg)
     /* Tell the host that we are ready to receive packets */
     ble_ll_hci_send_noop();
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    ble_ll_rand_start();
+#endif
+
     /* Wait for an event */
     while (1) {
         ev = os_eventq_get(&g_ble_ll_data.ll_evq);
@@ -1113,6 +1108,10 @@ ble_ll_init(uint8_t ll_task_prio, uint8_t num_acl_pkts, uint16_t acl_pkt_size)
 #ifdef BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG
     features |= BLE_LL_FEAT_SLAVE_INIT;
 #endif
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    features |= BLE_LL_FEAT_LE_ENCRYPTION;
+    ble_ll_rand_init();
+#endif
 
     lldata->ll_supp_features = features;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/src/ble_ll_ctrl.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_ctrl.c b/net/nimble/controller/src/ble_ll_ctrl.c
index a9ace70..75a26df 100644
--- a/net/nimble/controller/src/ble_ll_ctrl.c
+++ b/net/nimble/controller/src/ble_ll_ctrl.c
@@ -572,15 +572,31 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
  * @param connsm 
  * @param dptr 
  * @param rspbuf 
+ * @param opcode
  * 
  * @return int 
  */
 static int
 ble_ll_ctrl_rx_feature_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
-                              uint8_t *rspbuf)
+                           uint8_t *rspbuf, uint8_t opcode)
 {
     uint8_t rsp_opcode;
 
+    /* 
+     * Only accept slave feature requests if we are a master and feature
+     * requests if we are a slave.
+     */
+    if (opcode ==  BLE_LL_CTRL_SLAVE_FEATURE_REQ) {
+        if (connsm->conn_role != BLE_LL_CONN_ROLE_MASTER) {
+            return BLE_LL_CTRL_UNKNOWN_RSP;
+        }
+    } else {
+        /* XXX: not sure this is correct but do it anyway */
+        if (connsm->conn_role != BLE_LL_CONN_ROLE_SLAVE) {
+            return BLE_LL_CTRL_UNKNOWN_RSP;
+        }
+    }
+
     /* Add put logical AND of their features and our features*/
     /* XXX: right now, there is only one byte of supported features */
     /* XXX: Used proper macros later */
@@ -754,14 +770,16 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
     uint16_t conn_events;
 
     /* If instant is in the past, we have to end the connection */
-    instant = le16toh(dptr + BLE_LL_CONN_CHMAP_LEN);
-    conn_events = (instant - connsm->event_cntr) & 0xFFFF;
-    if (conn_events >= 32767) {
-        ble_ll_conn_timeout(connsm, BLE_ERR_INSTANT_PASSED);
-    } else {
-        connsm->chanmap_instant = instant;
-        memcpy(connsm->req_chanmap, dptr, BLE_LL_CONN_CHMAP_LEN);
-        connsm->csmflags.cfbit.chanmap_update_scheduled = 1;
+    if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
+        instant = le16toh(dptr + BLE_LL_CONN_CHMAP_LEN);
+        conn_events = (instant - connsm->event_cntr) & 0xFFFF;
+        if (conn_events >= 32767) {
+            ble_ll_conn_timeout(connsm, BLE_ERR_INSTANT_PASSED);
+        } else {
+            connsm->chanmap_instant = instant;
+            memcpy(connsm->req_chanmap, dptr, BLE_LL_CONN_CHMAP_LEN);
+            connsm->csmflags.cfbit.chanmap_update_scheduled = 1;
+        }
     }
 }
 
@@ -1097,6 +1115,11 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
     case BLE_LL_CTRL_CONN_PARM_RSP:
         feature = BLE_LL_FEAT_CONN_PARM_REQ;
         break;
+    case BLE_LL_CTRL_ENC_REQ:
+    case BLE_LL_CTRL_START_ENC_REQ:
+    case BLE_LL_CTRL_PAUSE_ENC_REQ:
+        feature = BLE_LL_FEAT_LE_ENCRYPTION;
+        break;
     default:
         feature = 0;
         break;
@@ -1106,7 +1129,6 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
         features = ble_ll_read_supp_features();
         if ((features & feature) == 0) {
             /* Construct unknown rsp pdu */
-            rspbuf[1] = opcode;
             rsp_opcode = BLE_LL_CTRL_UNKNOWN_RSP;
             goto ll_ctrl_send_rsp;
         }
@@ -1119,9 +1141,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
         rsp_opcode = ble_ll_ctrl_rx_conn_update(connsm, dptr, rspbuf);
         break;
     case BLE_LL_CTRL_CHANNEL_MAP_REQ:
-        if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
-            ble_ll_ctrl_rx_chanmap_req(connsm, dptr);
-        }
+        ble_ll_ctrl_rx_chanmap_req(connsm, dptr);
         break;
     case BLE_LL_CTRL_LENGTH_REQ:
         /* Extract parameters and check if valid */
@@ -1143,10 +1163,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
         ble_ll_ctrl_datalen_upd_make(connsm, rspbuf);
         break;
     case BLE_LL_CTRL_LENGTH_RSP:
-        /* 
-         * According to specification, we should only process this if we
-         * asked for it.
-         */
+        /* According to specification, process this only if we asked for it. */
         if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_DATA_LEN_UPD) {
             /* Process the received data */
             if (ble_ll_ctrl_len_proc(connsm, dptr)) {
@@ -1161,14 +1178,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
         ble_ll_ctrl_proc_unk_rsp(connsm, dptr);
         break;
     case BLE_LL_CTRL_FEATURE_REQ:
-        if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
-            rsp_opcode = ble_ll_ctrl_rx_feature_req(connsm, dptr, rspbuf);
-        } else {
-            /* XXX: not sure this is correct but do it anyway */
-            /* Construct unknown pdu */
-            rspbuf[1] = opcode;
-            rsp_opcode = BLE_LL_CTRL_UNKNOWN_RSP;
-        }
+        rsp_opcode = ble_ll_ctrl_rx_feature_req(connsm, dptr, rspbuf, opcode);
         break;
     /* XXX: check to see if ctrl procedure was running? Do we care? */
     case BLE_LL_CTRL_FEATURE_RSP:
@@ -1183,21 +1193,16 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
         rsp_opcode = ble_ll_ctrl_rx_version_ind(connsm, dptr, rspbuf + 1);
         break;
     case BLE_LL_CTRL_SLAVE_FEATURE_REQ:
-        if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
-            rsp_opcode = ble_ll_ctrl_rx_feature_req(connsm, dptr, rspbuf);
-        } else {
-            /* Construct unknown pdu */
-            rspbuf[1] = opcode;
-            rsp_opcode = BLE_LL_CTRL_UNKNOWN_RSP;
-        }
+        rsp_opcode = ble_ll_ctrl_rx_feature_req(connsm, dptr, rspbuf, opcode);
         break;
-    /* XXX: remember to check if feature supported. Implement! */
+#if defined(BLE_LL_CFG_FEAT_LE_ENCYPTION)
     case BLE_LL_CTRL_ENC_REQ:
+        rsp_opcode = ble_ll_ctrl_rx_enc_req(connsm, dptr, rspbuf);
     case BLE_LL_CTRL_START_ENC_REQ:
     case BLE_LL_CTRL_PAUSE_ENC_REQ:
+        break;
+#endif
     case BLE_LL_CTRL_PING_REQ:
-        /* Construct unknown pdu */
-        rspbuf[1] = opcode;
         rsp_opcode = BLE_LL_CTRL_UNKNOWN_RSP;
         break;
     case BLE_LL_CTRL_CONN_PARM_REQ:
@@ -1216,7 +1221,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
         }
         break;
     default:
-        /* We really should never get here */
+        /* Nothing to do here */
         break;
     }
 
@@ -1226,6 +1231,9 @@ ll_ctrl_send_rsp:
         os_mbuf_free_chain(om);
     } else {
         rspbuf[0] = rsp_opcode;
+        if (rsp_opcode == BLE_LL_CTRL_UNKNOWN_RSP) {
+            rspbuf[1] = opcode;
+        }
         len = g_ble_ll_ctrl_pkt_lengths[rsp_opcode] + 1;
         ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL, len);
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/src/ble_ll_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c
index 9f22326..e73b0de 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -24,6 +24,7 @@
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
 #include "nimble/hci_transport.h"
+#include "controller/ble_hw.h"
 #include "controller/ble_ll_adv.h"
 #include "controller/ble_ll_scan.h"
 #include "controller/ble_ll.h"
@@ -101,6 +102,7 @@ ble_ll_hci_send_noop(void)
     return rc;
 }
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
 /**
  * LE encrypt command
  * 
@@ -132,6 +134,26 @@ ble_ll_hci_le_encrypt(uint8_t *cmdbuf, uint8_t *rspbuf, uint8_t *rsplen)
 }
 
 /**
+ * LE rand command
+ * 
+ * @param cmdbuf 
+ * @param rspbuf 
+ * @param rsplen 
+ * 
+ * @return int 
+ */
+static int
+ble_ll_hci_le_rand(uint8_t *rspbuf, uint8_t *rsplen)
+{
+    int rc;
+
+    rc = ble_ll_rand_data_get(rspbuf, BLE_HCI_LE_RAND_LEN);
+    *rsplen = BLE_HCI_LE_RAND_LEN;
+    return rc;
+}
+#endif
+
+/**
  * Read local version
  * 
  * @param rspbuf 
@@ -511,9 +533,14 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
     case BLE_HCI_OCF_LE_RD_REM_FEAT:
         rc = ble_ll_conn_hci_read_rem_features(cmdbuf);
         break;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     case BLE_HCI_OCF_LE_ENCRYPT:
         rc = ble_ll_hci_le_encrypt(cmdbuf, rspbuf, rsplen);
         break;
+    case BLE_HCI_OCF_LE_RAND:
+        rc = ble_ll_hci_le_rand(rspbuf, rsplen);
+        break;
+#endif
     case BLE_HCI_OCF_LE_RD_SUPP_STATES :
         rc = ble_ll_hci_le_read_supp_states(rspbuf, rsplen);
         break;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/src/ble_ll_rand.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_rand.c b/net/nimble/controller/src/ble_ll_rand.c
new file mode 100644
index 0000000..f70c474
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll_rand.c
@@ -0,0 +1,136 @@
+/**
+ * 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 <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "nimble/nimble_opt.h"
+#include "controller/ble_hw.h"
+#include "controller/ble_ll.h"
+
+#if defined(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
+/* This is a simple circular buffer for holding N samples of random data */
+struct ble_ll_rnum_data
+{
+    uint8_t *rnd_in;
+    uint8_t *rnd_out;
+    uint8_t rnd_size;
+};
+
+struct ble_ll_rnum_data g_ble_ll_rnum_data;
+uint8_t g_ble_ll_rnum_buf[NIMBLE_OPT_LL_RNG_BUFSIZE];
+
+#define IS_RNUM_BUF_END(x)  (x == &g_ble_ll_rnum_buf[NIMBLE_OPT_LL_RNG_BUFSIZE])
+
+void
+ble_ll_rand_sample(uint8_t rnum)
+{
+    os_sr_t sr;
+
+    OS_ENTER_CRITICAL(sr);
+    if (g_ble_ll_rnum_data.rnd_size < NIMBLE_OPT_LL_RNG_BUFSIZE) {
+        ++g_ble_ll_rnum_data.rnd_size;
+        g_ble_ll_rnum_data.rnd_in[0] = rnum;
+        if (IS_RNUM_BUF_END(g_ble_ll_rnum_data.rnd_in)) {
+            g_ble_ll_rnum_data.rnd_in = g_ble_ll_rnum_buf;
+        } else {
+            ++g_ble_ll_rnum_data.rnd_in;
+        }
+    } else {
+        /* Stop generating random numbers as we are full */
+        ble_hw_rng_stop();
+    }
+    OS_EXIT_CRITICAL(sr);
+}
+
+/* Get 'len' bytes of random data */
+int
+ble_ll_rand_data_get(uint8_t *buf, uint8_t len)
+{
+    uint8_t rnums;
+    os_sr_t sr;
+
+    while (len != 0) {
+        OS_ENTER_CRITICAL(sr);
+        rnums = g_ble_ll_rnum_data.rnd_size; 
+        if (rnums > len) {
+            rnums = len;
+        }
+        len -= rnums;
+        g_ble_ll_rnum_data.rnd_size -= rnums;
+        while (rnums) {
+            buf[0] = g_ble_ll_rnum_data.rnd_out[0];
+            if (IS_RNUM_BUF_END(g_ble_ll_rnum_data.rnd_out)) {
+                g_ble_ll_rnum_data.rnd_out = g_ble_ll_rnum_buf;
+            } else {
+                ++g_ble_ll_rnum_data.rnd_out;
+            }
+            ++buf;
+            --rnums;
+        }
+        OS_EXIT_CRITICAL(sr);
+
+        /* Make sure rng is started! */
+        ble_hw_rng_start();
+
+        /* Wait till bytes are in buffer. */
+        if (len) {
+            while ((g_ble_ll_rnum_data.rnd_size < len) && 
+                   (g_ble_ll_rnum_data.rnd_size < NIMBLE_OPT_LL_RNG_BUFSIZE)) {
+                /* Spin here */
+            }
+        }
+    }
+
+    return BLE_ERR_SUCCESS;
+}
+
+/**
+ * Start the generation of random numbers
+ * 
+ * @return int 
+ */
+int
+ble_ll_rand_start(void)
+{
+    /* Start the generation of numbers if we are not full */
+    if (g_ble_ll_rnum_data.rnd_size < NIMBLE_OPT_LL_RNG_BUFSIZE) {
+        ble_hw_rng_start();
+    }
+    return 0;
+}
+
+/**
+ * Initialize LL random number generation. Should be called only once on 
+ * initialization. 
+ * 
+ * @return int 
+ */
+int
+ble_ll_rand_init(void)
+{
+    g_ble_ll_rnum_data.rnd_in = g_ble_ll_rnum_buf;
+    g_ble_ll_rnum_data.rnd_out = g_ble_ll_rnum_buf;
+    ble_hw_rng_init(ble_ll_rand_sample, 1);
+    return 0;
+}
+#endif
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/src/ble_ll_rng.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_rng.c b/net/nimble/controller/src/ble_ll_rng.c
new file mode 100644
index 0000000..3bbd456
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll_rng.c
@@ -0,0 +1,60 @@
+/**
+ * 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 <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "controller/ble_hw.h"
+#include "controller/ble_ll.h"
+
+/* This is a simple circular buffer for holding N samples of random data */
+struct ble_ll_rnum_data
+{
+    uint8_t rnd_in;
+    uint8_t rnd_out;
+    uint8_t rnd_size;
+    uint8_t _pad;
+};
+
+#if defined BLE_LL_CFG_FEAT_LE_ENCRYPTION
+int
+ble_ll_rng_init(void)
+{
+    return 0;
+}
+
+/* Get 'len' bytes of random data */
+int
+ble_ll_rand_data_get(uint8_t *buf, uint8_t len)
+{
+    os_sr_t sr;
+
+    while (len != 0) {
+        OS_ENTER_CRITICAL(sr);
+
+        OS_EXIT_CRITICAL(sr);
+        --len;
+    }
+
+    return 0;
+}
+#endif
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/controller/src/ble_ll_supp_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_supp_cmd.c b/net/nimble/controller/src/ble_ll_supp_cmd.c
index f3e9868..594c832 100644
--- a/net/nimble/controller/src/ble_ll_supp_cmd.c
+++ b/net/nimble/controller/src/ble_ll_supp_cmd.c
@@ -106,19 +106,24 @@
 #define BLE_SUPP_CMD_LE_SET_HOST_CHAN_CLASS (1 << 3)
 #define BLE_SUPP_CMD_LE_RD_CHAN_MAP         (1 << 4)
 #define BLE_SUPP_CMD_LE_RD_REM_USED_FEAT    (1 << 5)
+#if defined(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
 #define BLE_SUPP_CMD_LE_ENCRYPT             (1 << 6)
+#define BLE_SUPP_CMD_LE_RAND                (1 << 7)
+#else
+#define BLE_SUPP_CMD_LE_ENCRYPT             (0 << 6)
 #define BLE_SUPP_CMD_LE_RAND                (0 << 7)
+#endif
 
 #define BLE_LL_SUPP_CMD_OCTET_27            \
 (                                           \
+    BLE_SUPP_CMD_LE_ENCRYPT             |   \
+    BLE_SUPP_CMD_LE_RAND                |   \
     BLE_SUPP_CMD_LE_ADD_DEV_WHITELIST   |   \
     BLE_SUPP_CMD_LE_RMV_DEV_WHITELIST   |   \
     BLE_SUPP_CMD_LE_CONN_UPDATE         |   \
     BLE_SUPP_CMD_LE_SET_HOST_CHAN_CLASS |   \
     BLE_SUPP_CMD_LE_RD_CHAN_MAP         |   \
-    BLE_SUPP_CMD_LE_RD_REM_USED_FEAT    |   \
-    BLE_SUPP_CMD_LE_ENCRYPT             |   \
-    BLE_SUPP_CMD_LE_RAND                    \
+    BLE_SUPP_CMD_LE_RD_REM_USED_FEAT        \
 )
 
 /* Octet 28 */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/drivers/native/src/ble_hw.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/native/src/ble_hw.c b/net/nimble/drivers/native/src/ble_hw.c
index 35b25ff..1b8c10f 100644
--- a/net/nimble/drivers/native/src/ble_hw.c
+++ b/net/nimble/drivers/native/src/ble_hw.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include "os/os.h"
 #include "nimble/ble.h"
+#include "controller/ble_hw.h"
 
 /* Total number of white list elements supported by nrf52 */
 #define BLE_HW_WHITE_LIST_SIZE      (0)
@@ -114,3 +115,50 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb)
 {
     return -1;
 }
+
+/**
+ * Initialize the random number generator
+ * 
+ * @param cb 
+ * @param bias 
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
+{
+    return -1;
+}
+
+/**
+ * Start the random number generator
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_start(void)
+{
+    return -1;
+}
+
+/**
+ * Stop the random generator
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_stop(void)
+{
+    return -1;
+}
+
+/**
+ * Read the random number generator.
+ * 
+ * @return uint8_t 
+ */
+uint8_t
+ble_hw_rng_read(void)
+{
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/drivers/nrf51/src/ble_hw.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf51/src/ble_hw.c b/net/nimble/drivers/nrf51/src/ble_hw.c
index b624016..cc9dcbd 100644
--- a/net/nimble/drivers/nrf51/src/ble_hw.c
+++ b/net/nimble/drivers/nrf51/src/ble_hw.c
@@ -23,6 +23,8 @@
 #include "os/os.h"
 #include "nimble/ble.h"
 #include "mcu/nrf51_bitfields.h"
+#include "controller/ble_hw.h"
+#include "bsp/cmsis_nvic.h"
 
 /* Total number of white list elements supported by nrf52 */
 #define BLE_HW_WHITE_LIST_SIZE      (8)
@@ -30,6 +32,9 @@
 /* We use this to keep track of which entries are set to valid addresses */
 static uint8_t g_ble_hw_whitelist_mask;
 
+/* Random number generator isr callback */
+ble_rng_isr_cb_t g_ble_rng_isr_cb;
+
 /**
  * Clear the whitelist
  * 
@@ -193,3 +198,120 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb)
 
     return rc;
 }
+
+/**
+ * Random number generator ISR.
+ */
+static void
+ble_rng_isr(void)
+{
+    uint8_t rnum;
+
+    /* No callback? Clear and disable interrupts */
+    if (g_ble_rng_isr_cb == NULL) {
+        NRF_RNG->INTENCLR = 1;
+        NRF_RNG->EVENTS_VALRDY = 0;
+        (void)NRF_RNG->SHORTS;
+        return;
+    }
+
+    /* If there is a value ready grab it */
+    if (NRF_RNG->EVENTS_VALRDY) {
+        NRF_RNG->EVENTS_VALRDY = 0;
+        rnum = (uint8_t)NRF_RNG->VALUE;
+        (*g_ble_rng_isr_cb)(rnum);
+    }
+}
+
+/**
+ * Initialize the random number generator
+ * 
+ * @param cb 
+ * @param bias 
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
+{
+    /* Set bias */
+    if (bias) {
+        NRF_RNG->CONFIG = 1;
+    } else {
+        NRF_RNG->CONFIG = 0;
+    }
+
+    /* If we were passed a function pointer we need to enable the interrupt */
+    if (cb != NULL) {
+        NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
+        NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr);
+        NVIC_EnableIRQ(RNG_IRQn);
+        g_ble_rng_isr_cb = cb;
+    }
+
+    return 0;
+}
+
+/**
+ * Start the random number generator
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_start(void)
+{
+    os_sr_t sr;
+
+    /* No need for interrupt if there is no callback */
+    OS_ENTER_CRITICAL(sr);
+    if (NRF_RNG->TASKS_START == 0) {
+        NRF_RNG->EVENTS_VALRDY = 0;
+        if (g_ble_rng_isr_cb) {
+            NRF_RNG->INTENSET = 1;
+        }
+        NRF_RNG->TASKS_START = 1;
+    }
+    OS_EXIT_CRITICAL(sr);
+
+    return 0;
+}
+
+/**
+ * Stop the random generator
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_stop(void)
+{
+    os_sr_t sr;
+
+    /* No need for interrupt if there is no callback */
+    OS_ENTER_CRITICAL(sr);
+    NRF_RNG->INTENCLR = 1;
+    NRF_RNG->TASKS_STOP = 1;
+    NRF_RNG->EVENTS_VALRDY = 0;
+    OS_EXIT_CRITICAL(sr);
+
+    return 0;
+}
+
+/**
+ * Read the random number generator.
+ * 
+ * @return uint8_t 
+ */
+uint8_t
+ble_hw_rng_read(void)
+{
+    uint8_t rnum;
+
+    /* Wait for a sample */
+    while (NRF_RNG->EVENTS_VALRDY == 0) {
+    }
+
+    NRF_RNG->EVENTS_VALRDY = 0;
+    rnum = (uint8_t)NRF_RNG->VALUE;
+
+    return rnum;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/drivers/nrf52/src/ble_hw.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf52/src/ble_hw.c b/net/nimble/drivers/nrf52/src/ble_hw.c
index b9a086d..36d5ac7 100644
--- a/net/nimble/drivers/nrf52/src/ble_hw.c
+++ b/net/nimble/drivers/nrf52/src/ble_hw.c
@@ -22,7 +22,9 @@
 #include <string.h>
 #include "os/os.h"
 #include "nimble/ble.h"
+#include "controller/ble_hw.h"
 #include "mcu/nrf52_bitfields.h"
+#include "bsp/cmsis_nvic.h"
 
 /* Total number of white list elements supported by nrf52 */
 #define BLE_HW_WHITE_LIST_SIZE      (8)
@@ -30,6 +32,9 @@
 /* We use this to keep track of which entries are set to valid addresses */
 static uint8_t g_ble_hw_whitelist_mask;
 
+/* Random number generator isr callback */
+ble_rng_isr_cb_t g_ble_rng_isr_cb;
+
 /**
  * Clear the whitelist
  * 
@@ -193,3 +198,120 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb)
 
     return rc;
 }
+
+/**
+ * Random number generator ISR.
+ */
+static void
+ble_rng_isr(void)
+{
+    uint8_t rnum;
+
+    /* No callback? Clear and disable interrupts */
+    if (g_ble_rng_isr_cb == NULL) {
+        NRF_RNG->INTENCLR = 1;
+        NRF_RNG->EVENTS_VALRDY = 0;
+        (void)NRF_RNG->SHORTS;
+        return;
+    }
+
+    /* If there is a value ready grab it */
+    if (NRF_RNG->EVENTS_VALRDY) {
+        NRF_RNG->EVENTS_VALRDY = 0;
+        rnum = (uint8_t)NRF_RNG->VALUE;
+        (*g_ble_rng_isr_cb)(rnum);
+    }
+}
+
+/**
+ * Initialize the random number generator
+ * 
+ * @param cb 
+ * @param bias 
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
+{
+    /* Set bias */
+    if (bias) {
+        NRF_RNG->CONFIG = 1;
+    } else {
+        NRF_RNG->CONFIG = 0;
+    }
+
+    /* If we were passed a function pointer we need to enable the interrupt */
+    if (cb != NULL) {
+        NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
+        NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr);
+        NVIC_EnableIRQ(RNG_IRQn);
+        g_ble_rng_isr_cb = cb;
+    }
+
+    return 0;
+}
+
+/**
+ * Start the random number generator
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_start(void)
+{
+    os_sr_t sr;
+
+    /* No need for interrupt if there is no callback */
+    OS_ENTER_CRITICAL(sr);
+    if (NRF_RNG->TASKS_START == 0) {
+        NRF_RNG->EVENTS_VALRDY = 0;
+        if (g_ble_rng_isr_cb) {
+            NRF_RNG->INTENSET = 1;
+        }
+        NRF_RNG->TASKS_START = 1;
+    }
+    OS_EXIT_CRITICAL(sr);
+
+    return 0;
+}
+
+/**
+ * Stop the random generator
+ * 
+ * @return int 
+ */
+int
+ble_hw_rng_stop(void)
+{
+    os_sr_t sr;
+
+    /* No need for interrupt if there is no callback */
+    OS_ENTER_CRITICAL(sr);
+    NRF_RNG->INTENCLR = 1;
+    NRF_RNG->TASKS_STOP = 1;
+    NRF_RNG->EVENTS_VALRDY = 0;
+    OS_EXIT_CRITICAL(sr);
+
+    return 0;
+}
+
+/**
+ * Read the random number generator.
+ * 
+ * @return uint8_t 
+ */
+uint8_t
+ble_hw_rng_read(void)
+{
+    uint8_t rnum;
+
+    /* Wait for a sample */
+    while (NRF_RNG->EVENTS_VALRDY == 0) {
+    }
+
+    NRF_RNG->EVENTS_VALRDY = 0;
+    rnum = (uint8_t)NRF_RNG->VALUE;
+
+    return rnum;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/host/include/host/host_hci.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/host_hci.h b/net/nimble/host/include/host/host_hci.h
index 2021c60..643b367 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -66,6 +66,7 @@ int host_hci_cmd_le_conn_param_neg_reply(struct hci_conn_param_neg_reply
*hcn);
 int host_hci_cmd_le_read_supp_states(void);
 int host_hci_cmd_le_read_max_datalen(void);
 int host_hci_cmd_le_encrypt(uint8_t *key, uint8_t *pt);
+int host_hci_cmd_le_rand(void);
 int host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts);
 
 uint16_t host_hci_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/host/src/host_dbg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_dbg.c b/net/nimble/host/src/host_dbg.c
index 0fb8bf1..aba309b 100644
--- a/net/nimble/host/src/host_dbg.c
+++ b/net/nimble/host/src/host_dbg.c
@@ -312,6 +312,12 @@ host_hci_dbg_cmd_complete_disp(uint8_t *evdata, uint8_t len)
                        evdata[3], evdata[2], evdata[1], evdata[0]);
 
             break;
+        case BLE_HCI_OCF_LE_RAND:
+            evdata += 4;
+            BLE_HS_LOG(DEBUG, "rand=0x%02x%02x%02x%02x%02x%02x%02x%02x",
+                       evdata[0], evdata[1], evdata[2], evdata[3],
+                       evdata[4], evdata[5], evdata[6], evdata[7]);
+            break;
         default:
             break;
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/host/src/host_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c
index b29e29f..e0c2e89 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -321,6 +321,14 @@ host_hci_cmd_le_set_event_mask(uint64_t event_mask)
     return rc;
 }
 
+/**
+ * LE Read buffer size
+ *  
+ * OGF = 0x08 (LE) 
+ * OCF = 0x0002 
+ * 
+ * @return int 
+ */
 int
 host_hci_cmd_le_read_buffer_size(void)
 {
@@ -746,8 +754,10 @@ host_hci_cmd_le_set_host_chan_class(uint8_t *chanmap)
 
 /**
  * Encrypt a block.
- * 
- * 
+ *  
+ * OGF = 0x08 (LE) 
+ * OCF = 0x0017 
+ *  
  * @param key 
  * @param pt 
  * 
@@ -767,6 +777,20 @@ host_hci_cmd_le_encrypt(uint8_t *key, uint8_t *pt)
 }
 
 /**
+ * Get random data
+ *  
+ * OGF = 0x08 (LE) 
+ * OCF = 0x0018
+ *  
+ * @return int 
+ */
+int
+host_hci_cmd_le_rand(void)
+{
+    return host_hci_le_cmd_send(BLE_HCI_OCF_LE_RAND, 0, NULL);
+}
+
+/**
  * Read the RSSI for a given connection handle
  * 
  * NOTE: OGF=0x05 OCF=0x0005 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index 986fd4f..ef43a11 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -298,6 +298,9 @@
 /* --- LE encrypt (OCF 0x0017) */
 #define BLE_HCI_LE_ENCRYPT_LEN              (32)
 
+/* --- LE rand (OCF 0x0018) */
+#define BLE_HCI_LE_RAND_LEN                 (8)
+
 /* ---  LE long term key request reply command (OCF 0x001a) */
 #define BLE_HCI_LT_KEY_REQ_REPLY_LEN        (18)
 #define BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN (3) /* Includes status byte. */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/include/nimble/nimble_opt.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/nimble_opt.h b/net/nimble/include/nimble/nimble_opt.h
index 4a8467a..eb652cf 100644
--- a/net/nimble/include/nimble/nimble_opt.h
+++ b/net/nimble/include/nimble/nimble_opt.h
@@ -256,20 +256,25 @@
  * size of the PDU's that will be sent and/or received in a connection. 
  */
 #ifndef NIMBLE_OPT_LL_SUPP_MAX_RX_BYTES
-#define NIMBLE_OPT_LL_SUPP_MAX_RX_BYTES        (251)
+#define NIMBLE_OPT_LL_SUPP_MAX_RX_BYTES         (251)
 #endif
 
 #ifndef NIMBLE_OPT_LL_SUPP_MAX_TX_BYTES
-#define NIMBLE_OPT_LL_SUPP_MAX_TX_BYTES        (251)
+#define NIMBLE_OPT_LL_SUPP_MAX_TX_BYTES         (251)
 #endif
 
 #ifndef NIMBLE_OPT_LL_CONN_INIT_MAX_TX_BYTES
-#define NIMBLE_OPT_LL_CONN_INIT_MAX_TX_BYTES   (251)
+#define NIMBLE_OPT_LL_CONN_INIT_MAX_TX_BYTES    (251)
 #endif
 
 /* The number of slots that will be allocated to each connection */
 #ifndef NIMBLE_OPT_LL_CONN_INIT_SLOTS
-#define NIMBLE_OPT_LL_CONN_INIT_SLOTS          (2)
+#define NIMBLE_OPT_LL_CONN_INIT_SLOTS           (2)
+#endif
+
+/* The number of random bytes to store */
+#ifndef NIMBLE_OPT_LL_RNG_BUFSIZE
+#define NIMBLE_OPT_LL_RNG_BUFSIZE               (32)
 #endif
 
 /* Include automatically-generated settings. */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f936daef/net/nimble/src/hci_common.c
----------------------------------------------------------------------
diff --git a/net/nimble/src/hci_common.c b/net/nimble/src/hci_common.c
index 42bbb30..6a3f947 100644
--- a/net/nimble/src/hci_common.c
+++ b/net/nimble/src/hci_common.c
@@ -52,7 +52,7 @@ const uint8_t g_ble_hci_le_cmd_len[BLE_HCI_NUM_LE_CMDS] =
     sizeof(uint16_t),                   /* 0x0015: read channel map */
     BLE_HCI_CONN_RD_REM_FEAT_LEN,       /* 0x0016: read remote features */
     BLE_HCI_LE_ENCRYPT_LEN,             /* 0x0017: encrypt */
-    0xFF,
+    0,                                  /* 0x0018: rand */
     0xFF,
     0xFF,
     0xFF,


Mime
View raw message