1) The device sends an unencrypted Join Request message
This message consists of the AppEUI and DevEUI of the device, together with an unique DevNonce (a 16 bit random number which can only be used once in order to prevent replay attacks).
A checksum which is called the MIC (Message Integrity Code) is sent along with this message. The MIC is the result of a 128bit CMAC-AES encryption of this message with the AppKey.
2) The Gateway receives the Join Request and sends a Join Accept
The Join Accept message consists of an AppNonce (a NONCE generated by the application server), the NetID (Identifier for the replying network), the DevAddr, DLSettings, RxDelay and an optional CFList (list with additional frequencies to be used by the device).
The join-accept message is encrypted with the AppKey using 128bit CMAC-AES.
3) The device receives the Join Accept
The device uses the random Nonces (the DevNonce and the AppNonce) together with the the NetID to derive the session keys:
NwkSKey = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce | pad16)
AppSKey = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce | pad16)
As the key derivation is done at the Join Procedure and is using random generated keys, these Session keys will appear random for each session too. When using ABP those keys are static during the device’s lifetime and thus prone to hackers.
As you might know, Semtech’s provided stack uses radio noise readings to generate the random key (DevNonce). The caveat here is that the noise readings and thus the DevNonce can be easily manipulated from outside.
The LoRaWAN stack which is used in our devices makes use of PSoC6’s hardware encryption engine to generate the DevNonce and cannot be influenced from outside. The ready implemented, isolated and easy to use LoRaWAN stack meets the industries highest security demands.