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 @@
  • 9.2 Message Interval
  • 10 Rerun The Firmware
  • -
  • 11 LoRaWAN Nonce
  • +
  • 11 LoRaWAN Nonce
  • 12 LoRaWAN Event Loop
  • 13 NimBLE Porting Layer
  • 14 GPIO Interrupts
  • @@ -746,53 +747,81 @@ CHANNEL MASK: 0003

    Join LoRaWAN Network

    11 LoRaWAN Nonce

    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…

    + +

    Now suppose the LoRaWAN Library crashes our device due to a bug. Watch what happens…

    +
    + + + + + + + + +
    Our DeviceLoRaWAN 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)

    +

    11.1 Random Number Generator

    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