Skip to content

Commit 7801aa8

Browse files
[nrf toup][nrfconnect] Handle DAC key in ITS when KMU migration is selected
Detect when the DAC private key remains in PSA ITS while factory data is configured to migrate the key to CRACEN KMU. Abort boot in that case unless CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK is enabled; then sign attestations with the ITS key and log a warning because ITS-to-KMU migration is not supported. Extend KMU-related Kconfig dependencies to CRACEN_LIB_KMU. Signed-off-by: Arkadiusz Balys <arkadiusz.balys@nordicsemi.no>
1 parent 9775b2c commit 7801aa8

3 files changed

Lines changed: 77 additions & 5 deletions

File tree

‎config/nrfconnect/chip-module/Kconfig‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ endif # CHIP_FACTORY_DATA_NRFCONNECT_BACKEND
319319

320320
# See config/zephyr/Kconfig for full definition
321321
config CHIP_FACTORY_RESET_ERASE_SETTINGS
322+
depends on !CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
322323
default y if !CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS || BUILD_WITH_TFM
323324

324325
config CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
@@ -331,7 +332,7 @@ if CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
331332

332333
choice CHIP_CRYPTO_PSA_DAC_PRIV_KEY_MIGRATION_DEST
333334
prompt "Destination for DAC private key migration"
334-
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU if CRACEN_KMU
335+
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU if (CRACEN_KMU || CRACEN_LIB_KMU)
335336
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS
336337

337338
config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS
@@ -344,7 +345,7 @@ config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS
344345

345346
config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
346347
bool "Migrate DAC private key from factory data to CRACEN KMU"
347-
depends on CRACEN_KMU
348+
depends on (CRACEN_KMU || CRACEN_LIB_KMU)
348349
help
349350
Move DAC private key from the factory data set to the CRACEN Key Management Unit (KMU) secure
350351
storage and remove it. After the first boot of the device the DAC private key will be
@@ -367,11 +368,22 @@ config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
367368
help
368369
Encrypt the DAC private key in the CRACEN KMU secure storage.
369370

371+
config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
372+
bool "Use DAC private key from PSA ITS when KMU migration is configured"
373+
depends on CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
374+
default y
375+
help
376+
When CRACEN KMU is selected as the DAC private key migration destination but
377+
the key is still stored in PSA ITS (for example after switching the migration
378+
destination from ITS to KMU), allow the device to boot by signing with the
379+
ITS key and logging a warning instead of aborting. Automatic migration from
380+
ITS to KMU is not supported, re-provision the device to move the key to KMU.
381+
370382
endif # CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
371383

372384
config CHIP_STORE_KEYS_IN_KMU
373385
bool "Use KMU to store crypto keys"
374-
depends on CRACEN_KMU
386+
depends on (CRACEN_KMU || CRACEN_LIB_KMU)
375387
select EXPERIMENTAL
376388
help
377389
Stores cryptographic materials like keys in the KMU if available on the device.

‎src/platform/nrfconnect/FactoryDataProvider.cpp‎

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::Init()
8585
}
8686

8787
#ifdef CONFIG_CHIP_CRYPTO_PSA
88+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
89+
FallbackToItsIfNeeded();
90+
#endif
8891
VerifyOrDie(MoveDACPrivateKeyToSecureStorage(factoryData, factoryDataSize) == CHIP_NO_ERROR);
8992
#endif
9093

@@ -125,14 +128,25 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
125128
memset(clearedDACPrivKey, 0x00, sizeof(clearedDACPrivKey));
126129

127130
// If key should be migrated to KMU save the KMU key slot to keyId.
128-
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
131+
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && !defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
129132
mDACPrivKeyId = static_cast<psa_key_id_t>(PSA_KEY_ID_FROM_CRACEN_KMU_SLOT(
130133
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
131134
CRACEN_KMU_KEY_USAGE_SCHEME_ENCRYPTED,
132135
#else
133136
CRACEN_KMU_KEY_USAGE_SCHEME_RAW,
134137
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
135138
CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID));
139+
#elif defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
140+
if (!mUseDacPrivKeyFromIts)
141+
{
142+
mDACPrivKeyId = static_cast<psa_key_id_t>(PSA_KEY_ID_FROM_CRACEN_KMU_SLOT(
143+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
144+
CRACEN_KMU_KEY_USAGE_SCHEME_ENCRYPTED,
145+
#else
146+
CRACEN_KMU_KEY_USAGE_SCHEME_RAW,
147+
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
148+
CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID));
149+
}
136150
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
137151

