-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[nrfconnect] Implement KMUKeyAllocator
KMUKeyAllocator is used to overwrite PSAKeyAllocator for the specific use-cases of KMU driver. This feature is available only on the device which run Cracen. Signed-off-by: Arkadiusz Balys <[email protected]>
- Loading branch information
1 parent
56a0278
commit fcdf98d
Showing
6 changed files
with
178 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright (c) 2025 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#pragma once | ||
#include <cracen_psa_kmu.h> | ||
#include <crypto/PSAKeyAllocator.h> | ||
|
||
// Define the number of slots per NOC and ICD key. | ||
#define KMU_SLOTS_PER_NOC_KEY 2 | ||
#define KMU_SLOTS_PER_ICD_KEY 2 // ICD KEY means a pair of AES and HMAC keys per fabric | ||
#define KMU_SLOTS_PER_GROUP_KEY 1 | ||
|
||
#define KMU_SLOTS_NOC_MAX_NUMBER (KMU_SLOTS_PER_NOC_KEY * CONFIG_CHIP_MAX_FABRICS) | ||
#define KMU_SLOTS_ICD_MAX_NUMBER (KMU_SLOTS_PER_ICD_KEY * CONFIG_CHIP_MAX_FABRICS * CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC) | ||
#define KMU_SLOTS_GROUP_MAX_NUMBER (KMU_SLOTS_PER_GROUP_KEY * CHIP_CONFIG_MAX_GROUP_KEYS_PER_FABRIC * CONFIG_CHIP_MAX_FABRICS) | ||
|
||
// Check whether the number of slots is within the range of the KMU. | ||
#if ((KMU_SLOTS_NOC_MAX_NUMBER + KMU_SLOTS_ICD_MAX_NUMBER + KMU_SLOTS_GROUP_MAX_NUMBER) > \ | ||
CONFIG_CHIP_KMU_SLOT_RANGE_END - CONFIG_CHIP_KMU_SLOT_RANGE_START) | ||
{ | ||
#pragma message("NOC keys: " STRINGIFY(KMU_SLOTS_NOC_MAX_NUMBER) "+ ICD keys: " STRINGIFY( \ | ||
KMU_SLOTS_ICD_MAX_NUMBER) "+ GROUP keys: " STRINGIFY(KMU_SLOTS_GROUP_MAX_NUMBER) ">" STRINGIFY(KMU_AVAILABLE_MATTER_SLOTS)) | ||
#error \ | ||
"The number of slots exceeds the range of the KMU defined in CONFIG_CHIP_KMU_SLOT_RANGE_START and CONFIG_CHIP_KMU_SLOT_RANGE_END" | ||
} | ||
#endif | ||
|
||
// Define the start of the KMU slots for Matter. | ||
#define KMU_NOC_SLOT_START PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, CONFIG_CHIP_KMU_SLOT_RANGE_START) | ||
#define KMU_ICD_SLOT_START \ | ||
PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, (KMU_NOC_SLOT_START + KMU_SLOTS_NOC_MAX_NUMBER)) | ||
#define KMU_GROUP_KEYS_SLOT_START \ | ||
PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, (KMU_ICD_SLOT_START + KMU_SLOTS_ICD_MAX_NUMBER)) | ||
|
||
// Check whether the DAC KMU slot doesn not overlap with the KMU slots dedicated for Matter core. | ||
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && \ | ||
(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID >= CONFIG_CHIP_KMU_SLOT_RANGE_START && \ | ||
CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID <= CONFIG_CHIP_KMU_SLOT_RANGE_END) | ||
#error "CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID cannot overlap with KMU slots dedicated for Matter core" | ||
#endif | ||
|
||
namespace chip { | ||
namespace DeviceLayer { | ||
class KMUKeyAllocator : public chip::Crypto::PSAKeyAllocator | ||
{ | ||
public: | ||
psa_key_id_t GetDacKeyId() override | ||
{ | ||
return PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, | ||
CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID); | ||
} | ||
psa_key_id_t GetOpKeyId(FabricIndex fabricIndex) override | ||
{ | ||
return static_cast<psa_key_id_t>(KMU_NOC_SLOT_START + ((fabricIndex - 1) * KMU_SLOTS_PER_NOC_KEY)); | ||
} | ||
psa_key_id_t AllocateICDKeyId() override | ||
{ | ||
psa_key_id_t newKeyId = PSA_KEY_ID_NULL; | ||
if (CHIP_NO_ERROR != FindFreeSlot(newKeyId, KMU_ICD_SLOT_START, KMU_ICD_SLOT_START + KMU_SLOTS_ICD_MAX_NUMBER)) | ||
{ | ||
newKeyId = PSA_KEY_ID_NULL; | ||
} | ||
return newKeyId; | ||
} | ||
void UpdateKeyAttributes(psa_key_attributes_t & attrs) override | ||
{ | ||
// Set the key lifetime to persistent and the location to CRACEN_KMU if key is in a proper range | ||
if (psa_get_key_id(&attrs) >= | ||
PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, CONFIG_CHIP_KMU_SLOT_RANGE_START) && | ||
psa_get_key_id(&attrs) < | ||
PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, CONFIG_CHIP_KMU_SLOT_RANGE_END)) | ||
{ | ||
psa_set_key_lifetime( | ||
&attrs, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_CRACEN_KMU)); | ||
} | ||
// TODO: Currently ECDSA keys are supported only if HASH_ANY is provided, so change it. | ||
// Remove this workaround once KMU supports ECDSA SHA256. | ||
if (psa_get_key_algorithm(&attrs) == PSA_ALG_ECDSA(PSA_ALG_SHA_256)) | ||
{ | ||
psa_set_key_algorithm(&attrs, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)); | ||
} | ||
|
||
// TODO: Change PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8) to PSA_ALG_CCM | ||
// To be compatible with the KMU. Remove this workaround once KMU supports PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG. | ||
// Currently we need to use EXPORT flag because the Cracen does not support copying keys from ITS to KMU | ||
if (psa_get_key_algorithm(&attrs) == PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8)) | ||
{ | ||
psa_set_key_algorithm(&attrs, PSA_ALG_CCM); | ||
psa_set_key_usage_flags(&attrs, psa_get_key_usage_flags(&attrs) | PSA_KEY_USAGE_EXPORT); | ||
} | ||
|
||
// TODO: Currently we need to use EXPORT flag because the Cracen does not support copying keys from ITS to KMU | ||
if (psa_get_key_type(&attrs) == PSA_KEY_TYPE_HMAC) | ||
{ | ||
psa_set_key_usage_flags(&attrs, psa_get_key_usage_flags(&attrs) | PSA_KEY_USAGE_EXPORT); | ||
} | ||
} | ||
|
||
private: | ||
CHIP_ERROR FindFreeSlot(psa_key_id_t & keyId, psa_key_id_t start, psa_key_id_t end) | ||
{ | ||
psa_key_attributes_t attributes; | ||
psa_status_t status = PSA_SUCCESS; | ||
for (keyId = start; keyId < end; ++keyId) | ||
{ | ||
status = psa_get_key_attributes(keyId, &attributes); | ||
if (status == PSA_ERROR_INVALID_HANDLE) | ||
{ | ||
return CHIP_NO_ERROR; | ||
} | ||
else if (status != PSA_SUCCESS) | ||
{ | ||
return CHIP_ERROR_INTERNAL; | ||
} | ||
psa_reset_key_attributes(&attributes); | ||
} | ||
return CHIP_ERROR_NOT_FOUND; | ||
} | ||
}; | ||
|
||
} // namespace DeviceLayer | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters