courses

LoRa and LoRaWAN

Why this matters

LoRa is the course’s main radio target, and it earns that position for a teaching reason as much as a practical one: you can see the modulation. A waterfall plot of LoRa traffic shows unmistakable diagonal sweeps. Concepts that are abstract in every other protocol — spreading, processing gain, the trade between data rate and range — are visible on screen.

It is also the cleanest illustration in the course of a distinction students routinely get wrong, and which determines every security property that follows:

LoRa is a physical layer with no security whatsoever. LoRaWAN is the MAC layer that adds it. They are not the same thing and the difference is not pedantic.

The radio layer

Chirp spread spectrum

LoRa encodes symbols as chirps — signals that sweep linearly across the channel bandwidth. A symbol’s value is encoded in where the sweep starts; it wraps around the band and continues, so every symbol occupies the full bandwidth for its full duration.

This is spread spectrum, and it buys processing gain: the receiver correlates against the known chirp shape, which concentrates the signal and disperses the noise. LoRa demodulates reliably at signal levels below the noise floor — down to about −137 dBm at the slowest settings. That is the whole trick, and it is why a 25 mW transmitter reaches several kilometres.

Spreading factor

SF sets how many chips make up one symbol: SFn means 2ⁿ chips. Higher SF means each symbol takes longer, carries the same few bits, and survives worse conditions.

SF Chips/symbol Bit rate (125 kHz) Airtime, 20-byte payload Relative range
7 128 ~5470 b/s ~60 ms Shortest
8 256 ~3125 b/s ~110 ms  
9 512 ~1760 b/s ~190 ms  
10 1024 ~980 b/s ~370 ms  
11 2048 ~440 b/s ~740 ms  
12 4096 ~250 b/s ~1.5 s Longest

Three consequences worth internalising:

Bandwidth, coding rate, and the sync word

Bandwidth is 125, 250 or 500 kHz. Wider is faster and less sensitive. Coding rate (4/5 through 4/8) sets the forward error correction overhead.

The sync word is a small detail with outsized diagnostic value:

Sync word Meaning
0x34 Public LoRaWAN networks
0x12 Private / point-to-point LoRa

A receiver configured for one will not hear the other. When a student’s capture is empty and every other parameter looks right, this is usually why.

Regional bands

Region Band Notes
EU868 863–870 MHz Duty cycle limited (typically 1%)
US915 902–928 MHz 64 × 125 kHz uplink + 8 × 500 kHz; dwell-time limited
AS923 920–925 MHz Varies by country
AU915 915–928 MHz Similar plan to US915
IN865 865–867 MHz  

⚠️ Receiving is not transmitting. Passive reception is legal; unlicensed transmission in the ISM band is permitted only within Part 15 power and duty-cycle limits, and transmitting into someone else’s network is not a spectrum question at all. Course hardware, in lab, on course networks. See Radio Protocols.

Capturing it

LoRa’s narrow channels make it SDR-friendly — the opposite of WiFi.

Tool Notes
RTL-SDR / HackRF + URH Visual identification; chirps are obvious
gr-lora_sdr (GNU Radio) Full open-source LoRa demodulator
SX1301/SX1302 concentrator A real gateway; receives 8 channels at once
RFM95 / Heltec / RAK node Single-channel; what the course uses
CatSniffer, LoRa sniffers Purpose-built multiprotocol boards

For a 125 kHz channel you need at least 125 kS/s by Nyquist and realistically 250 kS/s or more for margin against filter roll-off — see the three capture parameters.

Worked example: identifying LoRa and reading its parameters

Sweep the band first to find the active channel:

$ rtl_power -f 902M:928M:25k -i 20 -e 2m -g 40 us915.csv
Number of frequency hops: 10
Dongle bandwidth: 2600000Hz
Total FFT bins: 1280
FFT bin size: 20312.50Hz
Reporting every 20 seconds

Read those numbers rather than skipping past them. rtl_power hops by the dongle’s bandwidth, not by your bin size — 26 MHz in 2.6 MHz steps is ten retunes, not one per megahertz — and it rounds the bin count to a power of two, so the 25 kHz you asked for became 20.3 kHz. Both matter when you convert a column index back to a frequency.

Then capture the hot channel and open it in URH:

$ rtl_sdr -f 903900000 -s 1024000 -g 40 -n 20480000 lora.iq
Found Rafael Micro R820T tuner
Sampling at 1024000 S/s.
Tuned to 903900000 Hz.

In the waterfall you are looking for the signature: a run of identical up-chirps (the preamble), then two down-chirps (the sync/frame delimiter), then chirps starting at varying offsets (the payload).

You can read the parameters straight off the display:

That measurement is the exercise. Everything else is software.

LoRaWAN: the layer that adds security

