Skip to content

Commit

Permalink
[nrf toup] Migrate DAC to CRACEN KMU on nRF54L devices
Browse files Browse the repository at this point in the history
On nRF54L devices we can use KMU to store the DAC private key,
and allow using it directly by CRACEN.
By default the DAC private key is encrypted so it needs
4 KMU slots.

Signed-off-by: Arkadiusz Balys <arkadiusz.balys@nordicsemi.no>
  • Loading branch information
ArekBalysNordic committed Oct 23, 2024
1 parent 731aac5 commit 317ff0e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 15 deletions.
34 changes: 33 additions & 1 deletion config/nrfconnect/chip-module/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -365,15 +365,47 @@ config CHIP_ENABLE_READ_CLIENT
Disabling this config can save flash and RAM space.

config CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
bool "Migrate DAC private key from factory data to PSA ITS"
bool "Migrate DAC private key from factory data to a secure storage"
depends on CHIP_CRYPTO_PSA
depends on CHIP_FACTORY_DATA

choice CHIP_CRYPTO_PSA_DAC_PRIV_KEY_MIGRATION_DEST
prompt "Destination for DAC private key migration"
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS

config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS
bool "Migrate DAC private key from factory data to PSA ITS"
help
Move DAC private key from the factory data set to the PSA ITS secure storage
and remove it. After the first boot of the device the DAC private key will be moved
to the PSA ITS secure storage and will not be available in the factory data anymore.
It will be overwritten in the factory data set by zeros.

config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
bool "Migrate DAC private key from factory data to CRACEN KMU"
depends on CRACEN_LIB_KMU
help
Move DAC private key from the factory data set to the CRACEN Key Management Unit (KMU) secure
storage and remove it. After the first boot of the device the DAC private key will be
moved to the CRACEN KMU secure storage and will not be available in the factory data anymore.
It will be overwritten in the factory data set by zeros.

endchoice

config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID
int "Destination DAC private key slot ID inside CRACEN KMU"
depends on CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
range 0 179 # Allow using the application usage space only
default 176 if CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
default 178

config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
bool "Encrypt DAC private key in CRACEN KMU"
default y
depends on CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
help
Encrypt the DAC private key in the CRACEN KMU secure storage.

config CHIP_PERSISTENT_SUBSCRIPTIONS
default n
# selecting experimental for this feature since there is an issue with multiple controllers.
Expand Down
47 changes: 33 additions & 14 deletions src/platform/nrfconnect/FactoryDataProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

#include <lib/support/logging/CHIPLogging.h>

#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
#include <cracen_psa_kmu.h>
#endif

#ifdef CONFIG_CHIP_CRYPTO_PSA
#include <lib/support/ScopedBuffer.h>
#include <psa/crypto.h>
Expand Down Expand Up @@ -129,6 +133,17 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
uint8_t clearedDACPrivKey[kDACPrivateKeyLength];
memset(clearedDACPrivKey, 0x00, sizeof(clearedDACPrivKey));

// If key should be migrated to KMU save the KMU key slot to keyId.
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
mDACPrivKeyId = static_cast<psa_key_id_t>(PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
CRACEN_KMU_KEY_USAGE_SCHEME_ENCRYPTED,
#else
CRACEN_KMU_KEY_USAGE_SCHEME_RAW,
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID));
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU

// Check if factory data contains DAC private key
if (memcmp(mFactoryData.dac_priv_key.data, clearedDACPrivKey, kDACPrivateKeyLength) != 0)
{
Expand All @@ -145,19 +160,24 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
psa_reset_key_attributes(&attributes);
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&attributes, kDACPrivateKeyLength * 8);
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
psa_set_key_id(&attributes, mDACPrivKeyId);
#ifdef CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS)
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
psa_set_key_id(&attributes, mDACPrivKeyId);
#elif defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU)
psa_set_key_lifetime(
&attributes,
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_CRACEN_KMU));
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS || CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
#else
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
#endif
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);

VerifyOrReturnError(psa_import_key(&attributes, reinterpret_cast<uint8_t *>(mFactoryData.dac_priv_key.data),
kDACPrivateKeyLength, &mDACPrivKeyId) == PSA_SUCCESS,
CHIP_ERROR_INTERNAL);
}
#endif // CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
} // namespace DeviceLayer
VerifyOrReturnError(psa_import_key(&attributes, reinterpret_cast<uint8_t *>(mFactoryData.dac_priv_key.data),
mFactoryData.dac_priv_key.len, &mDACPrivKeyId) == PSA_SUCCESS,
CHIP_ERROR_INTERNAL);

#ifdef CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
#ifdef CONFIG_CHIP_FACTORY_RESET_ERASE_SETTINGS
Expand Down Expand Up @@ -203,12 +223,12 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
// Verify if the factory data does not contain the DAC private key anymore.
VerifyOrReturnError(memcmp(mFactoryData.dac_priv_key.data, clearedDACPrivKey, kDACPrivateKeyLength) == 0,
CHIP_ERROR_INTERNAL);
#endif
}
#endif // CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
} // namespace chip

return CHIP_NO_ERROR;
}
#endif
#endif // CONFIG_CHIP_CRYPTO_PSA

template <class FlashFactoryData>
CHIP_ERROR FactoryDataProvider<FlashFactoryData>::GetCertificationDeclaration(MutableByteSpan & outBuffer)
Expand Down Expand Up @@ -275,7 +295,6 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::SignWithDeviceAttestationKey(c

#ifdef CONFIG_CHIP_CRYPTO_PSA
size_t outputLen = 0;

psa_status_t err = psa_sign_message(mDACPrivKeyId, PSA_ALG_ECDSA(PSA_ALG_SHA_256), messageToSign.data(), messageToSign.size(),
signature.Bytes(), signature.Capacity(), &outputLen);

Expand All @@ -293,7 +312,7 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::SignWithDeviceAttestationKey(c
LoadKeypairFromRaw(ByteSpan(reinterpret_cast<uint8_t *>(mFactoryData.dac_priv_key.data), mFactoryData.dac_priv_key.len),
ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair));
ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature));
#endif
#endif // CONFIG_CHIP_CRYPTO_PSA

return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer);
}
Expand Down

0 comments on commit 317ff0e

Please sign in to comment.