Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions config/nrfconnect/chip-module/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ endif # CHIP_FACTORY_DATA_NRFCONNECT_BACKEND

# See config/zephyr/Kconfig for full definition
config CHIP_FACTORY_RESET_ERASE_SETTINGS
depends on !CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
default y if !CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS || BUILD_WITH_TFM

config CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
Expand All @@ -331,7 +332,7 @@ if CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY

choice CHIP_CRYPTO_PSA_DAC_PRIV_KEY_MIGRATION_DEST
prompt "Destination for DAC private key migration"
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU if CRACEN_KMU
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU if (CRACEN_KMU || CRACEN_LIB_KMU)
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS

config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS
Expand All @@ -344,7 +345,7 @@ config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS

config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
bool "Migrate DAC private key from factory data to CRACEN KMU"
depends on CRACEN_KMU
depends on (CRACEN_KMU || 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
Expand All @@ -367,11 +368,22 @@ config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
help
Encrypt the DAC private key in the CRACEN KMU secure storage.

config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
bool "Use DAC private key from PSA ITS when KMU migration is configured"
depends on CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
default y
help
When CRACEN KMU is selected as the DAC private key migration destination but
the key is still stored in PSA ITS (for example after switching the migration
destination from ITS to KMU), allow the device to boot by signing with the
ITS key and logging a warning instead of aborting. Automatic migration from
ITS to KMU is not supported, re-provision the device to move the key to KMU.

endif # CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY

config CHIP_STORE_KEYS_IN_KMU
bool "Use KMU to store crypto keys"
depends on CRACEN_KMU
depends on (CRACEN_KMU || CRACEN_LIB_KMU)
select EXPERIMENTAL
help
Stores cryptographic materials like keys in the KMU if available on the device.
Expand Down
57 changes: 55 additions & 2 deletions src/platform/nrfconnect/FactoryDataProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::Init()
}

#ifdef CONFIG_CHIP_CRYPTO_PSA
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
FallbackToItsIfNeeded();
#endif
VerifyOrDie(MoveDACPrivateKeyToSecureStorage(factoryData, factoryDataSize) == CHIP_NO_ERROR);
#endif

Expand Down Expand Up @@ -125,14 +128,25 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
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
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && !defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
mDACPrivKeyId = static_cast<psa_key_id_t>(PSA_KEY_ID_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));
#elif defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
if (!mUseDacPrivKeyFromIts)
{
mDACPrivKeyId = static_cast<psa_key_id_t>(PSA_KEY_ID_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
Expand Down Expand Up @@ -220,6 +234,37 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora

return CHIP_NO_ERROR;
}

#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
template <class FlashFactoryData>
void FactoryDataProvider<FlashFactoryData>::FallbackToItsIfNeeded()
{
const psa_key_id_t itsDacKeyId = to_underlying(chip::Crypto::KeyIdBase::DACPrivKey);

psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
const psa_status_t status = psa_get_key_attributes(itsDacKeyId, &attributes);

psa_reset_key_attributes(&attributes);

if (status == PSA_SUCCESS)
{
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
ChipLogProgress(DeviceLayer,
"Warning: DAC private key found in PSA ITS while CRACEN KMU storage is configured. "
"Using the ITS key for attestation signing. Automatic migration from ITS to KMU is "
"not supported; re-provision the device to move the key to KMU.");
mUseDacPrivKeyFromIts = true;
mDACPrivKeyId = itsDacKeyId;
#else
ChipLogError(DeviceLayer,
"DAC private key found in PSA ITS while CRACEN KMU storage is configured. "
"Automatic migration from ITS to KMU is not supported. "
"Re-provision the device.");
VerifyOrDie(false);
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
}
}
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
#endif // CONFIG_CHIP_CRYPTO_PSA

template <class FlashFactoryData>
Expand Down Expand Up @@ -288,7 +333,15 @@ 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(),
psa_key_id_t dacPrivKeyId = mDACPrivKeyId;
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
if (mUseDacPrivKeyFromIts)
{
dacPrivKeyId = static_cast<psa_key_id_t>(to_underlying(chip::Crypto::KeyIdBase::DACPrivKey));
}
#endif

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

VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL);
Expand Down
7 changes: 7 additions & 0 deletions src/platform/nrfconnect/FactoryDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ class FactoryDataProvider : public FactoryDataProviderBase
CHIP_ERROR MoveDACPrivateKeyToSecureStorage(uint8_t * factoryDataPartition, size_t factoryDataSize);
#endif

#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
void FallbackToItsIfNeeded();
#endif // CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU

// ===== Members functions that implement the DeviceAttestationCredentialsProvider
CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override;
CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override;
Expand Down Expand Up @@ -200,6 +204,9 @@ class FactoryDataProvider : public FactoryDataProviderBase
FlashFactoryData mFlashFactoryData;
#ifdef CONFIG_CHIP_CRYPTO_PSA
psa_key_id_t mDACPrivKeyId = to_underlying(chip::Crypto::KeyIdBase::DACPrivKey);
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
bool mUseDacPrivKeyFromIts = false;
#endif
#endif
};

Expand Down
Loading