Crypto: AES KW

The AES KW sample demonstrates how to use the PSA Crypto API to perform key wrapping and unwrapping operations using AES Key-Encryption Key.

The sample can be configured to use either AES-KW (Key Wrap) or AES-KWP (Key Wrap with padding) algorithm and to make use of Key Management Unit (KMU) to store the Key-Encryption Key.

Requirements

The sample supports the following development kits:

Hardware platforms

PCA

Board name

Board target

nRF54L15 DK (emulating nRF54L05)

PCA10156

nrf54l15dk

nrf54l15dk/nrf54l05/cpuapp

nRF54L15 DK (emulating nRF54L10)

PCA10156

nrf54l15dk

nrf54l15dk/nrf54l10/cpuapp

nrf54l15dk/nrf54l10/cpuapp/ns

nRF54L15 DK

PCA10156

nrf54l15dk

nrf54l15dk/nrf54l15/cpuapp

nrf54l15dk/nrf54l15/cpuapp/ns

nRF54LM20 DK

PCA10184

nrf54lm20dk

nrf54lm20dk/nrf54lm20a/cpuapp

nRF54LM20 DK

PCA10184

nrf54lm20dk

nrf54lm20dk/nrf54lm20a/cpuapp/ns

nRF54LV10 DK

PCA10188

nrf54lv10dk

nrf54lv10dk/nrf54lv10a/cpuapp

nRF54LV10 DK

PCA10188

nrf54lv10dk

nrf54lv10dk/nrf54lv10a/cpuapp/ns

Note

If CONFIG_SAMPLE_AES_KW_KMU_DEMO is set, */ns board targets are not supported by this sample.

Overview

The sample enables PSA Crypto API and configures the following Kconfig options for the cryptographic features:

The sample also configures the cryptographic drivers for each board target using Kconfig options in the overlay files in the boards directory.

These Kconfig options are then used by the build system to compile the required cryptographic PSA directives and make the configured cryptographic drivers available at runtime. See Driver selection for more information about this process.

Key Encryption Key used by the sample

The location and value of the Key Encryption Key depend on the configuration:

Configuration option

Key location

Key value

CONFIG_SAMPLE_AES_KW_KMU_DEMO=y

KMU

Generated by the sample firmware.

CONFIG_SAMPLE_AES_KW_KMU_DEMO=n

PSA crypto keystore

Imported using psa_import_key().

Note

You can add the Kconfig option when you use the KMU demo overlay file.

Once built and run, the sample performs the following operations:

  1. Initialization:

    1. The sample initializes the PSA Crypto API using psa_crypto_init().

    2. If CONFIG_SAMPLE_AES_KW_KMU_DEMO is set, the sample imports a predefined 128-bit or 192-bit AES key (Key Encryption Key) using psa_import_key() and stores it in the PSA crypto keystore. Otherwise, the sample generates the Key Encryption Key using psa_generate_key() and stores it in the Key Management Unit (KMU). The key is configured with usage flags for both wrapping and unwrapping.

    3. The sample imports a predefined plain key using psa_import_key() and stores it in the PSA crypto keystore. The key is configured with usage flags for export. This step enables the wrapping operation.

  2. Wrapping and unwrapping of a sample plain key:

    1. The sample performs a wrapping operation using psa_wrap_key() with either the PSA_ALG_KW or PSA_ALG_KWP algorithm, depending on the sample configuration.

    2. If CONFIG_SAMPLE_AES_KW_KMU_DEMO is not set, the sample compares the wrapped key with the expected value defined in RFC3394 or RFC5649.

    3. The sample removes the plain key from the PSA crypto keystore using psa_destroy_key().

    4. The sample performs an unwrapping operation using psa_unwrap_key() with key usage configured for export. Retrieve the decrypted key value and compare it with the original key when the Key Encryption Key is predefined.

    5. The sample performs a key export operation using psa_export_key().

    6. The sample compares the exported key with the original plain key to verify correctness.

  3. Demonstrating key blocking functionality when CONFIG_SAMPLE_AES_KW_KMU_DEMO is set:

    1. The sample blocks the Key Encryption Key using cracen_kmu_block().

    2. The sample attempts a wrapping operation to demonstrate that the key can no longer be used for subsequent cryptographic operations until the next device reset. This behavior imitates bootloader functionality, where the key is blocked before jumping to the application.

  4. Cleanup:

    1. The sample removes both the Key Encryption Key and the unwrapped plain key from the PSA crypto keystore using psa_destroy_key().

Note

