Overall goal is to remove the requirement that hosts keep track of a packet counter across resets. This is a common source of implementation difficulty. When not implemented correctly, it can severely compromise the security of the network.
In the symmetric version of this scheme, there is a single secret
MASTER_KEY
that all participants on the mesh network know. From this
key we derive the following keys using some as-of-yet unspecified
mechanism:
SEED_AUTH_KEY
SECONDARY_KEY
SECONDARY_KEY
is used to generate pair-wise keys as well as a
broadcast key for each device.
Each device keeps track of two values for a given boot:
FRAME_COUNTER
and KEY_SEED
, both of which are public. Devices
periodically scan for nearby peers, fetching their frame counters and
key seed.
When a device wishes to communicate with a peer, it calculates the
PEER_KEY
to use in the following manner: The KEY_SEED
of each peer
is collected, sorted and concatenated in ascending order (big endian).
PEER_KEY
is the result of calculating the AES128-CBC-MAC of this
concatenation using SECONDARY_KEY
.
If a device wishes to send out a broadcast message to its peers, it
calculates the BROADCAST_KEY
to use in the following manner:
- Let our key seed be
KEY_SEED
. KEY_SEED
is encrypted withSECONDARY_KEY
using AES-128-ECB, yieldingBROADCAST_KEY
.
At every power cycle, we reset our frame counter and choose a random
seed key. We then announce to our peers that our KEY_SEED
has
changed, and they fetch our KEY_SEED
and continue.
The KEY_SEED
for a peer is authenticated by a challenge-response.
When a peer asks for the KEY_SEED
of other peers, it includes
SEED_NONCE
, the length of which is the difference between the size
of the block-cipher key and the size of FRAME_COUNTER
. This nonce is
used to generate a SEED_REQUEST_MAC
(to avoid replay attacks) which
is included with the response. The key used for the MAC is
SEED_AUTH_KEY
.
SEED_REQUEST_MAC
is calculated as follows:
FRAME_COUNTER
is appended big-endian toSEED_NONCE
, yieldingNONCE_FC
.NONCE_FC
is encrypted withSEED_AUTH_KEY
using AES-128-ECB, yieldingMAC_X
.MAC_X
is XORed withKEY_SEED
, yieldingMAC_Y
.MAC_Y
is encrypted withSEED_AUTH_KEY
using AES-128-ECB, yieldingSEED_REQUEST_MAC
.
The asymmetric-crypto version has the following benefits:
- More secure: Unicast keys between any two peers are known only to those peers.
- More flexible: Individual devices can also be securely ejected from the network.
This comes at a cost: it is significantly more resource intensive. At least two expensive asymmetric cryptographic operations is required for every peer we interact with. The fact that at least one asymmetric cryptographic operation would be required to identify an invalid request from an attacker could lead to denial of service attacks.
These expensive operations can be offloaded to dedicated secure elements. Luckily, such secure elements are now becoming fairly inexpensive.
In the asymmetric version of this scheme, each network has a public
and private key, NET_KEY_PUB
and NET_KEY_PRI
. This key is
used to generate "certificates" for devices that are a part of the network.
Each device on the network also has their own public/private key pair:
DEVICE_KEY_PUB
and DEVICE_KEY_PRI
. To become a part of the mesh
network, the device gives DEVICE_KEY_PUB
to a commissioner, who then
uses NET_KEY_PRI
to generate a certificate: DEVICE_NET_CERT
(This
certificate also contains NET_KEY_PUB
). DEVICE_NET_CERT
is then given
to the device, providing the device with the credentials to authenticate
itself to other devices. It is not necessary (and highly discouraged)
for devices on the network to know NET_KEY_PRI
unless those devices are
used to commission new devices onto the network.
Note that the DEVICE_NET_CERT
doesn't need to be a full X.509 certificate,
it could be little more than a concatenation of the NET_KEY_PUB
,
DEVICE_KEY_PUB
, and a signature.
Devices on the mesh need to communicate with their peers individually to set up pair-wise symmetric keys as well as identify a broadcast key for each peer. An authenticated diffie hellman scheme would be used to generate a pair-wise key, and an encryption scheme suitable for the given cryptosystem can be used for broadcast key sharing.
The rough steps per peer-pair would be:
- Device A requests a key sync by sending Device B
DEVICE_NET_CERT_A
along with the public diffe-helman parameterDH_A
, with a signatureDH_SIG_A
signed byDEVICE_KEY_PRI_A
. - Device B responds to the key sync request by sending Device A
DEVICE_NET_CERT_B
along with the public diffe-helman parameterDH_B
, with a signatureDH_SIG_B
signed byDEVICE_KEY_PRI_A
. - Both sides verify each other's certificates and the signature on the diffe-helman
parameter. If that all checks out, diffe-helman is used to generate a secret
shared key:
PEER_KEY_AB
. - Each side finishes the sync by sending each other their own unique broadcast key
in packets encrypted with keys derived from
PEER_KEY_AB
.
To be continued...
Great work. Am following it.