mesh: Move Replay Protect to seperate module

Move RPL to seperate module, and remove it in bt_mesh
structure.

this is port of 2a6b1bab93fbfa31f7469b351ca0d84934cb0966
This commit is contained in:
Krzysztof Kopyściński
2020-11-04 14:32:06 +01:00
committed by Łukasz Rymanowski
parent 2bcd23d6d9
commit 97279150a1
17 changed files with 260 additions and 182 deletions
+1
View File
@@ -10,6 +10,7 @@
#include "mesh/mesh.h"
#include "net.h"
#include "rpl.h"
#include "settings.h"
#include "mesh_priv.h"
#include "mesh/glue.h"
+1
View File
@@ -18,6 +18,7 @@
#include "mesh_priv.h"
#include "adv.h"
#include "net.h"
#include "rpl.h"
#include "lpn.h"
#include "transport.h"
#include "crypto.h"
+1
View File
@@ -19,6 +19,7 @@
#include "adv.h"
#include "prov.h"
#include "net.h"
#include "rpl.h"
#include "beacon.h"
#include "lpn.h"
#include "friend.h"
+2 -21
View File
@@ -20,6 +20,7 @@
#include "adv.h"
#include "mesh_priv.h"
#include "net.h"
#include "rpl.h"
#include "lpn.h"
#include "friend.h"
#include "proxy.h"
@@ -554,26 +555,6 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key)
return false;
}
void bt_mesh_rpl_reset(void)
{
int i;
/* Discard "old old" IV Index entries from RPL and flag
* any other ones (which are valid) as old.
*/
for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i];
if (rpl->src) {
if (rpl->old_iv) {
memset(rpl, 0, sizeof(*rpl));
} else {
rpl->old_iv = true;
}
}
}
}
#if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST)
void bt_mesh_iv_update_test(bool enable)
{
@@ -651,7 +632,7 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
if (iv_index > bt_mesh.iv_index + 1) {
BT_WARN("Performing IV Index Recovery");
memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
bt_mesh_rpl_clear();
bt_mesh.iv_index = iv_index;
bt_mesh.seq = 0;
goto do_update;
-13
View File
@@ -82,15 +82,6 @@ struct bt_mesh_subnet {
} keys[2];
};
struct bt_mesh_rpl {
u16_t src;
bool old_iv;
#if (MYNEWT_VAL(BLE_MESH_SETTINGS))
bool store;
#endif
u32_t seq;
};
#if MYNEWT_VAL(BLE_MESH_FRIEND)
#define FRIEND_SEG_RX MYNEWT_VAL(BLE_MESH_FRIEND_SEG_RX)
#define FRIEND_SUB_LIST_SIZE MYNEWT_VAL(BLE_MESH_FRIEND_SUB_LIST_SIZE)
@@ -265,8 +256,6 @@ struct bt_mesh_net {
struct bt_mesh_app_key app_keys[MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)];
struct bt_mesh_subnet sub[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)];
struct bt_mesh_rpl rpl[MYNEWT_VAL(BLE_MESH_CRPL)];
};
/* Network interface */
@@ -331,8 +320,6 @@ void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub);
int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub);
void bt_mesh_rpl_reset(void);
bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update);
void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub);
+1
View File
@@ -18,6 +18,7 @@
#include "atomic.h"
#include "adv.h"
#include "net.h"
#include "rpl.h"
#include "beacon.h"
#include "access.h"
#include "foundation.h"
+1
View File
@@ -19,6 +19,7 @@
#include "mesh_priv.h"
#include "adv.h"
#include "net.h"
#include "rpl.h"
#include "prov.h"
#include "beacon.h"
#include "foundation.h"
+162
View File
@@ -0,0 +1,162 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Copyright (c) 2020 Lingao Meng
*
* SPDX-License-Identifier: Apache-2.0
*/
#define MESH_LOG_MODULE BLE_MESH_RPL_LOG
#include "log/log.h"
#include "mesh_priv.h"
#include "adv.h"
#include "net.h"
#include "rpl.h"
#include "settings.h"
static struct bt_mesh_rpl replay_list[MYNEWT_VAL(BLE_MESH_CRPL)];
void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl,
struct bt_mesh_net_rx *rx)
{
rpl->src = rx->ctx.addr;
rpl->seq = rx->seq;
rpl->old_iv = rx->old_iv;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_rpl(rpl);
}
}
/* Check the Replay Protection List for a replay attempt. If non-NULL match
* parameter is given the RPL slot is returned but it is not immediately
* updated (needed for segmented messages), whereas if a NULL match is given
* the RPL is immediately updated (used for unsegmented messages).
*/
bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx,
struct bt_mesh_rpl **match)
{
int i;
/* Don't bother checking messages from ourselves */
if (rx->net_if == BT_MESH_NET_IF_LOCAL) {
return false;
}
/* The RPL is used only for the local node */
if (!rx->local_match) {
return false;
}
for (i = 0; i < ARRAY_SIZE(replay_list); i++) {
struct bt_mesh_rpl *rpl = &replay_list[i];
/* Empty slot */
if (!rpl->src) {
if (match) {
*match = rpl;
} else {
bt_mesh_rpl_update(rpl, rx);
}
return false;
}
/* Existing slot for given address */
if (rpl->src == rx->ctx.addr) {
if (rx->old_iv && !rpl->old_iv) {
return true;
}
if ((!rx->old_iv && rpl->old_iv) ||
rpl->seq < rx->seq) {
if (match) {
*match = rpl;
} else {
bt_mesh_rpl_update(rpl, rx);
}
return false;
} else {
return true;
}
}
}
BT_ERR("RPL is full!");
return true;
}
void bt_mesh_rpl_clear(void)
{
BT_DBG("");
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_clear_rpl();
} else {
(void)memset(replay_list, 0, sizeof(replay_list));
}
}
struct bt_mesh_rpl *bt_mesh_rpl_find(uint16_t src)
{
int i;
for (i = 0; i < ARRAY_SIZE(replay_list); i++) {
if (replay_list[i].src == src) {
return &replay_list[i];
}
}
return NULL;
}
struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src)
{
int i;
for (i = 0; i < ARRAY_SIZE(replay_list); i++) {
if (!replay_list[i].src) {
replay_list[i].src = src;
return &replay_list[i];
}
}
return NULL;
}
void bt_mesh_rpl_foreach(bt_mesh_rpl_func_t func, void *user_data)
{
int i;
for (i = 0; i < ARRAY_SIZE(replay_list); i++) {
func(&replay_list[i], user_data);
}
}
void bt_mesh_rpl_reset(void)
{
int i;
/* Discard "old old" IV Index entries from RPL and flag
* any other ones (which are valid) as old.
*/
for (i = 0; i < ARRAY_SIZE(replay_list); i++) {
struct bt_mesh_rpl *rpl = &replay_list[i];
if (rpl->src) {
if (rpl->old_iv) {
(void)memset(rpl, 0, sizeof(*rpl));
} else {
rpl->old_iv = true;
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_rpl(rpl);
}
}
}
}
+30
View File
@@ -0,0 +1,30 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Copyright (c) 2020 Lingao Meng
*
* SPDX-License-Identifier: Apache-2.0
*/
struct bt_mesh_rpl {
uint16_t src;
bool old_iv;
#if defined(CONFIG_BT_SETTINGS)
bool store;
#endif
uint32_t seq;
};
typedef void (*bt_mesh_rpl_func_t)(struct bt_mesh_rpl *rpl,
void *user_data);
void bt_mesh_rpl_reset(void);
bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx,
struct bt_mesh_rpl **match);
void bt_mesh_rpl_clear(void);
struct bt_mesh_rpl *bt_mesh_rpl_find(uint16_t src);
struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src);
void bt_mesh_rpl_foreach(bt_mesh_rpl_func_t func, void *user_data);
void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl,
struct bt_mesh_net_rx *rx);
+24 -62
View File
@@ -13,6 +13,7 @@
#include "mesh/mesh.h"
#include "mesh/glue.h"
#include "net.h"
#include "rpl.h"
#include "crypto.h"
#include "transport.h"
#include "access.h"
@@ -297,33 +298,6 @@ static int seq_set(int argc, char **argv, char *val)
return 0;
}
static struct bt_mesh_rpl *rpl_find(u16_t src)
{
int i;
for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
if (bt_mesh.rpl[i].src == src) {
return &bt_mesh.rpl[i];
}
}
return NULL;
}
static struct bt_mesh_rpl *rpl_alloc(u16_t src)
{
int i;
for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
if (!bt_mesh.rpl[i].src) {
bt_mesh.rpl[i].src = src;
return &bt_mesh.rpl[i];
}
}
return NULL;
}
static int rpl_set(int argc, char **argv, char *val)
{
struct bt_mesh_rpl *entry;
@@ -339,7 +313,7 @@ static int rpl_set(int argc, char **argv, char *val)
BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)");
src = strtol(argv[0], NULL, 16);
entry = rpl_find(src);
entry = bt_mesh_rpl_find(src);
if (!val) {
if (entry) {
@@ -352,7 +326,7 @@ static int rpl_set(int argc, char **argv, char *val)
}
if (!entry) {
entry = rpl_alloc(src);
entry = bt_mesh_rpl_alloc(src);
if (!entry) {
BT_ERR("Unable to allocate RPL entry for 0x%04x", src);
return -ENOMEM;
@@ -1399,45 +1373,33 @@ static void store_rpl(struct bt_mesh_rpl *entry)
}
}
static void clear_rpl(void)
static void clear_rpl(struct bt_mesh_rpl *rpl, void *user_data)
{
int i, err;
int err;
char path[18];
BT_DBG("");
for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i];
char path[18];
if (!rpl->src) {
continue;
}
snprintk(path, sizeof(path), "bt_mesh/RPL/%x", rpl->src);
err = settings_save_one(path, NULL);
if (err) {
BT_ERR("Failed to clear RPL");
} else {
BT_DBG("Cleared RPL");
}
memset(rpl, 0, sizeof(*rpl));
if (!rpl->src) {
return;
}
snprintk(path, sizeof(path), "bt/mesh/RPL/%x", rpl->src);
err = settings_save_one(path, NULL);
if (err) {
BT_ERR("Failed to clear RPL");
} else {
BT_DBG("Cleared RPL");
}
(void)memset(rpl, 0, sizeof(*rpl));
}
static void store_pending_rpl(void)
static void store_pending_rpl(struct bt_mesh_rpl *rpl, void *user_data)
{
int i;
BT_DBG("");
for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i];
if (rpl->store) {
rpl->store = false;
store_rpl(rpl);
}
if (rpl->store) {
rpl->store = false;
store_rpl(rpl);
}
}
@@ -2143,9 +2105,9 @@ static void store_pending(struct ble_npl_event *work)
if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_RPL_PENDING)) {
if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
store_pending_rpl();
bt_mesh_rpl_foreach(store_pending_rpl, NULL);
} else {
clear_rpl();
bt_mesh_rpl_foreach(clear_rpl, NULL);
}
}
+1
View File
@@ -25,6 +25,7 @@
/* Private includes for raw Network & Transport layer access */
#include "net.h"
#include "rpl.h"
#include "access.h"
#include "mesh_priv.h"
#include "lpn.h"
+1
View File
@@ -13,6 +13,7 @@
#include "mesh/access.h"
#include "net.h"
#include "rpl.h"
#include "testing.h"
#include "access.h"
#include "foundation.h"
+6 -84
View File
@@ -19,6 +19,7 @@
#include "crypto.h"
#include "adv.h"
#include "net.h"
#include "rpl.h"
#include "lpn.h"
#include "friend.h"
#include "access.h"
@@ -676,75 +677,6 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg,
return err;
}
static void update_rpl(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx)
{
rpl->src = rx->ctx.addr;
rpl->seq = rx->seq;
rpl->old_iv = rx->old_iv;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_rpl(rpl);
}
}
/* Check the Replay Protection List for a replay attempt. If non-NULL match
* parameter is given the RPL slot is returned but it is not immediately
* updated (needed for segmented messages), whereas if a NULL match is given
* the RPL is immediately updated (used for unsegmented messages).
*/
static bool is_replay(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match)
{
int i;
/* Don't bother checking messages from ourselves */
if (rx->net_if == BT_MESH_NET_IF_LOCAL) {
return false;
}
/* The RPL is used only for the local node */
if (!rx->local_match) {
return false;
}
for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i];
/* Empty slot */
if (!rpl->src) {
if (match) {
*match = rpl;
} else {
update_rpl(rpl, rx);
}
return false;
}
/* Existing slot for given address */
if (rpl->src == rx->ctx.addr) {
if (rx->old_iv && !rpl->old_iv) {
return true;
}
if ((!rx->old_iv && rpl->old_iv) ||
rpl->seq < rx->seq) {
if (match) {
*match = rpl;
} else {
update_rpl(rpl, rx);
}
return false;
} else {
return true;
}
}
}
BT_ERR("RPL is full!");
return true;
}
static void seg_rx_assemble(struct seg_rx *rx, struct os_mbuf *buf,
u8_t aszmic)
{
@@ -1228,7 +1160,7 @@ static int trans_unseg(struct os_mbuf *buf, struct bt_mesh_net_rx *rx,
return -EINVAL;
}
if (is_replay(rx, NULL)) {
if (bt_mesh_rpl_check(rx, NULL)) {
BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x",
rx->ctx.addr, rx->ctx.recv_dst, (unsigned) rx->seq);
return -EINVAL;
@@ -1520,7 +1452,7 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx,
return -EINVAL;
}
if (is_replay(net_rx, &rpl)) {
if (bt_mesh_rpl_check(net_rx, &rpl)) {
BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x",
net_rx->ctx.addr, net_rx->ctx.recv_dst, net_rx->seq);
return -EINVAL;
@@ -1591,7 +1523,7 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx,
seq_auth, rx->block, rx->obo);
if (rpl) {
update_rpl(rpl, net_rx);
bt_mesh_rpl_update(rpl, net_rx);
}
return -EALREADY;
@@ -1704,7 +1636,7 @@ found_rx:
BT_DBG("Complete SDU");
if (rpl) {
update_rpl(rpl, net_rx);
bt_mesh_rpl_update(rpl, net_rx);
}
*pdu_type = BT_MESH_FRIEND_PDU_COMPLETE;
@@ -1827,11 +1759,7 @@ void bt_mesh_rx_reset(void)
seg_rx_reset(&seg_rx[i], true);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_clear_rpl();
} else {
memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
}
bt_mesh_rpl_clear();
}
void bt_mesh_tx_reset(void)
@@ -1863,12 +1791,6 @@ void bt_mesh_trans_init(void)
}
}
void bt_mesh_rpl_clear(void)
{
BT_DBG("");
memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
}
int bt_mesh_heartbeat_send(const struct bt_mesh_send_cb *cb, void *cb_data)
{
struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get();
-2
View File
@@ -101,8 +101,6 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx);
void bt_mesh_trans_init(void);
void bt_mesh_rpl_clear(void);
int bt_mesh_heartbeat_send(const struct bt_mesh_send_cb *cb, void *cb_data);
int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx,
+13
View File
@@ -658,6 +658,15 @@ syscfg.defs:
Minimum level for the BLE Mesh Transport Layer log.
value: 1
BLE_MESH_RPL_LOG_MOD:
description: >
Numeric module ID to use for BLE Mesh Replay protection list messages.
value: 22
BLE_MESH_RPL_LOG_LVL:
description: >
Minimum level for the BLE Mesh Replay protection list log.
value: 1
syscfg.logs:
BLE_MESH_LOG:
module: MYNEWT_VAL(BLE_MESH_LOG_MOD)
@@ -707,6 +716,10 @@ syscfg.logs:
module: MYNEWT_VAL(BLE_MESH_SETTINGS_LOG_MOD)
level: MYNEWT_VAL(BLE_MESH_SETTINGS_LOG_LVL)
BLE_MESH_RPL_LOG:
module: MYNEWT_VAL(BLE_MESH_RPL_LOG_MOD)
level: MYNEWT_VAL(BLE_MESH_RPL_LOG_LVL)
BLE_MESH_TRANS_LOG:
module: MYNEWT_VAL(BLE_MESH_TRANS_LOG_MOD)
level: MYNEWT_VAL(BLE_MESH_TRANS_LOG_LVL)
@@ -106,6 +106,13 @@
#define BLE_MESH_TRANS_LOG_CRITICAL(...) MODLOG_CRITICAL(21, __VA_ARGS__)
#define BLE_MESH_TRANS_LOG_DISABLED(...) MODLOG_DISABLED(21, __VA_ARGS__)
#define BLE_MESH_RPL_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
#define BLE_MESH_RPL_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__)
#define BLE_MESH_RPL_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__)
#define BLE_MESH_RPL_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__)
#define BLE_MESH_RPL_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__)
#define BLE_MESH_RPL_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__)
#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__)
#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__)
@@ -1146,6 +1146,15 @@
#define MYNEWT_VAL_BLE_MESH_TRANS_LOG_MOD (21)
#endif
/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */
#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL
#define MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL (1)
#endif
#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD
#define MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD (22)
#endif
/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */
#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MAX
#define MYNEWT_VAL_BLE_MESH_TX_SEG_MAX (6)