mirror of
https://github.com/espressif/openthread.git
synced 2026-08-07 03:07:47 +00:00
[crypto-storage] add KeyRefManager to select KeyRef values (#11102)
This commit introduces `Crypto::Storage::KeyRefManager`, which manages and selects the `KeyRef` values. `ot::Instance` now will have its own `KeyRefManager`. Under `MULTIPLE_INSTANCE_ENABLE`, this allows different `ot::Instance`s to use different `KeyRef` ranges by setting an instance-specific offset. This offset is used when determining the `KeyRef` numerical value for secure storage access.
This commit is contained in:
@@ -39,6 +39,7 @@ namespace ot {
|
||||
namespace Crypto {
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
Error Key::ExtractKey(uint8_t *aKeyBuffer, uint16_t &aKeyLength) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
@@ -56,17 +57,18 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Storage::DestroyPersistentKeys(void)
|
||||
void Storage::KeyRefManager::DestroyPersistentKeys(void)
|
||||
{
|
||||
DestroyKey(kNetworkKeyRef);
|
||||
DestroyKey(kPskcRef);
|
||||
DestroyKey(kActiveDatasetNetworkKeyRef);
|
||||
DestroyKey(kActiveDatasetPskcRef);
|
||||
DestroyKey(kPendingDatasetNetworkKeyRef);
|
||||
DestroyKey(kPendingDatasetPskcRef);
|
||||
DestroyKey(kEcdsaRef);
|
||||
DestroyKey(KeyRefFor(kNetworkKey));
|
||||
DestroyKey(KeyRefFor(kPskc));
|
||||
DestroyKey(KeyRefFor(kActiveDatasetNetworkKey));
|
||||
DestroyKey(KeyRefFor(kActiveDatasetPskc));
|
||||
DestroyKey(KeyRefFor(kPendingDatasetNetworkKey));
|
||||
DestroyKey(KeyRefFor(kPendingDatasetPskc));
|
||||
DestroyKey(KeyRefFor(kEcdsa));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
LiteralKey::LiteralKey(const Key &aKey)
|
||||
: mKey(aKey.GetBytes())
|
||||
|
||||
+79
-13
@@ -42,6 +42,7 @@
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
|
||||
namespace ot {
|
||||
@@ -94,14 +95,84 @@ enum StorageType : uint8_t
|
||||
*/
|
||||
typedef otCryptoKeyRef KeyRef;
|
||||
|
||||
constexpr KeyRef kInvalidKeyRef = 0x80000000; ///< Invalid `KeyRef` value (PSA_KEY_ID_VENDOR_MAX + 1).
|
||||
constexpr KeyRef kNetworkKeyRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 1;
|
||||
constexpr KeyRef kPskcRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 2;
|
||||
constexpr KeyRef kActiveDatasetNetworkKeyRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 3;
|
||||
constexpr KeyRef kActiveDatasetPskcRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 4;
|
||||
constexpr KeyRef kPendingDatasetNetworkKeyRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 5;
|
||||
constexpr KeyRef kPendingDatasetPskcRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 6;
|
||||
constexpr KeyRef kEcdsaRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 7;
|
||||
constexpr KeyRef kInvalidKeyRef = 0x80000000; ///< Invalid `KeyRef` value (PSA_KEY_ID_VENDOR_MAX + 1).
|
||||
|
||||
/**
|
||||
* Manages and selects the `KeyRef` values.
|
||||
*/
|
||||
class KeyRefManager : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Represents difference `KeyRef` types.
|
||||
*/
|
||||
enum Type : uint8_t
|
||||
{
|
||||
kNetworkKey = 1,
|
||||
kPskc = 2,
|
||||
kActiveDatasetNetworkKey = 3,
|
||||
kActiveDatasetPskc = 4,
|
||||
kPendingDatasetNetworkKey = 5,
|
||||
kPendingDatasetPskc = 6,
|
||||
kEcdsa = 7,
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the `KeyRefManager`.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*/
|
||||
explicit KeyRefManager(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
|
||||
, mExtraOffset(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the `KeyRef` to use for a given `Type`.
|
||||
*
|
||||
* @param[in] aType The key ref type.
|
||||
*
|
||||
* @returns The `KeyRef` associated with @p aType.
|
||||
*/
|
||||
KeyRef KeyRefFor(Type aType)
|
||||
{
|
||||
KeyRef keyRef = kPsaItsNvmOffset + aType;
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
|
||||
keyRef += mExtraOffset;
|
||||
#endif
|
||||
return keyRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the persistent keys.
|
||||
*/
|
||||
void DestroyPersistentKeys(void);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
|
||||
static constexpr uint32_t kKeyRefExtraOffset = 32; ///< Recommended extra offset to use.
|
||||
|
||||
/**
|
||||
* Sets the additional `KeyRef` offset value to use when determining the `KeyRef`s.
|
||||
*
|
||||
* This is intended for when `MULTIPLE_INSTANCE_ENABLE` is enabled to ensure different `ot::Instance`s use
|
||||
* different `KeyRef` value ranges.
|
||||
*
|
||||
* @param[in] aOffset The offset value.
|
||||
*/
|
||||
void SetKeyRefExtraOffset(uint32_t aOffset) { mExtraOffset = aOffset; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
static constexpr KeyRef kPsaItsNvmOffset = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET;
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
|
||||
uint32_t mExtraOffset;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if a given `KeyRef` is valid or not.
|
||||
@@ -181,11 +252,6 @@ inline void DestroyKey(KeyRef aKeyRef)
|
||||
*/
|
||||
inline bool HasKey(KeyRef aKeyRef) { return otPlatCryptoHasKey(aKeyRef); }
|
||||
|
||||
/**
|
||||
* Delete all the persistent keys stored in PSA ITS.
|
||||
*/
|
||||
void DestroyPersistentKeys(void);
|
||||
|
||||
} // namespace Storage
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
@@ -75,6 +75,9 @@ Instance::Instance(void)
|
||||
: mTimerMilliScheduler(*this)
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
||||
, mTimerMicroScheduler(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
, mCryptoStorageKeyRefManager(*this)
|
||||
#endif
|
||||
, mRadio(*this)
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
@@ -276,6 +279,14 @@ Instance::Instance(void)
|
||||
, mIsInitialized(false)
|
||||
, mId(Random::NonCrypto::GetUint32())
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
|
||||
mCryptoStorageKeyRefManager.SetKeyRefExtraOffset(Crypto::Storage::KeyRefManager::kKeyRefExtraOffset * GetIdx(this));
|
||||
#else
|
||||
#error "MULTIPLE_INSTANCE (without static allocation) is used with PLATFORM_KEY_REFERENCES_ENABLE " \
|
||||
"The `KeyRef` values will be shared across different `Instance` objects"
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/settings.hpp"
|
||||
#include "crypto/mbedtls.hpp"
|
||||
#include "crypto/storage.hpp"
|
||||
#include "mac/mac.hpp"
|
||||
#include "mac/wakeup_tx_scheduler.hpp"
|
||||
#include "meshcop/border_agent.hpp"
|
||||
@@ -464,6 +465,10 @@ private:
|
||||
|
||||
Random::Manager mRandomManager;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::KeyRefManager mCryptoStorageKeyRefManager;
|
||||
#endif
|
||||
|
||||
// Radio is initialized before other member variables
|
||||
// (particularly, SubMac and Mac) to allow them to use its methods
|
||||
// from their constructor.
|
||||
@@ -769,6 +774,10 @@ template <> inline SettingsDriver &Instance::Get(void) { return mSettingsDriver;
|
||||
|
||||
template <> inline MeshForwarder &Instance::Get(void) { return mMeshForwarder; }
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
template <> inline Crypto::Storage::KeyRefManager &Instance::Get(void) { return mCryptoStorageKeyRefManager; }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
template <> inline RadioSelector &Instance::Get(void) { return mRadioSelector; }
|
||||
#endif
|
||||
|
||||
@@ -755,13 +755,13 @@ void DatasetManager::TlvList::Add(uint8_t aTlvType)
|
||||
const DatasetManager::SecurelyStoredTlv DatasetManager::kSecurelyStoredTlvs[] = {
|
||||
{
|
||||
Tlv::kNetworkKey,
|
||||
Crypto::Storage::kActiveDatasetNetworkKeyRef,
|
||||
Crypto::Storage::kPendingDatasetNetworkKeyRef,
|
||||
KeyRefManager::kActiveDatasetNetworkKey,
|
||||
KeyRefManager::kPendingDatasetNetworkKey,
|
||||
},
|
||||
{
|
||||
Tlv::kPskc,
|
||||
Crypto::Storage::kActiveDatasetPskcRef,
|
||||
Crypto::Storage::kPendingDatasetPskcRef,
|
||||
KeyRefManager::kActiveDatasetPskc,
|
||||
KeyRefManager::kPendingDatasetPskc,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -769,7 +769,7 @@ void DatasetManager::DestroySecurelyStoredKeys(void) const
|
||||
{
|
||||
for (const SecurelyStoredTlv &entry : kSecurelyStoredTlvs)
|
||||
{
|
||||
Crypto::Storage::DestroyKey(entry.GetKeyRef(mType));
|
||||
Crypto::Storage::DestroyKey(Get<KeyRefManager>().KeyRefFor(entry.GetKeyRefType(mType)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,7 +777,9 @@ void DatasetManager::MoveKeysToSecureStorage(Dataset &aDataset) const
|
||||
{
|
||||
for (const SecurelyStoredTlv &entry : kSecurelyStoredTlvs)
|
||||
{
|
||||
SaveTlvInSecureStorageAndClearValue(aDataset, entry.mTlvType, entry.GetKeyRef(mType));
|
||||
KeyRef keyRef = Get<KeyRefManager>().KeyRefFor(entry.GetKeyRefType(mType));
|
||||
|
||||
SaveTlvInSecureStorageAndClearValue(aDataset, entry.mTlvType, keyRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -792,7 +794,9 @@ void DatasetManager::EmplaceSecurelyStoredKeys(Dataset &aDataset) const
|
||||
|
||||
for (const SecurelyStoredTlv &entry : kSecurelyStoredTlvs)
|
||||
{
|
||||
if (ReadTlvFromSecureStorage(aDataset, entry.mTlvType, entry.GetKeyRef(mType)) != kErrorNone)
|
||||
KeyRef keyRef = Get<KeyRefManager>().KeyRefFor(entry.GetKeyRefType(mType));
|
||||
|
||||
if (ReadTlvFromSecureStorage(aDataset, entry.mTlvType, keyRef) != kErrorNone)
|
||||
{
|
||||
moveKeys = true;
|
||||
}
|
||||
|
||||
@@ -238,18 +238,20 @@ private:
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
using KeyRef = Crypto::Storage::KeyRef;
|
||||
using KeyRef = Crypto::Storage::KeyRef;
|
||||
using KeyRefManager = Crypto::Storage::KeyRefManager;
|
||||
using KeyRefType = Crypto::Storage::KeyRefManager::Type;
|
||||
|
||||
struct SecurelyStoredTlv
|
||||
{
|
||||
KeyRef GetKeyRef(Dataset::Type aType) const
|
||||
KeyRefType GetKeyRefType(Dataset::Type aType) const
|
||||
{
|
||||
return (aType == Dataset::kActive) ? mActiveKeyRef : mPendingKeyRef;
|
||||
return (aType == Dataset::kActive) ? mActiveKeyRefType : mPendingKeyRefType;
|
||||
}
|
||||
|
||||
Tlv::Type mTlvType;
|
||||
KeyRef mActiveKeyRef;
|
||||
KeyRef mPendingKeyRef;
|
||||
Tlv::Type mTlvType;
|
||||
KeyRefType mActiveKeyRefType;
|
||||
KeyRefType mPendingKeyRefType;
|
||||
};
|
||||
|
||||
static const SecurelyStoredTlv kSecurelyStoredTlvs[];
|
||||
|
||||
@@ -1110,7 +1110,7 @@ Error Client::PrepareUpdateMessage(MsgInfo &aInfo)
|
||||
aInfo.mRecordCount = 0;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
aInfo.mKeyInfo.SetKeyRef(kSrpEcdsaKeyRef);
|
||||
aInfo.mKeyInfo.SetKeyRef(Get<Crypto::Storage::KeyRefManager>().KeyRefFor(Crypto::Storage::KeyRefManager::kEcdsa));
|
||||
#endif
|
||||
|
||||
SuccessOrExit(error = ReadOrGenerateKey(aInfo.mKeyInfo));
|
||||
|
||||
@@ -749,10 +749,6 @@ private:
|
||||
// Number of fast data polls after SRP Update tx (11x 188ms = ~2 seconds)
|
||||
static constexpr uint8_t kFastPollsAfterUpdateTx = 11;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
static constexpr uint32_t kSrpEcdsaKeyRef = Crypto::Storage::kEcdsaRef;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_SWITCH_SERVER_ON_FAILURE
|
||||
static constexpr uint8_t kMaxTimeoutFailuresToSwitchServer =
|
||||
OPENTHREAD_CONFIG_SRP_CLIENT_MAX_TIMEOUT_FAILURES_TO_SWITCH_SERVER;
|
||||
|
||||
@@ -586,7 +586,7 @@ void KeyManager::StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteE
|
||||
{
|
||||
NetworkKeyRef keyRef;
|
||||
|
||||
keyRef = Crypto::Storage::kNetworkKeyRef;
|
||||
keyRef = Get<Crypto::Storage::KeyRefManager>().KeyRefFor(Crypto::Storage::KeyRefManager::kNetworkKey);
|
||||
|
||||
if (!aOverWriteExisting)
|
||||
{
|
||||
@@ -617,7 +617,7 @@ exit:
|
||||
|
||||
void KeyManager::StorePskc(const Pskc &aPskc)
|
||||
{
|
||||
PskcRef keyRef = Crypto::Storage::kPskcRef;
|
||||
PskcRef keyRef = Get<Crypto::Storage::KeyRefManager>().KeyRefFor(Crypto::Storage::KeyRefManager::kPskc);
|
||||
|
||||
Crypto::Storage::DestroyKey(keyRef);
|
||||
|
||||
@@ -671,7 +671,8 @@ void KeyManager::DestroyTemporaryKeys(void)
|
||||
Get<Mac::Mac>().ClearMode2Key();
|
||||
}
|
||||
|
||||
void KeyManager::DestroyPersistentKeys(void) { Crypto::Storage::DestroyPersistentKeys(); }
|
||||
void KeyManager::DestroyPersistentKeys(void) { Get<Crypto::Storage::KeyRefManager>().DestroyPersistentKeys(); }
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
} // namespace ot
|
||||
|
||||
Reference in New Issue
Block a user