Skip to content
Permalink
Browse files

Bluetooth: Mesh: Fix segmented message RPL behavior

Update the Replay Protection List handling for segmented messages to
be more in line with Figure 3.43 in Mesh Profile Specification 1.0.
This means that the RPL check and update need to be split into two
independent steps rather than always doing these together.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
  • Loading branch information...
jhedberg committed Jun 18, 2019
1 parent 69406e0 commit 4857cb852c109d7430f12fd497500e97d1a41c97
Showing with 46 additions and 19 deletions.
  1. +46 −19 subsys/bluetooth/host/mesh/transport.c
@@ -531,7 +531,23 @@ int bt_mesh_trans_resend(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
return err;
}

static bool is_replay(struct bt_mesh_net_rx *rx)
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;

@@ -540,17 +556,20 @@ static bool is_replay(struct bt_mesh_net_rx *rx)
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) {
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);
if (match) {
*match = rpl;
} else {
update_rpl(rpl, rx);
}

return false;
@@ -564,11 +583,10 @@ static bool is_replay(struct bt_mesh_net_rx *rx)

if ((!rx->old_iv && rpl->old_iv) ||
rpl->seq < rx->seq) {
rpl->seq = rx->seq;
rpl->old_iv = rx->old_iv;

if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_rpl(rpl);
if (match) {
*match = rpl;
} else {
update_rpl(rpl, rx);
}

return false;
@@ -879,7 +897,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx,
return -EINVAL;
}

if (rx->local_match && is_replay(rx)) {
if (is_replay(rx, NULL)) {
BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x",
rx->ctx.addr, rx->ctx.recv_dst, rx->seq);
return -EINVAL;
@@ -1160,6 +1178,7 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
enum bt_mesh_friend_pdu_type *pdu_type, u64_t *seq_auth)
{
struct bt_mesh_rpl *rpl = NULL;
struct seg_rx *rx;
u8_t *hdr = buf->data;
u16_t seq_zero;
@@ -1172,6 +1191,12 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
return -EINVAL;
}

if (is_replay(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;
}

BT_DBG("ASZMIC %u AKF %u AID 0x%02x", ASZMIC(hdr), AKF(hdr), AID(hdr));

net_buf_simple_pull(buf, 1);
@@ -1228,9 +1253,15 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,

if (rx->block == BLOCK_COMPLETE(rx->seg_n)) {
BT_WARN("Got segment for already complete SDU");

send_ack(net_rx->sub, net_rx->ctx.recv_dst,
net_rx->ctx.addr, net_rx->ctx.send_ttl,
seq_auth, rx->block, rx->obo);

if (rpl) {
update_rpl(rpl, net_rx);
}

return -EALREADY;
}

@@ -1318,12 +1349,8 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,

BT_DBG("Complete SDU");

if (net_rx->local_match && is_replay(net_rx)) {
BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x",
net_rx->ctx.addr, net_rx->ctx.recv_dst, net_rx->seq);
/* Clear the segment's bit */
rx->block &= ~BIT(seg_o);
return -EINVAL;
if (rpl) {
update_rpl(rpl, net_rx);
}

*pdu_type = BT_MESH_FRIEND_PDU_COMPLETE;

0 comments on commit 4857cb8

Please sign in to comment.
You can’t perform that action at this time.