From ba33b6bf13c1666777763c7029da6caa8800b677 Mon Sep 17 00:00:00 2001 From: silabs-HarshaK Date: Mon, 30 Mar 2026 23:56:07 +0530 Subject: [PATCH] [crypto] update mbedtls psa crypto context structs (#12699) This commit hardens OpenThread against Mbed TLS/PSA ABI variation across customer configurations. Because Mbed TLS/PSA does not guarantee a stable ABI across build-time option sets, application-level config changes can alter crypto context struct size/layout, causing precompiled stack libraries to assume incompatible memory layouts and potentially fail at runtime. To address this, this PR makes the following changes: 1. Add OPENTHREAD_CONFIG_PLATFORM_ALLOCS_CRYPTO_CONTEXTS to let platforms allocate/manage crypto contexts when required, while preserving existing static context storage as the default path. 2. Update AES/HKDF/HMAC/SHA256 context initialization to support both platform-managed and internally managed context memory models. --- include/openthread/instance.h | 2 +- include/openthread/platform/crypto.h | 18 ++++++++++++++++-- src/core/config/crypto.h | 9 +++++++++ src/core/crypto/aes_ecb.cpp | 5 +++++ src/core/crypto/aes_ecb.hpp | 2 ++ src/core/crypto/hkdf_sha256.cpp | 5 +++++ src/core/crypto/hkdf_sha256.hpp | 2 ++ src/core/crypto/hmac_sha256.cpp | 5 +++++ src/core/crypto/hmac_sha256.hpp | 2 ++ src/core/crypto/sha256.cpp | 6 ++++++ src/core/crypto/sha256.hpp | 2 ++ 11 files changed, 55 insertions(+), 3 deletions(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 1fbce5816..9a3e0c761 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (586) +#define OPENTHREAD_API_VERSION (587) /** * @addtogroup api-instance diff --git a/include/openthread/platform/crypto.h b/include/openthread/platform/crypto.h index 852da7ad8..a7fbc7646 100644 --- a/include/openthread/platform/crypto.h +++ b/include/openthread/platform/crypto.h @@ -123,6 +123,9 @@ typedef struct otCryptoKey * @struct otCryptoContext * * Stores the context object for platform APIs. + * + * If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, the platform allocates and populates this. + * Otherwise OpenThread core allocates and populates this. */ typedef struct otCryptoContext { @@ -325,6 +328,9 @@ void otPlatCryptoFree(void *aPtr); * @retval OT_ERROR_FAILED Failed to initialize HMAC operation. * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL * + * @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform. + * Otherwise OpenThread core allocates and populates it. + * * @note The platform driver shall point the context to the correct object such as psa_mac_operation_t or * mbedtls_md_context_t. */ @@ -389,6 +395,9 @@ otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, s * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL * @retval OT_ERROR_NO_BUFS Cannot allocate the context. * + * @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform. + * Otherwise OpenThread core allocates and populates it. + * * @note The platform driver shall point the context to the correct object such as psa_key_id * or mbedtls_aes_context_t. */ @@ -435,10 +444,13 @@ otError otPlatCryptoAesFree(otCryptoContext *aContext); * * @param[in] aContext Context for HKDF operation. * - * @retval OT_ERROR_NONE Successfully Initialised AES operation. - * @retval OT_ERROR_FAILED Failed to Initialise AES operation. + * @retval OT_ERROR_NONE Successfully Initialised HKDF operation. + * @retval OT_ERROR_FAILED Failed to Initialise HKDF operation. * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL * + * @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform. + * Otherwise OpenThread core allocates and populates it. + * * @note The platform driver shall point the context to the correct object such as psa_key_derivation_operation_t * or HmacSha256::Hash */ @@ -499,6 +511,8 @@ otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext); * @retval OT_ERROR_FAILED Failed to initialise SHA-256 operation. * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL * + * @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform. + * Otherwise OpenThread core allocates and populates it. * * @note The platform driver shall point the context to the correct object such as psa_hash_operation_t * or mbedtls_sha256_context. diff --git a/src/core/config/crypto.h b/src/core/config/crypto.h index a3607b670..15ae293e4 100644 --- a/src/core/config/crypto.h +++ b/src/core/config/crypto.h @@ -59,6 +59,15 @@ /** Use platform provided crypto library */ #define OPENTHREAD_CONFIG_CRYPTO_LIB_PLATFORM 2 +/** + * @def OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT + * + * Define to 1 to enable the platform to allocate crypto operation context. + */ +#ifndef OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT +#define OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT 0 +#endif + #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PLATFORM /** diff --git a/src/core/crypto/aes_ecb.cpp b/src/core/crypto/aes_ecb.cpp index 70966e5ac..d06970888 100644 --- a/src/core/crypto/aes_ecb.cpp +++ b/src/core/crypto/aes_ecb.cpp @@ -40,8 +40,13 @@ namespace Crypto { AesEcb::AesEcb(void) { +#if OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT + mContext.mContext = nullptr; + mContext.mContextSize = 0; +#else mContext.mContext = mContextStorage; mContext.mContextSize = sizeof(mContextStorage); +#endif SuccessOrAssert(otPlatCryptoAesInit(&mContext)); } diff --git a/src/core/crypto/aes_ecb.hpp b/src/core/crypto/aes_ecb.hpp index ef29ef2fa..54f734783 100644 --- a/src/core/crypto/aes_ecb.hpp +++ b/src/core/crypto/aes_ecb.hpp @@ -86,7 +86,9 @@ public: private: otCryptoContext mContext; +#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT OT_DEFINE_ALIGNED_VAR(mContextStorage, kAesContextSize, uint64_t); +#endif }; /** diff --git a/src/core/crypto/hkdf_sha256.cpp b/src/core/crypto/hkdf_sha256.cpp index b47b3a461..2002db27b 100644 --- a/src/core/crypto/hkdf_sha256.cpp +++ b/src/core/crypto/hkdf_sha256.cpp @@ -44,8 +44,13 @@ namespace Crypto { HkdfSha256::HkdfSha256(void) { +#if OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT + mContext.mContext = nullptr; + mContext.mContextSize = 0; +#else mContext.mContext = mContextStorage; mContext.mContextSize = sizeof(mContextStorage); +#endif SuccessOrAssert(otPlatCryptoHkdfInit(&mContext)); } diff --git a/src/core/crypto/hkdf_sha256.hpp b/src/core/crypto/hkdf_sha256.hpp index b2fed0c81..dd27bbb2c 100644 --- a/src/core/crypto/hkdf_sha256.hpp +++ b/src/core/crypto/hkdf_sha256.hpp @@ -94,7 +94,9 @@ public: private: otCryptoContext mContext; +#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT OT_DEFINE_ALIGNED_VAR(mContextStorage, kHkdfContextSize, uint64_t); +#endif }; /** diff --git a/src/core/crypto/hmac_sha256.cpp b/src/core/crypto/hmac_sha256.cpp index 0f49da049..b08502a0b 100644 --- a/src/core/crypto/hmac_sha256.cpp +++ b/src/core/crypto/hmac_sha256.cpp @@ -41,8 +41,13 @@ namespace Crypto { HmacSha256::HmacSha256(void) { +#if OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT + mContext.mContext = nullptr; + mContext.mContextSize = 0; +#else mContext.mContext = mContextStorage; mContext.mContextSize = sizeof(mContextStorage); +#endif SuccessOrAssert(otPlatCryptoHmacSha256Init(&mContext)); } diff --git a/src/core/crypto/hmac_sha256.hpp b/src/core/crypto/hmac_sha256.hpp index dcfb25406..ffd095e9c 100644 --- a/src/core/crypto/hmac_sha256.hpp +++ b/src/core/crypto/hmac_sha256.hpp @@ -124,7 +124,9 @@ public: private: otCryptoContext mContext; +#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT OT_DEFINE_ALIGNED_VAR(mContextStorage, kHmacSha256ContextSize, uint64_t); +#endif }; /** diff --git a/src/core/crypto/sha256.cpp b/src/core/crypto/sha256.cpp index c4c5225da..7d41f2c89 100644 --- a/src/core/crypto/sha256.cpp +++ b/src/core/crypto/sha256.cpp @@ -42,8 +42,14 @@ namespace Crypto { Sha256::Sha256(void) { +#if OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT + mContext.mContext = nullptr; + mContext.mContextSize = 0; +#else mContext.mContext = mContextStorage; mContext.mContextSize = sizeof(mContextStorage); +#endif + SuccessOrAssert(otPlatCryptoSha256Init(&mContext)); } diff --git a/src/core/crypto/sha256.hpp b/src/core/crypto/sha256.hpp index 2e6c272a7..3f76f3ec0 100644 --- a/src/core/crypto/sha256.hpp +++ b/src/core/crypto/sha256.hpp @@ -136,7 +136,9 @@ public: private: otCryptoContext mContext; +#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT OT_DEFINE_ALIGNED_VAR(mContextStorage, kSha256ContextSize, uint64_t); +#endif }; /**