Bluetooth: SMP: Handle security request from slave

If sufficently strong key exists enable encryption. If no key is
present or key doesn't meet auth requirements start pairing.

Change-Id: I50be66f895d02dbbce49290c21bbc445ab734b4b
Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 755a699..5d90843 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -680,6 +680,39 @@
 	return 0;
 }
 
+static uint8_t smp_security_request(struct bt_conn *conn, struct bt_buf *buf)
+{
+	struct bt_smp_security_request *req = (void *)buf->data;
+	struct bt_keys *keys;
+	uint8_t auth;
+
+	BT_DBG("\n");
+
+	keys = bt_keys_find(BT_KEYS_IRK, &conn->dst);
+	if (!keys) {
+		goto pair;
+	}
+
+	auth = req->auth_req & BT_SMP_AUTH_MASK;
+	if (auth & (BT_SMP_AUTH_MITM | BT_SMP_AUTH_SC)) {
+		BT_WARN("Unsupported auth requirements: 0x%x, repairing", auth);
+		goto pair;
+	}
+
+	if (bt_hci_le_start_encryption(conn->handle, keys->ltk.rand,
+				       keys->ltk.ediv, keys->ltk.val) < 0) {
+		return BT_SMP_ERR_UNSPECIFIED;
+	}
+
+	return 0;
+pair:
+	if (smp_send_pairing_req(conn) < 0) {
+		return BT_SMP_ERR_UNSPECIFIED;
+	}
+
+	return 0;
+}
+
 static const struct {
 	uint8_t  (*func)(struct bt_conn *conn, struct bt_buf *buf);
 	uint8_t  expect_len;
@@ -694,6 +727,8 @@
 	{ smp_pairing_master,      sizeof(struct bt_smp_master_ident) },
 	{ smp_ident_info,          sizeof(struct bt_smp_ident_info) },
 	{ smp_ident_addr_info,     sizeof(struct bt_smp_ident_addr_info) },
+	{ }, /* Signing Information - Not yet implemented */
+	{ smp_security_request,    sizeof(struct bt_smp_security_request) },
 };
 
 static void bt_smp_recv(struct bt_conn *conn, struct bt_buf *buf)
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 70a1a1c..c7fd255 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -126,6 +126,11 @@
 	bt_addr_le_t addr;
 } __packed;
 
+#define BT_SMP_CMD_SECURITY_REQUEST		0x0b
+struct bt_smp_security_request {
+	uint8_t  auth_req;
+} __packed;
+
 bool bt_smp_irk_matches(const uint8_t irk[16], const bt_addr_t *addr);
 int smp_send_pairing_req(struct bt_conn *conn);