MKW41z NXP Thread stack socket decryption

cancel
Showing results for 
Search instead for 
Did you mean: 

MKW41z NXP Thread stack socket decryption

Jump to solution
4,117 Views
gbh
Contributor III

Hello,

I've got a couple of custom boards which I've set up to control the KW41z over SPI, with a k64 as the host device. I'm able to create a network and join it, and discover other devices on the network. I can also create/bind/connect sockets and establish a connection between the two devices. Everything looks good between the two with a couple of major exceptions:

  • The length of the data received by the recv call in THCI_BSDSockReqRecv matches the data I'm sending, but the data is never what I sent. I have verified that the data looks good at the 'send' call in THCI_BSDSockReqSend.
  • After receiving some number of messages (correct length, incorrect data, as described above), the recv call in THC_BSDSockReqRecv returns 0. This seems odd, given that there continue to be ACKs to the transmitted data in my Wireshark trace. Those ACKs aren't present when I haven't joined a second device and set up a socket on that port, so it seems like the stack is receiving the data, but not delivering it.

I haven't seen many mentions of encryption/decryption in the documentation (and nothing that pertains to the sockets), and I've been operating under the assumption that Socket-Receive.Request/recv would return cleartext, but maybe I'm wrong about that. I haven't been able to find any other calls to recv in the demo I'm looking at, either. What is the correct way to retrieve that data? Any idea what's causing the stack/THCI to stop returning data, even though the KW41Z is still ACKing incoming transmissions?

The setup for the sender:

  1. create network
  2. add expected joiner
  3. sync steering data
  4. find child (and create/store LL address)
  5. create socket (domain:0x0A, type:0x00, protocol:0x11) (index is stored and used in 6/7/8)
  6. bind to local address (socket domain:0x0A, local ip retrieved from KW41z)
  7. connect to child from 4 (socket domain:0x0A)
  8. send 'send' message to kw41z periodically (~2s period, have tried with 10 and 42 byte payloads, same behavior.)

Setup for the receiver:

  1. join network
  2. find a neighbor
  3. create socket (same options as sender) index is stored and used in 4/5/6)
  4. bind to local address (same options as sender)
  5. connect to neighbor address from 2 (same options as sender)
  6. send 'receive' message to kw41z (length 100) and output responses to a serial port.

I've also been trying to use the CoAP FSCI commands from the test tool, but it's not clear to me what success looks like there. I created an instance, registered a URI with the CoapRegister command, and then sent from another board (client and server are both FRDM-kw41z running hybrid_ble_thread_host_controlled_device demo). I can see the traffic in Wireshark, but nothing happens on the destination node, as far as I can tell.

I haven't been able to verify the data in flight, as I haven't yet figured out how to decrypt it in Wireshark. I found this post about setting that up: Decrypting ZigBee packets with Wireshark.  I tried putting in the network master key (retrieved via GetAttr) in that field and wasn't able to decrypt the message. I tried the default key listed in that link as well, and that didn't work either. I've also tried setting the key in the IEEE 802.15.4 dissector, to no avail. What key(s) do I need to set up in Wireshark to decrypt traffic from my Thread network, and how do I need to request that information from the module? 

Thanks,

Ben

Previous post

KW41Z host-controlled example THCI 

Labels (2)
1 Solution
963 Views
gbh
Contributor III

I have a workaround running based on the sockets implementation in the shell demo. I used Session_Init in APP_FsciInterface and register a callback (Session_RegisterCb) per-port on socket creation, unregistering it on socket shutdown(Session_UnRegisterCb). In thci.c, I implemented an array of a struct containing a socket descriptor and the necessary elements for a simple circular buffer.

Once I had that all together, I had an issue crop up with writing to a member of a null-pointer'd struct in GenericList.c/RemoveHead. I'm not sure what the deal is there and why it was never an issue before I made the above changes, but once I wrapped the troublesome assignments, I'm now receiving data as expected, on one socket anyway. I trapped the crashing down to GenericList using the HandlerC function in debug_log.c and this writeup Debugging Hard Faults on ARM Cortex-M | MCU on Eclipse

Thanks again for the assistance so far JC. Seeing that shell demo working got me on a good path.

View solution in original post

9 Replies
964 Views
gbh
Contributor III

I have a workaround running based on the sockets implementation in the shell demo. I used Session_Init in APP_FsciInterface and register a callback (Session_RegisterCb) per-port on socket creation, unregistering it on socket shutdown(Session_UnRegisterCb). In thci.c, I implemented an array of a struct containing a socket descriptor and the necessary elements for a simple circular buffer.

