You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/06/05 11:52:03 UTC

[16/43] incubator-mynewt-core git commit: BLE Host - Use tinycrypt for SC.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/libs/tinycrypt/src/sha256.c
----------------------------------------------------------------------
diff --git a/libs/tinycrypt/src/sha256.c b/libs/tinycrypt/src/sha256.c
new file mode 100644
index 0000000..1dced76
--- /dev/null
+++ b/libs/tinycrypt/src/sha256.c
@@ -0,0 +1,219 @@
+/* sha256.c - TinyCrypt SHA-256 crypto hash algorithm implementation */
+
+/*
+ *  Copyright (C) 2015 by Intel Corporation, All Rights Reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *    - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *
+ *    - 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.
+ *
+ *    - Neither the name of Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <tinycrypt/sha256.h>
+#include <tinycrypt/constants.h>
+#include <tinycrypt/utils.h>
+
+static void compress(uint32_t *iv, const uint8_t *data);
+
+int32_t tc_sha256_init(TCSha256State_t s)
+{
+	/* input sanity check: */
+	if (s == (TCSha256State_t) 0) {
+		return TC_FAIL;
+	}
+
+	/*
+	 * Setting the initial state values.
+	 * These values correspond to the first 32 bits of the fractional parts
+	 * of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17
+	 * and 19.
+	 */
+	_set((uint8_t *) s, 0x00, sizeof(*s));
+	s->iv[0] = 0x6a09e667;
+	s->iv[1] = 0xbb67ae85;
+	s->iv[2] = 0x3c6ef372;
+	s->iv[3] = 0xa54ff53a;
+	s->iv[4] = 0x510e527f;
+	s->iv[5] = 0x9b05688c;
+	s->iv[6] = 0x1f83d9ab;
+	s->iv[7] = 0x5be0cd19;
+
+	return TC_SUCCESS;
+}
+
+int32_t tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen)
+{
+	/* input sanity check: */
+	if (s == (TCSha256State_t) 0 ||
+	    s->iv == (uint32_t *) 0 ||
+	    data == (void *) 0) {
+		return TC_FAIL;
+	} else if (datalen == 0) {
+		return TC_SUCCESS;
+	}
+
+	while (datalen-- > 0) {
+		s->leftover[s->leftover_offset++] = *(data++);
+		if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) {
+			compress(s->iv, s->leftover);
+			s->leftover_offset = 0;
+			s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3);
+		}
+	}
+
+	return TC_SUCCESS;
+}
+
+int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s)
+{
+	uint32_t i;
+
+	/* input sanity check: */
+	if (digest == (uint8_t *) 0 ||
+	    s == (TCSha256State_t) 0 ||
+	    s->iv == (uint32_t *) 0) {
+		return TC_FAIL;
+	}
+
+	s->bits_hashed += (s->leftover_offset << 3);
+
+	s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */
+	if (s->leftover_offset > (sizeof(s->leftover) - 8)) {
+		/* there is not room for all the padding in this block */
+		_set(s->leftover + s->leftover_offset, 0x00,
+		     sizeof(s->leftover) - s->leftover_offset);
+		compress(s->iv, s->leftover);
+		s->leftover_offset = 0;
+	}
+
+	/* add the padding and the length in big-Endian format */
+	_set(s->leftover + s->leftover_offset, 0x00,
+	     sizeof(s->leftover) - 8 - s->leftover_offset);
+	s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed);
+	s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8);
+	s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16);
+	s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24);
+	s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32);
+	s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40);
+	s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48);
+	s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56);
+
+	/* hash the padding and length */
+	compress(s->iv, s->leftover);
+
+	/* copy the iv out to digest */
+	for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) {
+		uint32_t t = *((uint32_t *) &s->iv[i]);
+		*digest++ = (uint8_t)(t >> 24);
+		*digest++ = (uint8_t)(t >> 16);
+		*digest++ = (uint8_t)(t >> 8);
+		*digest++ = (uint8_t)(t);
+	}
+
+	/* destroy the current state */
+	_set(s, 0, sizeof(*s));
+
+	return TC_SUCCESS;
+}
+
+/*
+ * Initializing SHA-256 Hash constant words K.
+ * These values correspond to the first 32 bits of the fractional parts of the
+ * cube roots of the first 64 primes between 2 and 311.
+ */
+static const uint32_t k256[64] = {
+	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+	0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+	0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+	0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+	0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+	0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static inline uint32_t ROTR(uint32_t a, uint32_t n)
+{
+	return (((a) >> n) | ((a) << (32 - n)));
+}
+
+#define Sigma0(a)(ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22))
+#define Sigma1(a)(ROTR((a), 6) ^ ROTR((a), 11) ^ ROTR((a), 25))
+#define sigma0(a)(ROTR((a), 7) ^ ROTR((a), 18) ^ ((a) >> 3))
+#define sigma1(a)(ROTR((a), 17) ^ ROTR((a), 19) ^ ((a) >> 10))
+
+#define Ch(a, b, c)(((a) & (b)) ^ ((~(a)) & (c)))
+#define Maj(a, b, c)(((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c)))
+
+static inline uint32_t BigEndian(const uint8_t **c)
+{
+	uint32_t n = 0;
+
+	n = (((uint32_t)(*((*c)++))) << 24);
+	n |= ((uint32_t)(*((*c)++)) << 16);
+	n |= ((uint32_t)(*((*c)++)) << 8);
+	n |= ((uint32_t)(*((*c)++)));
+	return n;
+}
+
+static void compress(uint32_t *iv, const uint8_t *data)
+{
+	uint32_t a, b, c, d, e, f, g, h;
+	uint32_t s0, s1;
+	uint32_t t1, t2;
+	uint32_t work_space[16];
+	uint32_t n;
+	uint32_t i;
+
+	a = iv[0]; b = iv[1]; c = iv[2]; d = iv[3];
+	e = iv[4]; f = iv[5]; g = iv[6]; h = iv[7];
+
+	for (i = 0; i < 16; ++i) {
+		n = BigEndian(&data);
+		t1 = work_space[i] = n;
+		t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
+		t2 = Sigma0(a) + Maj(a, b, c);
+		h = g; g = f; f = e; e = d + t1;
+		d = c; c = b; b = a; a = t1 + t2;
+	}
+
+	for ( ; i < 64; ++i) {
+		s0 = work_space[(i+1)&0x0f];
+		s0 = sigma0(s0);
+		s1 = work_space[(i+14)&0x0f];
+		s1 = sigma1(s1);
+
+		t1 = work_space[i&0xf] += s0 + s1 + work_space[(i+9)&0xf];
+		t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
+		t2 = Sigma0(a) + Maj(a, b, c);
+		h = g; g = f; f = e; e = d + t1;
+		d = c; c = b; b = a; a = t1 + t2;
+	}
+
+	iv[0] += a; iv[1] += b; iv[2] += c; iv[3] += d;
+	iv[4] += e; iv[5] += f; iv[6] += g; iv[7] += h;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/libs/tinycrypt/src/utils.c
----------------------------------------------------------------------
diff --git a/libs/tinycrypt/src/utils.c b/libs/tinycrypt/src/utils.c
new file mode 100644
index 0000000..7f05939
--- /dev/null
+++ b/libs/tinycrypt/src/utils.c
@@ -0,0 +1,78 @@
+/* utils.c - TinyCrypt platform-dependent run-time operations */
+
+/*
+ *  Copyright (C) 2015 by Intel Corporation, All Rights Reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *    - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *
+ *    - 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.
+ *
+ *    - Neither the name of Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <tinycrypt/utils.h>
+#include <tinycrypt/constants.h>
+
+#include <string.h>
+
+#define MASK_MOST_SIG_BIT 0x80
+#define MASK_TWENTY_SEVEN 0x1b
+
+uint32_t _copy(uint8_t *to, uint32_t to_len,
+	       const uint8_t *from, uint32_t from_len)
+{
+	if (from_len <= to_len) {
+		(void)memcpy(to, from, from_len);
+		return from_len;
+	} else {
+		return TC_FAIL;
+	}
+}
+
+void _set(void *to, uint8_t val, uint32_t len)
+{
+	(void)memset(to, val, len);
+}
+
+/*
+ * Doubles the value of a byte for values up to 127. Original 'return
+ * ((a<<1) ^ ((a>>7) * 0x1b))' re-written to avoid extra multiplication which
+ * the compiler won't be able to optimize
+ */
+uint8_t _double_byte(uint8_t a)
+{
+	return (a & MASK_MOST_SIG_BIT) ?
+		((a << 1) ^ MASK_TWENTY_SEVEN) : (a << 1);
+}
+
+int32_t _compare(const uint8_t *a, const uint8_t *b, size_t size)
+{
+	const uint8_t *tempa = a;
+	const uint8_t *tempb = b;
+	uint8_t result = 0;
+
+	for (uint32_t i = 0; i < size; i++) {
+		result |= tempa[i] ^ tempb[i];
+	}
+	return result;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/include/host/ble_sm.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_sm.h b/net/nimble/host/include/host/ble_sm.h
index d6c54a9..1c3edeb 100644
--- a/net/nimble/host/include/host/ble_sm.h
+++ b/net/nimble/host/include/host/ble_sm.h
@@ -78,6 +78,7 @@
 #define BLE_SM_PKACT_OOB                        1
 #define BLE_SM_PKACT_INPUT                      2
 #define BLE_SM_PKACT_DISP                       3
+#define BLE_SM_PKACT_NUMCMP                     4
 
 struct ble_sm_passkey {
     uint8_t action;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml
index 0cea14f..e9dfd80 100644
--- a/net/nimble/host/pkg.yml
+++ b/net/nimble/host/pkg.yml
@@ -32,6 +32,7 @@ pkg.deps:
     - libs/util
     - libs/mbedtls
     - net/nimble
+    - libs/tinycrypt
 
 pkg.req_apis:
     - console

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c
index d22a85b..dc91ee7 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -433,6 +433,8 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
     ble_hs_dbg_mutex_locked = 0;
 #endif
 
+    ble_sm_sc_init();
+
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/src/ble_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm.c b/net/nimble/host/src/ble_sm.c
index 0dbbdf6..a81f316 100644
--- a/net/nimble/host/src/ble_sm.c
+++ b/net/nimble/host/src/ble_sm.c
@@ -386,8 +386,7 @@ ble_sm_gen_csrk(struct ble_sm_proc *proc, uint8_t *csrk)
 }
 
 int
-ble_sm_gen_pub_priv(struct ble_sm_proc *proc,
-                          uint8_t *pub, uint8_t *priv)
+ble_sm_gen_pub_priv(uint8_t *pub, uint8_t *priv)
 {
     int rc;
 
@@ -520,6 +519,51 @@ ble_sm_fill_store_value(uint8_t peer_addr_type, uint8_t *peer_addr,
     }
 }
 
+int
+ble_sm_peer_addr(struct ble_sm_proc *proc,
+                 uint8_t *out_type, uint8_t **out_addr)
+{
+    struct ble_hs_conn *conn;
+
+    conn = ble_hs_conn_find(proc->conn_handle);
+    if (conn == NULL) {
+        return BLE_HS_ENOTCONN;
+    }
+
+    *out_type = conn->bhc_addr_type;
+    *out_addr = conn->bhc_addr;
+
+    return 0;
+}
+
+int
+ble_sm_addrs(struct ble_sm_proc *proc, uint8_t *out_iat, uint8_t **out_ia,
+             uint8_t *out_rat, uint8_t **out_ra)
+{
+    struct ble_hs_conn *conn;
+
+    conn = ble_hs_conn_find(proc->conn_handle);
+    if (conn == NULL) {
+        return BLE_HS_ENOTCONN;
+    }
+
+    if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
+        *out_iat = BLE_ADDR_TYPE_PUBLIC; /* XXX: Support random addresses. */
+        *out_ia = ble_hs_our_dev.public_addr;
+
+        *out_rat = conn->bhc_addr_type;
+        *out_ra = conn->bhc_addr;
+    } else {
+        *out_rat = BLE_ADDR_TYPE_PUBLIC; /* XXX: Support random addresses. */
+        *out_ra = ble_hs_our_dev.public_addr;
+
+        *out_iat = conn->bhc_addr_type;
+        *out_ia = conn->bhc_addr;
+    }
+
+    return 0;
+}
+
 static void
 ble_sm_persist_keys(uint16_t conn_handle,
                     struct ble_sm_keys *our_keys,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/src/ble_sm_alg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_alg.c b/net/nimble/host/src/ble_sm_alg.c
index 25834d4..53da486 100644
--- a/net/nimble/host/src/ble_sm_alg.c
+++ b/net/nimble/host/src/ble_sm_alg.c
@@ -21,8 +21,11 @@
 #include <inttypes.h>
 #include <string.h>
 #include "mbedtls/aes.h"
-#include "mbedtls/cmac.h"
-#include "mbedtls/ecdsa.h"
+#include "tinycrypt/aes.h"
+#include "tinycrypt/constants.h"
+#include "tinycrypt/utils.h"
+#include "tinycrypt/cmac_mode.h"
+#include "tinycrypt/ecc_dh.h"
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "ble_hs_priv.h"
@@ -30,8 +33,6 @@
 #if NIMBLE_OPT(SM)
 
 static mbedtls_aes_context ble_sm_alg_ctxt;
-//static mbedtls_ecdh_context ble_sm_alg_ecdh_ctx;
-//static mbedtls_cmac_context ble_sm_alg_cmac_ctxt;
 
 /* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */
 static const uint32_t ble_sm_alg_dbg_priv_key[8] = {
@@ -67,7 +68,6 @@ static const uint8_t ble_sm_alg_dbg_f6[16] = {
     0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3,
 };
 
-#if 0
 static void
 ble_sm_alg_log_buf(char *name, uint8_t *buf, int len)
 {
@@ -75,7 +75,6 @@ ble_sm_alg_log_buf(char *name, uint8_t *buf, int len)
     ble_hs_misc_log_flat_buf(buf, len);
     BLE_HS_LOG(DEBUG, "\n");
 }
-#endif
 
 static void
 ble_sm_alg_xor_128(uint8_t *p, uint8_t *q, uint8_t *r)
@@ -114,6 +113,36 @@ ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data)
     return 0;
 }
 
+/**
+ * Cypher based Message Authentication Code (CMAC) with AES 128 bit
+ *
+ * @param key                   128-bit key.
+ * @param in                    Message to be authenticated.
+ * @param len                   Length of the message in octets.
+ * @param out                   Output; message authentication code.
+ */
+static int
+ble_sm_alg_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len,
+                    uint8_t *out)
+{
+    struct tc_aes_key_sched_struct sched;
+    struct tc_cmac_struct state;
+
+    if (tc_cmac_setup(&state, key, &sched) == TC_FAIL) {
+        return BLE_HS_EUNKNOWN;
+    }
+
+    if (tc_cmac_update(&state, in, len) == TC_FAIL) {
+        return BLE_HS_EUNKNOWN;
+    }
+
+    if (tc_cmac_final(out, &state) == TC_FAIL) {
+        return BLE_HS_EUNKNOWN;
+    }
+
+    return 0;
+}
+
 int
 ble_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out)
 {
@@ -223,7 +252,6 @@ int
 ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z,
               uint8_t *out_enc_data)
 {
-#if 0
     uint8_t xs[16];
     uint8_t m[65];
     int rc;
@@ -236,8 +264,6 @@ ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z,
     ble_hs_misc_log_flat_buf(x, 16);
     BLE_HS_LOG(DEBUG, "\n    z=0x%02x\n", z);
 
-    mbedtls_cmac_init(&ble_sm_alg_cmac_ctxt);
-
     /*
      * U, V and Z are concatenated and used as input m to the function
      * AES-CMAC and X is used as the key k.
@@ -245,7 +271,7 @@ ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z,
      * Core Spec 4.2 Vol 3 Part H 2.2.5
      *
      * note:
-     * XXX bt_smp_aes_cmac uses BE data and smp_f4 accept LE so we swap
+     * ble_sm_alg_aes_cmac uses BE data; ble_sm_alg_f4 accepts LE so we swap.
      */
     swap_buf(m, u, 32);
     swap_buf(m + 32, v, 32);
@@ -253,8 +279,7 @@ ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z,
 
     swap_buf(xs, x, 16);
 
-    rc = mbedtls_aes_cmac_prf_128(&ble_sm_alg_cmac_ctxt, xs, sizeof xs,
-                                  m, sizeof m, out_enc_data);
+    rc = ble_sm_alg_aes_cmac(xs, m, sizeof(m), out_enc_data);
     if (rc != 0) {
         return BLE_HS_EUNKNOWN;
     }
@@ -264,46 +289,6 @@ ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z,
     BLE_HS_LOG(DEBUG, "    out_enc_data=");
     ble_hs_misc_log_flat_buf(out_enc_data, 16);
     BLE_HS_LOG(DEBUG, "\n");
-#endif
-
-    memcpy(out_enc_data, ble_sm_alg_dbg_f4,
-           sizeof ble_sm_alg_dbg_f4);
-    return 0;
-}
-
-int
-ble_sm_alg_g2(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t *y,
-              uint32_t *passkey)
-{
-#if 0
-    uint8_t m[80], xs[16];
-    int rc;
-
-    ble_sm_alg_log_buf("u", u, 32);
-    ble_sm_alg_log_buf("v", v, 32);
-    ble_sm_alg_log_buf("x", x, 16);
-    ble_sm_alg_log_buf("y", y, 16);
-
-    mbedtls_cmac_init(&ble_sm_alg_cmac_ctxt);
-
-    swap_buf(m, u, 32);
-    swap_buf(m + 32, v, 32);
-    swap_buf(m + 64, y, 16);
-
-    swap_buf(xs, x, 16);
-
-    /* reuse xs (key) as buffer for result */
-    rc = mbedtls_aes_cmac_prf_128(&ble_sm_alg_cmac_ctxt, xs, sizeof xs,
-                                  m, sizeof m, xs);
-    if (rc != 0) {
-        return BLE_HS_EUNKNOWN;
-    }
-
-    ble_sm_alg_log_buf("res", xs, 16);
-
-    *passkey = be32toh(xs + 12) % 1000000;
-    BLE_HS_LOG(DEBUG, "    passkey=%u", *passkey);
-#endif
 
     return 0;
 }
