(Generated by Fable.)
Crypto acceleration notes: nRF52 (and RP2040/RP2350)
Research notes for extending mbedtls-rs-sys' hooking mechanism beyond the ESP32 family.
Status: research/decision record (2026-07); no nRF/RP backend implemented yet.
TL;DR
On nRF52, only P-256 is worth accelerating, and the best vehicle is not the CC310
crypto engine but hand-written Cortex-M4 assembly (Emill/P256-Cortex-M4, wrapped for
Rust by ycrypto/p256-cortex-m4), plugged in behind ECDSA/ECDH-level _ALT hooks.
The CC310's measured P-256 performance is within what the assembly achieves on the CPU
itself, so the hardware buys nothing where it matters — a conclusion Nordic's own Matter
stack implicitly agrees with (it runs all Matter crypto in software on nRF52).
What is worth accelerating
Matter/Thread session establishment (PASE/CASE, commissioning, ECJPAKE joining) is
dominated by P-256 point multiplications: roughly 6–12 per handshake, at tens to a few
hundred ms each in portable software on a 64 MHz Cortex-M4. Everything else is noise:
- AES-CCM / SHA-256 per packet is sub-millisecond in software — irrelevant next to
radio/network latency.
- The documented ECB peripheral (AES-128, encrypt-only, ~7.2 µs/block) is roughly at
parity with good software AES — a marginal win at best.
- The CCM peripheral is hard-wired to the BLE on-air frame format (1-byte AAD, 4-byte
MIC) and cannot do Matter-style CCM (13-byte nonce, arbitrary AAD).
- The RNG/TRNG is trivially available and already the right entropy source.
The options, ranked
1. p256-cortex-m4 assembly behind ECDSA/ECDH _ALT hooks (recommended)
Emill/P256-Cortex-M4: MIT-licensed, ~8.9 kB code, ≤2 kB stack, constant-time
(constant code-access pattern; optional constant RAM-access mode). Measured on nRF52840
@ 64 MHz: keygen 5.1 ms, ECDSA sign 5.9 ms, verify 15.3 ms, ECDH 14.2 ms — i.e. it
matches or beats the CC310 hardware (~18–21 ms/op end-to-end, measured via wolfSSL and
the EWSN 2021 study).
Why it is this fast: the inner loops are hand-scheduled around the ARMv7E-M DSP
UMAAL/UMULL instructions, keeping the 256-bit operands register-resident. Compilers
do not generate comparable code from portable C/Rust — this is why no pure-Rust
implementation (RustCrypto p256 included) is in the same class.
Integration path in mbedtls-rs-sys: the vendored Espressif fork supports the upstream
MBEDTLS_ECDSA_SIGN_ALT / MBEDTLS_ECDSA_VERIFY_ALT / MBEDTLS_ECDH_COMPUTE_SHARED_ALT
(and ECDSA_GENKEY_ALT) options — the same hook pattern already used for SHA/AES/ECP/exp-mod
can be extended with these.
Caveats:
- The public API is protocol-level only (keygen/sign/verify/ECDH + point compression).
No raw k*P / point addition is exposed, so SPAKE2+/ECJPAKE (which need arbitrary
point math with full point results) stay on the software path unless the internal
scalar-mult is exposed via a small upstream patch. CASE and cert validation get the
full benefit; PASE only partially.
- Maintenance status: dormant since ~2021 (the Rust wrapper is
0.1.0-alpha.5). This is
less alarming than it sounds for a dependency-free, ISA-frozen, finished artifact — but
it has had no formal verification and no public third-party audit.
- Verification status (better than expected): the upstream repo ships a Wycheproof-based
test harness in-tree (testgen.js pulls the ecdsa_secp256r1*/ecdh_secp256r1* vector
sets and contains an independent slow reference implementation for differential test
generation; runs on nRF52840). The Rust wrapper additionally cross-tests keygen/ECDH/
sign/verify against RustCrypto p256. Zero correctness/timing issues filed in 5+ years
while shipping in FIDO2 security keys (SoloKeys Solo 2, Nitrokey 3 via Trussed).
Remaining diligence before adoption: regenerate the vectors against current
C2SP/wycheproof and re-run on the exact GCC-converted build we'd ship; the
constant-time claim still rests on design-by-construction + code review.
2. Status quo (portable software)
Matches the reference platform behavior: Nordic's own Matter stack (NCS) sets
PSA_CRYPTO_DRIVER_CC3XX default n on nRF52/53 and runs everything — including
SPAKE2+/ECJPAKE — on the nrf_oberon software driver, keeping CC310 only for the TRNG
(and AEAD key derivation). rs-matter with either software backend is ~5–10× slower than
NCS's Oberon on P-256 (Oberon is heavily optimized closed-source C); cheap partial
remedy for the mbedtls backend: raise MBEDTLS_ECP_WINDOW_SIZE (upstream default is 2)
for ~1.5–2× at a couple kB of heap.
3. Nordic binary blobs (nrf_oberon / nrf_cc3xx) — not recommended
Legally redistributable (Nordic-5-Clause permits binary redistribution with the license
text; the nrfxlib-sys crate is live precedent) and ocrypto 3.0.19 is even built against
Mbed TLS 3.6.5 (the exact version vendored here), with SPAKE2+/ECJPAKE P-256 APIs. But:
the APIs are protocol-level (don't fit the ecp_mul hook granularity), the mbedtls _ALT
shim layer was removed upstream (NCS is PSA-only now), the license restricts use to Nordic
silicon, and it taints an otherwise fully-open stack.
4. CC310 register-level drivers — now possible, poor ROI
The historical "only the ENABLE register is documented" situation is over: current Nordic
SVDs (nrfx, mirrored in the BSD-3 nrf-pac) expose the full CC_AES / CC_HASH / CC_PKA /
CC_RNG / CC_CTL register blocks, the live nRF52840 product spec documents them, and
embassy-nrf already ships a register-level CryptoCell TRNG driver. So blob-free drivers
are possible — but the engine only wins big on bulk SHA-256 (~30×) and bulk AES (~9×),
neither of which matters for Matter; its P-256 (~20 ms/op incl. driver overhead, blocking,
single-context, RAM-only inputs) does not beat option 1; and a PKA (EC engine) driver
would be a reverse-engineering project. The nRF54L's CRACEN is the properly-documented
future (full SVD + source-available Nordic drivers).
RP2040 / RP2350 (Pico) portability
- RP2040 (Cortex-M0+,
thumbv6m): no. The assembly technique fundamentally does not
port: ARMv6-M has no long-multiply instructions at all (no UMULL/UMLAL/UMAAL,
only 32×32→32 MULS), and the whole design is built around UMAAL chains. RP2040 also
has zero crypto peripherals. Portable software (RustCrypto / p256-m class) is the only
option; the 133 MHz+ clock partially compensates. mbedtls-rs-sys already ships
thumbv6m-none-eabi prebuilts for exactly this path.
- RP2350 (Pico 2, Cortex-M33): yes, most likely. Its M33 cores ship with the DSP
extension (confirm in the datasheet), which is an explicitly supported target of the
assembly. RP2350 additionally has a hardware SHA-256 accelerator and TRNG, so it
would merit a SHA hook backend as well.
Reference numbers (nRF52840 @ 64 MHz unless noted)
| Engine |
ECDSA sign |
ECDSA verify |
ECDH |
| P256-Cortex-M4 asm (measured, author) |
5.9 ms |
15.3 ms |
14.2 ms |
| CC310 hardware (measured, wolfSSL/EWSN) |
~20 ms |
~21 ms |
~18 ms |
| nrf_oberon (estimate; no public table) |
~10–40 ms/op |
|
|
| mbedTLS software, default knobs |
~100–300 ms/op |
|
|
RustCrypto p256 (no published M4 numbers) |
portable-C class, as above |
|
|
| p256-m (size-first C, M4 @ 100 MHz) |
155 ms |
309 ms |
144 ms |
Sources
(Generated by Fable.)
Crypto acceleration notes: nRF52 (and RP2040/RP2350)
Research notes for extending
mbedtls-rs-sys' hooking mechanism beyond the ESP32 family.Status: research/decision record (2026-07); no nRF/RP backend implemented yet.
TL;DR
On nRF52, only P-256 is worth accelerating, and the best vehicle is not the CC310
crypto engine but hand-written Cortex-M4 assembly (Emill/P256-Cortex-M4, wrapped for
Rust by ycrypto/p256-cortex-m4), plugged in behind ECDSA/ECDH-level
_ALThooks.The CC310's measured P-256 performance is within what the assembly achieves on the CPU
itself, so the hardware buys nothing where it matters — a conclusion Nordic's own Matter
stack implicitly agrees with (it runs all Matter crypto in software on nRF52).
What is worth accelerating
Matter/Thread session establishment (PASE/CASE, commissioning, ECJPAKE joining) is
dominated by P-256 point multiplications: roughly 6–12 per handshake, at tens to a few
hundred ms each in portable software on a 64 MHz Cortex-M4. Everything else is noise:
radio/network latency.
parity with good software AES — a marginal win at best.
MIC) and cannot do Matter-style CCM (13-byte nonce, arbitrary AAD).
The options, ranked
1.
p256-cortex-m4assembly behind ECDSA/ECDH_ALThooks (recommended)Emill/P256-Cortex-M4: MIT-licensed, ~8.9 kB code, ≤2 kB stack, constant-time
(constant code-access pattern; optional constant RAM-access mode). Measured on nRF52840
@ 64 MHz: keygen 5.1 ms, ECDSA sign 5.9 ms, verify 15.3 ms, ECDH 14.2 ms — i.e. it
matches or beats the CC310 hardware (~18–21 ms/op end-to-end, measured via wolfSSL and
the EWSN 2021 study).
Why it is this fast: the inner loops are hand-scheduled around the ARMv7E-M DSP
UMAAL/UMULLinstructions, keeping the 256-bit operands register-resident. Compilersdo not generate comparable code from portable C/Rust — this is why no pure-Rust
implementation (RustCrypto
p256included) is in the same class.Integration path in
mbedtls-rs-sys: the vendored Espressif fork supports the upstreamMBEDTLS_ECDSA_SIGN_ALT/MBEDTLS_ECDSA_VERIFY_ALT/MBEDTLS_ECDH_COMPUTE_SHARED_ALT(and
ECDSA_GENKEY_ALT) options — the same hook pattern already used for SHA/AES/ECP/exp-modcan be extended with these.
Caveats:
No raw
k*P/ point addition is exposed, so SPAKE2+/ECJPAKE (which need arbitrarypoint math with full point results) stay on the software path unless the internal
scalar-mult is exposed via a small upstream patch. CASE and cert validation get the
full benefit; PASE only partially.
0.1.0-alpha.5). This isless alarming than it sounds for a dependency-free, ISA-frozen, finished artifact — but
it has had no formal verification and no public third-party audit.
test harness in-tree (
testgen.jspulls theecdsa_secp256r1*/ecdh_secp256r1*vectorsets and contains an independent slow reference implementation for differential test
generation; runs on nRF52840). The Rust wrapper additionally cross-tests keygen/ECDH/
sign/verify against RustCrypto
p256. Zero correctness/timing issues filed in 5+ yearswhile shipping in FIDO2 security keys (SoloKeys Solo 2, Nitrokey 3 via Trussed).
Remaining diligence before adoption: regenerate the vectors against current
C2SP/wycheproof and re-run on the exact GCC-converted build we'd ship; the
constant-time claim still rests on design-by-construction + code review.
2. Status quo (portable software)
Matches the reference platform behavior: Nordic's own Matter stack (NCS) sets
PSA_CRYPTO_DRIVER_CC3XX default non nRF52/53 and runs everything — includingSPAKE2+/ECJPAKE — on the nrf_oberon software driver, keeping CC310 only for the TRNG
(and AEAD key derivation). rs-matter with either software backend is ~5–10× slower than
NCS's Oberon on P-256 (Oberon is heavily optimized closed-source C); cheap partial
remedy for the mbedtls backend: raise
MBEDTLS_ECP_WINDOW_SIZE(upstream default is 2)for ~1.5–2× at a couple kB of heap.
3. Nordic binary blobs (nrf_oberon / nrf_cc3xx) — not recommended
Legally redistributable (Nordic-5-Clause permits binary redistribution with the license
text; the
nrfxlib-syscrate is live precedent) and ocrypto 3.0.19 is even built againstMbed TLS 3.6.5 (the exact version vendored here), with SPAKE2+/ECJPAKE P-256 APIs. But:
the APIs are protocol-level (don't fit the
ecp_mulhook granularity), the mbedtls_ALTshim layer was removed upstream (NCS is PSA-only now), the license restricts use to Nordic
silicon, and it taints an otherwise fully-open stack.
4. CC310 register-level drivers — now possible, poor ROI
The historical "only the ENABLE register is documented" situation is over: current Nordic
SVDs (nrfx, mirrored in the BSD-3 nrf-pac) expose the full CC_AES / CC_HASH / CC_PKA /
CC_RNG / CC_CTL register blocks, the live nRF52840 product spec documents them, and
embassy-nrf already ships a register-level CryptoCell TRNG driver. So blob-free drivers
are possible — but the engine only wins big on bulk SHA-256 (~30×) and bulk AES (~9×),
neither of which matters for Matter; its P-256 (~20 ms/op incl. driver overhead, blocking,
single-context, RAM-only inputs) does not beat option 1; and a PKA (EC engine) driver
would be a reverse-engineering project. The nRF54L's CRACEN is the properly-documented
future (full SVD + source-available Nordic drivers).
RP2040 / RP2350 (Pico) portability
thumbv6m): no. The assembly technique fundamentally does notport: ARMv6-M has no long-multiply instructions at all (no
UMULL/UMLAL/UMAAL,only 32×32→32
MULS), and the whole design is built aroundUMAALchains. RP2040 alsohas zero crypto peripherals. Portable software (RustCrypto / p256-m class) is the only
option; the 133 MHz+ clock partially compensates.
mbedtls-rs-sysalready shipsthumbv6m-none-eabiprebuilts for exactly this path.extension (confirm in the datasheet), which is an explicitly supported target of the
assembly. RP2350 additionally has a hardware SHA-256 accelerator and TRNG, so it
would merit a SHA hook backend as well.
Reference numbers (nRF52840 @ 64 MHz unless noted)
p256(no published M4 numbers)Sources
config/nrfconnect/chip-module/Kconfig.defaultsinhttps://github.com/project-chip/connectedhomeip and
https://github.com/nrfconnect/sdk-nrf/blob/main/doc/nrf/protocols/matter/end_product/security.rst