Crypto: KMU usage with CRACEN
The KMU usage with CRACEN sample demonstrates how to generate cryptographic keys and securely store them in the Key Management Unit (KMU) on devices with the CRACEN hardware peripheral.
The sample also demonstrates how to use the PSA Key Attributes generator script to generate the keys.json file and then provision it to the KMU using nRF Util.
This provisioning operation can be done before the sample generates the keys.
Requirements
The sample supports the following development kits:
Hardware platforms |
PCA |
Board name |
|
|---|---|---|---|
nRF7120 DK |
nrf7120dk |
|
|
nRF54LV10 DK |
PCA10188 |
|
|
PCA10184 |
|
||
nRF54LC10 DK |
PCA10226 |
nrf54lc10dk |
|
PCA10156 |
|
||
PCA10156 |
|
||
PCA10156 |
|
For more security, it is recommended to use the */ns variant of the board target.
When built for this variant, the sample is configured to compile and run as a non-secure application using security by separation.
Therefore, it automatically includes Trusted Firmware-M that prepares the required peripherals and secure services to be available for the application.
Overview
The KMU usage with CRACEN sample enables the PSA Crypto API to generate various persistent keys. These keys are stored in the Key Management Unit (KMU) of the device and retain their value between device resets. The KMU is one of the key storage options in the nRF Connect SDK.
The sample uses the Oberon PSA Crypto and the CRACEN driver. The usage of the nrf_oberon driver is disabled in the sample.
Keys used by the sample
The sample uses the following cryptographic operations:
Cryptographic operation |
Type |
Usage |
|---|---|---|
AES-128 |
Provisioned using |
|
AES-128 |
Generated by the sample firmware. |
|
EdDSA with Ed25519 curve |
Provisioned using |
|
ECDSA with secp256r1 curve |
Generated by the sample firmware. |
The sample provides examples of the keys and key pairs that are provisioned before programming the sample.
You can find these examples in the keys/sources directory.
See the Configuration files section for more information.
Note
These examples are not intended for production use.
Sample operations
After you provision the keys to the KMU using keys.json and program the sample to the device, the sample performs the following operations:
Initialization of the PSA Crypto API.
Generation of a persistent AES 128-bit key and ECDSA key pair.
Removal of the keys from RAM.
Encryption and decryption using both keys (key pairs) provisioned before programming the sample and keys (key pairs) generated by the sample firmware. Alternatively, signing and verifying a message or its hash.
Cleanup. All persistent keys (key pairs) generated by the sample firmware are removed from the KMU, while all keys (key pairs) provisioned before programming the sample remain in the KMU between device resets.
Note
The read-only type of persistent keys cannot be destroyed with the psa_destroy_key() function.
The PSA_KEY_PERSISTENCE_READ_ONLY macro is used for read-only keys.
The key ID of a read-only key is writable again after a full erase of the device memory.
Use the standard programming command for the full erase.
Configuration
See Configuring and building for information about how to permanently or temporarily change the configuration.
Configuration files
Note
These files are not intended for production use.
The sample provides the following configuration files:
File |
Location |
Description |
|---|---|---|
|
JSON file used for provisioning keys to the device before programming the sample. This file was created with the PSA Key Attributes generator script and is meant to be provisioned to the KMU using nRF Util. See Generating example keys from scratch for information on how to generate these keys from scratch. |
|
|
|
Source file for the AES-128 key that is used for crating the |
|
|
Source file for the EdDSA with Ed25519 curve key pair that is used for crating the |
Generating example keys from scratch
If you do not want to use the provided examples, you can generate the keys and key pairs from scratch.
Generating AES-128 key
To generate the AES-128 key, you can use the OpenSSL command.
The following command was used to generate the key saved in the aes_128_key.txt file available as an example in the keys/sources directory:
openssl rand -hex -out aes_128_key.txt 16
Generating EdDSA with Ed25519 curve key pair
To generate the EdDSA with Ed25519 curve key pair, you can use the bootloader/mcuboot/scripts/imgtool.py script.
See the Managing keys section in the MCUboot documentation for more information.
The following command was used to generate the key saved in the my_ed25519_priv_key.pem file available as an example in the keys/sources directory:
python3 imgtool.py keygen -k my_ed25519_priv_key.pem -t ed25519
Generating the JSON file
After keys have been generated, you must put them to the keys.json file, which then will be used to manually provision the keys using nRF Util.
See PSA Key Attributes generator script for more information.
The following commands were used to generate the keys.json file available as an example in the keys directory:
The following command was used to add the AES-128 key to the
keys.jsonfile:python3 generate_psa_key_attributes.py \ --usage ENCRYPT_DECRYPT \ --id 1 \ --type AES \ --key-bits 128 \ --location LOCATION_CRACEN_KMU \ --cracen-usage PROTECTED \ --algorithm CTR \ --persistence PERSISTENCE_DEFAULT \ --key 0x44daa497a188ad60c7962cba7c5c7d8f \ --file keys.json
The following command was used to add the EdDSA with Ed25519 curve key pair to the
keys.jsonfile:python3 generate_psa_key_attributes.py \ --usage SIGN \ --id 2 \ --type ECC_KEY_PAIR_TWISTED_EDWARDS \ --key-bits 255 \ --location LOCATION_CRACEN_KMU \ --cracen-usage RAW \ --algorithm EDDSA_PURE \ --persistence PERSISTENCE_DEFAULT \ --key-from-file sources/my_ed25519_priv_key.pem \ --file keys.json
Note
In case you need to provision the key with --cracen-usage ENCRYPTED option, make sure the seed value is provisioned.
See the Testing with KMU encryption section for more information.
For more information about the seed value, see CRACEN Isolated Key Generator.
Building and running
Note
Do not program the sample after building it. Program the sample only after provisioning the keys to the board using nRF Util. See the Testing section for more information.
This sample can be found under samples/crypto/kmu_cracen_usage in the nRF Connect SDK folder structure.
For more security, it is recommended to use the */ns variant of the board target (see the Requirements section above.)
When built for this variant, the sample is configured to compile and run as a non-secure application using security by separation.
Therefore, it automatically includes Trusted Firmware-M that prepares the required peripherals and secure services to be available for the application.
To build the sample, follow the instructions in Building an application for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.
Note
When building repository applications in the SDK repositories, building with sysbuild is enabled by default.
If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.
Testing
Before you program the sample to your development kit, complete the following steps:
Connect the kit to the computer using a USB cable. The kit is assigned a serial port. Serial ports are referred to as COM ports on Windows, /dev/ttyACM devices on Linux, and /dev/tty devices on macOS. To list Nordic Semiconductor devices connected to your computer together with their serial ports, open a terminal and run the
nrfutil device listcommand. Alternatively, check your operating system’s device manager or its equivalent.Connect to the kit with a terminal emulator (for example, the Serial Terminal app). See Testing and optimization for the required settings and steps.
Perform a full erase of the device. You can use nRF Util’s device command for this purpose:
nrfutil device erase --allRun the following nRF Util command to provision the example keys to the board:
nrfutil device x-provision-keys --key-file keys\keys.jsonFor more information, see Provisioning keys to the board.
Build the sample if you have not built it yet.
Program the sample to your device. The sample now runs the steps listed in the Sample operations section and generates a second pair of keys.
In the terminal, observe the logs from the application. Expand the following section for a sample output.
*** Booting nRF Connect SDK v3.1.99-08eeaae7de8f *** *** Using Zephyr OS v4.2.99-318b87179093 *** [00:00:00.011,510] <inf> kmu_cracen_usage: Starting KMU Cracen usage example... [00:00:00.011,519] <inf> kmu_cracen_usage: Preparing non-provisioned keys... [00:00:00.011,523] <inf> kmu_cracen_usage: Generating key [2] [00:00:00.011,528] <inf> kmu_cracen_usage: Generating random AES key... [00:00:00.014,202] <inf> kmu_cracen_usage: A key generated successfully! [00:00:00.014,208] <inf> kmu_cracen_usage: Generating key [3] [00:00:00.014,212] <inf> kmu_cracen_usage: Generating random ECDSA keypair... [00:00:00.015,768] <inf> kmu_cracen_usage: ECDSA key pair generated successfully! [00:00:00.015,774] <inf> kmu_cracen_usage: All keys prepared [00:00:00.015,778] <inf> kmu_cracen_usage: Using keys... [00:00:00.015,783] <inf> kmu_cracen_usage: Using key [0] [00:00:00.016,114] <inf> kmu_cracen_usage: Encryption successful! [00:00:00.016,133] <inf> kmu_cracen_usage: ---- Plaintext (len: 100): ---- [00:00:00.016,148] <inf> kmu_cracen_usage: Content: 45 78 61 6d 70 6c 65 20 73 74 72 69 6e 67 20 74 |Example string t 6f 20 64 65 6d 6f 6e 73 74 72 61 74 65 20 62 61 |o demons trate ba 73 69 63 20 75 73 61 67 65 20 6f 66 20 4b 4d 55 |sic usag e of KMU 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 |.... [00:00:00.016,159] <inf> kmu_cracen_usage: ---- Plaintext end ---- [00:00:00.016,170] <inf> kmu_cracen_usage: ---- Encrypted text (len: 116): ---- [00:00:00.016,186] <inf> kmu_cracen_usage: Content: 3a df a0 75 54 5a 39 c5 ec 42 a1 3e ec 0e a3 01 |:..uTZ9. .B.>.... 1a 67 bf 85 fa 25 ff 17 24 47 34 fb a7 c2 de af |.g...%.. $G4..... f4 99 e4 4d 6b cb 0c d4 78 31 4f 5e c3 ef 22 aa |...Mk... x1O^..". 58 9d d4 03 b4 c0 71 91 9e da f1 b4 3d 09 a8 b3 |X.....q. ....=... cb 13 b1 74 57 41 29 cb e2 44 8d 38 e3 4a 20 5c |...tWA). .D.8.J \ 04 05 e1 fe 32 60 87 19 3b e0 0f c3 4a 2b da 8d |....2`.. ;...J+.. 1f 10 82 f3 77 db 77 3a a9 69 58 da 4e 8d 3b cb |....w.w: .iX.N.;. dd c8 45 46 |..EF [00:00:00.016,198] <inf> kmu_cracen_usage: ---- Encrypted text end ---- [00:00:00.016,390] <inf> kmu_cracen_usage: ---- Decrypted text (len: 100): ---- [00:00:00.016,406] <inf> kmu_cracen_usage: Content: 45 78 61 6d 70 6c 65 20 73 74 72 69 6e 67 20 74 |Example string t 6f 20 64 65 6d 6f 6e 73 74 72 61 74 65 20 62 61 |o demons trate ba 73 69 63 20 75 73 61 67 65 20 6f 66 20 4b 4d 55 |sic usag e of KMU 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 |.... [00:00:00.016,418] <inf> kmu_cracen_usage: ---- Decrypted text end ---- [00:00:00.016,433] <inf> kmu_cracen_usage: Decryption successful! [00:00:00.016,438] <inf> kmu_cracen_usage: Using key [1] [00:00:00.016,442] <inf> kmu_cracen_usage: Using EdDSA key pair... [00:00:00.017,553] <inf> kmu_cracen_usage: ---- Public-key (len: 32): ---- [00:00:00.017,567] <inf> kmu_cracen_usage: Content: c3 ee 92 c7 67 1c 53 38 9e 00 95 b1 0a 09 32 e7 |....g.S8 ......2. 64 37 8b 33 31 93 59 e9 54 2e 8b b4 ac 49 cb 28 |d7.31.Y. T....I.( [00:00:00.017,578] <inf> kmu_cracen_usage: ---- Public-key end ---- [00:00:00.017,620] <inf> kmu_cracen_usage: Signing a message using EDDSA... [00:00:00.019,918] <inf> kmu_cracen_usage: Message signed successfully! [00:00:00.019,937] <inf> kmu_cracen_usage: ---- Plaintext (len: 100): ---- [00:00:00.019,952] <inf> kmu_cracen_usage: Content: 45 78 61 6d 70 6c 65 20 73 74 72 69 6e 67 20 74 |Example string t 6f 20 64 65 6d 6f 6e 73 74 72 61 74 65 20 62 61 |o demons trate ba 73 69 63 20 75 73 61 67 65 20 6f 66 20 4b 4d 55 |sic usag e of KMU 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 |.... [00:00:00.019,963] <inf> kmu_cracen_usage: ---- Plaintext end ---- [00:00:00.019,974] <inf> kmu_cracen_usage: ---- Signature (len: 64): ---- [00:00:00.019,988] <inf> kmu_cracen_usage: Content: 33 08 d6 64 ce 2f c1 9e 99 da 85 47 06 06 e5 1d |3..d./.. ...G.... 8a f7 5f 8f 5b 6f d8 eb 9b 1f 11 30 07 4f a0 2e |.._.[o.. ...0.O.. da 43 27 f6 89 d9 fa 9c b2 e2 01 60 d0 0e 9a 79 |.C'..... ...`...y fe 76 25 c3 c7 2c 13 9f ee 34 fb 6a 61 90 58 09 |.v%..,.. .4.ja.X. [00:00:00.020,001] <inf> kmu_cracen_usage: ---- Signature end ---- [00:00:00.020,005] <inf> kmu_cracen_usage: Verifying EDDSA signature... [00:00:00.021,464] <inf> kmu_cracen_usage: EdDSA signature verification was successful! [00:00:00.021,489] <inf> kmu_cracen_usage: Using key [2] [00:00:00.022,813] <inf> kmu_cracen_usage: Encryption successful! [00:00:00.022,832] <inf> kmu_cracen_usage: ---- Plaintext (len: 100): ---- [00:00:00.022,847] <inf> kmu_cracen_usage: Content: 45 78 61 6d 70 6c 65 20 73 74 72 69 6e 67 20 74 |Example string t 6f 20 64 65 6d 6f 6e 73 74 72 61 74 65 20 62 61 |o demons trate ba 73 69 63 20 75 73 61 67 65 20 6f 66 20 4b 4d 55 |sic usag e of KMU 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 |.... [00:00:00.022,859] <inf> kmu_cracen_usage: ---- Plaintext end ---- [00:00:00.022,870] <inf> kmu_cracen_usage: ---- Encrypted text (len: 116): ---- [00:00:00.022,885] <inf> kmu_cracen_usage: Content: 03 da 50 08 37 e9 26 a0 5b 82 71 dc 82 fb 1e 44 |..P.7.&. [.q....D e0 ad 9b 38 87 e1 4f 67 a7 39 67 4b 70 39 ad 08 |...8..Og .9gKp9.. 00 c3 b6 9c 25 de a5 9d 79 3f 52 61 bf 4d 43 1b |....%... y?Ra.MC. 92 b3 78 0c 1f 29 4c 98 7d 25 05 0f 28 ee 81 2a |..x..)L. }%..(..* 1d 63 d4 a4 cc 1f 15 9a 46 9f da 12 f4 15 31 c8 |.c...... F.....1. 9e 16 79 b0 32 e7 4a 4b 42 5f 52 8b c1 d9 5a fe |..y.2.JK B_R...Z. ab 7f 25 45 f0 f9 f2 39 c5 ee 80 d9 33 81 4f 34 |..%E...9 ....3.O4 ea 45 6b 24 |.Ek$ [00:00:00.022,897] <inf> kmu_cracen_usage: ---- Encrypted text end ---- [00:00:00.024,081] <inf> kmu_cracen_usage: ---- Decrypted text (len: 100): ---- [00:00:00.024,097] <inf> kmu_cracen_usage: Content: 45 78 61 6d 70 6c 65 20 73 74 72 69 6e 67 20 74 |Example string t 6f 20 64 65 6d 6f 6e 73 74 72 61 74 65 20 62 61 |o demons trate ba 73 69 63 20 75 73 61 67 65 20 6f 66 20 4b 4d 55 |sic usag e of KMU 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 |.... [00:00:00.024,109] <inf> kmu_cracen_usage: ---- Decrypted text end ---- [00:00:00.024,124] <inf> kmu_cracen_usage: Decryption successful! [00:00:00.024,129] <inf> kmu_cracen_usage: Using key [3] [00:00:00.024,133] <inf> kmu_cracen_usage: Using ECDSA key pair... [00:00:00.025,163] <inf> kmu_cracen_usage: ---- Public-key (len: 65): ---- [00:00:00.025,178] <inf> kmu_cracen_usage: Content: 04 2e 82 70 82 27 1e 1a ea d1 84 aa 51 5a d1 78 |...p.'.. ....QZ.x 12 d2 10 ac 25 88 5a d7 53 12 6d 03 42 12 de 84 |....%.Z. S.m.B... 35 3a c5 a7 75 29 00 ea 7f e3 3b d2 d1 a0 a3 ba |5:..u).. ..;..... 18 2b b1 42 3c bd d9 9b c8 99 14 61 f4 b6 1c bc |.+.B<... ...a.... 42 |B [00:00:00.025,190] <inf> kmu_cracen_usage: ---- Public-key end ---- [00:00:00.025,240] <inf> kmu_cracen_usage: Signing a message using ECDSA... [00:00:00.026,471] <inf> kmu_cracen_usage: Message signed successfully! [00:00:00.026,490] <inf> kmu_cracen_usage: ---- Plaintext (len: 100): ---- [00:00:00.026,505] <inf> kmu_cracen_usage: Content: 45 78 61 6d 70 6c 65 20 73 74 72 69 6e 67 20 74 |Example string t 6f 20 64 65 6d 6f 6e 73 74 72 61 74 65 20 62 61 |o demons trate ba 73 69 63 20 75 73 61 67 65 20 6f 66 20 4b 4d 55 |sic usag e of KMU 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |........ ........ 00 00 00 00 |.... [00:00:00.026,516] <inf> kmu_cracen_usage: ---- Plaintext end ---- [00:00:00.026,528] <inf> kmu_cracen_usage: ---- SHA256 hash (len: 32): ---- [00:00:00.026,540] <inf> kmu_cracen_usage: Content: 09 55 cb 12 be 3e ab 93 ef d8 3b a8 1d 4c 7c a8 |.U...>.. ..;..L|. 47 83 26 c6 f1 d5 ee ae b7 b6 43 08 82 e8 64 03 |G.&..... ..C...d. [00:00:00.026,552] <inf> kmu_cracen_usage: ---- SHA256 hash end ---- [00:00:00.026,564] <inf> kmu_cracen_usage: ---- Signature (len: 64): ---- [00:00:00.026,577] <inf> kmu_cracen_usage: Content: 26 ed 21 c1 85 28 f2 6c 65 2e 87 82 4c 71 e9 41 |&.!..(.l e...Lq.A 99 90 f8 12 c0 06 c0 ea f5 d7 06 1c 30 c6 3d eb |........ ....0.=. 0a 9e 61 6f 0f 48 54 5c 6b 75 6a 37 38 ee a9 15 |..ao.HT\ kuj78... 57 8f 6f 0b 60 d5 56 03 0a 6c ee f8 c2 84 73 d4 |W.o.`.V. .l....s. [00:00:00.026,589] <inf> kmu_cracen_usage: ---- Signature end ---- [00:00:00.026,594] <inf> kmu_cracen_usage: Verifying ECDSA signature... [00:00:00.027,899] <inf> kmu_cracen_usage: ECDSA signature verification was successful! [00:00:00.027,925] <inf> kmu_cracen_usage: Key usage finished [00:00:00.027,930] <inf> kmu_cracen_usage: Destroying non-provisioned keys... [00:00:00.029,407] <inf> kmu_cracen_usage: Example finished successfully!
Testing with KMU encryption
In case you need to provision the key with --cracen-usage ENCRYPTED option, make sure the seed value is properly provisioned.
Complete the following steps instead of the ones listed in the Testing section:
Connect the kit to the computer using a USB cable. The kit is assigned a serial port. Serial ports are referred to as COM ports on Windows, /dev/ttyACM devices on Linux, and /dev/tty devices on macOS. To list Nordic Semiconductor devices connected to your computer together with their serial ports, open a terminal and run the
nrfutil device listcommand. Alternatively, check your operating system’s device manager or its equivalent.Connect to the kit with a terminal emulator (for example, the Serial Terminal app). See Testing and optimization for the required settings and steps.
Run the following command to perform a full erase of the device:
nrfutil device erase --allProgram the sample to your device. The 384-bit seed value is generated automatically and stored to the KMU during the first boot. The sample also runs the steps listed in the Sample operations section and generates a second pair of keys.
Run the following command to provision the example keys to the board:
nrfutil device x-provision-keys --key-file keys\keys.jsonIn the terminal, observe the logs from the application.
Testing with seed value provisioned first
Note
This method is supported only using nrfutil device v2.14.1 and later.
See Installing specific versions of nRF Util commands for more information.
You can also provision the seed value before other keys or key pairs and before programming the sample. For this, you need to create a second JSON file with a single entry with a SEED value of 384 bits and then provision it to the board.