From 20d45639a6be89e40f76641929016a0ef2667757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 14 Aug 2018 14:21:50 +0200 Subject: [PATCH] mesh/transport: Fix calculating seqAuth This patch fixes case where Mesh is receiving segmented data with SEQ and SeqZero as in logs below: bt_mesh_trans_recv: src 0x07FF dst 0x0001 seq 0x00031FFF friend_match 0 bt_mesh_trans_recv: Payload dd7ffc016e5c7f861272e5f7577a6644 trans_seg: ASZMIC 0 AKF 1 AID 0x1D trans_seg: SeqZero 0x1FFF SegO 0 SegN 1 trans_seg: ######## seq_auth=204799 bt_mesh_trans_recv: src 0x07FF dst 0x0001 seq 0x00032000 friend_match 0 bt_mesh_trans_recv: Payload dd7ffc21abb5a7 trans_seg: ASZMIC 0 AKF 1 AID 0x1D trans_seg: SeqZero 0x1FFF SegO 1 SegN 1 trans_seg: ######## seq_auth=212991 --- nimble/host/mesh/src/transport.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 702f11ca5..3261efb52 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -1177,8 +1177,21 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, return -EINVAL; } + /* According to Mesh 1.0 specification: + * "The SeqAuth is composed of the IV Index and the sequence number (SEQ) + * of the first segment " + * + * Therefore we need to calculate very first SEQ in order to find seqAuth. + * We can calculate as below: + * + * SEQ(0) = SEQ(n) - (delta between seqZero and SEQ(n) by looking into + * 14 least significant bits of SEQ(n)) + * + * Mentioned delta shall be >= 0, if it is not then seq_auth will + * be broken and it will be verified by the code below. + */ *seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_RX(net_rx), - (net_rx->seq & 0xffffe000) | seq_zero); + (net_rx->seq - ((((net_rx->seq & BIT_MASK(14)) - seq_zero)) & BIT_MASK(13)))); /* Look for old RX sessions */ rx = seg_rx_find(net_rx, seq_auth);