192-bit AES keys are not supported by the CRACEN driver for nRF54LM20 and nRF54LV10A devices. See also AES key size configuration.

If CONFIG_SAMPLE_AES_KW_KMU_DEMO is set and the Key Encryption Key is blocked, it cannot be removed from the KMU. Reprogram the sample with the ERASEALL option by running the following command:

west flash --erase

Configuration

See Configuring and building for information about how to permanently or temporarily change the configuration.

AES-KW algorithm overlay

The sample allows you to use either the AES-KW or the AES-KWP algorithm. By default, the sample demonstrates AES-KW algorithm usage.

If you want to configure the sample to work with the AES-KWP algorithm, use the aes_kwp.conf file to extend the main configuration file. To provide this extra overlay file, use the EXTRA_CONF_FILE CMake option when building the sample (-DEXTRA_CONF_FILE=aes_kwp.conf).

KMU demo overlay

The sample allows you to generate and store a Key Encryption Key in the KMU, as well as demonstrating the capability to block the key, preventing its use in cryptographic operations. By default, the sample uses the PSA crypto keystore.

If you want to configure the sample to work with the KMU, use the kmu_demo.conf file to extend the main configuration file. To provide this extra overlay file, use the EXTRA_CONF_FILE CMake option when building the sample (-DEXTRA_CONF_FILE=kmu_demo.conf).

Note

Using this extra overlay file changes the sample workflow, so that it is possible to provision the Key Encryption Key just once since it is blocked during the first sample run. Reprogram the board to make it work.

Building and running

This sample can be found under samples/crypto/aes_kw in the nRF Connect SDK folder structure.

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

After programming the sample to your development kit, complete the following steps to test it:

  1. Connect to the kit with a terminal emulator (for example, the Serial Terminal app). See Testing and optimization for the required settings and steps.

  2. Build and program the application.

  3. Observe the logs from the application using the terminal emulator. For example, the log output should look like this:

*** Using Zephyr OS v4.3.99-a7c2a12b9134 ***
[00:00:00.002,512] <inf> aes_kw: Starting AES-KW example...
[00:00:00.002,526] <inf> aes_kw: Using AES-KWP algorithm
[00:00:00.002,535] <inf> aes_kw: Importing Key-Encryption Key...
[00:00:00.002,563] <inf> aes_kw: Key-Encryption Key imported successfully!
[00:00:00.002,568] <inf> aes_kw: Importing key (to wrap)...
[00:00:00.002,579] <inf> aes_kw: ---- Source key (len: 20): ----
[00:00:00.002,589] <inf> aes_kw: Content:
                                 c3 7b 7e 64 92 58 43 40  be d1 22 07 80 89 41 15 |.{~d.XC@ .."...A.
                                 50 68 f7 38                                      |Ph.8
[00:00:00.002,598] <inf> aes_kw: ---- Source key end  ----
[00:00:00.002,622] <inf> aes_kw: KEY key imported successfully!
[00:00:00.002,627] <inf> aes_kw: Wrapping key...
[00:00:00.012,626] <inf> aes_kw: ---- Wrapped key (len: 32): ----
[00:00:00.012,637] <inf> aes_kw: Content:
                                 13 8b de aa 9b 8f a7 fc  61 f9 77 42 e7 22 48 ee |........ a.wB."H.
                                 5a e6 ae 53 60 d1 ae 6a  5f 54 f3 73 fa 54 3b 6a |Z..S`..j _T.s.T;j
[00:00:00.012,647] <inf> aes_kw: ---- Wrapped key end  ----
[00:00:00.012,660] <inf> aes_kw: Wrapped key size is expected: 32 bytes
[00:00:00.012,676] <inf> aes_kw: Wrapped key data is correct!
[00:00:00.012,702] <inf> aes_kw: Unwrapping key...
[00:00:00.013,875] <inf> aes_kw: ---- Unwrapped key (len: 20): ----
[00:00:00.013,886] <inf> aes_kw: Content:
                                 c3 7b 7e 64 92 58 43 40  be d1 22 07 80 89 41 15 |.{~d.XC@ .."...A.
                                 50 68 f7 38                                      |Ph.8
[00:00:00.013,896] <inf> aes_kw: ---- Unwrapped key end  ----
[00:00:00.013,909] <inf> aes_kw: Unwrapped key size is expected: 20 bytes
[00:00:00.013,925] <inf> aes_kw: Unwrapped key data is correct!
[00:00:00.013,963] <inf> aes_kw: Example finished successfully!