From 06ed4dce4e868d7cefec063ee1594e361461bdca Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 13 Apr 2026 20:48:35 -0700 Subject: [PATCH] [crypto] add `ContextWith` template to simplify context allocation (#12885) This commit introduces the `Context` and `ContextWith` helper classes in the `Crypto` namespace to wrap `otCryptoContext` and manage its storage allocation. `ContextWith` handles the buffer allocation based on the configuration `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT`, automatically clearing and setting the buffer. The `AesEcb`, `HkdfSha256`, `HmacSha256`, and `Sha256` classes are updated to use the new `ContextWith` template for their `mContext` members. This simplifies their initialization sequences and constructors. --- src/core/common/num_utils.hpp | 4 +-- src/core/crypto/aes_ecb.cpp | 12 +------ src/core/crypto/aes_ecb.hpp | 5 +-- src/core/crypto/hkdf_sha256.cpp | 12 +------ src/core/crypto/hkdf_sha256.hpp | 6 ++-- src/core/crypto/hmac_sha256.cpp | 13 +------- src/core/crypto/hmac_sha256.hpp | 5 +-- src/core/crypto/sha256.cpp | 13 +------- src/core/crypto/sha256.hpp | 6 ++-- src/core/crypto/storage.hpp | 56 +++++++++++++++++++++++++++++++++ 10 files changed, 68 insertions(+), 64 deletions(-) diff --git a/src/core/common/num_utils.hpp b/src/core/common/num_utils.hpp index 61fad4290..b40b0d332 100644 --- a/src/core/common/num_utils.hpp +++ b/src/core/common/num_utils.hpp @@ -272,7 +272,7 @@ exit: * * @return The result of division and rounding to the closest integer. */ -template inline IntType DivideAndRoundToClosest(IntType aDividend, IntType aDivisor) +template inline constexpr IntType DivideAndRoundToClosest(IntType aDividend, IntType aDivisor) { return (aDividend + (aDivisor / 2)) / aDivisor; } @@ -287,7 +287,7 @@ template inline IntType DivideAndRoundToClosest(IntType aDivi * * @return The result of division and rounding up. */ -template inline IntType DivideAndRoundUp(IntType aDividend, IntType aDivisor) +template inline constexpr IntType DivideAndRoundUp(IntType aDividend, IntType aDivisor) { return (aDividend + (aDivisor - 1)) / aDivisor; } diff --git a/src/core/crypto/aes_ecb.cpp b/src/core/crypto/aes_ecb.cpp index d06970888..577103e8b 100644 --- a/src/core/crypto/aes_ecb.cpp +++ b/src/core/crypto/aes_ecb.cpp @@ -38,17 +38,7 @@ namespace ot { 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)); -} +AesEcb::AesEcb(void) { SuccessOrAssert(otPlatCryptoAesInit(&mContext)); } void AesEcb::SetKey(const Key &aKey) { SuccessOrAssert(otPlatCryptoAesSetKey(&mContext, &aKey)); } diff --git a/src/core/crypto/aes_ecb.hpp b/src/core/crypto/aes_ecb.hpp index 54f734783..d518a0dc9 100644 --- a/src/core/crypto/aes_ecb.hpp +++ b/src/core/crypto/aes_ecb.hpp @@ -85,10 +85,7 @@ public: void Encrypt(const uint8_t aInput[kBlockSize], uint8_t aOutput[kBlockSize]); private: - otCryptoContext mContext; -#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT - OT_DEFINE_ALIGNED_VAR(mContextStorage, kAesContextSize, uint64_t); -#endif + ContextWith mContext; }; /** diff --git a/src/core/crypto/hkdf_sha256.cpp b/src/core/crypto/hkdf_sha256.cpp index 2002db27b..431f69486 100644 --- a/src/core/crypto/hkdf_sha256.cpp +++ b/src/core/crypto/hkdf_sha256.cpp @@ -42,17 +42,7 @@ namespace ot { 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)); -} +HkdfSha256::HkdfSha256(void) { SuccessOrAssert(otPlatCryptoHkdfInit(&mContext)); } HkdfSha256::~HkdfSha256(void) { SuccessOrAssert(otPlatCryptoHkdfDeinit(&mContext)); } diff --git a/src/core/crypto/hkdf_sha256.hpp b/src/core/crypto/hkdf_sha256.hpp index dd27bbb2c..d7c37c6f0 100644 --- a/src/core/crypto/hkdf_sha256.hpp +++ b/src/core/crypto/hkdf_sha256.hpp @@ -42,6 +42,7 @@ #include "common/code_utils.hpp" #include "crypto/context_size.hpp" #include "crypto/hmac_sha256.hpp" +#include "crypto/storage.hpp" namespace ot { namespace Crypto { @@ -93,10 +94,7 @@ public: void Expand(const uint8_t *aInfo, uint16_t aInfoLength, uint8_t *aOutputKey, uint16_t aOutputKeyLength); private: - otCryptoContext mContext; -#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT - OT_DEFINE_ALIGNED_VAR(mContextStorage, kHkdfContextSize, uint64_t); -#endif + ContextWith mContext; }; /** diff --git a/src/core/crypto/hmac_sha256.cpp b/src/core/crypto/hmac_sha256.cpp index b08502a0b..bca670970 100644 --- a/src/core/crypto/hmac_sha256.cpp +++ b/src/core/crypto/hmac_sha256.cpp @@ -39,18 +39,7 @@ namespace ot { 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)); -} +HmacSha256::HmacSha256(void) { SuccessOrAssert(otPlatCryptoHmacSha256Init(&mContext)); } HmacSha256::~HmacSha256(void) { SuccessOrAssert(otPlatCryptoHmacSha256Deinit(&mContext)); } diff --git a/src/core/crypto/hmac_sha256.hpp b/src/core/crypto/hmac_sha256.hpp index ffd095e9c..7b79896a4 100644 --- a/src/core/crypto/hmac_sha256.hpp +++ b/src/core/crypto/hmac_sha256.hpp @@ -123,10 +123,7 @@ public: void Finish(Hash &aHash); private: - otCryptoContext mContext; -#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT - OT_DEFINE_ALIGNED_VAR(mContextStorage, kHmacSha256ContextSize, uint64_t); -#endif + ContextWith mContext; }; /** diff --git a/src/core/crypto/sha256.cpp b/src/core/crypto/sha256.cpp index 7d41f2c89..b453f1f7b 100644 --- a/src/core/crypto/sha256.cpp +++ b/src/core/crypto/sha256.cpp @@ -40,18 +40,7 @@ namespace ot { 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)); -} +Sha256::Sha256(void) { SuccessOrAssert(otPlatCryptoSha256Init(&mContext)); } Sha256::~Sha256(void) { SuccessOrAssert(otPlatCryptoSha256Deinit(&mContext)); } diff --git a/src/core/crypto/sha256.hpp b/src/core/crypto/sha256.hpp index 3f76f3ec0..dadb6f0c7 100644 --- a/src/core/crypto/sha256.hpp +++ b/src/core/crypto/sha256.hpp @@ -47,6 +47,7 @@ #include "common/equatable.hpp" #include "common/type_traits.hpp" #include "crypto/context_size.hpp" +#include "crypto/storage.hpp" namespace ot { @@ -135,10 +136,7 @@ public: void Finish(Hash &aHash); private: - otCryptoContext mContext; -#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT - OT_DEFINE_ALIGNED_VAR(mContextStorage, kSha256ContextSize, uint64_t); -#endif + ContextWith mContext; }; /** diff --git a/src/core/crypto/storage.hpp b/src/core/crypto/storage.hpp index e1c11ee72..d2a1d9668 100644 --- a/src/core/crypto/storage.hpp +++ b/src/core/crypto/storage.hpp @@ -44,6 +44,7 @@ #include "common/error.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" +#include "common/num_utils.hpp" namespace ot { namespace Crypto { @@ -263,6 +264,60 @@ inline bool HasKey(KeyRef aKeyRef) { return otPlatCryptoHasKey(aKeyRef); } #endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE +/** + * Represents a crypto context. + */ +class Context : public otCryptoContext +{ +public: + /** + * Gets the pointer to the context buffer. + * + * @returns A pointer to the context buffer. + */ + void *GetContext(void) { return mContext; } + + /** + * Gets the size of the context buffer. + * + * @returns The size of the context buffer in bytes. + */ + uint16_t GetSize(void) const { return mContextSize; } + + /** + * Sets the context buffer. + * + * @param[in] aContext A pointer to the context buffer. + * @param[in] aSize The size of the context buffer in bytes. + */ + void SetContext(void *aContext, uint16_t aSize) { mContext = aContext, mContextSize = aSize; } +}; + +/** + * Represents a crypto context with a locally allocated buffer. + * + * @tparam kContextSize The size of the context buffer in bytes. + */ +template class ContextWith : public Context +{ +public: + /** + * Initializes the context and the locally allocated buffer. + */ + ContextWith(void) + { + ClearAllBytes(*this); +#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT + SetContext(mStorage, kContextSize); +#endif + } + +private: +#if !OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT + uint64_t mStorage[DivideAndRoundUp(kContextSize, sizeof(uint64_t))]; +#endif +}; + /** * Represents a crypto key. * @@ -393,6 +448,7 @@ private: } // namespace Crypto +DefineCoreType(otCryptoContext, Crypto::Context); DefineCoreType(otCryptoKey, Crypto::Key); } // namespace ot