@@ -313,7 +298,6 @@ ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t,
               uint8_t *a1, uint8_t a2t, uint8_t *a2, uint8_t *mackey,
               uint8_t *ltk)
 {
-#if 0
     static const uint8_t salt[16] = { 0x6c, 0x88, 0x83, 0x91, 0xaa, 0xf5,
                       0xa5, 0x38, 0x60, 0x37, 0x0b, 0xdb,
                       0x5a, 0x60, 0x83, 0xbe };
@@ -336,12 +320,9 @@ ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t,
     ble_sm_alg_log_buf("n1", n1, 16);
     ble_sm_alg_log_buf("n2", n2, 16);
 
-    mbedtls_cmac_init(&ble_sm_alg_cmac_ctxt);
-
     swap_buf(ws, w, 32);
 
-    rc = mbedtls_aes_cmac_prf_128(&ble_sm_alg_cmac_ctxt,
-                                  salt, sizeof salt, ws, sizeof ws, t);
+    rc = ble_sm_alg_aes_cmac(salt, ws, 32, t);
     if (rc != 0) {
         return BLE_HS_EUNKNOWN;
     }
@@ -355,8 +336,7 @@ ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t,
     m[44] = a2t;
     swap_buf(m + 45, a2, 6);
 
-    rc = mbedtls_aes_cmac_prf_128(&ble_sm_alg_cmac_ctxt,
-                                  t, sizeof t, m, sizeof m, mackey);
+    rc = ble_sm_alg_aes_cmac(t, m, sizeof(m), mackey);
     if (rc != 0) {
         return BLE_HS_EUNKNOWN;
     }
@@ -365,11 +345,10 @@ ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t,
 
     swap_in_place(mackey, 16);
 
-    /* counter for ltk is 1 */
+    /* Counter for ltk is 1. */
     m[0] = 0x01;
 
-    rc = mbedtls_aes_cmac_prf_128(&ble_sm_alg_cmac_ctxt,
-                                  t, sizeof t, m, sizeof m, ltk);
+    rc = ble_sm_alg_aes_cmac(t, m, sizeof(m), ltk);
     if (rc != 0) {
         return BLE_HS_EUNKNOWN;
     }
@@ -377,10 +356,7 @@ ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t,
     ble_sm_alg_log_buf("ltk", ltk, 16);
 
     swap_in_place(ltk, 16);
-#endif
 
-    memcpy(mackey, ble_sm_alg_dbg_f5 + 16, 16);
-    memcpy(ltk, ble_sm_alg_dbg_f5, 16);
     return 0;
 }
 
