sandeepmistry / arduino-LoRa

An Arduino library for sending and receiving data using LoRa radios.
MIT License
1.69k stars 637 forks source link

byte LoRaClass::random() Improper Handling of RegRssiWideband for TRNG #394

Open Kongduino opened 4 years ago

Kongduino commented 4 years ago

LoRaClass::random() reads the register once and returns the byte.

byte LoRaClass::random() {
  return readRegister(REG_RSSI_WIDEBAND);
}

This is wrong for two reasons:

1) LoRa chip must be set in a specific mode before that, you can't get random number at any given time. LoRa must be stopped and set to continuous mode first, and so on.

2) There should be 8 reads, keeping only the least significant bit (LSB), and build the output byte from that.

See Chapter 4 of Random Number Generation for Cryptography.

To generate an N bit random number, perform N read operation of the register RegRssiWideband (address 0x2c) and use the LSB of the fetched value. The value from RegRssiWideband is derived from a wideband (4MHz) signal strength at the receiver input and the LSB of this value constantly and randomly changes.

Example code from LoRandom.h

#define RegOpMode 0x01
#define RegModemConfig1 0x1D
#define RegModemConfig2 0x1E
#define RegRssiWideband 0x2C

void setupLoRandom() {
  LoRa.writeRegister(RegOpMode, 0b10001101);
  // LoRa mode enable Receive Continuous mode
  LoRa.writeRegister(RegModemConfig1, 0b01110010);
  // ‘0111’ for 125kHz modulation Bandwidth
  // 4/5 error coding rate
  // Packets have up-front header
  LoRa.writeRegister(RegModemConfig2, 0b01110000);
  // ‘0111’ (SF7) = 6kbit/s
}

uint8_t getLoRandomByte() {
  uint8_t x = 0;
  for (uint8_t j = 0; j < 8; j++) {
    x += (LoRa.readRegister(RegRssiWideband) & 0b00000001);
    x = x << 1;
    delay(1);
  }
  return x;
}

You need to put the SX1276/8 in Receive Continuous mode, SF7, C/R 4/5, BW 125KHz (call to setupLoRandom(), and then read 8 bytes to get one random byte (call to getLoRandomByte()). After which you need to put back your LoRa chip to whatever settings you were using.

In BastWAN_LoRa_RNG I build a buffer of 256 random bytes at once.

tobozo commented 4 years ago

Indeed this is what Lora.random() produces :

image

highest values are 0x45, 0x47 ...

engeen-nl commented 3 years ago

I also struggled with this and expected a random byte from this function. Thanks for the example @Kongduino

Can this be adjusted in the next version of the library?