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 ?