Skip to content

Commit

Permalink
samples: mesh: distributor: Add note about securing LE connection
Browse files Browse the repository at this point in the history
Add note about securing LE connection in the distributor sample when
accessing SMP characteristics.

Signed-off-by: Pavel Vasilyev <[email protected]>
  • Loading branch information
PavelVPV authored and rlubos committed Dec 8, 2023
1 parent 087d46b commit d703cdb
Show file tree
Hide file tree
Showing 16 changed files with 485 additions and 39 deletions.
1 change: 1 addition & 0 deletions doc/nrf/libraries/bluetooth_services/mesh/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ For more information about these and other models, see also `Bluetooth Mesh mode
scheduler.rst
vnd/silvair_enocean_srv.rst
vnd/dm.rst
vnd/le_pair_resp.rst
59 changes: 59 additions & 0 deletions doc/nrf/libraries/bluetooth_services/mesh/vnd/le_pair_resp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.. _bt_mesh_le_pair_resp_readme:

LE Pairing Responder
####################

.. contents::
:local:
:depth: 2

The LE Pairing Responder model can be used to hand over a passkey that will authenticate a Bluetooth LE connection over a mesh network when it is not possible to use other pairing methods.

Before the pairing is initiated, an initiator should send an LE Pairing message with Passkey Reset sub-opcode to set a new passkey for the next pairing request.
The passkey returned in the LE Pairing message with the Passkey Status sub-opcode should be used for the next pairing.

This model requires an application to only enable the display capability for the LE pairing by setting the :c:member:`bt_conn_auth_cb.pairing_display` callback.
After every pairing request, the application must invalidate the previously used passkey by calling the :c:func:`bt_mesh_le_pair_resp_passkey_invalidate` function.
This function can be called from callbacks :c:member:`bt_conn_auth_info_cb.pairing_complete` and :c:member:`bt_conn_auth_info_cb.pairing_failed`.
See the :file:`samples/bluetooth/mesh/common/smp_bt_auth.c` file for the reference.

Messages
========

The LE Pairing Request model defines a single message with opcode ``0x11``, which defines at least 1-byte long sub-opcode field.
The supported sub-opcodes are:

Passkey Reset
Sent to instruct a node to generate a new passkey for the next pairing request.
The sub-opcode field value is ``0x00``.

Passkey Status
Sent as a response to the Passkey Reset message.
The sub-opcode field value is ``0x01``.
The message contains the 1-byte long request status, and optionally a 3-byte long, 6-digit passkey.
If the passkey was generated successfully (the status field is ``0x00``), the message contains a 3-byte long, 6-digit passkey.

States
======

None

Extended models
===============

None

Persistent storage
==================

None

API documentation
=================

| Header file: :file:`include/bluetooth/mesh/vnd/le_pair_resp.h`
| Source file: :file:`subsys/bluetooth/mesh/vnd/le_pair_resp.c`
.. doxygengroup:: bt_mesh_le_pair_resp
:project: nrf
:members:
76 changes: 41 additions & 35 deletions doc/nrf/protocols/bt/bt_mesh/reserved_ids.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,44 +40,50 @@ The table below lists all vendor-assigned model identifiers allocated by Nordic
+-----------------------------+-----------------+
| Distance Measurement Client | 0x000C |
+-----------------------------+-----------------+
| LE Pairing Initiator | 0x000D |
+-----------------------------+-----------------+
| LE Pairing Responder | 0x000E |
+-----------------------------+-----------------+

Reserved opcodes
****************

The table below lists the manufacturer-specific opcodes allocated by Nordic Semiconductor:

+------------------------------------+--------+
| Message name | Opcode |
+====================================+========+
| Simple OnOff Set | 0x01 |
+------------------------------------+--------+
| Simple OnOff Get | 0x02 |
+------------------------------------+--------+
| Simple OnOff Set Unreliable | 0x03 |
+------------------------------------+--------+
| Simple OnOff Status | 0x04 |
+------------------------------------+--------+
| Rssi Ack | 0x05 |
+------------------------------------+--------+
| Rssi Send Data | 0x06 |
+------------------------------------+--------+
| Rssi Util Request Database Beacon | 0x07 |
+------------------------------------+--------+
| Rssi Util Send Database Beacon | 0x08 |
+------------------------------------+--------+
| Thingy52 RGB Set | 0x09 |
+------------------------------------+--------+
| Chat Message | 0x0A |
+------------------------------------+--------+
| Chat Private Message | 0x0B |
+------------------------------------+--------+
| Chat Message Reply | 0x0C |
+------------------------------------+--------+
| Chat Presence | 0x0D |
+------------------------------------+--------+
| Chat Presence Get | 0x0E |
+------------------------------------+--------+
| Distance Measurement Server | 0x0F |
+------------------------------------+--------+
| Distance Measurement Client | 0x10 |
+------------------------------------+--------+
+-----------------------------------+--------+
| Message name | Opcode |
+===================================+========+
| Simple OnOff Set | 0x01 |
+-----------------------------------+--------+
| Simple OnOff Get | 0x02 |
+-----------------------------------+--------+
| Simple OnOff Set Unreliable | 0x03 |
+-----------------------------------+--------+
| Simple OnOff Status | 0x04 |
+-----------------------------------+--------+
| Rssi Ack | 0x05 |
+-----------------------------------+--------+
| Rssi Send Data | 0x06 |
+-----------------------------------+--------+
| Rssi Util Request Database Beacon | 0x07 |
+-----------------------------------+--------+
| Rssi Util Send Database Beacon | 0x08 |
+-----------------------------------+--------+
| Thingy52 RGB Set | 0x09 |
+-----------------------------------+--------+
| Chat Message | 0x0A |
+-----------------------------------+--------+
| Chat Private Message | 0x0B |
+-----------------------------------+--------+
| Chat Message Reply | 0x0C |
+-----------------------------------+--------+
| Chat Presence | 0x0D |
+-----------------------------------+--------+
| Chat Presence Get | 0x0E |
+-----------------------------------+--------+
| Distance Measurement Server | 0x0F |
+-----------------------------------+--------+
| Distance Measurement Client | 0x10 |
+-----------------------------------+--------+
| LE Pairing Related Messages | 0x11 |
+-----------------------------------+--------+
13 changes: 13 additions & 0 deletions doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ Bluetooth Mesh
* :ref:`bt_mesh_sensors_readme` now use an updated API with sensor values represented by :c:struct:`bt_mesh_sensor_value` instead of :c:struct:`sensor_value`.
This makes it possible to accurately represent all encodable sensor values.
The old APIs based on the :c:struct:`sensor_value` type are deprecated, but are still available for backward compatibility, and can be enabled for use by setting the :kconfig:option:`CONFIG_BT_MESH_SENSOR_USE_LEGACY_SENSOR_VALUE` Kconfig option.
* :ref:`bt_mesh_ug_reserved_ids` with model ID and opcodes for the new :ref:`bt_mesh_le_pair_resp_readme` model.

Matter
------
Expand Down Expand Up @@ -244,6 +245,12 @@ Bluetooth samples
Bluetooth Mesh samples
----------------------

* :ref:`ble_mesh_dfu_distributor` sample:

* Added:

* Support for pairing with display capability and the :ref:`bt_mesh_le_pair_resp_readme`.

|no_changes_yet_note|

Cellular samples
Expand Down Expand Up @@ -438,6 +445,12 @@ Bluetooth libraries and services

* Improved the :ref:`bt_fast_pair_readme` library documentation to include the description of the missing Kconfig options.

* :ref:`bt_mesh` library:

* Added:

* The :ref:`bt_mesh_le_pair_resp_readme` model to allow passing a passkey used in LE pairing over a mesh network.

Bootloader libraries
--------------------

Expand Down
64 changes: 64 additions & 0 deletions include/bluetooth/mesh/vnd/le_pair_resp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/**
* @file
* @defgroup bt_mesh_le_pair_resp LE Pairing Responder model
* @{
* @brief API for the LE Pairing Responder model.
*/

#ifndef BT_MESH_LE_PAIR_RESP_H__
#define BT_MESH_LE_PAIR_RESP_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <zephyr/bluetooth/mesh/access.h>

#define BT_MESH_VENDOR_COMPANY_ID_LE_PAIR_RESP 0x0059
#define BT_MESH_MODEL_ID_LE_PAIR_RESP 0x000E

/** @def BT_MESH_MODEL_LE_PAIR_RESP
*
* @brief LE Pairing Responder model entry.
*/
#define BT_MESH_MODEL_LE_PAIR_RESP \
BT_MESH_MODEL_VND_CB(BT_MESH_VENDOR_COMPANY_ID_LE_PAIR_RESP, BT_MESH_MODEL_ID_LE_PAIR_RESP,\
_bt_mesh_le_pair_resp_op, NULL, NULL, \
&_bt_mesh_le_pair_resp_cb)

/* @brief Invalidate previously used passkey.
*
* A user must call this function when a pairing request completes regardless of the status.
*/
void bt_mesh_le_pair_resp_passkey_invalidate(void);

/* @brief Set own passkey instead of using randomly generating passkeys.
*
* By default, passkeys will be randomly generated on every new request. This function allows to use
* pre-defined passkey instead.
*
* @params passkey Passkey to use for the pairing, or @ref BT_PASSKEY_INVALID to use randomly
* generated passkey again.
*/
void bt_mesh_le_pair_resp_passkey_set(uint32_t passkey);

/** @cond INTERNAL_HIDDEN */

extern const struct bt_mesh_model_op _bt_mesh_le_pair_resp_op[];
extern const struct bt_mesh_model_cb _bt_mesh_le_pair_resp_cb;

/** @endcond */

#ifdef __cplusplus
}
#endif

#endif /* BT_MESH_LE_PAIR_RESP_H__ */

/** @} */
15 changes: 15 additions & 0 deletions samples/bluetooth/mesh/common/smp_bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>

#include "smp_bt_auth.h"

static void pending_adv_start(struct k_work *work);

static struct bt_le_ext_adv *adv;
Expand Down Expand Up @@ -142,6 +144,19 @@ int smp_service_adv_init(void)

int smp_dfu_init(void)
{
if (IS_ENABLED(CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN) &&
IS_ENABLED(CONFIG_BT_MESH_LE_PAIR_RESP)) {
int err;

err = smp_bt_auth_init();
if (err) {
printk("Can't enable authentication for SMP (err: %d)\n", err);
return err;
}
} else {
printk("Authentication for SMP over BLE is disabled\n");
}

/* .. include_startingpoint_mesh_smp_dfu_rst_2 */
bt_conn_cb_register(&conn_callbacks);

Expand Down
104 changes: 104 additions & 0 deletions samples/bluetooth/mesh/common/smp_bt_auth.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/init.h>

/* .. include_startingpoint_mesh_smp_dfu_rst_1 */
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <bluetooth/mesh/vnd/le_pair_resp.h>

static void passkey_display(struct bt_conn *conn, unsigned int passkey)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("Please enter passkey (%d) on %s\n", passkey, addr);
}

static void cancel(struct bt_conn *conn)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("Pairing cancelled: %s\n", addr);
}

static void pairing_confirm(struct bt_conn *conn)
{
int err;

/* Automatically confirm pairing request from the device side. */
err = bt_conn_auth_pairing_confirm(conn);
if (err) {
printf("Can't confirm pairing (err: %d)\n", err);
return;
}

char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("Pairing confirmed: %s\n", addr);
}

static struct bt_conn_auth_cb auth_cb = {
/* Enable passkey_display callback to enable the display capability. */
.passkey_display = passkey_display,
/* These 2 callbacks are required for passkey_display callback. */
.cancel = cancel,
.pairing_confirm = pairing_confirm,
};

static void pairing_complete(struct bt_conn *conn, bool bonded)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("Pairing completed: %s, bonded: %d\n", addr, bonded);

/* Invalidate the previously used passkey. */
bt_mesh_le_pair_resp_passkey_invalidate();
}

static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("Pairing failed: %s, reason %d\n", addr, reason);

/* Invalidate the previously used passkey. */
bt_mesh_le_pair_resp_passkey_invalidate();
}

static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
.pairing_complete = pairing_complete,
.pairing_failed = pairing_failed
};

int smp_bt_auth_init(void)
{
int err;

err = bt_conn_auth_cb_register(&auth_cb);
if (err) {
printk("Can't register authentication callbacks (err: %d)\n", err);
return err;
}

err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
if (err) {
printk("Can't register authentication information callbacks (err: %d)\n", err);
return err;
}

return 0;
}
Loading

0 comments on commit d703cdb

Please sign in to comment.