mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[mac] enforce KEK validation for Key ID Mode 0 frames (#13056)
This commit adds validation to ensure that Key ID Mode 0 (implied KEK) secured frames are only accepted if a KEK is configured. If KEK is not configured, the frame is rejected. Specifically: - Added `mIsKekSet` boolean member variable to `KeyManager` to track KEK status. - Implemented `KeyManager::IsKekSet()` to check if a KEK is configured. - Enforced a guard in `Mac::ProcessReceiveSecurity()` under `kKeyIdMode0` to immediately reject incoming frames with `kErrorSecurity` when the KEK is not configured. - Added unit test `TestKeyManagerKek()` in `test_pskc.cpp` to verify that `IsKekSet()` transitions from `false` to `true` as expected.
This commit is contained in:
@@ -1536,6 +1536,7 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig
|
||||
switch (keyIdMode)
|
||||
{
|
||||
case Frame::kKeyIdMode0:
|
||||
VerifyOrExit(keyManager.IsKekSet(), error = kErrorSecurity);
|
||||
macKey = &keyManager.GetKek();
|
||||
extAddress = &aSrcAddr.GetExtended();
|
||||
break;
|
||||
|
||||
@@ -175,6 +175,7 @@ KeyManager::KeyManager(Instance &aInstance)
|
||||
, mKeyRotationTimer(aInstance)
|
||||
, mKekFrameCounter(0)
|
||||
, mIsPskcSet(false)
|
||||
, mIsKekSet(false)
|
||||
{
|
||||
otPlatCryptoInit();
|
||||
|
||||
@@ -512,6 +513,7 @@ void KeyManager::SetKek(const Kek &aKek)
|
||||
{
|
||||
mKek.SetFrom(aKek, /* aIsExportable */ true);
|
||||
mKekFrameCounter = 0;
|
||||
mIsKekSet = true;
|
||||
}
|
||||
|
||||
void KeyManager::SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy)
|
||||
@@ -695,6 +697,7 @@ void KeyManager::DestroyTemporaryKeys(void)
|
||||
{
|
||||
mMleKey.Clear();
|
||||
mKek.Clear();
|
||||
mIsKekSet = false;
|
||||
Get<Mac::SubMac>().ClearMacKeys();
|
||||
}
|
||||
|
||||
|
||||
@@ -456,6 +456,14 @@ public:
|
||||
*/
|
||||
const KekKeyMaterial &GetKek(void) const { return mKek; }
|
||||
|
||||
/**
|
||||
* Indicates whether or not the KEK is set.
|
||||
*
|
||||
* @retval TRUE If the KEK is set.
|
||||
* @retval FALSE If the KEK is not set.
|
||||
*/
|
||||
bool IsKekSet(void) const { return mIsKekSet; }
|
||||
|
||||
/**
|
||||
* Retrieves the KEK as literal `Kek` key.
|
||||
*
|
||||
@@ -646,6 +654,7 @@ private:
|
||||
|
||||
SecurityPolicy mSecurityPolicy;
|
||||
bool mIsPskcSet : 1;
|
||||
bool mIsKekSet : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "meshcop/commissioner.hpp"
|
||||
#include "meshcop/meshcop.hpp"
|
||||
#include "thread/key_manager.hpp"
|
||||
|
||||
#include "test_platform.h"
|
||||
#include "test_util.h"
|
||||
@@ -108,6 +109,22 @@ void TestExampleInSpec(void)
|
||||
testFreeInstance(instance);
|
||||
}
|
||||
|
||||
void TestKeyManagerKek(void)
|
||||
{
|
||||
Instance *instance = testInitInstance();
|
||||
KeyManager &keyManager = instance->Get<KeyManager>();
|
||||
|
||||
VerifyOrQuit(!keyManager.IsKekSet());
|
||||
|
||||
Kek kek;
|
||||
memset(kek.m8, 0xaa, sizeof(kek.m8));
|
||||
keyManager.SetKek(kek);
|
||||
|
||||
VerifyOrQuit(keyManager.IsKekSet());
|
||||
|
||||
testFreeInstance(instance);
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace ot
|
||||
|
||||
@@ -119,6 +136,7 @@ int main(void)
|
||||
ot::MeshCoP::TestMinimumPassphrase();
|
||||
ot::MeshCoP::TestMaximumPassphrase();
|
||||
ot::MeshCoP::TestExampleInSpec();
|
||||
ot::MeshCoP::TestKeyManagerKek();
|
||||
printf("All tests passed\n");
|
||||
#else
|
||||
printf("PSKc generation is not supported on non-ftd build\n");
|
||||
|
||||
Reference in New Issue
Block a user