Why the same block have two different valid MIC?

There are two valid PHYPayload as blow. They contained the same data but different MIC. Could anyone tell me the reason?

PHYPayload = 6005050201A004003526F2A1
PHYPayload = 6005020201A00400DD59B184

The key is as below.

lora-packet-decode --nwkkey 2B7E151628AED2A6ABF7158809CF4F3C --appkey 2B7E151628AED2A6ABF7158809CF4F3C --hex 6005050201A004003526F2A1

The MIC covers more than the literal phy payload, for example it includes the upper 16 bits of the frame count which are not transmitted.

For what full (32 bit) frame count values does the MIC on each of the above packets validate?

The 6005050201A004003526F2A1 was catught by pkt-fwd log so I couldn’t get the whole MIC.
The whole MIC of 6005020201A00400DD59B184 is MIC: dd59b1846b8d4cbeec1bc23faec8a09f.

That seems to be a misunderstanding. The MIC is a 32-bit value only.

But it depends not only on the transmitted packet, but also on the full 32-bit frame counter, only 16 bits of which are transmitted.

To say that the MIC is valid is to say that there is a value of the full frame counter (including the un-transmitted portion) for which it matches.

What are those values of the frame counter, for which the MIC is valid?

Is it actually valid?

I calculated the MIC with RFC 4993 as Lora protocol says. The whole MIC of RFC 4993 is 128-bits as URL https://tools.ietf.org/html/rfc4493. The Lora only use the first 32-bits.

I didn’t understand the un-transmitted portion. When I calculated the MIC DD59B184 I only used the frame 6005050201A00400 without any other data.

I tested both PHYPayload with lora-packet-decode cmd as below. Both are valid.

[root@monitoring ~]# lora-packet-decode --nwkkey 2B7E151628AED2A6ABF7158809CF4F3C --appkey 2B7E151628AED2A6ABF7158809CF4F3C --hex 6005050201A004003526F2A1
decoding from Hex: 6005050201A004003526F2A1
Decoded packet
--------------
Message Type = Data

  •        PHYPayload = 6005050201A004003526F2A1*
    
  •      ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )*
    
  •              MHDR = 60*
    
  •        MACPayload = 05050201A00400*
    
  •               MIC = 3526F2A1 (OK)*
    
  •      ( MACPayload = FHDR | FPort | FRMPayload )*
    
  •              FHDR = 05050201A00400*
    
  •             FPort = *
    
  •        FRMPayload = *
    
  •            ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )*
    
  •           DevAddr = 01020505 (Big Endian)*
    
  •             FCtrl = A0*
    
  •              FCnt = 0004 (Big Endian)*
    
  •             FOpts = *
    
  •      Message Type = Unconfirmed Data Down*
    
  •         Direction = down*
    
  •              FCnt = 4*
    
  •         FCtrl.ACK = true*
    
  •         FCtrl.ADR = true*
    

*[root@monitoring ~]# *

[root@monitoring ~]# lora-packet-decode --nwkkey 2B7E151628AED2A6ABF7158809CF4F3C --appkey 2B7E151628AED2A6ABF7158809CF4F3C --hex 6005020201A00400DD59B184
decoding from Hex: 6005020201A00400DD59B184
Decoded packet
--------------
Message Type = Data

  •        PHYPayload = 6005020201A00400DD59B184*
    
  •      ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )*
    
  •              MHDR = 60*
    
  •        MACPayload = 05020201A00400*
    
  •               MIC = DD59B184 (OK)*
    
  •      ( MACPayload = FHDR | FPort | FRMPayload )*
    
  •              FHDR = 05020201A00400*
    
  •             FPort = *
    
  •        FRMPayload = *
    
  •            ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )*
    
  •           DevAddr = 01020205 (Big Endian)*
    
  •             FCtrl = A0*
    
  •              FCnt = 0004 (Big Endian)*
    
  •             FOpts = *
    
  •      Message Type = Unconfirmed Data Down*
    
  •         Direction = down*
    
  •              FCnt = 4*
    
  •         FCtrl.ACK = true*
    
  •         FCtrl.ADR = true*
    

[root@monitoring ~]#

Doing what you did “without any other data” is not in accordance with the LoRaWAN specification.

Please read the LoRaWAN specification of the MIC, paying particular attention to the definition of the B0 block, which must include all 32 bits of the frame count, even though only 16 bits are transmitted.

Also simply think about it logically - you can’t have the same input, follow the same procedure, and get two different answers. For different answers to result from the same procedure, the input must differ.

I’m sorry. I forgot to mention the B0 block as below.

But as the B0 block says I think if the simplest msg is the same the B0 block should be the same too. So I was confused why the same msg have diffrent valid MIC.

No, because for the third time and as shown in your quote above, the MIC includes the full 32 bit frame count (4 bytes), while only 16 bits (2 bytes) are transmitted as part of the message.

So I was confused why the same msg have diffrent valid MIC

The same circumstances cannot yield a different result not only as that is the basis of mathematics, but practically because otherwise the whole idea of using the MIC to (provisionally) validate a message would not work. Different circumstance can occasionally collide to produce the same result, but the same circumstances can never produce a different result, or the whole thing would be unworkably broken.

Your mistaken belief that it does occurs because you are either ignoring a difference in inputs, or because the belief that one of the MICs is valid is itself mistaken.

When you figure out all of the inputs into the calculation for validating the MIC, you’ll figure out what the difference driving the difference in MICs is, or you’ll find that one of them is wrong and invalid.

The 2 presented payloads are different.

60 05 **05** 02 01 A0 04 00 35 26 F2 A1
60 05 **02** 02 01 A0 04 00 DD 59 B1 84

That’s why the MIC is different.

1 Like

The last 32-bit is the MIC, so I ask the question.

I’m sorry. I made such a stupid mistake.

mlusi1 You are right. Thank you very musch.