@@ -389,7 +365,6 @@ ble_sm_alg_f6(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t *r,
               uint8_t *iocap, uint8_t a1t, uint8_t *a1,
               uint8_t a2t, uint8_t *a2, uint8_t *check)
 {
-#if 0
     uint8_t ws[16];
     uint8_t m[65];
     int rc;
@@ -404,8 +379,6 @@ ble_sm_alg_f6(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t *r,
     ble_sm_alg_log_buf("a2t", &a2t, 1);
     ble_sm_alg_log_buf("a2", a2, 6);
 
-    mbedtls_cmac_init(&ble_sm_alg_cmac_ctxt);
-
     swap_buf(m, n1, 16);
     swap_buf(m + 16, n2, 16);
     swap_buf(m + 32, r, 16);
@@ -421,8 +394,7 @@ ble_sm_alg_f6(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t *r,
 
     swap_buf(ws, w, 16);
 
-    rc = mbedtls_aes_cmac_prf_128(&ble_sm_alg_cmac_ctxt,
-                                  ws, sizeof ws, m, sizeof m, check);
+    rc = ble_sm_alg_aes_cmac(ws, m, sizeof(m), check);
     if (rc != 0) {
         return BLE_HS_EUNKNOWN;
     }
@@ -430,23 +402,65 @@ ble_sm_alg_f6(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t *r,
     ble_sm_alg_log_buf("res", check, 16);
 
     swap_in_place(check, 16);
-#endif
 
-    memcpy(check, ble_sm_alg_dbg_f6, sizeof ble_sm_alg_dbg_f6);
     return 0;
 }
 
-/**
- * Passed to mbedtls ecc function.
- */
-#if 0
-static int
-ble_sm_alg_rnd(void *arg, unsigned char *dst, size_t len)
+int
+ble_sm_alg_g2(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t *y, uint32_t *passkey)
+{
+    uint8_t m[80], xs[16];
+    int rc;
+
+    ble_sm_alg_log_buf("u", u, 32);
+    ble_sm_alg_log_buf("v", v, 32);
+    ble_sm_alg_log_buf("x", x, 16);
+    ble_sm_alg_log_buf("y", y, 16);
+
+    swap_buf(m, u, 32);
+    swap_buf(m + 32, v, 32);
+    swap_buf(m + 64, y, 16);
+
+    swap_buf(xs, x, 16);
+
+    /* reuse xs (key) as buffer for result */
+    rc = ble_sm_alg_aes_cmac(xs, m, sizeof(m), xs);
+    if (rc != 0) {
+        return BLE_HS_EUNKNOWN;
+    }
+
+    ble_sm_alg_log_buf("res", xs, 16);
+
+    *passkey = be32toh(xs + 12) % 1000000;
+    BLE_HS_LOG(DEBUG, "    passkey=%u", *passkey);
+
+    return 0;
+}
+
+int
+ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y,
+                     uint8_t *our_priv_key, void *out_dhkey)
 {
-    // XXX
+    uint32_t priv_key32[8];
+    uint32_t dh[8];
+    EccPoint pk;
+
+    memcpy(pk.x, peer_pub_key_x, 32);
+    memcpy(pk.y, peer_pub_key_y, 32);
+
+    if (ecc_valid_public_key(&pk) < 0) {
+        return BLE_HS_EUNKNOWN;
+    }
+
+    memcpy(priv_key32, our_priv_key, sizeof priv_key32);
+    if (ecdh_shared_secret(dh, &pk, priv_key32) == TC_FAIL) {
+        return BLE_HS_EUNKNOWN;
+    }
+
+    memcpy(out_dhkey, dh, 32);
+
     return 0;
 }
-#endif
 
 /**
  * pub: 64 bytes
@@ -455,8 +469,31 @@ ble_sm_alg_rnd(void *arg, unsigned char *dst, size_t len)
 int
 ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv)
 {
-    memcpy(pub, ble_sm_alg_dbg_pub_key, sizeof ble_sm_alg_dbg_pub_key);
-    memcpy(priv, ble_sm_alg_dbg_priv_key, sizeof ble_sm_alg_dbg_priv_key);
+    //memcpy(pub, ble_sm_alg_dbg_pub_key, sizeof ble_sm_alg_dbg_pub_key);
+    //memcpy(priv, ble_sm_alg_dbg_priv_key, sizeof ble_sm_alg_dbg_priv_key);
+
+    uint32_t temp_priv[8];
+    uint32_t random[16];
+    EccPoint pkey;
+    int rc;
+
+    do {
+        rc = ble_hci_util_rand(random, sizeof random);
+        if (rc != 0) {
+            return rc;
+        }
+
+        rc = ecc_make_key(&pkey, temp_priv, random);
+        if (rc != TC_CRYPTO_SUCCESS) {
+            return BLE_HS_EUNKNOWN;
+        }
+
+        /* Make sure generated key isn't debug key. */
+    } while (memcmp(temp_priv, ble_sm_alg_dbg_priv_key, 32) == 0);
+
+    memcpy(priv, temp_priv, sizeof temp_priv);
+    memcpy(pub + 0, pkey.x, 32);
+    memcpy(pub + 32, pkey.y, 32);
 
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/src/ble_sm_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_priv.h b/net/nimble/host/src/ble_sm_priv.h
index 8e155cb..f97b9ee 100644
--- a/net/nimble/host/src/ble_sm_priv.h
+++ b/net/nimble/host/src/ble_sm_priv.h
@@ -257,7 +257,6 @@ struct ble_sm_proc {
 
     struct ble_sm_pair_cmd pair_req;
     struct ble_sm_pair_cmd pair_rsp;
-    struct ble_sm_public_key pub_key_our;
     struct ble_sm_public_key pub_key_their;
     uint8_t priv_key_our[32];
     uint8_t tk[16];
@@ -266,6 +265,7 @@ struct ble_sm_proc {
     uint8_t rands[16];
     uint8_t ltk[16];
     uint8_t mackey[16];
+    uint8_t dhkey[32];
 
     uint16_t ediv;
     uint64_t rand_num;
@@ -291,6 +291,7 @@ void ble_sm_dbg_set_next_start_rand(uint64_t next_start_rand);
 void ble_sm_dbg_set_next_ltk(uint8_t *next_ltk);
 void ble_sm_dbg_set_next_irk(uint8_t *next_irk);
 void ble_sm_dbg_set_next_csrk(uint8_t *next_csrk);
+void ble_sm_dbg_set_sc_keys(uint8_t *pubkey, uint8_t *privkey);
 int ble_sm_dbg_num_procs(void);
 #endif
 
@@ -339,6 +340,8 @@ int ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t,
 int ble_sm_alg_f6(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t *r,
                   uint8_t *iocap, uint8_t a1t, uint8_t *a1,
                   uint8_t a2t, uint8_t *a2, uint8_t *check);
+int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y,
+                         uint8_t *our_priv_key, void *out_dhkey);
 int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv);
 
 void ble_sm_enc_info_parse(void *payload, int len,
@@ -400,15 +403,20 @@ void ble_sm_sc_dhkey_check_go(struct ble_sm_proc *proc,
                               struct ble_sm_result *res, void *arg);
 void ble_sm_sc_rx_dhkey_check(uint16_t conn_handle, uint8_t op,
                               struct os_mbuf **om, struct ble_sm_result *res);
+void ble_sm_sc_init(void);
 
 struct ble_sm_proc *ble_sm_proc_find(uint16_t conn_handle, uint8_t state,
                                      int is_initiator,
                                      struct ble_sm_proc **out_prev);
-int ble_sm_gen_pub_priv(struct ble_sm_proc *proc, uint8_t *pub, uint8_t *priv);
+int ble_sm_gen_pub_priv(uint8_t *pub, uint8_t *priv);
 uint8_t *ble_sm_our_pair_rand(struct ble_sm_proc *proc);
 uint8_t *ble_sm_their_pair_rand(struct ble_sm_proc *proc);
 void ble_sm_go(struct ble_sm_proc *proc, struct ble_sm_result *res, void *arg);
 void ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res);
+int ble_sm_peer_addr(struct ble_sm_proc *proc,
+                     uint8_t *out_type, uint8_t **out_addr);
+int ble_sm_addrs(struct ble_sm_proc *proc, uint8_t *out_iat, uint8_t **out_ia,
+                 uint8_t *out_rat, uint8_t **out_ra);
 
 void ble_sm_heartbeat(void);
 void ble_sm_connection_broken(uint16_t conn_handle);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/src/ble_sm_sc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_sc.c b/net/nimble/host/src/ble_sm_sc.c
index b06703d..9e6ccee 100644
--- a/net/nimble/host/src/ble_sm_sc.c
+++ b/net/nimble/host/src/ble_sm_sc.c
@@ -23,6 +23,61 @@
 #include "ble_hs_priv.h"
 #include "ble_sm_priv.h"
 
+/**
+ * Create some shortened names for the passkey actions so that the table is
+ * easier to read.
+ */
+#define PKACT_NONE      BLE_SM_PKACT_NONE
+#define PKACT_OOB       BLE_SM_PKACT_OOB
+#define PKACT_INPUT     BLE_SM_PKACT_INPUT
+#define PKACT_DISP      BLE_SM_PKACT_DISP
+#define PKACT_NUMCMP    BLE_SM_PKACT_NUMCMP
+
+/* This is the initiator passkey action action dpeneding on the io
+ * capabilties of both parties
+ */
+static const uint8_t ble_sm_lgcy_init_pka[5 /*resp*/ ][5 /*init */] =
+{
+    {PKACT_NONE,    PKACT_NONE,   PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
+    {PKACT_NONE,    PKACT_NUMCMP, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
+    {PKACT_DISP,    PKACT_DISP,   PKACT_INPUT, PKACT_NONE, PKACT_DISP},
+    {PKACT_NONE,    PKACT_NONE,   PKACT_NONE,  PKACT_NONE, PKACT_NONE},
+    {PKACT_DISP,    PKACT_NUMCMP, PKACT_INPUT, PKACT_NONE, PKACT_NUMCMP},
+};
+
+/* This is the responder passkey action action depending on the io
+ * capabilities of both parties
+ */
+static const uint8_t ble_sm_lgcy_resp_pka[5 /*init*/ ][5 /*resp */] =
+{
+    {PKACT_NONE,    PKACT_NONE,   PKACT_DISP,  PKACT_NONE, PKACT_DISP},
+    {PKACT_NONE,    PKACT_NUMCMP, PKACT_DISP,  PKACT_NONE, PKACT_NUMCMP},
+    {PKACT_INPUT,   PKACT_INPUT,  PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
+    {PKACT_NONE,    PKACT_NONE,   PKACT_NONE,  PKACT_NONE, PKACT_NONE},
+    {PKACT_INPUT,   PKACT_NUMCMP, PKACT_DISP,  PKACT_NONE, PKACT_NUMCMP},
+};
+
+static uint8_t ble_sm_sc_pub_key[64];
+static uint8_t ble_sm_sc_priv_key[32];
+static uint8_t ble_sm_sc_keys_generated;
+
+static int
+ble_sm_sc_ensure_keys_generated(void)
+{
+    int rc;
+
+    if (!ble_sm_sc_keys_generated) {
+        rc = ble_sm_gen_pub_priv(ble_sm_sc_pub_key, ble_sm_sc_priv_key);
+        if (rc != 0) {
+            return rc;
+        }
+
+        ble_sm_sc_keys_generated = 1;
+    }
+
+    return 0;
+}
+
 static int
 ble_sm_sc_initiator_txes_confirm(struct ble_sm_proc *proc)
 {
@@ -64,9 +119,8 @@ ble_sm_sc_confirm_go(struct ble_sm_proc *proc, struct ble_sm_result *res)
     struct ble_sm_pair_confirm cmd;
     int rc;
 
-    rc = ble_sm_alg_f4(proc->pub_key_our.x, proc->pub_key_their.x,
-                             ble_sm_our_pair_rand(proc), 0,
-                             cmd.value);
+    rc = ble_sm_alg_f4(ble_sm_sc_pub_key, proc->pub_key_their.x,
+                       ble_sm_our_pair_rand(proc), 0, cmd.value);
     if (rc != 0) {
         res->app_status = rc;
         res->enc_cb = 1;
@@ -110,19 +164,20 @@ ble_sm_sc_random_go(struct ble_sm_proc *proc,
 }
 
 void
-ble_sm_sc_rx_pair_random(struct ble_sm_proc *proc,
-                        struct ble_sm_result *res)
+ble_sm_sc_rx_pair_random(struct ble_sm_proc *proc, struct ble_sm_result *res)
 {
     uint8_t confirm_val[16];
+    uint8_t *ia;
+    uint8_t *ra;
+    uint8_t iat;
+    uint8_t rat;
     int rc;
 
     if (proc->flags & BLE_SM_PROC_F_INITIATOR ||
         ble_sm_sc_responder_verifies_random(proc)) {
 
-        rc = ble_sm_alg_f4(proc->pub_key_our.x,
-                                 proc->pub_key_their.x,
-                                 ble_sm_their_pair_rand(proc), 0,
-                                 confirm_val);
+        rc = ble_sm_alg_f4(ble_sm_sc_pub_key, proc->pub_key_their.x,
+                           ble_sm_their_pair_rand(proc), 0, confirm_val);
         if (rc != 0) {
             res->app_status = rc;
             res->sm_err = BLE_SM_ERR_UNSPECIFIED;
@@ -140,8 +195,16 @@ ble_sm_sc_rx_pair_random(struct ble_sm_proc *proc,
     }
 
     /* Calculate the mac key and ltk. */
-    rc = ble_sm_alg_f5(NULL, NULL, NULL, 0, NULL, 0, NULL,
-                             proc->mackey, proc->ltk);
+    rc = ble_sm_addrs(proc, &iat, &ia, &rat, &ra);
+    if (rc != 0) {
+        res->app_status = rc;
+        res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+        res->enc_cb = 1;
+        return;
+    }
+
+    rc = ble_sm_alg_f5(proc->dhkey, proc->randm, proc->rands,
+                       iat, ia, rat, ra, proc->mackey, proc->ltk);
     if (rc != 0) {
         res->app_status = rc;
         res->sm_err = BLE_SM_ERR_UNSPECIFIED;
@@ -161,19 +224,24 @@ ble_sm_sc_public_key_go(struct ble_sm_proc *proc,
                         struct ble_sm_result *res,
                         void *arg)
 {
+    struct ble_sm_public_key cmd;
     int initiator_txes;
     int is_initiator;
-    int rc;
 
-    rc = ble_sm_gen_pub_priv(proc, proc->pub_key_our.x,
-                                   proc->priv_key_our);
-    if (rc != 0) {
-        goto err;
+    res->app_status = ble_sm_sc_ensure_keys_generated();
+    if (res->app_status != 0) {
+        res->enc_cb = 1;
+        res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+        return;
     }
 
-    rc = ble_sm_public_key_tx(proc->conn_handle, &proc->pub_key_our);
-    if (rc != 0) {
-        goto err;
+    memcpy(cmd.x, ble_sm_sc_pub_key + 0, 32);
+    memcpy(cmd.y, ble_sm_sc_pub_key + 32, 32);
+    res->app_status = ble_sm_public_key_tx(proc->conn_handle, &cmd);
+    if (res->app_status != 0) {
+        res->enc_cb = 1;
+        res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+        return;
     }
 
     initiator_txes = ble_sm_sc_initiator_txes_confirm(proc);
@@ -184,31 +252,6 @@ ble_sm_sc_public_key_go(struct ble_sm_proc *proc,
         proc->state = BLE_SM_PROC_STATE_CONFIRM;
         res->execute = 1;
     }
-
-    return;
-
-err:
-    res->app_status = rc;
-    res->enc_cb = 1;
-    res->sm_err = BLE_SM_ERR_UNSPECIFIED;
-}
-
-void
-ble_sm_sc_public_key_handle(struct ble_sm_proc *proc,
-                            struct ble_sm_public_key *cmd,
-                            struct ble_sm_result *res)
-{
-    proc->pub_key_their = *cmd;
-
-    if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
-        proc->state = BLE_SM_PROC_STATE_CONFIRM;
-
-        if (ble_sm_sc_initiator_txes_confirm(proc)) {
-            res->execute = 1;
-        }
-    } else {
-        res->execute = 1;
-    }
 }
 
 void
@@ -218,6 +261,7 @@ ble_sm_sc_rx_public_key(uint16_t conn_handle, uint8_t op, struct os_mbuf **om,
     struct ble_sm_public_key cmd;
     struct ble_sm_proc *proc;
     struct ble_sm_proc *prev;
+    int rc;
 
     res->app_status = ble_hs_misc_pullup_base(om, BLE_SM_PUBLIC_KEY_SZ);
     if (res->app_status != 0) {
@@ -225,6 +269,13 @@ ble_sm_sc_rx_public_key(uint16_t conn_handle, uint8_t op, struct os_mbuf **om,
         return;
     }
 
+    res->app_status = ble_sm_sc_ensure_keys_generated();
+    if (res->app_status != 0) {
+        res->enc_cb = 1;
+        res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+        return;
+    }
+
     ble_sm_public_key_parse((*om)->om_data, (*om)->om_len, &cmd);
 
     BLE_HS_LOG(DEBUG, "rxed sm public key cmd\n");
@@ -236,7 +287,25 @@ ble_sm_sc_rx_public_key(uint16_t conn_handle, uint8_t op, struct os_mbuf **om,
         res->app_status = BLE_HS_ENOENT;
         res->sm_err = BLE_SM_ERR_UNSPECIFIED;
     } else {
-        ble_sm_sc_public_key_handle(proc, &cmd, res);
+        proc->pub_key_their = cmd;
+        rc = ble_sm_alg_gen_dhkey(proc->pub_key_their.x,
+                                  proc->pub_key_their.y,
+                                  ble_sm_sc_priv_key, proc->dhkey);
+        if (rc != 0) {
+            res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_DHKEY);
+            res->sm_err = BLE_SM_ERR_DHKEY;
+            res->enc_cb = 1;
+        } else {
+            if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
+                proc->state = BLE_SM_PROC_STATE_CONFIRM;
+
+                if (ble_sm_sc_initiator_txes_confirm(proc)) {
+                    res->execute = 1;
+                }
+            } else {
+                res->execute = 1;
+            }
+        }
     }
     ble_hs_unlock();
 }
@@ -246,10 +315,33 @@ ble_sm_sc_dhkey_check_go(struct ble_sm_proc *proc, struct ble_sm_result *res,
                          void *arg)
 {
     struct ble_sm_dhkey_check cmd;
+    uint8_t iocap[3];
+    uint8_t *peer_addr;
+    uint8_t peer_addr_type;
     int rc;
 
-    rc = ble_sm_alg_f6(NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL,
-                             cmd.value);
+    uint8_t zeros[16] = { 0 };
+
+    if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
+        iocap[0] = proc->pair_req.io_cap;
+        iocap[1] = proc->pair_req.oob_data_flag;
+        iocap[2] = proc->pair_req.authreq;
+    } else {
+        iocap[0] = proc->pair_rsp.io_cap;
+        iocap[1] = proc->pair_rsp.oob_data_flag;
+        iocap[2] = proc->pair_rsp.authreq;
+    }
+
+    rc = ble_sm_peer_addr(proc, &peer_addr_type, &peer_addr);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_sm_alg_f6(proc->mackey, ble_sm_our_pair_rand(proc),
+                       ble_sm_their_pair_rand(proc), zeros, iocap,
+                       0, ble_hs_our_dev.public_addr,
+                       peer_addr_type, peer_addr,
+                       cmd.value);
     if (rc != 0) {
         goto err;
     }
@@ -277,16 +369,46 @@ ble_sm_dhkey_check_handle(struct ble_sm_proc *proc,
                           struct ble_sm_result *res)
 {
     uint8_t exp_value[16];
+    uint8_t iocap[3];
+    uint8_t *peer_addr;
+    uint8_t peer_addr_type;
+
+    uint8_t zeros[16] = { 0 };
+
+    if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
+        iocap[0] = proc->pair_rsp.io_cap;
+        iocap[1] = proc->pair_rsp.oob_data_flag;
+        iocap[2] = proc->pair_rsp.authreq;
+    } else {
+        iocap[0] = proc->pair_req.io_cap;
+        iocap[1] = proc->pair_req.oob_data_flag;
+        iocap[2] = proc->pair_req.authreq;
+    }
+
+    res->app_status = ble_sm_peer_addr(proc, &peer_addr_type, &peer_addr);
+    if (res->app_status != 0) {
+        res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+        res->enc_cb = 1;
+        return;
+    }
 
-    res->app_status = ble_sm_alg_f6(NULL, NULL, NULL, NULL, NULL, 0,
-                                    NULL, 0, NULL, exp_value);
+    res->app_status = ble_sm_alg_f6(proc->mackey,
+                                    ble_sm_their_pair_rand(proc),
+                                    ble_sm_our_pair_rand(proc), zeros, iocap,
+                                    peer_addr_type, peer_addr,
+                                    0, ble_hs_our_dev.public_addr,
+                                    exp_value);
     if (res->app_status != 0) {
+        res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+        res->enc_cb = 1;
         return;
     }
+
     if (memcmp(cmd->value, exp_value, 16) != 0) {
         /* Random number mismatch. */
         res->sm_err = BLE_SM_ERR_DHKEY;
         res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_DHKEY);
+        res->enc_cb = 1;
         return;
     }
 
@@ -330,3 +452,9 @@ ble_sm_sc_rx_dhkey_check(uint16_t conn_handle, uint8_t op, struct os_mbuf **om,
     }
     ble_hs_unlock();
 }
+
+void
+ble_sm_sc_init(void)
+{
+    ble_sm_sc_keys_generated = 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/net/nimble/host/src/test/ble_sm_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_sm_test.c b/net/nimble/host/src/test/ble_sm_test.c
index c83e4a6..6237af9 100644
--- a/net/nimble/host/src/test/ble_sm_test.c
+++ b/net/nimble/host/src/test/ble_sm_test.c
@@ -94,6 +94,7 @@ struct ble_sm_test_sc_params {
     int pair_alg;
     unsigned authenticated:1;
     uint8_t ltk[16];
+    uint8_t our_priv_key[32];
 
     struct ble_sm_pair_fail pair_fail;
 
@@ -439,7 +440,7 @@ ble_sm_test_util_verify_tx_pair_confirm(
     struct os_mbuf *om;
 
     om = ble_sm_test_util_verify_tx_hdr(BLE_SM_OP_PAIR_CONFIRM,
-                                              BLE_SM_PAIR_CONFIRM_SZ);
+                                        BLE_SM_PAIR_CONFIRM_SZ);
     ble_sm_pair_confirm_parse(om->om_data, om->om_len, &cmd);
 
     TEST_ASSERT(memcmp(cmd.value, exp_cmd->value, 16) == 0);
@@ -453,7 +454,7 @@ ble_sm_test_util_verify_tx_pair_random(
     struct os_mbuf *om;
 
     om = ble_sm_test_util_verify_tx_hdr(BLE_SM_OP_PAIR_RANDOM,
-                                              BLE_SM_PAIR_RANDOM_SZ);
+                                        BLE_SM_PAIR_RANDOM_SZ);
     ble_sm_pair_random_parse(om->om_data, om->om_len, &cmd);
 
     TEST_ASSERT(memcmp(cmd.value, exp_cmd->value, 16) == 0);
@@ -2240,6 +2241,8 @@ ble_sm_test_util_peer_sc_good(struct ble_sm_test_sc_params *params)
     ble_hs_test_util_set_public_addr(params->rsp_addr);
     ble_sm_dbg_set_next_pair_rand(params->random_rsp.value);
 
+    ble_sm_dbg_set_sc_keys(params->public_key_rsp.x, params->our_priv_key);
+
     ble_hs_test_util_create_conn(2, params->init_addr,
                                  ble_sm_test_util_conn_cb,
                                  NULL);
@@ -2363,80 +2366,76 @@ TEST_CASE(ble_sm_test_case_peer_sc_jw_good)
     struct ble_sm_test_sc_params params;
 
     params = (struct ble_sm_test_sc_params) {
-        .init_addr = {0xec, 0xfb, 0x73, 0x73, 0x21, 0x65},
-        .rsp_addr = {0x1c, 0xfc, 0xd2, 0x07, 0x31, 0x7a},
+        .init_addr = {0xe0, 0x94, 0x67, 0xa0, 0x61, 0xca},
+        .rsp_addr = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07},
         .pair_req = (struct ble_sm_pair_cmd) {
-            .io_cap = 0x00,
+            .io_cap = 0x03,
             .oob_data_flag = 0x00,
-            .authreq = 0x08,
+            .authreq = 0x09,
             .max_enc_key_size = 16,
-            .init_key_dist = 0x00,
-            .resp_key_dist = 0x00,
+            .init_key_dist = 0x0d,
+            .resp_key_dist = 0x0f,
         },
         .pair_rsp = (struct ble_sm_pair_cmd) {
-            .io_cap = 0x00,
+            .io_cap = 0x03,
             .oob_data_flag = 0x00,
-            .authreq = 0x08,
+            .authreq = 0x09,
             .max_enc_key_size = 16,
-            .init_key_dist = 0x00,
-            .resp_key_dist = 0x00,
+            .init_key_dist = 0x01,
+            .resp_key_dist = 0x01,
         },
         .public_key_req = (struct ble_sm_public_key) {
             .x = {
-                0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
-                0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
-                0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
-                0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
+                0x23, 0x5a, 0x60, 0x98, 0x6c, 0xa8, 0xe4, 0x4a,
+                0xb2, 0x60, 0x99, 0xc5, 0xae, 0xda, 0x3b, 0x81,
+                0xf9, 0x08, 0xc6, 0x55, 0xee, 0xf7, 0x79, 0x3c,
+                0xf1, 0x44, 0xe8, 0x2c, 0xc3, 0x39, 0x22, 0xe6
             },
+
             .y = {
-                0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
-                0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
-                0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
-                0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
-            }
+                0xb5, 0xc0, 0x00, 0x4e, 0x25, 0xb7, 0x19, 0xaa,
+                0x97, 0xb3, 0x63, 0x21, 0x62, 0x99, 0x3c, 0xa4,
+                0x04, 0x50, 0xfe, 0x12, 0x77, 0xce, 0x7f, 0x1e,
+                0xc2, 0x3e, 0xdc, 0x76, 0x8f, 0xfb, 0xcf, 0x9d
+            },
         },
         .public_key_rsp = (struct ble_sm_public_key) {
             .x = {
-                0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
-                0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
-                0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
-                0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
+                0xcb, 0xf9, 0x99, 0x2c, 0x42, 0x17, 0xe4, 0x1b,
+                0xc1, 0x3d, 0x76, 0xcb, 0x23, 0x7d, 0x83, 0xad,
+                0xeb, 0x75, 0x29, 0x91, 0x5d, 0x08, 0x17, 0x28,
+                0xf4, 0x8f, 0x91, 0x04, 0x68, 0xff, 0xbd, 0xe8
             },
+
             .y = {
-                0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
-                0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
-                0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
-                0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
-            }
-        },
-        .confirm_req = (struct ble_sm_pair_confirm) {
-            .value = {
-                0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
-                0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2,
+                0x49, 0x86, 0x67, 0xa1, 0xeb, 0x26, 0xe4, 0xee,
+                0x9d, 0x6a, 0x60, 0x33, 0x5e, 0x79, 0x47, 0x37,
+                0xdf, 0xeb, 0xd7, 0xcd, 0x1c, 0x7c, 0x07, 0x86,
+                0x3a, 0x29, 0xf4, 0xb6, 0xc7, 0x40, 0x06, 0x40
             },
         },
         .confirm_rsp = (struct ble_sm_pair_confirm) {
             .value = {
-                0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
-                0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2,
+                0xa3, 0x44, 0x7f, 0x34, 0x18, 0x6d, 0xbd, 0x86,
+                0xc5, 0x2b, 0x26, 0x20, 0x31, 0x8d, 0x57, 0x0a
             },
         },
         .random_req = (struct ble_sm_pair_random) {
             .value = {
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x33, 0x19, 0x47, 0x4c, 0xe8, 0x55, 0xca, 0x09,
+                0x48, 0xc8, 0x4d, 0x13, 0xb3, 0xf0, 0x26, 0x89
             },
         },
         .random_rsp = (struct ble_sm_pair_random) {
             .value = {
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x9d, 0xa0, 0x38, 0x13, 0x27, 0xc7, 0x7a, 0x15,
+                0xe2, 0x28, 0xa1, 0xa2, 0x2e, 0xe2, 0xd1, 0x7d
             },
         },
         .dhkey_check_req = (struct ble_sm_dhkey_check) {
             .value = {
-                0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
-                0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3,
+                0xf2, 0x55, 0xc9, 0x60, 0xec, 0x69, 0xe6, 0xd6,
+                0xb9, 0x3c, 0x46, 0x21, 0xb8, 0x6b, 0x3f, 0x5c
             }
         },
         .dhkey_check_rsp = (struct ble_sm_dhkey_check) {
@@ -2451,12 +2450,124 @@ TEST_CASE(ble_sm_test_case_peer_sc_jw_good)
             0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
             0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29,
         },
+        .our_priv_key = {
+            0x02, 0xcc, 0x3f, 0x8d, 0x5b, 0x5e, 0x89, 0x18,
+            0x51, 0x9b, 0xa3, 0x38, 0xf9, 0x4c, 0xc1, 0xc5,
+            0x64, 0xff, 0x01, 0xa2, 0x74, 0x00, 0x15, 0x77,
+            0xdb, 0xcd, 0x7c, 0x62, 0x29, 0x38, 0xb8, 0x0b
+        }
     };
     ble_sm_test_util_peer_sc_good(&params);
 }
 
+TEST_CASE(ble_sm_test_case_f4)
+{
+	uint8_t u[32] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
+			  0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
+			  0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
+			  0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
+	uint8_t v[32] = { 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
+			  0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
+			  0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
+			  0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
+	uint8_t x[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
+			  0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
+	uint8_t z = 0x00;
+	uint8_t exp[16] = { 0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
+			    0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 };
+	uint8_t res[16];
+	int err;
+
+	err = ble_sm_alg_f4(u, v, x, z, res);
+	TEST_ASSERT_FATAL(err == 0);
+    TEST_ASSERT(memcmp(res, exp, 16) == 0);
+}
+
+TEST_CASE(ble_sm_test_case_f5)
+{
+	uint8_t w[32] = { 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
+			  0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
+			  0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
+			  0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
+	uint8_t n1[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
+			   0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
+	uint8_t n2[16] = { 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
+			   0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
+    uint8_t a1t = 0x00;
+	uint8_t a1[6] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56 };
+    uint8_t a2t = 0x00;
+    uint8_t a2[6] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7 };
+	uint8_t exp_ltk[16] = { 0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05,
+				0x98, 0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79,
+				0x86, 0x69 };
+	uint8_t exp_mackey[16] = { 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f,
+				   0xfd, 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1,
+				   0x65, 0x29 };
+	uint8_t mackey[16], ltk[16];
+	int err;
+
+	err = ble_sm_alg_f5(w, n1, n2, a1t, a1, a2t, a2, mackey, ltk);
+	TEST_ASSERT_FATAL(err == 0);
+    TEST_ASSERT(memcmp(mackey, exp_mackey, 16) == 0);
+    TEST_ASSERT(memcmp(ltk, exp_ltk, 16) == 0);
+}
+
+TEST_CASE(ble_sm_test_case_f6)
+{
+	uint8_t w[16] = { 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
+			  0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
+	uint8_t n1[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
+			   0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
+	uint8_t n2[16] = { 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
+			   0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
+	uint8_t r[16] = { 0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
+			  0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 };
+	uint8_t io_cap[3] = { 0x02, 0x01, 0x01 };
+    uint8_t a1t = 0x00;
+	uint8_t a1[6] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56 };
+    uint8_t a2t = 0x00;
+    uint8_t a2[6] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7 };
+	uint8_t exp[16] = { 0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
+			    0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 };
+	uint8_t res[16];
+	int err;
+
+	err = ble_sm_alg_f6(w, n1, n2, r, io_cap, a1t, a1, a2t, a2, res);
+	TEST_ASSERT_FATAL(err == 0);
+    TEST_ASSERT(memcmp(res, exp, 16) == 0);
+}
+
+TEST_CASE(ble_sm_test_case_g2)
+{
+	uint8_t u[32] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
+			  0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
+			  0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
+			  0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
+	uint8_t v[32] = { 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
+			  0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
+			  0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
+			  0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
+	uint8_t x[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
+			  0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
+	uint8_t y[16] = { 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
+			  0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
+	uint32_t exp_val = 0x2f9ed5ba % 1000000;
+	uint32_t val;
+	int err;
+
+	err = ble_sm_alg_g2(u, v, x, y, &val);
+	TEST_ASSERT_FATAL(err == 0);
+	TEST_ASSERT(val == exp_val);
+}
+
+
 TEST_SUITE(ble_sm_test_suite)
 {
+    ble_sm_test_case_f4();
+    ble_sm_test_case_f5();
+    ble_sm_test_case_f6();
+    ble_sm_test_case_g2();
+
     ble_sm_test_case_peer_fail_inval();
     ble_sm_test_case_peer_lgcy_fail_confirm();
     ble_sm_test_case_peer_lgcy_jw_good();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/892a80a1/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 a5e7cc2..4e42f99 100644
--- a/net/nimble/include/nimble/nimble_opt.h
+++ b/net/nimble/include/nimble/nimble_opt.h
@@ -52,12 +52,18 @@
 #define NIMBLE_OPT_WHITELIST                    1
 #endif
 
-/** HOST / CONTROLLER: Security manager.  Enabled by default. */
+/** HOST: Security manager.  Enabled by default. */
 
 #ifndef NIMBLE_OPT_SM
 #define NIMBLE_OPT_SM                           1
 #endif
 
+/** HOST: Security connections (4.2).  Enabled by default. */
+
+#ifndef NIMBLE_OPT_SM_SC
+#define NIMBLE_OPT_SM_SC                        1
+#endif
+
 /** HOST: Supported GATT procedures.  By default, all are enabled. */
 
 #ifndef NIMBLE_OPT_GATT_DISC_ALL_SVCS