Raw LoRa is bytes in, RF out. No confidentiality, no integrity, no replay protection — not as a defect, but because it is a physical layer and those are not physical-layer jobs. Capture the bytes, retransmit them, and the receiver cannot tell the difference. HW #4 demonstrates exactly this.

LoRaWAN adds a MAC layer and a network architecture:

End device  <--LoRa-->  Gateway  <--IP-->  Network Server  <-->  Application Server
                       (dumb relay)        (holds NwkSKey)       (holds AppSKey)

The gateway is deliberately dumb — it forwards packets it cannot read. All protocol logic lives in the network server.

Device classes:

Class Downlink behaviour Power
A Two short receive windows after each uplink Lowest
B Scheduled receive slots synchronised by beacons Medium
C Receiving continuously except when transmitting Highest

Class A is the default and means the network cannot reach a device until it speaks first — which is a security property as much as a power one. It also means a command queued for a sensor may sit for hours.

The key hierarchy

In LoRaWAN 1.0.x a root AppKey is provisioned per device, and joining derives two session keys:

Key Protects
NwkSKey Frame integrity (the MIC) and MAC commands
AppSKey Payload confidentiality, end to end to the application server

The split lets a network operator route and verify frames without reading payloads — a sensible separation, and one reason LoRaWAN scales to shared public networks like The Things Network.

LoRaWAN 1.1 restructured this, splitting the root into NwkKey and AppKey and the session keys into four (FNwkSIntKey, SNwkSIntKey, NwkSEncKey, AppSKey) specifically so that a network server can no longer derive application keys. Adoption has been slow; networks frequently run 1.0 compatibility mode, which forfeits the benefit.

OTAA versus ABP

  OTAA ABP
Session keys Derived fresh at each join Fixed at manufacture
Join procedure JoinRequest / JoinAccept None — device is preloaded
Counters Reset legitimately on rejoin Must persist forever
Replay exposure Lower Higher

ABP is the weaker choice and it is chosen constantly, because it avoids implementing the join. Static session keys plus a frame counter that resets on reboot gives an attacker a window in which previously captured frames are accepted again.

The join, and DevNonce

OTAA’s JoinRequest carries the JoinEUI, DevEUI and a DevNonce; the JoinAccept returns a JoinNonce, a DevAddr and network settings, encrypted under the AppKey.

The history of DevNonce is a good miniature of specification evolution:

That fix is correct, and it moves the problem to exactly where every other protocol in this course has put it: the counter must survive power loss.

Replay protection is state

Uplinks and downlinks carry frame counters (FCntUp, FCntDown), transmitted as 16 bits with the upper 16 maintained at both ends. A receiver rejects a counter it has already seen. That is sound.

And a counter that must survive power loss has to live in flash, and flash has limited write endurance. So implementers write it every nth message, or skip forward in blocks on boot, or reset it and rely on the network to resynchronise. Every one of those choices reopens a replay window, and the network operator must then decide between rejecting a legitimately rebooted device forever and accepting a possibly replayed frame. They choose availability.

This is the generalisable lesson of the whole radio block, and it is not LoRaWAN-specific — Zigbee and Z-Wave have the identical tension. Replay protection is state, and embedded devices are bad at state.

What leaks without any key

As with Z-Wave, the header must be readable for the network to route:

+------+---------+-------+------+-------+--------------+-----+
| MHDR | DevAddr | FCtrl | FCnt | FPort | FRMPayload   | MIC |
+------+---------+-------+------+-------+--------------+-----+
         ^^^^^^^          ^^^^          ^^^^^^^^^^^^
         plaintext     plaintext        encrypted (AppSKey)

So a passive listener obtains the DevAddr — a stable per-session device identifier — and the frame counter, without holding a single key. That is enough to:

Payload confidentiality is not the same as privacy. Say so in the report.

The failure that actually happens

For all the protocol detail above, the most common real LoRaWAN compromise is not cryptographic. The AppKey is stored in the device’s flash, in plaintext, and the device is in a field where anyone can pick it up.

Recover the image via SWD or a flash dump (Dumping flash, JTAG and SWD), find the key, and you can clone the device, forge its telemetry, and decrypt everything it has ever sent. No AES was harmed.

This is why the hardware half of this course is not separate from the radio half — and it is the single highest-value check on a LoRaWAN assessment.

Key takeaways

References


Related course pages: Radio Protocols · HW #4 · Lab 3 · Other IoT radios · Dumping flash · JTAG and SWD · Attacks

🛠️ Maintenance note: the airtime and bit-rate figures are computed for 125 kHz bandwidth and coding rate 4/5 — recompute them if the course radios are reconfigured, and treat them as approximate in any case. LoRaWAN 1.1 adoption has been “imminent” for years and is worth re-checking annually; 1.0.4 remains the practical target. Regional band plans are revised by the LoRa Alliance periodically, and the US915 dwell-time rules in particular should be verified against the current regional parameters document before being taught as fact.