[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:
Jonathan Hui
2026-05-06 14:51:38 -07:00
committed by GitHub
parent 74c2531738
commit e2e7a78af5
4 changed files with 31 additions and 0 deletions
+1
View File
@@ -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;
+3
View File
@@ -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();
}
+9
View File
@@ -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;
};
/**
+18
View File
@@ -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");