2022-10-04 08:43:09

by Isak Westin

[permalink] [raw]
Subject: [PATCH BlueZ 0/4] Mesh: Fixes for friendship procedures

Hello,

Here are a few patches targeting the mesh friendship behaviour. Found
during PTS testing of:
- MESH/NODE/FRND/FN/*

Happy for any feedback.

Best regards,
Isak

Isak Westin (4):
mesh: Correct size of friend cache
mesh: Verify padding bits in Friend Poll messages
mesh: Queue a friend update on IV Update change
mesh: Always relay messages from Low Power nodes

mesh/friend.c | 2 +-
mesh/net.c | 50 ++++++++++++++++++++++++++++++++++++++------------
2 files changed, 39 insertions(+), 13 deletions(-)

--
2.20.1






2022-10-04 08:43:09

by Isak Westin

[permalink] [raw]
Subject: [PATCH BlueZ 4/4] mesh: Always relay messages from Low Power nodes

If we receive a message from one of our Low Power nodes, which is
encrypted using frendship credentials and where the destination is not
us, we must relay that message using master credentials.
See MshPRFv1.0.1 section 3.6.6.2.
---
mesh/net.c | 47 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/mesh/net.c b/mesh/net.c
index 577121f30..a1b586a0b 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -1763,7 +1763,8 @@ not_for_friend:
return true;
}

-static uint16_t key_id_to_net_idx(struct mesh_net *net, uint32_t net_key_id)
+static uint16_t key_id_to_net_idx(struct mesh_net *net,
+ uint32_t net_key_id, bool *frnd)
{
struct mesh_subnet *subnet;
struct mesh_friend *friend;
@@ -1771,6 +1772,9 @@ static uint16_t key_id_to_net_idx(struct mesh_net *net, uint32_t net_key_id)
if (!net)
return NET_IDX_INVALID;

+ if (frnd)
+ *frnd = false;
+
subnet = l_queue_find(net->subnets, match_key_id,
L_UINT_TO_PTR(net_key_id));

@@ -1780,8 +1784,12 @@ static uint16_t key_id_to_net_idx(struct mesh_net *net, uint32_t net_key_id)
friend = l_queue_find(net->friends, match_friend_key_id,
L_UINT_TO_PTR(net_key_id));

- if (friend)
+ if (friend) {
+ if (frnd)
+ *frnd = true;
+
return friend->net_idx;
+ }

friend = l_queue_find(net->negotiations, match_friend_key_id,
L_UINT_TO_PTR(net_key_id));
@@ -2078,7 +2086,7 @@ static bool ctl_received(struct mesh_net *net, uint32_t net_key_id,
return false;

print_packet("Rx-NET_OP_FRND_REQUEST", pkt, len);
- net_idx = key_id_to_net_idx(net, net_key_id);
+ net_idx = key_id_to_net_idx(net, net_key_id, NULL);
friend_request(net, net_idx, src, pkt[0], pkt[1],
l_get_be32(pkt + 1) & 0xffffff,
l_get_be16(pkt + 5), pkt[7],
@@ -2269,7 +2277,8 @@ static void send_msg_pkt(struct mesh_net *net, uint8_t cnt, uint16_t interval,
}

static enum _relay_advice packet_received(void *user_data,
- uint32_t net_key_id, uint32_t iv_index,
+ uint32_t net_key_id, uint16_t net_idx,
+ bool frnd, uint32_t iv_index,
const void *data, uint8_t size, int8_t rssi)
{
struct mesh_net *net = user_data;
@@ -2278,16 +2287,11 @@ static enum _relay_advice packet_received(void *user_data,
uint8_t net_ttl, key_aid, net_segO, net_segN, net_opcode;
uint32_t net_seq, cache_cookie;
uint16_t net_src, net_dst, net_seqZero;
- uint16_t net_idx;
uint8_t packet[31];
bool net_ctl, net_segmented, net_szmic, net_relay;

memcpy(packet + 2, data, size);

- net_idx = key_id_to_net_idx(net, net_key_id);
- if (net_idx == NET_IDX_INVALID)
- return RELAY_NONE;
-
print_packet("RX: Network [clr] :", packet + 2, size);

if (!mesh_crypto_packet_parse(packet + 2, size, &net_ctl, &net_ttl,
@@ -2389,6 +2393,13 @@ static enum _relay_advice packet_received(void *user_data,
return RELAY_DISALLOWED;
}

+ /*
+ * Messages that are encrypted with friendship credentials
+ * should *always* be relayed
+ */
+ if (frnd)
+ return RELAY_ALWAYS;
+
/* If relay not enable, or no more hops allowed */
if (!net->relay.enable || net_ttl < 0x02)
return RELAY_NONE;
@@ -2414,7 +2425,9 @@ static void net_rx(void *net_ptr, void *user_data)
uint8_t *out;
size_t out_size;
uint32_t net_key_id;
+ uint16_t net_idx;
int8_t rssi = 0;
+ bool frnd;
bool ivi_net = !!(net->iv_index & 1);
bool ivi_pkt = !!(data->data[0] & 0x80);

