2019-09-05 13:55:23

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: [PATCH BlueZ] mesh: Fix IV Recovery procedure when IV Update is in progress

This fixes erroneously cleared sequence number when node performs IV
Recovery procedure on startup in a following scenario:
- node has IV Index set to <N>
- node starts in IV_UPD_INIT state
- node receives a Secure Network Beacon with IV Index <N>+1 and IV
Update flag set

Upon reception, the node shall:
- increase its IV Index to <N>+1
- enter IV_UPD_UPDATING state

This means that the node keeps transmitting messages using IV Index
equal to <N>, therefore it shall not reset its Sequence Number before IV
Update procedure completes.

If, on the other hand, received Secure Network Beacon contains IV Index
<N>+2 (or more), the node shall:
- increase its IV Index to <N>+2 (or more)
- enter IV_UPD_UPDATING state
- reset the Sequence Number to 0
---
mesh/net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mesh/net.c b/mesh/net.c
index 2785039db..b4b390541 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -2735,7 +2735,7 @@ static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
}

if (net->iv_upd_state == IV_UPD_INIT) {
- if (iv_index > net->iv_index)
+ if (iv_index > net->iv_index + 1)
mesh_net_set_seq_num(net, 0);
net->iv_index = iv_index;

--
2.19.1


2019-09-06 07:33:17

by Gix, Brian

[permalink] [raw]
Subject: Re: [PATCH BlueZ] mesh: Fix IV Recovery procedure when IV Update is in progress

Hi Michał,

On Thu, 2019-09-05 at 15:12 +0200, Michał Lowas-Rzechonek wrote:
> This fixes erroneously cleared sequence number when node performs IV
> Recovery procedure on startup in a following scenario:
> - node has IV Index set to <N>
> - node starts in IV_UPD_INIT state
> - node receives a Secure Network Beacon with IV Index <N>+1 and IV
> Update flag set
>
> Upon reception, the node shall:
> - increase its IV Index to <N>+1
> - enter IV_UPD_UPDATING state
>
> This means that the node keeps transmitting messages using IV Index
> equal to <N>, therefore it shall not reset its Sequence Number before IV
> Update procedure completes.
>
> If, on the other hand, received Secure Network Beacon contains IV Index
> <N>+2 (or more), the node shall:
> - increase its IV Index to <N>+2 (or more)
> - enter IV_UPD_UPDATING state
> - reset the Sequence Number to 0
> ---
> mesh/net.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mesh/net.c b/mesh/net.c
> index 2785039db..b4b390541 100644
> --- a/mesh/net.c
> +++ b/mesh/net.c
> @@ -2735,7 +2735,7 @@ static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
> }
>
> if (net->iv_upd_state == IV_UPD_INIT) {
> - if (iv_index > net->iv_index)
> + if (iv_index > net->iv_index + 1)
> mesh_net_set_seq_num(net, 0);

I think you have found something, but I think we are missing something here...

If iv_index > net->iv_index, and iv_update == false, then we still want to reset to Seq Zero, I think...Even if
the increase is just 1.

This particular path is just covering the situation where this is the *first* SNB we are receiving after node
start-up (iv_upd_state == INIT) and it is very possible that the node has been away for long enough that a
single IV Update has started and finished.

So perhaps:
if (iv_index > net->iv_index && !iv_update)
mesh_net_set_seq_num(net, 0);
else if (iv_index > net->iv_index + 2)
mesh_net_set_seq_num(net, 0);

Or more esoterically (and maybe harder to follow):
if (iv_index > net->iv_index + iv_update)
mesh_net_set_seq_num(net, 0);

Or something like that.


> net->iv_index = iv_index;
>

2019-09-06 10:48:42

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: Re: [PATCH BlueZ] mesh: Fix IV Recovery procedure when IV Update is in progress

Brian,

On 09/05, Gix, Brian wrote:
> > if (net->iv_upd_state == IV_UPD_INIT) {
> > - if (iv_index > net->iv_index)
> > + if (iv_index > net->iv_index + 1)
> > mesh_net_set_seq_num(net, 0);
>
> I think you have found something, but I think we are missing something here...
>
> If iv_index > net->iv_index, and iv_update == false, then we still
> want to reset to Seq Zero, I think...Even if the increase is just 1.

Indeed. Let me re-test both scenarios and I'll get back to you with v2.

> So perhaps:
> if (iv_index > net->iv_index && !iv_update)
> mesh_net_set_seq_num(net, 0);
> else if (iv_index > net->iv_index + 2)
> mesh_net_set_seq_num(net, 0);
>
> Or more esoterically (and maybe harder to follow):
> if (iv_index > net->iv_index + iv_update)
> mesh_net_set_seq_num(net, 0);
>
> Or something like that.

Yeah, that looks reasonable.

--
Michał Lowas-Rzechonek <[email protected]>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND