diff --git a/articles/lorawan3.html b/articles/lorawan3.html index 39613f32e..982447ea5 100644 --- a/articles/lorawan3.html +++ b/articles/lorawan3.html @@ -82,7 +82,8 @@
Why did we configure NuttX to provide a Strong Random Number Generator with Entropy Pool?
-The Strong Random Number Generator fixes a Nonce Quirk in our LoRaWAN Library that we observed during development.
+The Strong Random Number Generator fixes a Nonce Quirk in our LoRaWAN Library that we observed during development…
+Remember that our LoRaWAN Library sends a Nonce to the LoRaWAN Gateway every time it starts. (Pic above)
+What’s a Nonce? It’s a Non-Repeating Number that prevents Replay Attacks
+By default our LoRaWAN Library initialises the Nonce to 1 and increments by 1 for every Join Network Request: 1, 2, 3, 4, …
+Now suppose the LoRaWAN Library crashes our device due to a bug. Watch what happens…
+Our Device | LoRaWAN Gateway |
---|---|
1️⃣ Here is Nonce 1 | |
2️⃣ OK I accept Nonce 1 | |
3️⃣ (Device crashes and restarts) | |
4️⃣ Here is Nonce 1 | |
5️⃣ (Rejects Nonce 1 because it’s repeated) | |
6️⃣ Here is Nonce 2 | |
7️⃣ OK I accept Nonce 2 | |
8️⃣ (Device crashes and restarts) |
If our device keeps crashing, the LoRaWAN Gateway will eventually reject a whole bunch of Nonces: 1, 2, 3, 4, …
+(Which makes development super slow and frustrating)
+Thus we generate LoRaWAN Nonces with a Strong Random Number Generator instead.
+(Random Numbers that won’t repeat upon restarting)
+TODO
From nuttx.c
/// Get random devnonce from the Random Number Generator
SecureElementStatus_t SecureElementRandomNumber( uint32_t* randomNum ) {
- // Open the Random Number Generator /dev/urandom
- int fd = open("/dev/urandom", O_RDONLY);
- assert(fd > 0);
+ // Open the Random Number Generator /dev/urandom
+ int fd = open("/dev/urandom", O_RDONLY);
+ assert(fd > 0);
- // Read the random number
- read(fd, randomNum, sizeof(uint32_t));
- close(fd);
+ // Read the random number
+ read(fd, randomNum, sizeof(uint32_t));
+ close(fd);
- printf("SecureElementRandomNumber: 0x%08lx\n", *randomNum);
- return SECURE_ELEMENT_SUCCESS;
+ printf("SecureElementRandomNumber: 0x%08lx\n", *randomNum);
+ return SECURE_ELEMENT_SUCCESS;
}
TODO
From LoRaMacCrypto.c
-LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest_t* macMsg )
-{
- if( macMsg == 0 )
- {
- return LORAMAC_CRYPTO_ERROR_NPE;
- }
- KeyIdentifier_t micComputationKeyID = NWK_KEY;
+LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest_t* macMsg ) {
+ if( macMsg == 0 ) {
+ return LORAMAC_CRYPTO_ERROR_NPE;
+ }
+ KeyIdentifier_t micComputationKeyID = NWK_KEY;
- // Add device nonce
#if ( USE_RANDOM_DEV_NONCE == 1 )
- uint32_t devNonce = 0;
- SecureElementRandomNumber( &devNonce );
- CryptoNvm->DevNonce = devNonce;
+ // Get Nonce from Random Number Generator
+ uint32_t devNonce = 0;
+ SecureElementRandomNumber( &devNonce );
+ CryptoNvm->DevNonce = devNonce;
#else
- CryptoNvm->DevNonce++;
+ // Init Nonce to 1
+ CryptoNvm->DevNonce++;
#endif
- macMsg->DevNonce = CryptoNvm->DevNonce;
+ macMsg->DevNonce = CryptoNvm->DevNonce;
TODO
From LoRaMacCrypto.h
/*!
* Indicates if a random devnonce must be used or not
*/
#ifdef __NuttX__ // For NuttX: Get random devnonce from the Random Number Generator
-#define USE_RANDOM_DEV_NONCE 1
+#define USE_RANDOM_DEV_NONCE 1
#else
-#define USE_RANDOM_DEV_NONCE 0
+#define USE_RANDOM_DEV_NONCE 0
#endif // __NuttX__
What happens if we don’t select the Entropy Pool?
TODO
+Non Volatile Memory
Our #NuttX App resends the same Nonce to the #LoRaWAN Gateway … Which (silently) rejects the Join Request due to Duplicate Nonce … Let’s fix our Random Number Generator
TODO34