@@ -2438,9 +2451,21 @@ static void net_rx(void *net_ptr, void *user_data)
rssi = data->info->rssi;
}

- relay_advice = packet_received(net, net_key_id, iv_index, out, out_size,
- rssi);
+ net_idx = key_id_to_net_idx(net, net_key_id, &frnd);
+
+ if (net_idx == NET_IDX_INVALID)
+ return;
+
+ relay_advice = packet_received(net, net_key_id, net_idx, frnd,
+ iv_index, out, out_size, rssi);
if (relay_advice > data->relay_advice) {
+ /*
+ * If packet was encrypted with friendship credentials,
+ * relay it using master credentials
+ */
+ if (frnd && !mesh_net_get_key(net, false, net_idx, &net_key_id))
+ return;
+
data->iv_index = iv_index;
data->relay_advice = relay_advice;
data->net_key_id = net_key_id;
--
2.20.1





2022-10-04 08:43:09

by Isak Westin

[permalink] [raw]
Subject: [PATCH BlueZ 2/4] mesh: Verify padding bits in Friend Poll messages

The padding bits in a Friend Poll message must be zero.
See MshPRFv1.0.1 section 3.6.5.1.
---
mesh/net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mesh/net.c b/mesh/net.c
index 379a6e250..a8a527c2f 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -2059,7 +2059,7 @@ static bool ctl_received(struct mesh_net *net, uint32_t net_key_id,
break;

case NET_OP_FRND_POLL:
- if (len != 1 || ttl)
+ if (len != 1 || ttl || pkt[0] > 1)
return false;

print_packet("Rx-NET_OP_FRND_POLL", pkt, len);
--
2.20.1





2022-10-04 08:43:12

by Isak Westin

[permalink] [raw]
Subject: [PATCH BlueZ 3/4] mesh: Queue a friend update on IV Update change

A friend update should be queued when we receive a Secure Network beacon
that changes the IV Update state.
---
mesh/net.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/mesh/net.c b/mesh/net.c
index a8a527c2f..577121f30 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -2703,6 +2703,7 @@ static bool update_iv_ivu_state(struct mesh_net *net, uint32_t iv_index,

net->iv_index = iv_index;
net->iv_update = ivu;
+ queue_friend_update(net);
return true;
}

--
2.20.1





2022-10-06 21:19:53

by patchwork-bot+bluetooth

[permalink] [raw]
Subject: Re: [PATCH BlueZ 0/4] Mesh: Fixes for friendship procedures

Hello:

This series was applied to bluetooth/bluez.git (master)
by Brian Gix <[email protected]>:

On Tue, 4 Oct 2022 10:25:26 +0200 you wrote:
> Hello,
>
> Here are a few patches targeting the mesh friendship behaviour. Found
> during PTS testing of:
> - MESH/NODE/FRND/FN/*
>
> Happy for any feedback.
>
> [...]

Here is the summary with links:
- [BlueZ,1/4] mesh: Correct size of friend cache
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=e9a8e884109c
- [BlueZ,2/4] mesh: Verify padding bits in Friend Poll messages
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=7ff3e10d92ba
- [BlueZ,3/4] mesh: Queue a friend update on IV Update change
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=3f3a7b8e192f
- [BlueZ,4/4] mesh: Always relay messages from Low Power nodes
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=c89e9c4b22b4

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html


2022-10-06 21:19:53

by Gix, Brian

[permalink] [raw]
Subject: Re: [PATCH BlueZ 0/4] Mesh: Fixes for friendship procedures

Patchset Applied... Thanks!
On Tue, 2022-10-04 at 10:25 +0200, Isak Westin wrote:
> Hello,
>
> Here are a few patches targeting the mesh friendship behaviour. Found
> during PTS testing of:
>   - MESH/NODE/FRND/FN/*
>
> Happy for any feedback.
>
> Best regards,
> Isak
>
> Isak Westin (4):
>   mesh: Correct size of friend cache
>   mesh: Verify padding bits in Friend Poll messages
>   mesh: Queue a friend update on IV Update change
>   mesh: Always relay messages from Low Power nodes
>
>  mesh/friend.c |  2 +-
>  mesh/net.c    | 50 ++++++++++++++++++++++++++++++++++++++-----------
> -
>  2 files changed, 39 insertions(+), 13 deletions(-)
>