LoraWAN® At A Glance
Application Messages
CRC is only present on
uplink messages.
Radio PHY Layer Preamble PHDR PHDR_CRC PHYpayload CRC*
Downlink messages are
protected by MIC
1 7..n-5 4 Cryptographic Message
PHYPayload MHDR MACPayload MIC Integrity code,
computed over
MHDR..Mpayload
(section 4.4) using Aj
below
7..5 4..2 1..0 7..23 0..1 0..nP-1
FRMPayload is always
MACPayload Mtype RFU Major FHDR FPort FRMPayload encrypted, if present. Data is
XORed with cipherstream B0
below using a key determined
by the value of FPort and
FPort is present if any possibly provisioning info.
4 1 2 0..15 FRMPayload bytes are present.
DevAddr FCtrl FCnt FOpts Values:
0: FRMPayload carries MAC
commands. Use NwkSKey
Non-zero: Use AppSKey or do
crypto in app (as provisioned).
7 6 5 4 3..0
Values 1..0xDF are defined by
DL:Fpending
ADR ADRACKReq ACK UL: RFU
FOptsLen the application; 0xE0 carries
compliance requests. 0xE1..0xFF
are RFU.
Bit 4 becomes UL: ClassB for nodes
in class B mode. (Should probably be
documented as ClassB rather than
RFU)
Cipher Keystreams
1 4 1 4 4 1 1 Compute aes128_encrypt(K, Ai) using K =
Ai 0x01 0x00 Dir (dl: 1) DevAddr
FCntUp /
FCntDown
0x00 i
NwkSKey or AppSKey, as needed to get 16-byte
ciphertext, then xor with corresponding payload
bytes; j is the block index for 16-byte blocks.
1 4 1 4 4 1 1
B0 0x49 0x00 Dir (dl: 1) DevAddr
FCntUp /
FCntDown
0x00 len(msg)
Compute aes128_cmac(NwkSKey, B0 | msg), then
MIC is cmac[0..3].
msg is MHdr|MPayload
Copyright © 2020, MCCI Corporation
LoRaWAN is a registered trademark of the LoRa Alliance
1 of 5
MCCI is a registered trademark of MCCI Corporation
Class A MAC Commands (1.03): 02..08
1 0..n Length of payload is implied by CID and originator of message. All
messages are in pairs; ...Rq from one side begins a sequence and …Ans
General Format CID payload from the other side concludes that sequence. Most sequences are initiated
by the Gateway, but LinkCheck* is initiated by a Node
CID values 0x00 and 0x01 are reserved
From Gateway From Node
1 1 1 1
LinkCheckAns [5.1] 0x02 Margin GwCnt LinkCheckReq [5.1] 0x02
1 1 2 1
LinkADRReq [5.2] 0x03
DataRate
TxPower
ChMask Redundancy
7..4 3..0 7 6..4 3..0
DataRate TxPower RFU ChMaskCntl NbRep
1 1
LinkADRAns [5.2] 0x03 Status
7..3 2 1 0
Data Rate Channel
RFU Power ACK
ACK Mask ACK
1 1 1
DutyCycleReq [5.3] 0x04 MaxDCycle DutyCycleAns [5.3] 0x04
1 1 3 1 1
RxParamSetupReq[5.4] 0x05 DLSettings Frequency RxParamSetupAns [5.4] 0x05 Status
7 6..4 3..0 7..3 2 1 0
RX1DRoffset RX2DataRate
RFU RX1DRoffset RX2DataRate RFU ACK ACK
Channel ACK
1 1 1 1
DeviceStatusReq [5.5] 0x06 DeviceStatusAns [5.5] 0x06 Battery Margin
7..6 5..0
RFU Margin
NewChannelRq [5.6] 1 1 3 1 NewChannelAns [5.6] 1 1
DlChannelReq [5.6] 0x07 ChIndex Freq DrRange DlChannelAns [5.6] 0x07 Status
7..4 3..0 7..2 1 0
Data Rate Channel
MaxDR MinDR RFU Range OK Frequency OK
1 1 1
RxTimingSetupRq [5.7] 0x08 Settings RxTimingSetupAns [5.7] 0x08
7..4 3..0
2 of 5
RFU Delay
Class A MAC Commands (1.03): 09..0D
1 0..n Length of payload is implied by CID and originator of message. All
messages are in pairs; ...Rq from one side begins a sequence and …Ans
General Format CID payload from the other side concludes that sequence. Most sequences are initiated
by the Gateway, but LinkCheck* is initiated by a Node
From Gateway From Node
1 1 1
TxParamSetupReq [5.8] 0x09
EIRP_-
DwellTime
TxParamSetupAns [5.8] 0x09
7..6 5 4 3:0
Downlink- Uplink-
RFU DwellTime DwellTime
MaxEIRP
1 1 3 1 1 1
DlChannelReq [5.6] 0x0A ChIndex Freq DrRange DlChannelAns [5.6] 0x0A Status
7..4 3..0 7..2 1 0
Data Rate Channel
MaxDR MinDR RFU Range OK Frequency OK
CID values 0x0B and 0x0C are reserved
1
DeviceTimeReq [5.9] 0x0D
1 4 1
DeviceTimeAns [5.9] Fractional
0x0D GPS time
second
Fraction of section in 1/256-th second steps
3 of 5
Join Messages
Join Request
PHDR_CR PHYpaylo
Radio PHY Layer Preamble PHDR
C ad
CRC*
1 18 4 Cryptographic Message Integrity
PHYPayload MHDR Mpayload MIC
code, computed over
MHDR..Mpayload (6.2.4) using:
cmac = aes128_cmac(AppKey, MHDR
| Mpayload), then taking bytes 0..3
of cmac[]. Presumably byte 0 of MIC
7..5 4..2 1..0 8 8 2
is cmac[0].
MACPayload Mtype =
0x0
RFU Major AppEUI DevEUI DevNonce
Join Accept
Cryptographic Message Integrity
code, computed using (6.2.5) cmac =
aes128_cmac(AppKey, MHDR |
Radio PHY Layer Preamble PHDR PHDR_CRC PHYpayload
AppNonce | NetID | DevAddr |
DLSetings | RxDelay | CFList), then
taking bytes 0..3 of cmac[].
Presumably byte 0 of MIC is cmac[0].
Note that this is computed on
plaintext, and then transmitted
encrypted.
1 12 or 28 4
PHYPayload MHDR Mpayload MIC
7..5 4..2 1..0 3 3 4 1 1 0 or 16
MACPayload Mtype =
0x1
RFU Major AppNonce NetID DevAddr DLSettings RxDelay CFList
Mpayload and MIC are encrypted.
7 6..4 3..0 Note that decryption is done by
RX2 Data doing an aes_encrpyt, not
RFU RX1DROffset
Rate aes_decrypt. Ciphertext is either 16
or 32 bytes long (one or two rounds
of AES128). Encryption is done using
ciphertext = aes_decrypt(AppKey,
AppNonce | NetID | DevAddr |
DLSettings | RxDelay | CFList);
decryption is therefore plaintext =
aes_encrypt(AppKey, ciphertext).
4 of 5
Message Types
MType (binary) 1.0.3 1.1
000 Join-Request Join-request
001 Join-Accept Join-Accept
010 Unconfirmed Data Up Unconfirmed Data Up
011 Unconfirmed Data Down Unconfirmed Data Down
100 Confirmed Data Up Confirmed Data Up
101 Confirmed Data Down Confirmed Data Down
110 RFU Rejoin-request
111 Proprietarry Proprietary
5 of 5