SE Manager#

The Secure Engine (SE) Manager provides thread-safe APIs for the Secure Engine's mailbox interface. Note that PSA Crypto is the recommended device independent crypto API and should be used whenever possible. The SE manager APIs can be used directly for performance or space constrained applications.

Available functionality will vary between devices: device management, such as secure firmware upgrade, secure boot and secure debug implementation, is available on all series 2 devices. Devices with the SE subsystem includes a low level crypto API where the SE Manager will use the SE hardware peripherals to accelerate cryptographic operations. Finally, Vault High devices also include secure key storage functionality, anti-tamper protection, advanced crypto API and attestation.

Note

Functionality#

The functionality of the SE Manager includes

  • Core API, inititalizing of SE Manager and SE command context (Core)

  • Secure key storage (Key handling)

    • Key wrapping

    • Storing keys in the SE volatile storage

    • Using key by reference

  • Configuration of tamper responses (Utilities)

    • The available signals include core hard-fault, glitch detectors, PRS, and failed authenticated commands, while the responses vary from triggering an interrupt to the hardware autonomously erasing the one-time-programmable (OTP) memory

  • Block ciphers (Cipher)

    • Supports AES-ECB, AES-CBC, AES-CFB128, AES-CFB8, AES-CTR, AES-CCM, AES-GCM, CMAC, HMAC and ChaCha20/Poly1305

    • The cipher operations can be performed using plaintext keys, wrapped keys or referencing a key in the SE

    • Streaming operations are supported for AES-GCM and CMAC

  • Block and streaming hash operations (Hashing)

    • Supports SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512

  • True Random Number Generator (Entropy)

    • Hardware block inside the SE used for generating random numbers. Can be used as a source of entropy, or to securely generate keys inside the SE

  • Elliptic Curve Signature operation (Signature)

    • ECDSA and EDDSA

  • Key agreement (Key derivation)

    • Perform Elliptic Curve Diffie-Hellman and J-PAKE key agreement operations inside the SE

  • Key derivation functions (Key derivation)

    • Perform HKDF and PBKDF2 key derivation functions inside the SE

  • Device configuration and utilities (Utilities)

    • Write to user data stored inside the SE

    • Configuration of debug locks

    • Configuration of secure boot

    • Configuration of flash lock

    • Read SE OTP contents

    • Read SE firmware version

    • Read provisioned certificates

  • Multi-thread safe APIs for MicriumOS and FreeRTOS

  • Retrieveing attestation tokens (Attestation)

Key Storage and Use of SE Wrapped Keys#

The way keys are stored and operated on depends on the options set in the key descriptor used (sl_se_key_descriptor_t). Each key descriptor is initialized with a storage location, a key type, and length of the key (some key types have a known length, and it is not required to be set). The storage location can either be application memory or inside the SE, for more details, see sl_se_storage_method_t. Depending on the use-case, the key descriptors will also store the pointer to a key and an SE key slot, see sl_se_key_slot_t for the list of available internal SE key slots.

For more information on the key handling APIs see Key handling.

Supported Key Types#

Symmetric keys

  • AES-128 (16 bytes)

  • AES-192 (24 bytes)

  • AES-256 (32 bytes)

  • ChaCha20 (32 bytes)

Asymmetric keys for ECC

  • NIST P-192

  • NIST P-256

  • NIST P-384

  • NIST P-521

  • Curve25519

  • Curve448

Custom Weierstrass Prime curves are also supported (sl_se_custom_weierstrass_prime_domain_t).

Example Usage of Keys#

#define WRAPPED_KEY_OVERHEAD (12UL + 16UL)
#define AES_256_KEY_SIZE 32UL

uint8_t key_buffer[AES_256_KEY_SIZE];
uint8_t wrapped_key_buffer[AES_256_KEY_SIZE + WRAPPED_KEY_OVERHEAD];

void demo_se_create_key_in_slot(void) {
    sl_se_key_descriptor_t new_key = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
        .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
        .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
    };
    sl_se_generate_key(&new_key);
}

void demo_se_create_plaintext_key(void) {
    sl_se_key_descriptor_t new_key = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
    };
    new_key.storage.location.buffer.pointer = key_buffer;
    new_key.storage.location.buffer.size = sizeof(key_buffer);
    sl_se_generate_key(&new_key);
}

void demo_se_create_wrapped_key(void) {
    sl_se_key_descriptor_t new_wrapped_key = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
        .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
    };
    new_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer;
    new_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer);
    sl_se_generate_key(&new_wrapped_key);
}

void demo_se_wrapped_key_to_volatile_slot(void) {
    sl_se_key_descriptor_t existing_wrapped_key = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
        .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
    };
    existing_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer;
    existing_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer);
    sl_se_key_descriptor_t key_in_slot = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
        .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
        .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
    };
    sl_se_import_key(&existing_wrapped_key, &key_in_slot);
}

void demo_se_volatile_slot_to_wrapped_key(void) {
    sl_se_key_descriptor_t existing_volatile_key = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
        .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
        .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
    };
    sl_se_key_descriptor_t wrapped_key_out = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
        .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
    };
    wrapped_key_out.storage.location.buffer.pointer = wrapped_key_buffer;
    wrapped_key_out.storage.location.buffer.size = sizeof(wrapped_key_buffer);
    sl_se_export_key(&existing_volatile_key, &wrapped_key_out);
}

void demo_se_delete_from_volatile_slot(void) {
    sl_se_key_descriptor_t existing_volatile_key = {
        .type = SL_SE_KEY_TYPE_AES_256,
        .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
        .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
        .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
    };
    sl_se_delete_key(&existing_volatile_key);
}

Tamper#

The Secure Engine (SE) tamper module connects a number of hardware and software-driven tamper signals to a set of configurable hardware and software responses. This can be used to program the device to automatically respond to external events that could signal that someone is trying to tamper with the device, and very rapidly remove secrets stored in the SE. The available tamper signals range from signals based on failed authentication and secure boot to specialized glitch detectors. When any of these signals fire, the tamper block can be configured to trigger several different responses, ranging from triggering an interrupt to erasing the one-time-programmable (OTP) memory, removing all SE secrets and resulting in a permanently destroyed device.

A tamper signal can lead to a series of different autonomous responses from the tamper module. These responses are listed in the table below.

Response

Description

0

Ignore

No action is taken.

1

Interrupt

The SETAMPERHOST interrupt on the host is triggered.

2

Filter

A counter in the tamper filter is increased.

4

Reset

The device is reset.

7

Erase OTP

Erases the OTP configuration of the device.

These responses are cumulative, meaning that if a filter response is triggered, an interrupt will also be triggered. For a full overview of the tamper signals, see

Modules#

sl_se_manager_defines.h

Attestation

Cipher

Core

Crypto Algorithm Utilities

Entropy

External memory support

Hashing

Key derivation

Key handling

Signature

Utilities