anthonykirby / lora-packet

LoRa radio packet decoder
MIT License
261 stars 83 forks source link

MIC always wrong for packets from Oyster? #29

Closed bitwombat closed 4 years ago

bitwombat commented 5 years ago

Hi,

The Digital Matters Oyster node sends packets like this:

800E21062602900AE4AE010FCD776DB3DF96F4CB75656695F9CC

However, lora-packet always says the MIC is wrong.


$ node_modules/lora-packet/bin/lora-packet-decode --appkey E144C6ACB81F17F05CFEB90EF55D615C --nwkkey 448B20D2E0ED62F3DC61ADE7B589B65A --hex $trimmed_line
decoding from Hex:  800e21062602900ae4ae010fcd776db3df96f4cb75656695f9cc
Decoded packet
--------------
Message Type = Data
            PHYPayload = 800E21062602900AE4AE010FCD776DB3DF96F4CB75656695F9CC

          ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
                  MHDR = 80
            MACPayload = 0E21062602900AE4AE010FCD776DB3DF96F4CB7565
                   MIC = 6695F9CC (BAD != F9CC34D1)

          ( MACPayload = FHDR | FPort | FRMPayload )
                  FHDR = 0E21062602900AE4AE
                 FPort = 01
            FRMPayload = 0FCD776DB3DF96F4CB7565
             Plaintext = E5F33FEDA757FB5A6900A5 ('..?..W.Zi..')

                ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
               DevAddr = 2606210E (Big Endian)
                 FCtrl = 02
                  FCnt = 0A90 (Big Endian)
                 FOpts = E4AE

          Message Type = Confirmed Data Up
             Direction = up
                  FCnt = 2704
             FCtrl.ACK = false
             FCtrl.ADR = false
`

I'm pretty confident in those keys because the FRMPayload plaintext is correct (it's an actual, accurate, GPS packet).

Let me know if I can provide anything else to help.
bitwombat commented 5 years ago

I just figured out (thanks to TTN Slack) that the Oyster is quite possibly the device is sending LoRaWAN v1.1 packets... can that be seen with the above?

avbentem commented 4 years ago

Quite late, but: no, one cannot tell the version from a LoRaWAN packet. A device can tell if it gets a 1.0.x or 1.1.x Join Accept (this allows it to fall back to 1.0.x if the server does not understand 1.1), but in regular uplinks and downlinks this cannot be seen.

However:

MIC = 6695F9CC (BAD != F9CC34D1)

Above, note that the F9CC part matches, and that is by design. That part is calculated just like a 1.0.x MIC, but in 1.1 only 16 bits are included in the full 32 bits MIC. To calculate the other 16 bits, one must also know at which data rate and channel the uplink was transmitted (and, in case of a downlink confirmation, also the downlink's frame counter), along with the secret SNwkSIntKey.

So maybe the answer is actually: yes, when using the 1.0 validation on a 1.1 packet, then when seeing that those 16 bits match, one can assume it's a valid 1.1 packet. And hence I'd say this issue can be closed.

(You can try yourself, but that does not add much.)

anthonykirby commented 4 years ago

excellent, thank you for the analysis!