mirror of
https://github.com/espressif/openthread.git
synced 2026-08-05 02:17:47 +00:00
[crypto] PSA API: support HKDF extraction with HMAC-SHA256 keys
The PSA platform now transparently handles HKDF operations when using HMAC-SHA256 keys by exporting and re-importing them as volatile HKDF-SHA256 keys. The export/import logic has been moved into the platform layer. This change is required to support TREL and the PSA API key usage restrictions. Signed-off-by: Łukasz Duda <[email protected]>
This commit is contained in:
@@ -451,9 +451,15 @@ OT_TOOL_WEAK otError otPlatCryptoHkdfExtract(otCryptoContext *aContext,
|
||||
uint16_t aSaltLength,
|
||||
const otCryptoKey *aInputKey)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_derivation_operation_t *operation;
|
||||
Error error = kErrorNone;
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_derivation_operation_t *operation = nullptr;
|
||||
otCryptoKeyRef keyRef = PSA_KEY_ID_NULL;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t keyAlg = PSA_ALG_NONE;
|
||||
size_t keyLength = 0;
|
||||
constexpr size_t kBufferSize = 128;
|
||||
uint8_t keyBuffer[kBufferSize];
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_derivation_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aInputKey != nullptr, error = kErrorInvalidArgs);
|
||||
@@ -463,10 +469,36 @@ OT_TOOL_WEAK otError otPlatCryptoHkdfExtract(otCryptoContext *aContext,
|
||||
status = psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SALT, aSalt, aSaltLength);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
|
||||
status = psa_key_derivation_input_key(operation, PSA_KEY_DERIVATION_INPUT_SECRET, aInputKey->mKeyRef);
|
||||
status = psa_get_key_attributes(aInputKey->mKeyRef, &attributes);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
|
||||
keyAlg = psa_get_key_algorithm(&attributes);
|
||||
|
||||
// The PSA API enforces a policy that restricts each key to a single algorithm.
|
||||
// If the key is already HKDF-SHA256, we can use it directly.
|
||||
// Otherwise, export and re-import it as a volatile HKDF key.
|
||||
if (keyAlg != toPsaAlgorithm(OT_CRYPTO_KEY_ALG_HKDF_SHA256))
|
||||
{
|
||||
SuccessOrExit(error = otPlatCryptoExportKey(aInputKey->mKeyRef, keyBuffer, sizeof(keyBuffer), &keyLength));
|
||||
SuccessOrExit(error = otPlatCryptoImportKey(&keyRef, OT_CRYPTO_KEY_TYPE_DERIVE, OT_CRYPTO_KEY_ALG_HKDF_SHA256,
|
||||
OT_CRYPTO_KEY_USAGE_DERIVE, OT_CRYPTO_KEY_STORAGE_VOLATILE,
|
||||
keyBuffer, keyLength));
|
||||
|
||||
status = psa_key_derivation_input_key(operation, PSA_KEY_DERIVATION_INPUT_SECRET, keyRef);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
}
|
||||
else
|
||||
{
|
||||
status = psa_key_derivation_input_key(operation, PSA_KEY_DERIVATION_INPUT_SECRET, aInputKey->mKeyRef);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
}
|
||||
|
||||
exit:
|
||||
if (keyRef != PSA_KEY_ID_NULL)
|
||||
{
|
||||
otPlatCryptoDestroyKey(keyRef);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -311,17 +311,7 @@ void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey) const
|
||||
Crypto::Key cryptoKey;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::KeyRef keyRef;
|
||||
NetworkKey networkKey;
|
||||
|
||||
GetNetworkKey(networkKey);
|
||||
|
||||
// Create temporary key to perform derive operation.
|
||||
SuccessOrAssert(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeDerive,
|
||||
Crypto::Storage::kKeyAlgorithmHkdfSha256, Crypto::Storage::kUsageDerive,
|
||||
Crypto::Storage::kTypeVolatile, networkKey.m8, NetworkKey::kSize));
|
||||
|
||||
cryptoKey.SetAsKeyRef(keyRef);
|
||||
cryptoKey.SetAsKeyRef(mNetworkKeyRef);
|
||||
#else
|
||||
cryptoKey.Set(mNetworkKey.m8, NetworkKey::kSize);
|
||||
#endif
|
||||
@@ -331,10 +321,6 @@ void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey) const
|
||||
|
||||
hkdf.Extract(salt, sizeof(salt), cryptoKey);
|
||||
hkdf.Expand(kTrelInfoString, sizeof(kTrelInfoString), aKey.m8, Mac::Key::kSize);
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::DestroyKey(keyRef);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -50,7 +50,11 @@ struct TestVector
|
||||
uint16_t mOutKeyLength;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
void TestHkdfSha256(Crypto::Storage::KeyAlgorithm aAlgorithm)
|
||||
#else
|
||||
void TestHkdfSha256(void)
|
||||
#endif
|
||||
{
|
||||
enum
|
||||
{
|
||||
@@ -147,9 +151,23 @@ void TestHkdfSha256(void)
|
||||
memset(outKey, kFillByte, sizeof(outKey));
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(
|
||||
keyRef, Crypto::Storage::kKeyTypeDerive, Crypto::Storage::kKeyAlgorithmHkdfSha256,
|
||||
Crypto::Storage::kUsageDerive, Crypto::Storage::kTypeVolatile, test->mInKey, test->mInKeyLength));
|
||||
if (aAlgorithm == Crypto::Storage::kKeyAlgorithmHkdfSha256)
|
||||
{
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(
|
||||
keyRef, Crypto::Storage::kKeyTypeDerive, Crypto::Storage::kKeyAlgorithmHkdfSha256,
|
||||
Crypto::Storage::kUsageDerive, Crypto::Storage::kTypeVolatile, test->mInKey, test->mInKeyLength));
|
||||
}
|
||||
else if (aAlgorithm == Crypto::Storage::kKeyAlgorithmHmacSha256)
|
||||
{
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeHmac,
|
||||
Crypto::Storage::kKeyAlgorithmHmacSha256,
|
||||
Crypto::Storage::kUsageSignHash | Crypto::Storage::kUsageExport,
|
||||
Crypto::Storage::kTypeVolatile, test->mInKey, test->mInKeyLength));
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(false);
|
||||
}
|
||||
|
||||
testInputKey.SetAsKeyRef(keyRef);
|
||||
#else
|
||||
@@ -180,7 +198,13 @@ void TestHkdfSha256(void)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
ot::TestHkdfSha256(ot::Crypto::Storage::kKeyAlgorithmHkdfSha256);
|
||||
ot::TestHkdfSha256(ot::Crypto::Storage::kKeyAlgorithmHmacSha256);
|
||||
#else
|
||||
ot::TestHkdfSha256();
|
||||
#endif
|
||||
|
||||
printf("All tests passed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user