BLE with coded PHY and CCM decryption

Hey, I'm trying to get a basic BLE with coded PHY (125Kbps) setup with on the fly encryption/decryption working but I'm running into a strange problem. I'm using a custom SDK which is why I spent a few weeks trying to figure it out my self before wasting people's time with having to deal with 3rd party SDKs. But honestly, I'm at a loss and can't seem to figure out the root cause of the issue.

Setup:

I have 2 nrf52840 dongles, one setup as a transmitter which simply transmits the same frame once every second. The other is setup as a receiver. Both are configured to operate in coded PHY mode (125Kbps). Without encryption, the receiver is able to receive all frames with CRC_OK events being generated after each frame.

Problem:

When I add encryption and decryption using the CCM peripheral, I run into a strange timing problem. Using a debugger, I can see that the transmitter successfully encrypts the frame and on the receiver side we receive the correct encrypted frame (CRC_OK event generated and the contents of the temp packet match the transmitted frame), however the ENDCRYPT event is generated, the MICSTATUS is CheckFailed. When I inspect the contents of the decrypted packet, I can see that all bytes are correctly decrypted except for the LAST byte (this holds true for the few packet sizes that I tried).

Now here is the interesting part, if instead of the hardcoded PPI channel that triggers the CRYPT task using the ADDRESS event, I use a custom PPI channel to trigger the CRYPT task using the PAYLOAD event (so much later in the packet reception), the frame is decrypted correctly. It seems like the CCM module (even though configured with the same data rate of 125Kbps) is running slightly faster than the RADIO and it's processing the last byte before the RADIO has written it to memory.

I've attached all of the relevant code. Please let me know if you have further questions or are missing important parts.

Parents Reply Children
  • Hi,

    I am sorry for the delay. Have you looked at the low-level implementation for Nordic in the Zephyr LL and used that as a reference? Unfortunately I have not had a chance to dig into it, but I suspect you may be able to find some inspiration in how things are done there.

  • Hey Einar, Sorry for the very late reply. Unfortunately I got Covid and had to self quarantine for a while.

    At last I'm back in the office and managed to do some testing.

    Thanks for sending the link for the Zephyr implementation. I went through it and couldn't spot any differences at first. Then went back to the code and started to experiment some more, until I realized that by setting PCNF0.S1LEN = 0, I could get the decryption to work!.

    Investigating this further and going back to the reference manual, showed that S1 field is marked as "Reserved for future use" in the CCM chapter. I took this as that I can use this field for my own purposes, however this is not the case. When looking at the zephyr code, they also set the S1LEN to either 0 or 8 depending on whether the device supports CTE (which is an extension for direction finding). Since the nrf52840 doesn't support direction finding, I assume the CCM module is not configured in a way to allow the use of the S1 field. If this field is transmitted by the radio, the CCM module will lag behind by 1 byte and thus not complete the decryption in sequence with the Radio module.

    At least that's my theory.

    In any case, I seem to have a good work around for my problem and can continue. Thanks for all of the help!

Related