diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig index 96ef72bf09..954ec96fa8 100644 --- a/config/nrfconnect/chip-module/Kconfig +++ b/config/nrfconnect/chip-module/Kconfig @@ -368,15 +368,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. diff --git a/src/platform/nrfconnect/FactoryDataProvider.cpp b/src/platform/nrfconnect/FactoryDataProvider.cpp index 0192dcd44d..204a4d6fc2 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.cpp +++ b/src/platform/nrfconnect/FactoryDataProvider.cpp @@ -26,6 +26,10 @@ #include +#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU +#include +#endif + #ifdef CONFIG_CHIP_CRYPTO_PSA #include #include @@ -129,6 +133,17 @@ CHIP_ERROR FactoryDataProvider::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_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) { @@ -145,19 +160,24 @@ CHIP_ERROR FactoryDataProvider::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(mFactoryData.dac_priv_key.data), - kDACPrivateKeyLength, &mDACPrivKeyId) == PSA_SUCCESS, - CHIP_ERROR_INTERNAL); +#endif // CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY } + VerifyOrReturnError(psa_import_key(&attributes, reinterpret_cast(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 @@ -203,12 +223,12 @@ CHIP_ERROR FactoryDataProvider::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 } return CHIP_NO_ERROR; } -#endif +#endif // CONFIG_CHIP_CRYPTO_PSA template CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) @@ -293,7 +313,7 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(c LoadKeypairFromRaw(ByteSpan(reinterpret_cast(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); }