Skip to content

Commit 317ff0e

Browse files
[nrf toup] Migrate DAC to CRACEN KMU on nRF54L devices
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>
1 parent 731aac5 commit 317ff0e

File tree

2 files changed

+66
-15
lines changed

2 files changed

+66
-15
lines changed

config/nrfconnect/chip-module/Kconfig

+33-1
Original file line numberDiff line numberDiff line change
@@ -365,15 +365,47 @@ config CHIP_ENABLE_READ_CLIENT
365365
Disabling this config can save flash and RAM space.
366366

367367
config CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
368-
bool "Migrate DAC private key from factory data to PSA ITS"
368+
bool "Migrate DAC private key from factory data to a secure storage"
369369
depends on CHIP_CRYPTO_PSA
370370
depends on CHIP_FACTORY_DATA
371+
372+
choice CHIP_CRYPTO_PSA_DAC_PRIV_KEY_MIGRATION_DEST
373+
prompt "Destination for DAC private key migration"
374+
default CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS
375+
376+
config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS
377+
bool "Migrate DAC private key from factory data to PSA ITS"
371378
help
372379
Move DAC private key from the factory data set to the PSA ITS secure storage
373380
and remove it. After the first boot of the device the DAC private key will be moved
374381
to the PSA ITS secure storage and will not be available in the factory data anymore.
375382
It will be overwritten in the factory data set by zeros.
376383

384+
config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
385+
bool "Migrate DAC private key from factory data to CRACEN KMU"
386+
depends on CRACEN_LIB_KMU
387+
help
388+
Move DAC private key from the factory data set to the CRACEN Key Management Unit (KMU) secure
389+
storage and remove it. After the first boot of the device the DAC private key will be
390+
moved to the CRACEN KMU secure storage and will not be available in the factory data anymore.
391+
It will be overwritten in the factory data set by zeros.
392+
393+
endchoice
394+
395+
config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID
396+
int "Destination DAC private key slot ID inside CRACEN KMU"
397+
depends on CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
398+
range 0 179 # Allow using the application usage space only
399+
default 176 if CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
400+
default 178
401+
402+
config CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
403+
bool "Encrypt DAC private key in CRACEN KMU"
404+
default y
405+
depends on CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
406+
help
407+
Encrypt the DAC private key in the CRACEN KMU secure storage.
408+
377409
config CHIP_PERSISTENT_SUBSCRIPTIONS
378410
default n
379411
# selecting experimental for this feature since there is an issue with multiple controllers.

src/platform/nrfconnect/FactoryDataProvider.cpp

+33-14
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

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

29+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
30+
#include <cracen_psa_kmu.h>
31+
#endif
32+
2933
#ifdef CONFIG_CHIP_CRYPTO_PSA
3034
#include <lib/support/ScopedBuffer.h>
3135
#include <psa/crypto.h>
@@ -129,6 +133,17 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
129133
uint8_t clearedDACPrivKey[kDACPrivateKeyLength];
130134
memset(clearedDACPrivKey, 0x00, sizeof(clearedDACPrivKey));
131135

136+
// If key should be migrated to KMU save the KMU key slot to keyId.
137+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
138+
mDACPrivKeyId = static_cast<psa_key_id_t>(PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(
139+
#ifdef CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
140+
CRACEN_KMU_KEY_USAGE_SCHEME_ENCRYPTED,
141+
#else
142+
CRACEN_KMU_KEY_USAGE_SCHEME_RAW,
143+
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_ENCRYPTED
144+
CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU_SLOT_ID));
145+
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
146+
132147
// Check if factory data contains DAC private key
133148
if (memcmp(mFactoryData.dac_priv_key.data, clearedDACPrivKey, kDACPrivateKeyLength) != 0)
134149
{
@@ -145,19 +160,24 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
145160
psa_reset_key_attributes(&attributes);
146161
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
147162
psa_set_key_bits(&attributes, kDACPrivateKeyLength * 8);
148-
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
163+
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
164+
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
165+
psa_set_key_id(&attributes, mDACPrivKeyId);
149166
#ifdef CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
167+
#if defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS)
150168
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
151-
psa_set_key_id(&attributes, mDACPrivKeyId);
169+
#elif defined(CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU)
170+
psa_set_key_lifetime(
171+
&attributes,
172+
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_CRACEN_KMU));
173+
#endif // CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_ITS || CONFIG_CHIP_CRYPTO_PSA_DAC_PRIV_KEY_KMU
152174
#else
153175
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
154-
#endif
155-
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
156-
157-
VerifyOrReturnError(psa_import_key(&attributes, reinterpret_cast<uint8_t *>(mFactoryData.dac_priv_key.data),
158-
kDACPrivateKeyLength, &mDACPrivKeyId) == PSA_SUCCESS,
159-
CHIP_ERROR_INTERNAL);
160-
}
176+
#endif // CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
177+
} // namespace DeviceLayer
178+
VerifyOrReturnError(psa_import_key(&attributes, reinterpret_cast<uint8_t *>(mFactoryData.dac_priv_key.data),
179+
mFactoryData.dac_priv_key.len, &mDACPrivKeyId) == PSA_SUCCESS,
180+
CHIP_ERROR_INTERNAL);
161181

162182
#ifdef CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
163183
#ifdef CONFIG_CHIP_FACTORY_RESET_ERASE_SETTINGS
@@ -203,12 +223,12 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::MoveDACPrivateKeyToSecureStora
203223
// Verify if the factory data does not contain the DAC private key anymore.
204224
VerifyOrReturnError(memcmp(mFactoryData.dac_priv_key.data, clearedDACPrivKey, kDACPrivateKeyLength) == 0,
205225
CHIP_ERROR_INTERNAL);
206-
#endif
207-
}
226+
#endif // CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY
227+
} // namespace chip
208228

209229
return CHIP_NO_ERROR;
210230
}
211-
#endif
231+
#endif // CONFIG_CHIP_CRYPTO_PSA
212232

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

276296
#ifdef CONFIG_CHIP_CRYPTO_PSA
277297
size_t outputLen = 0;
278-
279298
psa_status_t err = psa_sign_message(mDACPrivKeyId, PSA_ALG_ECDSA(PSA_ALG_SHA_256), messageToSign.data(), messageToSign.size(),
280299
signature.Bytes(), signature.Capacity(), &outputLen);
281300

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

298317
return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer);
299318
}

0 commit comments

Comments
 (0)