feat: use nrf52 hardware crypto where we can - #2824
Conversation
While working on some sensor code implementations, I ran into some hard crashes that root-caused to the 4KB loop task stack being exhausted. Looking for various optimization schemes resulted in this relatively low-lift fix. RAK3401 and RAK4631 both support hardware crypto. Rather than loading in one of the two software crypto libs, we can just use the onboard hardware. This is faster, should consume less power, and in testing used a scant up to 700 bytes in the run loop vs 2.5-3KB per advert. This change **only** affects advert verification processing, which currently consumes a significant chunk of the 4KB run loop. I figured such a change should likely be implemented in phases. After soaking, this hardware crypto verification process could be implemented across the entire MeshCore cryptographic function on RAK nodes. Also possible other nodes have available hardware crypto, however, I have not checked, so future improvements may also exist there. Tested on: - RAK3401 RAK 1W - RAK4631 19001
Tested Heltec t096 and Seeed t1000-e, both support this hardware feature.
|
Shouldn't this work on every NRF52840? |
|
@lbibass very likely! Although anything's possible to break with different hardware designs. So I added types that I could confirm work thus far. If you or anyone else can confirm this works on other node types, happy to add them. |
|
This is really cool. I'll try to remember to give it a test on some other boards and see how it plays out. |
After soaking for a bit on the adverts without issue on multiple nodes, I added more hardware crypto. Supported nodes is unchanged in this PR addition, but if others can verify, they can easily be added. Some info on the CC310: https://docs.nordicsemi.com/r/bundle/ps_nrf9151/page/cryptocell.html **Added:** - AES-128 packet encryption/decryption now use hardware crypto - HMAC-SHA-256 authentication now uses hardware crypto - ACK hash computation and channel ID derivation now use hardware crypto - RNG (random number generator) now uses hardware crypto rather than radio noise + weak software RNG (which can have issues if there's no surrounding radio noise.) NIST SP 800-90B certified. - Runs hardware self-tests on startup - Runs continuous health tests during operation - Uses thermal noise/shot noise for randomness **Unchanged:** - calcSharedSecret remains software - it would be a split hw/sw solution and added complexity for likely not a lot of gains. This only happens when establishing a new contact, so not too frequent to be worth it. - ed25519_create_keypair remains software. This is only called when a node is first initialized. It does use the hardware RNG change, however, so better randomization. Tested on (so far): - Heltec t096 Build test on: - Heltec t096 companion ble - t1000e companion ble - RAK 4631 repeater - RAK 3401 companion BLE - Heltec v3 companion wifi
|
I just wanted to say that I flashed my RAK4631 companion and RAK3401 repeater with this code - I don’t see any problems. Nice PR! |
for hardware encryption. Now `USE_CC310_HW_CRYPTO`
|
Also tested with WisMesh Tag - I don’t see any problems. |
|
Tested on Xiao nRF52840 (Repeater) - adverts sent, parse successfully on the receiving side. I'll test some more boards tomorrow if I can get time. Great work :) |
|
Worth noting - given the CC310 is in the nRF52840 MCU itself (and much much more), with enough board tests I think we shouldn't gate it by board and have it globally enabled. The maintainers might have a different view, but to keep things consistent that'd be my $0.02. Further tested boards - all OK:
Tests performed:
Companion BLE:
|
Select nodes had this flag enabled, testing by the community and hardware specs indicate this can be enabled global for all node types using this chipset. Any nodes down the line that may be quirky can be individually disabled with `-U USE_CC310_HW_CRYPTO`.
|
@entr0p1 very good point, and all the testing thus far (awesome y'all!) seems to indicate this should work just dandy. I pushed a change that removes the individual board-type enabled flags and enabled globally for nrf52. If a specific board ends up having issues, that board type can have it disabled with |
|
Has anyone actually benchmarked if this is faster? Clocking extra silicon, the extra flash consumption, it might not be worth it. |
|
@Avamander I didn’t compare, but maybe this paper will answer your questions https://ewsn.org/file-repository/ewsn2021/Article8.pdf |
|
@Avamander the advantages aren't just about potential speed. It is also about reducing the footprint of the processing run loop. The run loop is only 4KB of memory on RAK nodes and evicting encryption to hardware crypto removes ~2.5KB of memory consumption from the loop. (The software crypto advert processing alone I tested as consuming 2.5KB-3KB per advert.) This will increase node stability, especially on configs like RAK + sensors that may increase run loop consumption. Using hardware crypto (especially the RNG) also produces more durable encryption. tl;dr: improves stability first, better randomness, theoretical performance and/or power improvements, but the first two are good enough to warrant the effort. |
|
Agreed. I can't speak on behalf of the maintainers, but from my perspective, the more we offload to hardware the better. Especially if there's nothing to lose by doing it. On the memory usage, I suspect we have very little headroom as it is so if we're talking nearly 50% of it being freed by this change, that's not insignificant and should be prioritised. |
|
@IoTThinks Sorry to bother you, but maybe you might be interested in this PR for your powersaving fork? Perhaps you would be interested in assessing the impact of this code on energy consumption? |
|
@Magalex2x14 Let me test this PR on my RAK4631 and PowerSaving 16.1 this weekend. |
|
Thanks for this. Good work. |
Upstream dev: 01a4556..626a82f (8 commits) - Merge pull request meshcore-dev#2824 from NickDunklee/rak-advert-hw-encryption - Global nrf52 hardware crypto, removed from individual configs - Minor ifdef rename as it now covers more than just Ed25519 for hardware encryption. Now USE_CC310_HW_CRYPTO - feat: add more crypto - Added Heltec t096 and seeed t1000-e - feat: use RAK hardware crypto on advert processing Clean auto-merge (no conflicts). MQTT additions preserved.
|
@NickDunklee just wanted to throw some data in the mix to support this. Measured in a lab setting with low traffic (only strong so very little CRC errors involved). I'm running some stat probes at various points of operation in the stack, so was able to capture these in greater detail. Everything below is from actual measurements on hardware with real packets from the live mesh.
Columns run left-to-right in time: boot -> verify -> lifetime worst:
Timing-wise, it also halves the processing time:
It's not about it being "faster" per-se; what it really means (I think) is less time we're unable to process another packet because we're processing a Epic stuff mate. |
|
Exiting the cli stack and then running the command requested is another way I fixed this. I'll get a pull request for it. Setting up a huge region I was able to trigger a stack overflow. |
Hi @Magalex2x14 We may need PPK2 to see the realtime difference. |
|
@IoTThinks Thank you very much! |
I have a PPK2. I can look into doing some tests with one of my spare Heltec T114 later today. |
|
Thanks for the detailed test results @entr0p1 - that's great to see, especially the timing acceleration! I need to up my lab testing game. Thanks to everyone else that helped test this too. It was great to have such concrete feedback that it wouldn't break things. And thanks to @ripplebiz and team for allowing it into the codebase! |
These are the results of the test with the hardware crypto. Repeater powersaving is enabled, and I am running the most current dev commit, 8b9bee3 The first image is with it enabled, processing a flood advert from my local companion. in the main platform.io file, USE_CC310_HW_CRYPTO is set to 1. In this second image, I set USE_CC310_HW_CRYPTO to 0, and recompiled and reflashed. I sent another advert from the same companion. there is practically zero difference between the two in terms of power consumption, though it appears the time spent processing the packet itself is in fact lowered with the hardware crypto enabled. This lines up with expected behavior. Great job on this PR! |
|
seems that One of the issues triggered by talking it every time (apart from the big overhead it adds) is that it resets RNG ... To me, the use of hw functions should be reviewed by a specialist in hw crypto (at least for the correct use of HW RNG, which can be tricky) |
This is very interesting. I went and benchmarked the Unfortunately the opaque proprietary CC310 blob doesn't provide access to the low-level operations the CryptoCell can do, so that 114ms probably can't be improved upon by a lot. But I'm sure something similar is wasted there as well. |
…er adoptiert) Merge companion-v1.17.0 in den DL9SAU-Fork. Core-Protokoll 0-Diff (kein Wire-Bruch). Config (Weg B -- binaer behalten, JSON meshcore-dev#2982 NICHT adoptiert): - NodePrefs.h / DataStore.{cpp,h} / MyMesh.h savePrefs auf --ours (2-arg, unser feldweises Binaerformat). ConfigSerializer.* liegt ungenutzt (nur native-Test). Bestandsgeraete: null Migration (/new_prefs binaer weiter). - MyMesh.cpp: unsere Logik (client_repeat statt isRepeatEn/setRepeatEn, memset+ Sentinels, cad_enabled, 2-arg loadPrefs). Upstreams MCU-Temperatur-Telemetrie (onContactRequest + handleCmdFrame) BEHALTEN. Adoptiert: - interface_manager (MultiSerialInterface, multi-interface: USB-CLI + BLE-App gleichzeitig). main.cpp setup()/loop() rekonstruiert mit unseren Boot-Anpassungen (DIAG / earlyShutdownCheck / OTA-Skip / configureBatteryWake + applyShutdownPendingCheck NACH BLE = SoftDevice-up). - esp32 SerialBLEInterface: FreeRTOS thread-safe recv-Queue (meshcore-dev#3007) + unsere Diagnostik/Overflow-Counter + FRAME_QUEUE_SIZE 16. - USE_CC310_HW_CRYPTO (meshcore-dev#2824), listen-before-talk configSideDetectors (meshcore-dev#3036/meshcore-dev#2977). Auto-Merge-Fixes (Upstream-Refactors trafen unsere Andock-Zeilen): - AbstractUITask _serial -> _interfaceManager (ui-orig / ui-tiny). - DisplayDriver enum Color -> UIColor-Klasse (meshcore-dev#3034): YELLOW -> warning_txt (ui-new). CI: action.yml unsere -DL9SAU-Prefix-Strip + upstream dispatch-branch; build.sh unser Build-Tracking (kein set -e) + upstream Matrix-get-*-firmwares-Commands. FIRMWARE_VERSION -> v1.17.0-DL9SAU (dl9sau_version.py-Sync beim Release). Builds gruen: t1000e_companion_radio_ble (nRF52), Heltec_v3_companion_radio_ble (esp32). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@ripplebiz I am really upset that this got merged.
IMHO The only thing to keep is the HW acceleration of ed25519.verify(), everything else should be reverted (or at least benchmarked). This PR tries to do too many things at once and should never have been merged. |
| #ifdef USE_CC310_HW_CRYPTO | ||
| // CC310 TRNG is higher quality and environment-independent vs radio RSSI noise. | ||
| nRFCrypto.begin(); | ||
| nRFCrypto.Random.generate(dest, (uint16_t)sz); |
There was a problem hiding this comment.
'cause yeah... it's well known that nothing could ever go wrong. Why would you ever check the return code?
https://github.com/adafruit/Adafruit_nRFCrypto/blob/master/src/nRFCrypto_Random.cpp#L87
https://github.com/DiUS/nRF5-SDK-15.3.0-reduced/blob/master/components/libraries/crypto/backend/cc310/cc310_backend_rng.c
|
Let me take note of the effect of this PR. As a plan B, we can always comment this to disable this feature. -D USE_CC310_HW_CRYPTO=1 |


First PR, advert-only
While working on some sensor code implementations, I ran into some hard crashes that root-caused to the 4KB loop task stack being exhausted.
Looking for various optimization schemes resulted in this relatively low-lift fix. RAK3401 and RAK4631 both support hardware crypto. Edit: Heltec t096 and Seeed t1000-e support this as well, so I have tested them and added them.
Rather than loading in one of the two software crypto libs, we can just use the onboard hardware. This is faster, should consume less power, and in testing used a scant up to 700 bytes in the run loop vs 2.5-3KB per advert.
This change only affects advert verification processing, which currently consumes a significant chunk of the 4KB run loop.
I figured such a change should likely be implemented in phases.
After soaking, this hardware crypto verification
process could be implemented across the entire MeshCore cryptographic function on RAK nodes. Also possible other nodes have available hardware crypto, however, I have not checked, so future improvements may also exist there.
Tested on:
Addendum, more crypto added:
feat: add more crypto
After soaking for a bit on the adverts without issue on multiple nodes, I added more hardware crypto. While I haven't a chance to do a debug comparison of the run loop like I did with the advert code, moving more crypto out of software and into hardware should further reduce the memory footprint in the run loop by a couple to three hundred bytes which should contribute to overall stability, especially in devices with sensors/GPS consuming more run loop memory. (Possibly some minor performance and/or power improvements.)
Supported nodes is unchanged in this PR addition, but if others can verify, they can easily be added.
Some info on the CC310: https://docs.nordicsemi.com/r/bundle/ps_nrf9151/page/cryptocell.html
Added:
Unchanged:
Tested on (so far):
@Magalex2x14 tested on:
@entr0p1 tested on:
Build test on: