From c28002707df87416a63ceb78d49cbf17e2777bb6 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 23 Feb 2026 11:00:53 -0800 Subject: [PATCH] [key-manager] move initialization to `Instance::AfterInit` (#12476) Currently, `KeyManager` generates and stores a random `NetworkKey` in its constructor when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled. This invokes `StoreNetworkKey()`, which interacts with `KeyRefManager`. Accessing other components during construction can be unsafe if they are not yet fully initialized. This commit introduces a `KeyManager::Init()` method to handle this initialization. This method is called from `Instance::AfterInit()`, ensuring that the `Instance` and all dependencies, such as `KeyRefManager`, are fully constructed before the `KeyManager` attempts to access them. --- src/core/instance/instance.cpp | 2 ++ src/core/thread/key_manager.cpp | 21 ++++++++++++--------- src/core/thread/key_manager.hpp | 9 +++++++++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/core/instance/instance.cpp b/src/core/instance/instance.cpp index 7fdcb64e7..7a87b9b79 100644 --- a/src/core/instance/instance.cpp +++ b/src/core/instance/instance.cpp @@ -432,6 +432,8 @@ void Instance::AfterInit(void) mIsInitialized = true; #if OPENTHREAD_MTD || OPENTHREAD_FTD + Get().Init(); + // Restore datasets and network information Get().Init(); diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp index b29da08a3..d3f5e2ce7 100644 --- a/src/core/thread/key_manager.cpp +++ b/src/core/thread/key_manager.cpp @@ -179,15 +179,8 @@ KeyManager::KeyManager(Instance &aInstance) otPlatCryptoInit(); #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE - { - NetworkKey networkKey; - - mNetworkKeyRef = Crypto::Storage::kInvalidKeyRef; - mPskcRef = Crypto::Storage::kInvalidKeyRef; - - IgnoreError(networkKey.GenerateRandom()); - StoreNetworkKey(networkKey, /* aOverWriteExisting */ false); - } + mNetworkKeyRef = Crypto::Storage::kInvalidKeyRef; + mPskcRef = Crypto::Storage::kInvalidKeyRef; #else IgnoreError(mNetworkKey.GenerateRandom()); mPskc.Clear(); @@ -196,6 +189,16 @@ KeyManager::KeyManager(Instance &aInstance) mMacFrameCounters.Reset(); } +void KeyManager::Init(void) +{ +#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE + NetworkKey networkKey; + + IgnoreError(networkKey.GenerateRandom()); + StoreNetworkKey(networkKey, /* aOverWriteExisting */ false); +#endif +} + void KeyManager::Start(void) { mKeySwitchGuardTimer = 0; diff --git a/src/core/thread/key_manager.hpp b/src/core/thread/key_manager.hpp index a284ad645..4bb3bd987 100644 --- a/src/core/thread/key_manager.hpp +++ b/src/core/thread/key_manager.hpp @@ -228,6 +228,15 @@ public: */ explicit KeyManager(Instance &aInstance); + /** + * Initializes the `KeyManager`. + * + * This method is called after OpenThread `Instance` is fully initialized (from `Instance::AfterInit()`). This + * ensures that all `Instance` components (including `KeyManager`) have been constructed and are safe to interact + * with (e.g., to save a default key in `Crypto::Storage::KeyRefManager`). + */ + void Init(void); + /** * Starts KeyManager rotation timer and sets guard timer to initial value. */