Once I had that all together, I had an issue crop up with writing to a member of a null-pointer'd struct in GenericList.c/RemoveHead. I'm not sure what the deal is there and why it was never an issue before I made the above changes, but once I wrapped the troublesome assignments, I'm now receiving data as expected, on one socket anyway. I trapped the crashing down to GenericList using the HandlerC function in debug_log.c and this writeup Debugging Hard Faults on ARM Cortex-M | MCU on Eclipse

Thanks again for the assistance so far JC. Seeing that shell demo working got me on a good path.

View solution in original post

963 Views
shauno_brien
Contributor I

Ben,

I am having similar crashes in GenericList/RemoveHead.  What did you ever find?  What did you do when you "wrapped the troublesome assignments"?

Thanks,

Shaun

0 Kudos
963 Views
jc_pacheco
NXP Employee
NXP Employee

Hello Ben, 

There's a known bug that will be fixed in the upcoming maintenance release where the data received by the firmware using THCI for socket communication is incorrect. I'll gladly let you know here when the maintenance release is available with this fix.

0 Kudos
963 Views
jasonchiang
NXP Employee
NXP Employee

Hi JC,

    ***********************************************************************

There's a known bug that will be fixed in the upcoming maintenance release where the data received by the firmware using THCI for socket communication is incorrect.

*****************************************************************************

     Was the fixed version released ? 

0 Kudos
963 Views
jc_pacheco
NXP Employee
NXP Employee

It should be available in the latest SDK for KW41Z from MCUXpresso.

0 Kudos
963 Views
jasonchiang
NXP Employee
NXP Employee

Thanks. We will test it with the latest SDK.

0 Kudos
963 Views
gbh
Contributor III

So is there anything I can do in the meantime to get communications running with the current stack? The way you've phrased your response makes me think it's something I can work around if I were to use the API directly from code I write on the KW41z. Is that correct? Is there a public documentation of this bug I can look at to better understand the scope of it? Can you say approximately when that update will be released?

I've tried using the sockets in the shell demo (with two FRDM boards) as you mentioned in the previous thread, but I'm not sure how to tell if it's working. There's no receive functionality documented in the shell, and the receiving end doesn't present any kind of indication that it's received anything. I looked at the shell code to see if I could add the receive command, but there's no enum value for that command to be added to the pAppSockCmdParams.

I also tried using the shell to send to my custom board, which is set up to join a network, find a neighbor, open a socket, and start receiving. The behavior there is the same as when my custom board is the network leader sending data to the custom joiner/receiver: correct length, incorrect data.

Are you able to answer my question about decrypting messages in Wireshark? After looking around a bit more it seems like the tutorial I referenced above may not apply to the 802.15.4 messages I'm seeing (since they're decoded using the "IEEE 802.15.4" dissector), but putting the master key (still the default of 00112233445566778899aabbccddeeff) into the 802.15.4 dissector doesn't result in decrypted messages either. I see "MIC check failed"

Thanks,

Ben

0 Kudos
963 Views
jc_pacheco
NXP Employee
NXP Employee

Hello Ben, 

The sockets on the shell should work fine, you just need to enable the "#SOCK_DEMO" macro and you should be able to open a socket to a remote node and send/receive udp packets; by default the receiver will listen on port 1234 (see #UDP_PORT). Documentation on how to use the socket demo is available at C:\NXP\MKW41Z_ConnSw_1.0.2\docs\wireless\Thread\Kinetis Stack Shell Interface User's Guide.pdf 

sockets.PNG

The maintenance release is planned for early Q2, so this should address this sockets over THCI issue.

If you want to make use of COAP commands through THCI, take a look into IP Utils section in Test Tool.

- NWKU_CoapCreateInstance.Request

NWKU_CoapRegister.Request

- NWKU_CoapSend.Request

You can also find information about CoAP usage in the Chapter 6 - Constrained Application Protocol (CoAP) in Kinetis Thread Stack Application Development Guide.pdf.

Regarding Wireshark, the key you are currently entering is for IEEE802.15.4 layer only. A "Thread dissector" for Wireshark is currently available for Thread-members and it's in the process of public availability.

 

Regards,

JC

963 Views
gbh
Contributor III

Hey JC,

Thank you for sending that image. The sockets do work between shell instances, as you stated. I completely overlooked the specific port listed in the shell documentation.

Do you have any idea when the Thread dissector will be generally available?

0 Kudos