crypto: add Nordic SoftDevice AES-128 ECB backend for nRF5 SDK - #340
buckleypaul wants to merge 1 commit into
Conversation
Legacy nRF5 SDK products already ship a SoftDevice with an AES-128 ECB primitive. Building AES-CTR and CMAC on top of it avoids linking mbedTLS just for Hubble encryption, which matters on flash-constrained nRF52 parts. The SoftDevice only implements AES-128, so the backend refuses to build with 256-bit keys. SoftDevice SVC calls escalate to a HardFault when made at or above the SVC priority, so the backend checks the execution priority first and returns -EACCES instead of crashing. The calling-context rules are documented in the bare-metal quickstart. The backend is intentionally not exposed via Kconfig: nRF Connect SDK builds should keep using PSA. Bare-metal builds select it by compiling src/crypto/nrf_softdevice.c. Signed-off-by: Paul Buckley <paul@hubble.com>
| ``src/crypto/nrf_softdevice.c`` builds AES-CTR and AES-CMAC on the | ||
| SoftDevice's AES-128 ECB (``sd_ecb_blocks_encrypt``). It is intended for the | ||
| legacy nRF5 SDK only and works with the nRF52 SoftDevices (S112, S113, S122, | ||
| S132, S140). nRF51 devices are not supported. nRF Connect SDK builds should use |
There was a problem hiding this comment.
Does this work with S3XX SoftDevices (BLE + ANT)?
There was a problem hiding this comment.
I'm not sure. I would cross that bridge if it came - I don't think that's a particularly common choice.
| return NVIC_GetPriority((IRQn_Type)((int32_t)ipsr - 16)) > svc_prio; | ||
| } | ||
|
|
||
| static int _ecb_encrypt(const uint8_t key[HUBBLE_AES_BLOCK_SIZE], |
There was a problem hiding this comment.
I have found more than 1 instance where ECB exists, but CMAC and/or CTR don't (some Arduinos, Renesas).
What do you think about some ecb.c crypto implementation that is effectively this file, but it calls hubble_ecb_encrypt() which would live in its own file ecb_nrf_softdevice.c or ecb_renesas_da14xxx.c.
I see good value in making lines 94 to the end of the file 1 shared file, and everything above it modular for various devices
There was a problem hiding this comment.
I'll leave that to you and @ceolin - it might make sense and since ECB is needed for BLE it might make things a bit more portable? This isn't my area of expertise though.
Summary
Adds
src/crypto/nrf_softdevice.c, a crypto backend for legacy nRF5 SDK products that builds AES-CTR and AES-CMAC on the SoftDevice's AES-128 ECB primitive (sd_ecb_blocks_encrypt). Products that already ship a SoftDevice can then use Hubble encryption without linking mbedTLS, which saves flash on constrained nRF52 parts.#errorunlessCONFIG_HUBBLE_KEY_SIZEis 16. nRF51 is also rejected at compile time.-EACCESinstead of crashing.Testing
nrf.h/nrf_soc.hwere stubbed and the ECB call was backed by OpenSSL.CONFIG_HUBBLE_NETWORK_KEY_256fails at compile time, as intended.Footprint vs mbedTLS
These are the flash, RAM, stack and heap that the Hubble SDK adds to an nRF5 SDK firmware: the core (
hubble.c,hubble_ble.c,hubble_crypto.c), the crypto backend, the mbedTLS library objects, and any C library code they pull in. The rest of the application is not counted.-Os-O3hubble_ble_advertise_get(-Os)Compared with mbedTLS 2.16.10 with AES tables in flash (what the reference app currently ships):
-Os(−75%) and 7,264 B less at-O3(−54%).Compared with mbedTLS 2.16.10 with AES tables in RAM:
-Os.Methodology
hubble-reference-nordic-softdevicebuilt for nRF52840 / S140 (BOARD=pca10056) against this branch (HUBBLE_SDK_ROOT=<this tree>).-Osand-O3.MBEDTLS_AES_C,MBEDTLS_CIPHER_C,MBEDTLS_CMAC_CandMBEDTLS_CIPHER_MODE_CTR.MBEDTLS_AES_ROM_TABLESandMBEDTLS_AES_FEWER_TABLES. "AES tables in RAM" leaves both out.aes.c,cipher.c,cipher_wrap.c,cmac.candplatform_util.c. 3.6.6 also needsconstant_time.c..text+.rodata+.datainitialisers for flash,.data+.bssfor RAM).arm-none-eabi-sizeon the same app with the SDK stubbed out.malloc/free/memcpyare already linked in through the app'sprintf, so they aren't charged to any backend. mbedTLS addscalloc(76 B). An app with noprintfwould pay about 520 B more flash for the mbedTLS variants.-fstack-usage/-fcallgraph-info=su, plus reading the newlib function prologues in the disassembly.cipher_wrapfunction pointers were resolved by hand.cipher_setupandcmac_startsallocate the AES context (280 B) and the CMAC context (36 B). Both are freed beforehubble_crypto_cmac()returns. newlib-nano's per-allocation overhead is not included.-O3is larger: GCC unrolls the loops inhubble_crypto.cand in the backend.