mirror of
https://github.com/espressif/openthread.git
synced 2026-10-09 01:07:39 +00:00
[crypto] allow key reference usage for ECDSA (#8961)
Add new class to handle ECDSA using key refs. Update SRP to use key refs.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (310)
|
||||
#define OPENTHREAD_API_VERSION (311)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -60,9 +60,10 @@ extern "C" {
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data.
|
||||
OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES.
|
||||
OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
|
||||
OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data.
|
||||
OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES.
|
||||
OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
|
||||
OT_CRYPTO_KEY_TYPE_ECDSA, ///< Key Type: ECDSA.
|
||||
} otCryptoKeyType;
|
||||
|
||||
/**
|
||||
@@ -74,6 +75,7 @@ typedef enum
|
||||
OT_CRYPTO_KEY_ALG_VENDOR, ///< Key Algorithm: Vendor Defined.
|
||||
OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB.
|
||||
OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
|
||||
OT_CRYPTO_KEY_ALG_ECDSA, ///< Key Algorithm: ECDSA.
|
||||
} otCryptoKeyAlgorithm;
|
||||
|
||||
/**
|
||||
@@ -82,11 +84,12 @@ typedef enum
|
||||
*/
|
||||
enum
|
||||
{
|
||||
OT_CRYPTO_KEY_USAGE_NONE = 0, ///< Key Usage: Key Usage is empty.
|
||||
OT_CRYPTO_KEY_USAGE_EXPORT = 1 << 0, ///< Key Usage: Key can be exported.
|
||||
OT_CRYPTO_KEY_USAGE_ENCRYPT = 1 << 1, ///< Key Usage: Encryption (vendor defined).
|
||||
OT_CRYPTO_KEY_USAGE_DECRYPT = 1 << 2, ///< Key Usage: AES ECB.
|
||||
OT_CRYPTO_KEY_USAGE_SIGN_HASH = 1 << 3, ///< Key Usage: HMAC SHA-256.
|
||||
OT_CRYPTO_KEY_USAGE_NONE = 0, ///< Key Usage: Key Usage is empty.
|
||||
OT_CRYPTO_KEY_USAGE_EXPORT = 1 << 0, ///< Key Usage: Key can be exported.
|
||||
OT_CRYPTO_KEY_USAGE_ENCRYPT = 1 << 1, ///< Key Usage: Encryption (vendor defined).
|
||||
OT_CRYPTO_KEY_USAGE_DECRYPT = 1 << 2, ///< Key Usage: AES ECB.
|
||||
OT_CRYPTO_KEY_USAGE_SIGN_HASH = 1 << 3, ///< Key Usage: Sign Hash.
|
||||
OT_CRYPTO_KEY_USAGE_VERIFY_HASH = 1 << 4, ///< Key Usage: Verify Hash.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -650,6 +653,85 @@ otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature);
|
||||
|
||||
/**
|
||||
* Calculate the ECDSA signature for a hashed message using the Key reference passed.
|
||||
*
|
||||
* This method uses the deterministic digital signature generation procedure from RFC 6979.
|
||||
*
|
||||
* @param[in] aKeyRef Key Reference to the slot where the key-pair is stored.
|
||||
* @param[in] aHash A pointer to a SHA-256 hash structure where the hash value for signature calculation
|
||||
* is stored.
|
||||
* @param[out] aSignature A pointer to an ECDSA signature structure to output the calculated signature.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The signature was calculated successfully, @p aSignature was updated.
|
||||
* @retval OT_ERROR_PARSE The key-pair DER format could not be parsed (invalid format).
|
||||
* @retval OT_ERROR_NO_BUFS Failed to allocate buffer for signature calculation.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aContext is NULL.
|
||||
*
|
||||
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
|
||||
*
|
||||
*/
|
||||
otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
otPlatCryptoEcdsaSignature *aSignature);
|
||||
|
||||
/**
|
||||
* Get the associated public key from the key reference passed.
|
||||
*
|
||||
* The public key is stored differently depending on the crypto backend library being used
|
||||
* (OPENTHREAD_CONFIG_CRYPTO_LIB).
|
||||
*
|
||||
* This API must make sure to return the public key as a byte sequence representation of an
|
||||
* uncompressed curve point (RFC 6605 - sec 4)
|
||||
*
|
||||
* @param[in] aKeyRef Key Reference to the slot where the key-pair is stored.
|
||||
* @param[out] aPublicKey A pointer to an ECDSA public key structure to store the public key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Public key was retrieved successfully, and @p aBuffer is updated.
|
||||
* @retval OT_ERROR_PARSE The key-pair DER format could not be parsed (invalid format).
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aContext is NULL.
|
||||
*
|
||||
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
|
||||
*
|
||||
*/
|
||||
otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, otPlatCryptoEcdsaPublicKey *aPublicKey);
|
||||
|
||||
/**
|
||||
* Generate and import a new ECDSA key-pair at reference passed.
|
||||
*
|
||||
* @param[in] aKeyRef Key Reference to the slot where the key-pair is stored.
|
||||
*
|
||||
* @retval OT_ERROR_NONE A new key-pair was generated successfully.
|
||||
* @retval OT_ERROR_NO_BUFS Failed to allocate buffer for key generation.
|
||||
* @retval OT_ERROR_NOT_CAPABLE Feature not supported.
|
||||
* @retval OT_ERROR_FAILED Failed to generate key-pair.
|
||||
*
|
||||
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
|
||||
*
|
||||
*/
|
||||
otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef);
|
||||
|
||||
/**
|
||||
* Use the keyref to verify the ECDSA signature of a hashed message.
|
||||
*
|
||||
* @param[in] aKeyRef Key Reference to the slot where the key-pair is stored.
|
||||
* @param[in] aHash A pointer to a SHA-256 hash structure where the hash value for signature verification
|
||||
* is stored.
|
||||
* @param[in] aSignature A pointer to an ECDSA signature structure where the signature value to be verified is
|
||||
* stored.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The signature was verified successfully.
|
||||
* @retval OT_ERROR_SECURITY The signature is invalid.
|
||||
* @retval OT_ERROR_INVALID_ARGS The key or hash is invalid.
|
||||
* @retval OT_ERROR_NO_BUFS Failed to allocate buffer for signature verification.
|
||||
*
|
||||
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
|
||||
*
|
||||
*/
|
||||
otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature);
|
||||
|
||||
/**
|
||||
* Perform PKCS#5 PBKDF2 using CMAC (AES-CMAC-PRF-128).
|
||||
*
|
||||
|
||||
@@ -345,6 +345,10 @@ void Instance::Finalize(void)
|
||||
IgnoreError(otIp6SetEnabled(this, false));
|
||||
IgnoreError(otLinkSetEnabled(this, false));
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Get<KeyManager>().DestroyTemporaryKeys();
|
||||
#endif
|
||||
|
||||
Get<Settings>().Deinit();
|
||||
#endif
|
||||
|
||||
@@ -369,6 +373,10 @@ exit:
|
||||
void Instance::FactoryReset(void)
|
||||
{
|
||||
Get<Settings>().Wipe();
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Get<KeyManager>().DestroyTemporaryKeys();
|
||||
Get<KeyManager>().DestroyPersistentKeys();
|
||||
#endif
|
||||
otPlatReset(this);
|
||||
}
|
||||
|
||||
@@ -378,6 +386,10 @@ Error Instance::ErasePersistentInfo(void)
|
||||
|
||||
VerifyOrExit(Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
|
||||
Get<Settings>().Wipe();
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Get<KeyManager>().DestroyTemporaryKeys();
|
||||
Get<KeyManager>().DestroyPersistentKeys();
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -662,6 +662,53 @@ exit:
|
||||
|
||||
#endif // #if !OPENTHREAD_RADIO
|
||||
|
||||
#elif OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
|
||||
#if !OPENTHREAD_RADIO
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyPair);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair,
|
||||
otPlatCryptoEcdsaPublicKey *aPublicKey)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyPair);
|
||||
OT_UNUSED_VARIABLE(aPublicKey);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyPair);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature)
|
||||
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aPublicKey);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
#endif // #if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
|
||||
#endif // #if !OPENTHREAD_RADIO
|
||||
|
||||
#endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#include "common/error.hpp"
|
||||
#include "crypto/sha256.hpp"
|
||||
#include "crypto/storage.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Crypto {
|
||||
@@ -77,6 +78,9 @@ public:
|
||||
|
||||
class PublicKey;
|
||||
class KeyPair;
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
class KeyPairAsRef;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class represents an ECDSA signature.
|
||||
@@ -90,6 +94,9 @@ public:
|
||||
{
|
||||
friend class KeyPair;
|
||||
friend class PublicKey;
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
friend class KeyPairAsRef;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static constexpr uint8_t kSize = OT_CRYPTO_ECDSA_SIGNATURE_SIZE; ///< Signature size in bytes.
|
||||
@@ -204,6 +211,105 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
/**
|
||||
* This class represents a key pair (public and private keys) as a PSA KeyRef.
|
||||
*
|
||||
*/
|
||||
class KeyPairAsRef
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes a `KeyPairAsRef`.
|
||||
*
|
||||
* @param[in] aKeyRef PSA key reference to use while using the keypair.
|
||||
*/
|
||||
explicit KeyPairAsRef(otCryptoKeyRef aKeyRef = 0) { mKeyRef = aKeyRef; }
|
||||
|
||||
/**
|
||||
* This method generates a new keypair and imports it into PSA ITS.
|
||||
*
|
||||
* @retval kErrorNone A new key pair was generated successfully.
|
||||
* @retval kErrorNoBufs Failed to allocate buffer for key generation.
|
||||
* @retval kErrorNotCapable Feature not supported.
|
||||
* @retval kErrorFailed Failed to generate key.
|
||||
*
|
||||
*/
|
||||
Error Generate(void) const { return otPlatCryptoEcdsaGenerateAndImportKey(mKeyRef); }
|
||||
|
||||
/**
|
||||
* This method imports a new keypair into PSA ITS.
|
||||
*
|
||||
* @param[in] aKeyPair KeyPair to be imported in DER format.
|
||||
*
|
||||
* @retval kErrorNone A key pair was imported successfully.
|
||||
* @retval kErrorNotCapable Feature not supported.
|
||||
* @retval kErrorFailed Failed to import the key.
|
||||
*
|
||||
*/
|
||||
Error ImportKeyPair(const KeyPair &aKeyPair)
|
||||
{
|
||||
return Crypto::Storage::ImportKey(mKeyRef, Storage::kKeyTypeEcdsa, Storage::kKeyAlgorithmEcdsa,
|
||||
(Storage::kUsageSignHash | Storage::kUsageVerifyHash),
|
||||
Storage::kTypePersistent, aKeyPair.GetDerBytes(),
|
||||
aKeyPair.GetDerLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the associated public key from the keypair referenced by mKeyRef.
|
||||
*
|
||||
* @param[out] aPublicKey A reference to a `PublicKey` to output the value.
|
||||
*
|
||||
* @retval kErrorNone Public key was retrieved successfully, and @p aPublicKey is updated.
|
||||
* @retval kErrorFailed There was a error exporting the public key from PSA.
|
||||
*
|
||||
*/
|
||||
Error GetPublicKey(PublicKey &aPublicKey) const
|
||||
{
|
||||
return otPlatCryptoEcdsaExportPublicKey(mKeyRef, &aPublicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calculates the ECDSA signature for a hashed message using the private key from keypair
|
||||
* referenced by mKeyRef.
|
||||
*
|
||||
* This method uses the deterministic digital signature generation procedure from RFC 6979.
|
||||
*
|
||||
* @param[in] aHash The SHA-256 hash value of the message to use for signature calculation.
|
||||
* @param[out] aSignature A reference to a `Signature` to output the calculated signature value.
|
||||
*
|
||||
* @retval kErrorNone The signature was calculated successfully and @p aSignature was updated.
|
||||
* @retval kErrorParse The key-pair DER format could not be parsed (invalid format).
|
||||
* @retval kErrorInvalidArgs The @p aHash is invalid.
|
||||
* @retval kErrorNoBufs Failed to allocate buffer for signature calculation.
|
||||
*
|
||||
*/
|
||||
Error Sign(const Sha256::Hash &aHash, Signature &aSignature) const
|
||||
{
|
||||
return otPlatCryptoEcdsaSignUsingKeyRef(mKeyRef, &aHash, &aSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the Key reference for the keypair stored in the PSA.
|
||||
*
|
||||
* @returns The PSA key ref.
|
||||
*
|
||||
*/
|
||||
otCryptoKeyRef GetKeyRef(void) const { return mKeyRef; }
|
||||
|
||||
/**
|
||||
* This method sets the Key reference.
|
||||
*
|
||||
* @param[in] aKeyRef PSA key reference to use while using the keypair.
|
||||
*
|
||||
*/
|
||||
void SetKeyRef(otCryptoKeyRef aKeyRef) { mKeyRef = aKeyRef; }
|
||||
|
||||
private:
|
||||
otCryptoKeyRef mKeyRef;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class represents a public key.
|
||||
*
|
||||
@@ -214,6 +320,9 @@ public:
|
||||
class PublicKey : public otPlatCryptoEcdsaPublicKey, public Equatable<PublicKey>
|
||||
{
|
||||
friend class KeyPair;
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
friend class KeyPairAsRef;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static constexpr uint8_t kSize = OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE; ///< Size of the public key in bytes.
|
||||
@@ -242,6 +351,7 @@ public:
|
||||
{
|
||||
return otPlatCryptoEcdsaVerify(this, &aHash, &aSignature);
|
||||
}
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Crypto {
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Error Key::ExtractKey(uint8_t *aKeyBuffer, uint16_t &aKeyLength) const
|
||||
{
|
||||
Error error;
|
||||
Error error = kErrorNone;
|
||||
size_t readKeyLength;
|
||||
|
||||
OT_ASSERT(IsKeyRef());
|
||||
@@ -55,6 +55,17 @@ Error Key::ExtractKey(uint8_t *aKeyBuffer, uint16_t &aKeyLength) const
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Storage::DestroyPersistentKeys(void)
|
||||
{
|
||||
DestroyKey(kNetworkKeyRef);
|
||||
DestroyKey(kPskcRef);
|
||||
DestroyKey(kActiveDatasetNetworkKeyRef);
|
||||
DestroyKey(kActiveDatasetPskcRef);
|
||||
DestroyKey(kPendingDatasetNetworkKeyRef);
|
||||
DestroyKey(kPendingDatasetPskcRef);
|
||||
DestroyKey(kEcdsaRef);
|
||||
}
|
||||
#endif
|
||||
|
||||
LiteralKey::LiteralKey(const Key &aKey)
|
||||
|
||||
@@ -57,9 +57,10 @@ namespace Storage {
|
||||
*/
|
||||
enum KeyType : uint8_t
|
||||
{
|
||||
kKeyTypeRaw = OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data.
|
||||
kKeyTypeAes = OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES.
|
||||
kKeyTypeHmac = OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
|
||||
kKeyTypeRaw = OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data.
|
||||
kKeyTypeAes = OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES.
|
||||
kKeyTypeHmac = OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
|
||||
kKeyTypeEcdsa = OT_CRYPTO_KEY_TYPE_ECDSA, ///< Key Type: ECDSA.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -71,13 +72,15 @@ enum KeyAlgorithm : uint8_t
|
||||
kKeyAlgorithmVendor = OT_CRYPTO_KEY_ALG_VENDOR, ///< Key Algorithm: Vendor Defined.
|
||||
kKeyAlgorithmAesEcb = OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB.
|
||||
kKeyAlgorithmHmacSha256 = OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
|
||||
kKeyAlgorithmEcdsa = OT_CRYPTO_KEY_ALG_ECDSA, ///< Key Algorithm: ECDSA.
|
||||
};
|
||||
|
||||
constexpr uint8_t kUsageNone = OT_CRYPTO_KEY_USAGE_NONE; ///< Key Usage: Key Usage is empty.
|
||||
constexpr uint8_t kUsageExport = OT_CRYPTO_KEY_USAGE_EXPORT; ///< Key Usage: Key can be exported.
|
||||
constexpr uint8_t kUsageEncrypt = OT_CRYPTO_KEY_USAGE_ENCRYPT; ///< Key Usage: Encrypt (vendor defined).
|
||||
constexpr uint8_t kUsageDecrypt = OT_CRYPTO_KEY_USAGE_DECRYPT; ///< Key Usage: AES ECB.
|
||||
constexpr uint8_t kUsageSignHash = OT_CRYPTO_KEY_USAGE_SIGN_HASH; ///< Key Usage: HMAC SHA-256.
|
||||
constexpr uint8_t kUsageNone = OT_CRYPTO_KEY_USAGE_NONE; ///< Key Usage: Key Usage is empty.
|
||||
constexpr uint8_t kUsageExport = OT_CRYPTO_KEY_USAGE_EXPORT; ///< Key Usage: Key can be exported.
|
||||
constexpr uint8_t kUsageEncrypt = OT_CRYPTO_KEY_USAGE_ENCRYPT; ///< Key Usage: Encrypt (vendor defined).
|
||||
constexpr uint8_t kUsageDecrypt = OT_CRYPTO_KEY_USAGE_DECRYPT; ///< Key Usage: AES ECB.
|
||||
constexpr uint8_t kUsageSignHash = OT_CRYPTO_KEY_USAGE_SIGN_HASH; ///< Key Usage: Sign Hash.
|
||||
constexpr uint8_t kUsageVerifyHash = OT_CRYPTO_KEY_USAGE_VERIFY_HASH; ///< Key Usage: Verify Hash.
|
||||
|
||||
/**
|
||||
* This enumeration defines the key storage types.
|
||||
@@ -102,6 +105,7 @@ constexpr KeyRef kActiveDatasetNetworkKeyRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OF
|
||||
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;
|
||||
|
||||
/**
|
||||
* Determine if a given `KeyRef` is valid or not.
|
||||
@@ -186,6 +190,12 @@ 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
|
||||
|
||||
@@ -587,6 +587,12 @@ public:
|
||||
*/
|
||||
bool IsEnabled(void) const { return mEnabled; }
|
||||
|
||||
/**
|
||||
* This method clears the Mode2Key stored in PSA ITS.
|
||||
*
|
||||
*/
|
||||
void ClearMode2Key(void) { mMode2KeyMaterial.Clear(); }
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
/**
|
||||
* This method gets the CSL channel.
|
||||
|
||||
@@ -299,7 +299,7 @@ void KeyMaterial::SetFrom(const Key &aKey, bool aIsExportable)
|
||||
#endif
|
||||
}
|
||||
|
||||
void KeyMaterial::ExtractKey(Key &aKey)
|
||||
void KeyMaterial::ExtractKey(Key &aKey) const
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
aKey.Clear();
|
||||
|
||||
@@ -540,7 +540,7 @@ public:
|
||||
* @param[out] aKey A reference to the output the key.
|
||||
*
|
||||
*/
|
||||
void ExtractKey(Key &aKey);
|
||||
void ExtractKey(Key &aKey) const;
|
||||
|
||||
/**
|
||||
* This method converts `KeyMaterial` to a `Crypto::Key`.
|
||||
|
||||
@@ -477,6 +477,17 @@ public:
|
||||
*/
|
||||
const KeyMaterial &GetNextMacKey(void) const { return mNextKey; }
|
||||
|
||||
/**
|
||||
* This method clears the stored MAC keys.
|
||||
*
|
||||
*/
|
||||
void ClearMacKeys(void)
|
||||
{
|
||||
mPrevKey.Clear();
|
||||
mCurrKey.Clear();
|
||||
mNextKey.Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current MAC frame counter value.
|
||||
*
|
||||
|
||||
@@ -835,7 +835,12 @@ Error Client::PrepareUpdateMessage(Message &aMessage)
|
||||
|
||||
info.Clear();
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
info.mKeyRef.SetKeyRef(kSrpEcdsaKeyRef);
|
||||
SuccessOrExit(error = ReadOrGenerateKey(info.mKeyRef));
|
||||
#else
|
||||
SuccessOrExit(error = ReadOrGenerateKey(info.mKeyPair));
|
||||
#endif
|
||||
|
||||
// Generate random Message ID and ensure it is different from last one
|
||||
do
|
||||
@@ -885,6 +890,34 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Error Client::ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPairAsRef &aKeyRef)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Crypto::Ecdsa::P256::KeyPair keyPair;
|
||||
|
||||
VerifyOrExit(!Crypto::Storage::HasKey(aKeyRef.GetKeyRef()));
|
||||
error = Get<Settings>().Read<Settings::SrpEcdsaKey>(keyPair);
|
||||
|
||||
if (error == kErrorNone)
|
||||
{
|
||||
Crypto::Ecdsa::P256::PublicKey publicKey;
|
||||
|
||||
if (keyPair.GetPublicKey(publicKey) == kErrorNone)
|
||||
{
|
||||
SuccessOrExit(error = aKeyRef.ImportKeyPair(keyPair));
|
||||
IgnoreError(Get<Settings>().Delete<Settings::SrpEcdsaKey>());
|
||||
ExitNow();
|
||||
}
|
||||
IgnoreError(Get<Settings>().Delete<Settings::SrpEcdsaKey>());
|
||||
}
|
||||
|
||||
error = aKeyRef.Generate();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#else
|
||||
Error Client::ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair)
|
||||
{
|
||||
Error error;
|
||||
@@ -907,6 +940,7 @@ Error Client::ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair)
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
Error Client::AppendServiceInstructions(Message &aMessage, Info &aInfo)
|
||||
{
|
||||
@@ -1281,7 +1315,11 @@ Error Client::AppendKeyRecord(Message &aMessage, Info &aInfo) const
|
||||
key.SetAlgorithm(Dns::KeyRecord::kAlgorithmEcdsaP256Sha256);
|
||||
key.SetLength(sizeof(Dns::KeyRecord) - sizeof(Dns::ResourceRecord) + sizeof(Crypto::Ecdsa::P256::PublicKey));
|
||||
SuccessOrExit(error = aMessage.Append(key));
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrExit(error = aInfo.mKeyRef.GetPublicKey(publicKey));
|
||||
#else
|
||||
SuccessOrExit(error = aInfo.mKeyPair.GetPublicKey(publicKey));
|
||||
#endif
|
||||
SuccessOrExit(error = aMessage.Append(publicKey));
|
||||
aInfo.mRecordCount++;
|
||||
|
||||
@@ -1418,7 +1456,11 @@ Error Client::AppendSignature(Message &aMessage, Info &aInfo)
|
||||
sha256.Update(aMessage, 0, offset);
|
||||
|
||||
sha256.Finish(hash);
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrExit(error = aInfo.mKeyRef.Sign(hash, signature));
|
||||
#else
|
||||
SuccessOrExit(error = aInfo.mKeyPair.Sign(hash, signature));
|
||||
#endif
|
||||
|
||||
// Move back in message and append SIG RR now with compressed host
|
||||
// name (as signer's name) along with the calculated signature.
|
||||
|
||||
+33
-21
@@ -794,6 +794,10 @@ 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;
|
||||
@@ -981,29 +985,37 @@ private:
|
||||
{
|
||||
static constexpr uint16_t kUnknownOffset = 0; // Unknown offset value (used when offset is not yet set).
|
||||
|
||||
uint16_t mDomainNameOffset; // Offset of domain name serialization
|
||||
uint16_t mHostNameOffset; // Offset of host name serialization.
|
||||
uint16_t mRecordCount; // Number of resource records in Update section.
|
||||
Crypto::Ecdsa::P256::KeyPair mKeyPair; // The ECDSA key pair.
|
||||
uint16_t mDomainNameOffset; // Offset of domain name serialization
|
||||
uint16_t mHostNameOffset; // Offset of host name serialization.
|
||||
uint16_t mRecordCount; // Number of resource records in Update section.
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Ecdsa::P256::KeyPairAsRef mKeyRef; // The ECDSA key ref for key-pair.
|
||||
#else
|
||||
Crypto::Ecdsa::P256::KeyPair mKeyPair; // The ECDSA key pair.
|
||||
#endif
|
||||
};
|
||||
|
||||
Error Start(const Ip6::SockAddr &aServerSockAddr, Requester aRequester);
|
||||
void Stop(Requester aRequester, StopMode aMode);
|
||||
void Resume(void);
|
||||
void Pause(void);
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
void HandleRoleChanged(void);
|
||||
Error UpdateHostInfoStateOnAddressChange(void);
|
||||
void UpdateServiceStateToRemove(Service &aService);
|
||||
State GetState(void) const { return mState; }
|
||||
void SetState(State aState);
|
||||
void ChangeHostAndServiceStates(const ItemState *aNewStates, ServiceStateChangeMode aMode);
|
||||
void InvokeCallback(Error aError) const;
|
||||
void InvokeCallback(Error aError, const HostInfo &aHostInfo, const Service *aRemovedServices) const;
|
||||
void HandleHostInfoOrServiceChange(void);
|
||||
void SendUpdate(void);
|
||||
Error PrepareUpdateMessage(Message &aMessage);
|
||||
Error ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair);
|
||||
Error Start(const Ip6::SockAddr &aServerSockAddr, Requester aRequester);
|
||||
void Stop(Requester aRequester, StopMode aMode);
|
||||
void Resume(void);
|
||||
void Pause(void);
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
void HandleRoleChanged(void);
|
||||
Error UpdateHostInfoStateOnAddressChange(void);
|
||||
void UpdateServiceStateToRemove(Service &aService);
|
||||
State GetState(void) const { return mState; }
|
||||
void SetState(State aState);
|
||||
void ChangeHostAndServiceStates(const ItemState *aNewStates, ServiceStateChangeMode aMode);
|
||||
void InvokeCallback(Error aError) const;
|
||||
void InvokeCallback(Error aError, const HostInfo &aHostInfo, const Service *aRemovedServices) const;
|
||||
void HandleHostInfoOrServiceChange(void);
|
||||
void SendUpdate(void);
|
||||
Error PrepareUpdateMessage(Message &aMessage);
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Error ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPairAsRef &aKeyRef);
|
||||
#else
|
||||
Error ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair);
|
||||
#endif
|
||||
Error AppendServiceInstructions(Message &aMessage, Info &aInfo);
|
||||
bool CanAppendService(const Service &aService);
|
||||
Error AppendServiceInstruction(Service &aService, Message &aMessage, Info &aInfo);
|
||||
|
||||
@@ -284,7 +284,7 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys)
|
||||
void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys) const
|
||||
{
|
||||
Crypto::HmacSha256 hmac;
|
||||
uint8_t keySequenceBytes[sizeof(uint32_t)];
|
||||
@@ -306,7 +306,7 @@ void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys)
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey)
|
||||
void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey) const
|
||||
{
|
||||
Crypto::HkdfSha256 hkdf;
|
||||
uint8_t salt[sizeof(uint32_t) + sizeof(kHkdfExtractSaltString)];
|
||||
@@ -634,6 +634,15 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void KeyManager::DestroyTemporaryKeys(void)
|
||||
{
|
||||
mMleKey.Clear();
|
||||
mKek.Clear();
|
||||
Get<Mac::SubMac>().ClearMacKeys();
|
||||
Get<Mac::Mac>().ClearMode2Key();
|
||||
}
|
||||
|
||||
void KeyManager::DestroyPersistentKeys(void) { Crypto::Storage::DestroyPersistentKeys(); }
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
} // namespace ot
|
||||
|
||||
@@ -254,7 +254,7 @@ public:
|
||||
* @returns A key reference to the Thread Network Key.
|
||||
*
|
||||
*/
|
||||
NetworkKeyRef GetNetworkKeyRef(void) { return mNetworkKeyRef; }
|
||||
NetworkKeyRef GetNetworkKeyRef(void) const { return mNetworkKeyRef; }
|
||||
|
||||
/**
|
||||
* This method sets the Thread Network Key using Key Reference.
|
||||
@@ -299,7 +299,7 @@ public:
|
||||
* @returns A key reference to the PSKc.
|
||||
*
|
||||
*/
|
||||
const PskcRef &GetPskcRef(void) { return mPskcRef; }
|
||||
const PskcRef &GetPskcRef(void) const { return mPskcRef; }
|
||||
|
||||
/**
|
||||
* This method sets the PSKc as a Key reference.
|
||||
@@ -545,11 +545,25 @@ public:
|
||||
*
|
||||
* This is called to indicate the @p aMacFrameCounter value is now used.
|
||||
*
|
||||
* @param[in] aMacFrameCounter The 15.4 link MAC frame counter value.
|
||||
* @param[in] aMacFrameCounter The 15.4 link MAC frame counter value.
|
||||
*
|
||||
*/
|
||||
void MacFrameCounterUsed(uint32_t aMacFrameCounter);
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
/**
|
||||
* This method destroys all the volatile mac keys stored in PSA ITS.
|
||||
*
|
||||
*/
|
||||
void DestroyTemporaryKeys(void);
|
||||
|
||||
/**
|
||||
* This method destroys all the persistent keys stored in PSA ITS.
|
||||
*
|
||||
*/
|
||||
void DestroyPersistentKeys(void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
static constexpr uint32_t kDefaultKeySwitchGuardTime = 624;
|
||||
static constexpr uint32_t kOneHourIntervalInMsec = 3600u * 1000u;
|
||||
@@ -571,10 +585,10 @@ private:
|
||||
const Mac::Key &GetMacKey(void) const { return mKeys.mMacKey; }
|
||||
};
|
||||
|
||||
void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys);
|
||||
void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys) const;
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey);
|
||||
void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey) const;
|
||||
#endif
|
||||
|
||||
void StartKeyRotationTimer(void);
|
||||
|
||||
@@ -409,6 +409,43 @@ bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, otPlatCryptoEcdsaPublicKey *aPublicKey)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aPublicKey);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
Reference in New Issue
Block a user