138152
// Check if factory data contains DAC private key
@@ -220,6 +234,37 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
220234

221235
return CHIP_NO_ERROR;
222236
}
237+
238+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
239+
template <class FlashFactoryData>
240+
void FactoryDataProvider<FlashFactoryData>::FallbackToItsIfNeeded()
241+
{
242+
const psa_key_id_t itsDacKeyId = to_underlying(chip::Crypto::KeyIdBase::DACPrivKey);
243+
244+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
245+
const psa_status_t status = psa_get_key_attributes(itsDacKeyId, &attributes);
246+
247+
psa_reset_key_attributes(&attributes);
248+
249+
if (status == PSA_SUCCESS)
250+
{
251+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
252+
ChipLogProgress(DeviceLayer,
253+
"Warning: DAC private key found in PSA ITS while CRACEN KMU storage is configured. "
254+
"Using the ITS key for attestation signing. Automatic migration from ITS to KMU is "
255+
"not supported; re-provision the device to move the key to KMU.");
256+
mUseDacPrivKeyFromIts = true;
257+
mDACPrivKeyId = itsDacKeyId;
258+
#else
259+
ChipLogError(DeviceLayer,
260+
"DAC private key found in PSA ITS while CRACEN KMU storage is configured. "
261+
"Automatic migration from ITS to KMU is not supported. "
262+
"Re-provision the device.");
263+
VerifyOrDie(false);
264+
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK
265+
}
266+
}
267+
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
223268
#endif // CONFIG_CHIP_CRYPTO_PSA
224269

225270
template <class FlashFactoryData>
@@ -288,7 +333,15 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::SignWithDeviceAttestationKey(c
288333
#ifdef CONFIG_CHIP_CRYPTO_PSA
289334
size_t outputLen = 0;
290335

291-
psa_status_t err = psa_sign_message(mDACPrivKeyId, PSA_ALG_ECDSA(PSA_ALG_SHA_256), messageToSign.data(), messageToSign.size(),
336+
psa_key_id_t dacPrivKeyId = mDACPrivKeyId;
337+
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
338+
if (mUseDacPrivKeyFromIts)
339+
{
340+
dacPrivKeyId = static_cast<psa_key_id_t>(to_underlying(chip::Crypto::KeyIdBase::DACPrivKey));
341+
}
342+
#endif
343+
344+
psa_status_t err = psa_sign_message(dacPrivKeyId, PSA_ALG_ECDSA(PSA_ALG_SHA_256), messageToSign.data(), messageToSign.size(),
292345
signature.Bytes(), signature.Capacity(), &outputLen);
293346

294347
VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL);

‎src/platform/nrfconnect/FactoryDataProvider.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ class FactoryDataProvider : public FactoryDataProviderBase
153153
CHIP_ERROR MoveDACPrivateKeyToSecureStorage(uint8_t * factoryDataPartition, size_t factoryDataSize);
154154
#endif
155155

156+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
157+
void FallbackToItsIfNeeded();
158+
#endif // CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
159+
156160
// ===== Members functions that implement the DeviceAttestationCredentialsProvider
157161
CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override;
158162
CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override;
@@ -200,6 +204,9 @@ class FactoryDataProvider : public FactoryDataProviderBase
200204
FlashFactoryData mFlashFactoryData;
201205
#ifdef CONFIG_CHIP_CRYPTO_PSA
202206
psa_key_id_t mDACPrivKeyId = to_underlying(chip::Crypto::KeyIdBase::DACPrivKey);
207+
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU) && defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ITS_FALLBACK)
208+
bool mUseDacPrivKeyFromIts = false;
209+
#endif
203210
#endif
204211
};
205212

0 commit comments

Comments
 (0)