Bluetooth Mesh - Restore the replay protection list
Bluetooth mesh has a replay protection list that basically keeps a
link between a address and a sequence counter to protect against
replay attacks. It checks if messages are ok by making checking if the
sequence counter is increasing. This only works if this sequence
counter is restored when the node is rebooted, for this it has to be
stored in flash.
As some nodes (frequent receiver nodes) get lots of messages this
could wear out flash rapidly. In order to avoid this rapid wear the
current persistent storage solution (which by the way is a great
addition) utilizes a timer to limit the amount of writes to flash.
This however creates a security risk just after power on if the write
to flash was not performed.
Maybe there is another way to make sure that the replay protection
list gets initialized correctly. Suppose that we would only store the
addresses we need to restore the replay protection list. After power
on we could restore the correct sequence number by exchanging a
message with the node (of which we have the address). But what message
As all nodes have mandatory configuration server and health server
models we can only use these. As the configuration messages use the
devkey this is not possible, so only the health messages are left. The
"health fault get message" seems to fit the requirement: it is an
acknowledged message so it will return an answer and it is mandatory
and therefore required by all nodes.
So the idea would be: to restore the replay protection list a node
incorporates the health client model. After reboot it sends "health
fault get message" to all nodes it has in its address list, a
successful receive of an acknowledge sets the correct sequence
counter. The flash wear is removed as the nodes only need to store the
addresses. Replay attacks are not possible because the response to the
"health fault get message" has increased the counter.
Would this be a good solution or do you see any security risks in this ?
On Fri, May 18, 2018, laczenJMS wrote:
As all nodes have mandatory configuration server and health serverThis is an interesting idea, and definitely could be made to work.
However, only in some limited scenarios. One challenge is that it'll
work only if you have control of the entire network. The reason is that
it is completely up to the administrator of the network to choose which
application key to bind to the health server models. There's also no
guarantee that all health servers on the network are bound to the same
key. Even if you knew which keys the servers are bound to, each model
can only be bound to one key, so your health client could only talk to
health servers that are bound to the same key as the client.
There's also the issue with the small window between power up and not
having received responses from all nodes yet. Would we ignore any other
messages until we receive the Health Fault Get response? What if one of
the nodes in the RPL is powered off at that moment? This is quite likely
since the local node had just experienced a power cycle as well.
Additionally, this would constitute a layer violation, since the RPL is
handled on the network and transport layers, which have no knowledge of
model layer information.