You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
libwally's optional --enable-mbed-tls backend (HAVE_MBEDTLS_SHA256_H / HAVE_MBEDTLS_SHA512_H) uses the legacy mbedtls_sha256_* / mbedtls_sha512_* APIs and reaches into the private fields of mbedtls_sha256_context / mbedtls_sha512_context. Mbed TLS 4.0 (with cryptography split out into TF-PSA-Crypto 1.0) removes those headers from the public API, and ESP-IDF 6.0 ships Mbed TLS 4.0 with PSA Crypto as the primary cryptography interface. Consumers such as Jade (currently on ESP-IDF v5.5.4) will not be able to build libwally with hardware-accelerated hashing once they move to ESP-IDF 6.x.
This issue proposes adding a PSA Crypto hashing backend alongside the existing mbedtls one, and describes the scope so it can be discussed before a PR.
What breaks
From the TF-PSA-Crypto 1.0 migration guide:
mbedtls/sha256.h and mbedtls/sha512.h "are no longer available" as public headers. They now live under mbedtls/private/, and the guide "strongly recommend[s] against defining MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS or MBEDTLS_ALLOW_PRIVATE_ACCESS in your own application."
mbedtls/md.h remains with reduced functionality, but mbedtls_md_hmac_xxx() is gone.
"PSA is now the preferred interface for computing hashes and HMAC."
From the ESP-IDF 6.0 security migration guide:
"In ESP-IDF v6.0, multiple ESP-IDF components have been migrated from using legacy Mbed TLS cryptography APIs (for example, mbedtls_sha*_*(), mbedtls_md*_*(), etc.) to using the PSA Crypto API."
Hardware acceleration is now exposed "through PSA drivers where available". ESP-IDF master carries PSA drivers for SHA-1/256/512 (both the DMA engines and the ESP32 "parallel engine" with software fallback), including a hash_clone entry point.
psa_crypto_init() must be called before any cryptographic operation; ESP-IDF does this automatically at startup (esp_psa_crypto_init.c, secondary init priority 104).
Note also that the current libwally mbedtls branch is already ESP-IDF specific rather than generic mbedtls: sha256.h / sha512.h include <sdkconfig.h>, <soc/soc_caps.h> and <sha256_alt.h> / <sha512_alt.h>, and hmac.c / internal.c test CONFIG_MBEDTLS_HARDWARE_SHA, MBEDTLS_SHA256_ALT and SOC_SHA_SUPPORT_PARALLEL_ENG.
Reads c.MBEDTLS_PRIVATE(state) to export the SHA-256 midstate; byte-order special case for HW engines
PSA cannot export internal state. Keep the built-in software compression function for this one call (used by Elements asset/token issuance in transaction.c)
src/tx_io.c
TXIO_CTX_CACHEABLE 0 for external hash backends because contexts cannot be copied
With PSA, psa_hash_clone() makes context caching possible again (optional improvement)
src/ccan_config.h
Maps HAVE_MBEDTLS_SHA*_H to CCAN_CRYPTO_SHA*_USE_MBEDTLS
Nothing extra needed; the ccan sources are already included
None
Jade's ESP-IDF component (components/libwally-core/CMakeLists.txt) enables this path with -DHAVE_MBEDTLS_SHA256_H -DHAVE_MBEDTLS_SHA512_H and PRIV_REQUIRES mbedtls, and post-build strips the sha256_init/done / sha512_init/done symbols. Consumers would switch to a single -DHAVE_PSA_CRYPTO_H.
Proposed design
New backend, not a replacement. Add CCAN_CRYPTO_SHA256_USE_PSA / CCAN_CRYPTO_SHA512_USE_PSA next to the OpenSSL and mbedtls branches. Keep --enable-mbed-tls working for ESP-IDF 5.x users for now, and consider deprecating it once Jade and other consumers move to ESP-IDF 6.
sha256_init: op = PSA_HASH_OPERATION_INIT; psa_hash_setup(&op, PSA_ALG_SHA_256).
sha256_update: psa_hash_update.
sha256_done: psa_hash_finish(&op, res->u.u8, 32, &len), psa_hash_abort on failure.
Same for SHA-512 with PSA_ALG_SHA_512.
Keep the sha256() / sha512() one-shot helpers on psa_hash_compute() so the ESP driver's one-shot path (DMA) is used where available.
HMAC. Stop deriving the block size from the context layout. Define the pad size as 64 / 128 for the PSA backend (and ideally for all backends; it is a constant of the hash, not the context). No functional change. Moving HMAC/PBKDF2 to psa_mac_* / PSA_ALG_PBKDF2_HMAC is possible but out of scope; it needs key import per call and offers no benefit unless a platform has hardware HMAC.
Midstate.wally_sha256_midstate() only needs the compression function over whole blocks. With the PSA backend, compile the built-in ccan SHA-256 transform in as a private helper for this call only. Cost is a couple of KB of flash; it removes the byte-order special-casing currently keyed on MBEDTLS_SHA256_ALT / SOC_SHA_SUPPORT_PARALLEL_ENG.
Initialisation. Call psa_crypto_init() from wally_init() when the PSA backend is compiled in. It is idempotent, and ESP-IDF calls it itself at boot, so this only matters for non-ESP builds against TF-PSA-Crypto. Document that consumers who hash before wally_init() must call it themselves.
Context copying.psa_hash_clone() is part of the PSA API and is implemented by the ESP SHA drivers. tx_io.c could set TXIO_CTX_CACHEABLE 1 for PSA via a small sha256_ctx_clone() helper. Optional follow-up; the initial PR can keep caching off as it is for mbedtls today.
Remove ESP-IDF specifics from ccan headers. The PSA branch should not need <sdkconfig.h>, <soc/soc_caps.h> or <sha256_alt.h>; the driver selection happens inside TF-PSA-Crypto.
Estimated size
Roughly 150 to 250 lines changed across about 9 files; no public API or ABI change (the context structs are internal).
Mostly mechanical: the mbedtls branches being replaced are about 20 lines per hash, plus the HMAC and midstate cleanups.
Bindings, wasm and Python are unaffected.
Things to watch
Stack usage.psa_hash_operation_t is a union over all enabled hash contexts (the ESP driver's SHA-512 context alone is about 230 bytes) and is larger than mbedtls_sha256_context. struct sha256_ctx is used on the stack in tx_io.c, elements.c and the HMAC path. See Increased Stack Usage After Migrating to PSA Crypto (mbedTLS 4.x) Mbed-TLS/mbedtls#10537 ("Increased Stack Usage After Migrating to PSA Crypto"). Worth measuring on Jade.
Flash footprint. Espressif reports a 3 to 6 percent increase for their own examples after the PSA move; this is a platform cost, not a libwally one.
Testing. Nothing in libwally's CI exercises --enable-mbed-tls today. A CI job building against TF-PSA-Crypto on Linux (built from source, since distro packages still ship Mbed TLS 2.28 / 3.6) or inside the espressif/idf:v6.0 container would give the new backend real coverage and catch future PSA API churn.
Error handling. The ccan hash API returns void; PSA functions return psa_status_t. Failures (for example the hardware engine unavailable) would have to be surfaced by leaving the context in an aborted state so sha256_done produces an error rather than silently wrong output. This needs a small design decision.
Summary
libwally's optional
--enable-mbed-tlsbackend (HAVE_MBEDTLS_SHA256_H/HAVE_MBEDTLS_SHA512_H) uses the legacymbedtls_sha256_*/mbedtls_sha512_*APIs and reaches into the private fields ofmbedtls_sha256_context/mbedtls_sha512_context. Mbed TLS 4.0 (with cryptography split out into TF-PSA-Crypto 1.0) removes those headers from the public API, and ESP-IDF 6.0 ships Mbed TLS 4.0 with PSA Crypto as the primary cryptography interface. Consumers such as Jade (currently on ESP-IDF v5.5.4) will not be able to build libwally with hardware-accelerated hashing once they move to ESP-IDF 6.x.This issue proposes adding a PSA Crypto hashing backend alongside the existing mbedtls one, and describes the scope so it can be discussed before a PR.
What breaks
From the TF-PSA-Crypto 1.0 migration guide:
mbedtls/sha256.handmbedtls/sha512.h"are no longer available" as public headers. They now live undermbedtls/private/, and the guide "strongly recommend[s] against definingMBEDTLS_DECLARE_PRIVATE_IDENTIFIERSorMBEDTLS_ALLOW_PRIVATE_ACCESSin your own application."mbedtls/md.hremains with reduced functionality, butmbedtls_md_hmac_xxx()is gone.From the ESP-IDF 6.0 security migration guide:
mbedtls_sha*_*(),mbedtls_md*_*(), etc.) to using the PSA Crypto API."hash_cloneentry point.psa_crypto_init()must be called before any cryptographic operation; ESP-IDF does this automatically at startup (esp_psa_crypto_init.c, secondary init priority 104).Note also that the current libwally mbedtls branch is already ESP-IDF specific rather than generic mbedtls:
sha256.h/sha512.hinclude<sdkconfig.h>,<soc/soc_caps.h>and<sha256_alt.h>/<sha512_alt.h>, andhmac.c/internal.ctestCONFIG_MBEDTLS_HARDWARE_SHA,MBEDTLS_SHA256_ALTandSOC_SHA_SUPPORT_PARALLEL_ENG.Where libwally touches mbedtls today
src/ccan/ccan/crypto/sha256/sha256.h,sha256.cstruct sha256_ctxembedsmbedtls_sha256_context;sha256_init/update/donewrapmbedtls_sha256_*psa_hash_operation_t+psa_hash_setup/update/finish/abortsrc/ccan/ccan/crypto/sha512/sha512.h,sha512.csrc/hmac.c+src/hmac.inlsizeof(ctx.SHA_CTX_BUFF)to get the block size, readingc.MBEDTLS_PRIVATE(buffer)PSA_HASH_BLOCK_LENGTH())src/internal.c(sha256_midstate,wally_sha256_midstate)c.MBEDTLS_PRIVATE(state)to export the SHA-256 midstate; byte-order special case for HW enginestransaction.c)src/tx_io.cTXIO_CTX_CACHEABLE 0for external hash backends because contexts cannot be copiedpsa_hash_clone()makes context caching possible again (optional improvement)src/ccan_config.hHAVE_MBEDTLS_SHA*_HtoCCAN_CRYPTO_SHA*_USE_MBEDTLSHAVE_PSA_CRYPTO_H->CCAN_CRYPTO_SHA*_USE_PSAconfigure.ac,README.md--enable-mbed-tlsoption and docs--enable-psa-crypto; documentpsa_crypto_init()requirementsrc/amalgamation/combined.cJade's ESP-IDF component (
components/libwally-core/CMakeLists.txt) enables this path with-DHAVE_MBEDTLS_SHA256_H -DHAVE_MBEDTLS_SHA512_HandPRIV_REQUIRES mbedtls, and post-build strips thesha256_init/done/sha512_init/donesymbols. Consumers would switch to a single-DHAVE_PSA_CRYPTO_H.Proposed design
New backend, not a replacement. Add
CCAN_CRYPTO_SHA256_USE_PSA/CCAN_CRYPTO_SHA512_USE_PSAnext to the OpenSSL and mbedtls branches. Keep--enable-mbed-tlsworking for ESP-IDF 5.x users for now, and consider deprecating it once Jade and other consumers move to ESP-IDF 6.Context type.
struct sha256_ctx { psa_hash_operation_t op; }.sha256_init:op = PSA_HASH_OPERATION_INIT; psa_hash_setup(&op, PSA_ALG_SHA_256).sha256_update:psa_hash_update.sha256_done:psa_hash_finish(&op, res->u.u8, 32, &len),psa_hash_aborton failure.PSA_ALG_SHA_512.sha256()/sha512()one-shot helpers onpsa_hash_compute()so the ESP driver's one-shot path (DMA) is used where available.HMAC. Stop deriving the block size from the context layout. Define the pad size as 64 / 128 for the PSA backend (and ideally for all backends; it is a constant of the hash, not the context). No functional change. Moving HMAC/PBKDF2 to
psa_mac_*/PSA_ALG_PBKDF2_HMACis possible but out of scope; it needs key import per call and offers no benefit unless a platform has hardware HMAC.Midstate.
wally_sha256_midstate()only needs the compression function over whole blocks. With the PSA backend, compile the built-in ccan SHA-256 transform in as a private helper for this call only. Cost is a couple of KB of flash; it removes the byte-order special-casing currently keyed onMBEDTLS_SHA256_ALT/SOC_SHA_SUPPORT_PARALLEL_ENG.Initialisation. Call
psa_crypto_init()fromwally_init()when the PSA backend is compiled in. It is idempotent, and ESP-IDF calls it itself at boot, so this only matters for non-ESP builds against TF-PSA-Crypto. Document that consumers who hash beforewally_init()must call it themselves.Context copying.
psa_hash_clone()is part of the PSA API and is implemented by the ESP SHA drivers.tx_io.ccould setTXIO_CTX_CACHEABLE 1for PSA via a smallsha256_ctx_clone()helper. Optional follow-up; the initial PR can keep caching off as it is for mbedtls today.Remove ESP-IDF specifics from ccan headers. The PSA branch should not need
<sdkconfig.h>,<soc/soc_caps.h>or<sha256_alt.h>; the driver selection happens inside TF-PSA-Crypto.Estimated size
Things to watch
psa_hash_operation_tis a union over all enabled hash contexts (the ESP driver's SHA-512 context alone is about 230 bytes) and is larger thanmbedtls_sha256_context.struct sha256_ctxis used on the stack intx_io.c,elements.cand the HMAC path. See Increased Stack Usage After Migrating to PSA Crypto (mbedTLS 4.x) Mbed-TLS/mbedtls#10537 ("Increased Stack Usage After Migrating to PSA Crypto"). Worth measuring on Jade.--enable-mbed-tlstoday. A CI job building against TF-PSA-Crypto on Linux (built from source, since distro packages still ship Mbed TLS 2.28 / 3.6) or inside theespressif/idf:v6.0container would give the new backend real coverage and catch future PSA API churn.void; PSA functions returnpsa_status_t. Failures (for example the hardware engine unavailable) would have to be surfaced by leaving the context in an aborted state sosha256_doneproduces an error rather than silently wrong output. This needs a small design decision.References
I am happy to open a PR along these lines if the approach is acceptable.