How to use the EdgeLock® Secure Enclave (ELE) on i.MX 93: Storing and using encryption keys via PKCS#11 (Japanese blog)
This article explains how to use the cryptographic accelerator and key management functions of the i.MX 93's built-in EdgeLock ® Secure Enclave (ELE) via PKCS#11.
PKCS#11 is a widely used API in cryptography and can be integrated with OpenSSL, another widely used library. Therefore, protection can be applied to all applications that perform authentication using PKCS#11 or OpenSSL (e.g., Eclipse Mosquitto ™ etc.) without any modifications to the application itself .
The fact that it provides cryptographic acceleration and key management functions is something it shares with secure elements such as the SE050 , which are introduced in another article.
For an overview of cryptographic accelerators and key management, as well as a general comparison and usage guidelines with secure elements, please refer to the following article.
This article explains commonly heard features in semiconductor hardware security (Secure Element, Secure Enclave, TPM, HSM, TEE, TrustZone, etc.) (Japanese blog).
Estimated time: Approximately 55 minutes (excluding Yocto build)
Using ELE via pkcs11-tool: 10 minutes
Using ELE via openssl: 10 minutes
Creating a PKCS#11 URI PEM file: 5 minutes
Cloud connectivity to Azure IoT Hub: 30 minutes
Environment used for testing
Hardware:
FRDM i.MX 93 Development Board ( FRDM-IMX93 )
32GB microSD card (If you are writing an image to an SD card and using it. It is also thought that 16GB will work.)
software:
Linux BSP Version L6.18.2-1.0.0
*The pre-built image on the FRDM-IMX93 webpage does not work correctly, so please build it using the following instructions.
[Beginner's Guide] How to Build Yocto Linux BSP - i.MX FRDM Board Edition (Japanese Blog)
When I built it, I used the following commands when running repo init and imx-setup-release.sh:
repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-whinlatter -m imx-6.18.2-1.0.0.xml
DISTRO=fsl-imx-wayland MACHINE=imx93-11x11-lpddr4x-frdm source imx-setup-release.sh -b ./build
Overview of EdgeLock® Secure Enclave (ELE)
In i.MX 93, "EdgeLock® Secure Enclave (ELE)" is a security block that integrates numerous advanced security features provided by NXP, including cryptographic accelerators, key management, overall SoC monitoring, and access rights management.
Secure Boot is a representative feature for monitoring the entire SoC and managing access rights. For information on Secure Boot in i.MX 93 and how to use it, please refer to the following article.
i.MX 93 Processor: Explaining the Secure Boot Signature and Authentication Mechanism (Japanese Blog)
i.MX 93 Processor: How to Implement Secure Boot - Practical Guide
This article explains how to use cryptographic accelerator and key management functions via PKCS#11.
i.MX Security Middleware (SMW) Overview
NXP provides i.MX SMW (Security Middleware) as software for controlling the security hardware built into the i.MX processor.
GitHub - nxp-imx/imx-smw: i.MX Security Middleware Library · GitHub
SMW provides hardware-independent APIs, including the PKCS#11 API, which will be discussed later.
Since i.MX 93 has a built-in ELE, the part that actually controls the ELE is imx-secure-enclave.
GitHub - nxp-imx/imx-secure-enclave: Secure Enclave Userspace Library · GitHub
Overview of PKCS#11
PKCS#11 (Public-Key Cryptography Standards #11) is an API specification for unified use of cryptographic hardware and software (e.g., HSMs, smart cards, USB tokens, etc.) from applications. It is also known as "Cryptoki".
For this example, we will use pkcs11-tool as the application that uses PKCS#11.
The relationship including imx-smw can be illustrated as follows:
PKCS#11を使用するアプリケーション(pkcs11-tool etc.)
↓ (PKCS#11 API経由での使用)
imx-smw
↓
imx-secure-enclave
↓
EdgeLock Secure Enclave Hardware
Furthermore, in a previous article on using SE050 via OpenSSL , we explained how to use it via openssl using the openssl provider included in Plug and Trust Middleware.
SMW does not provide an openssl provider, but it is possible to use ELE via openssl because the PKCS#11 interface can be used from openssl by using the pkcs11-provider.
GitHub - openssl-projects/pkcs11-provider: A pkcs#11 provider for OpenSSL 3.0+ · GitHub
The relationship between not using an OpenSSL provider and using imx-smw + PKCS is illustrated below.
When a provider is not used, the key exists as a file on the file system, and encryption is performed by software.
When using imx-smw and pkcs11-provider, the key and encryption process are protected by ELE hardware. The key to be used is specified by a PKCS#11 URI located in the code or on the file system.
*What is a URI?
This is a standardized identifier (URI) used to specify private keys and certificates securely stored in hardware security modules (HSMs) or similar devices, instead of local file paths.
Note: Plug and Trust Middleware also provides a PKCS#11 API.
Using ELE via pkcs11-tool
The usage instructions are described in the PKCS11-Tool User Guide within SMW, but this explanation will focus specifically on the ECDSA signing and verification process.
First, run the following command to start nvm_daemon.
nvm_daemon is a service that manages filesystem space for use with ELE.
systemctl start nvm_daemon
systemctl status nvm_daemon
You can also configure it to start automatically the next time you boot by executing the following command.
systemctl enable nvm_daemon
To simplify subsequent commands, specify the location of libsmw_pkcs11 with the following command.
The number at the end may vary depending on the SMW version, so please adjust it to match your installed version.
export MODULE_PKCS11=/usr/lib/libsmw_pkcs11.so.5
The following command will check the tokens that can be verified via libsmw_pkcs11.
pkcs11-tool --module $MODULE_PKCS11 -L
If you see a display similar to the example below, it is working correctly.
Available slots:
Slot 0 (0x0): Security Middleware Abstraction
token label : smw
token manufacturer : NXP Semiconductor
token model :
token flags : login required, PIN pad present, token initialized
hardware version : 0.0
firmware version : 0.0
serial num :
pin min/max : 0/0
uri : pkcs11:model=;manufacturer=NXP%20Semiconductor;serial=;token=smw
The following command will display a list of available objects.
Nothing should be displayed at first.
pkcs11-tool --module $MODULE_PKCS11 --login -O
The following command will generate an ECC key pair.
pkcs11-tool --module $MODULE_PKCS11 \
--login \
--keypairgen \
--key-type EC:prime256v1 \
--id 02 \
--label "MyECCKey" \
--usage-sign \
--allowed-mechanisms "ECDSA-SHA256"
If you display the object list again, you should see the ECC key pair as shown below.
Using slot 0 with a present token (0x0)
Profile object 250360144
profile_id: CKP_BASELINE_PROVIDER (1)
Public Key Object; EC EC_POINT 256 bits
EC_POINT: 044104fe4c97a7a4f54702f9fc5740f62c0864e851098dc43cb4c9ba8633421e5bc362cdc559523118bb4fe4281851c051e24a88846a2d774eb3f928595761cf719e90
EC_PARAMS: 06082a8648ce3d030107 (OID 1.2.840.10045.3.1.7)
label: MyECCKey
ID: 02
Usage: verify
Access: none
Unique ID:
uri: pkcs11:model=;manufacturer=NXP%20Semiconductor;serial=;token=smw;id=%02;object=MyECCKey;type=public
Private Key Object; EC
label: MyECCKey
ID: 02
Usage: sign
Access: sensitive, always sensitive
Unique ID:
uri: pkcs11:model=;manufacturer=NXP%20Semiconductor;serial=;token=smw;id=%02;object=MyECCKey;type=private
The following command will generate a suitable message.txt file, and then you can generate and verify a signature on it.
echo hello > message.txt
pkcs11-tool --module $MODULE_PKCS11 \
--login \
--sign \
--id 02 \
--mechanism ECDSA-SHA256 \
--input-file message.txt \
--output-file signature.bin
pkcs11-tool --module $MODULE_PKCS11 \
--login \
--verify \
--id 02 \
--mechanism ECDSA-SHA256 \
--input-file message.txt \
--signature-file signature.bin
Using ELE via openssl
Similarly, we will explain the entire process, focusing specifically on ECDSA signing and verification.
This assumes that you have already started nvm_daemon and generated the ECC key pair using the procedure for pkcs11-tool described in the previous chapter.
Create an openssl.cnf file with the following content:
The lines for `module` and `pkcs11-module-path` at the end may need to be changed to match your actual system.
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
pkcs11 = pkcs11_sect
[default_sect]
activate = 1
[pkcs11_sect]
module = /usr/lib/ossl-modules/pkcs11.so
pkcs11-module-path = /usr/lib/libsmw_pkcs11.so.5
activate = 1
Use the following command to configure openssl to use the above configuration file.
export OPENSSL_CONF=<作成したopenssl.cnfの絶対path>
Signature generation and verification can be done using the following commands.
openssl pkeyutl -sign -inkey "pkcs11:object=MyECCKey;type=private" -in message.txt -out sig.bin -digest sha256
openssl pkeyutl -verify -pubin -inkey "pkcs11:object=MyECCKey;type=public" -in message.txt -sigfile sig.bin -digest sha256
Creating a PKCS#11 URI PEM file
In using the openssl provider, I used a URI that could be directly verified in the object list as the key.
However, the pkcs11-provider documentation , under "USE IN OLDER APPLICATIONS (URIs in PEM files)," states that this is a new method and may not be usable when using older applications.
In fact, the Mosquitto client, which will be discussed later, has code that prevents you from directly specifying a URI when using openssl 3.0 or later.
In such cases, you can use the CLI tool uri2pem.py to generate a file containing the URI and use it in the same way as specifying a regular key file.
Using uri2pem.py downloaded from the above page, generate a file containing the PKCS#11 URI with the following command.
python3 uri2pem.py --out MyECCKey.pem "pkcs11:object=MyECCKey;type=private"
Although I haven't been able to confirm the details, based on the contents of uri2pem.py, it seems that it's not possible to create pem files for URIs other than private keys.
By specifying the generated "MyECCKey.pem" as the signing key, you can perform the same actions as before.
openssl pkeyutl -sign -inkey MyECCKey.pem -in message.txt -out sig.bin -digest sha256
openssl pkeyutl -verify -pubin -inkey "pkcs11:object=MyECCKey;type=public" -in message.txt -sigfile sig.bin -digest sha256
Cloud connectivity to Azure IoT Hub via Eclipse Mosquitto ™ client using keys within ELE
We will attempt to establish a cloud connection to Azure IoT Hub using the Mosquitto client with the generated key.
Note: The RootCA certificate created using this procedure is for testing purposes only. It is recommended to delete the certificate from Azure IoT Hub after testing is complete.
In advance
How to use Secure Element SE05x: Setting up Plug and Trust Middleware on the FRDM-IMX93 development board (Japanese blog)
The chapter "Building and Installing the Mosquitto Client"
How to use Secure Element SE05x: Connecting to Azure IoT Hub using Eclipse Mosquitto client (Japanese blog)
In the chapter "Creating an Azure IoT Hub",
Follow each step to complete the installation of the Mosquitto client and the creation of the Azure IoT Hub.
First, on the FRDM-IMX93 side, execute the following command to create a certificate request for the public key of MyECCKey and verify its contents.
openssl req -new -key "pkcs11:object=MyECCKey" -outform PEM -subj /CN=frdmimx93_test -out frdmimx93_test.csr -sha256
openssl req -text -noout -in frdmimx93_test.csr
Next, move "frdmimx93_test.csr" to the host PC and execute the following:
openssl ecparam -genkey -name prime256v1 -out rootCA_key_pair.pem
openssl req -new -x509 -subj /CN=rootCA -key rootCA_key_pair.pem > rootCA_cert.cer
openssl x509 -req -in frdmimx93_test.csr -days 365 -CA rootCA_cert.cer -CAkey rootCA_key_pair.pem -out frdmimx93_test_cert.cer
Place the created "frdmimx93_test_cert.cer" back onto the FRDM-IMX93. Since it will be used later in conjunction with " MyECCKey.pem ", place it in the same directory where you created it.
Additionally, you will register the created "rootCA_cert.cer" file in Azure IoT Hub and create a device named "frdmimx93_test".
For instructions, please refer to the "Adding an Intermediate CA Certificate to Azure IoT Hub" section in the following article.
How to use Secure Element SE05x: Connecting to Azure IoT Hub using Eclipse Mosquitto client (Japanese blog)
Note: As mentioned above, the certificate registered here is for testing purposes only, so it is recommended to delete it after confirming its functionality.
Once you have completed these steps, you will be able to connect to Azure IoT Hub using the Mosquitto client.
Execute the following command. Please change IOT_HUB_NAME as appropriate.
export IOT_HUB_NAME=ShinjiIotHubTest
export DEVICE_NAME=frdmimx93_test
mosquitto_pub -h "${IOT_HUB_NAME}.azure-devices.net" -p 8883 -u "${IOT_HUB_NAME}.azure-devices.net/${DEVICE_NAME}/api-version=2016-11-14" -t "devices/${DEVICE_NAME}/messages/events/" -m '{"mes":"Hello Azure with i.MX93!"}' --capath /etc/ssl/certs/ --cert frdmimx93_test_cert.cer --key MyECCKey.pem -i ${DEVICE_NAME} -d -q 1
If you see output similar to the following, it's a success.
Client frdmimx93_test sending CONNECT
Client frdmimx93_test received CONNACK (0)
Client frdmimx93_test sending PUBLISH (d0, q1, r0, m1, 'devices/frdmimx93_test/messages/events/', ... (34 bytes))
Client frdmimx93_test received PUBACK (Mid: 1, RC:0)
Client frdmimx93_test sending DISCONNECT
By following the steps in the article below, "Checking messages sent to IoT Hub and sending messages to devices," you can also check received messages in Cloud Shell on the Azure IoT Hub side.
How to use Secure Element SE05x: Connecting to Azure IoT Hub using Eclipse Mosquitto client (Japanese blog)
=========================
We are currently unable to respond to comments left in the " Comment " section of this post . We apologize for the inconvenience, but please refer to " Technical Questions to NXP - How to Contact Us( Japanese Blog) " when making inquiries.(If you are already an NXP distributor or have a relationship with NXP, you may ask your representative directly.) This article explains how to use the cryptographic accelerator and key management functions of the i.MX 93's built-in EdgeLock® Secure Enclave (ELE) via PKCS#11.
PKCS#11 is a widely used API in cryptography and can be integrated with OpenSSL, another widely used library. Therefore, protection can be applied to all applications that perform authentication using PKCS#11 or OpenSSL (e.g., Eclipse Mosquitto ™ etc.) without any modifications to the application itself .
The fact that it provides cryptographic acceleration and key management functions is something it shares with secure elements such as the SE050, which are introduced in another article.
For an overview of cryptographic accelerators and key management, as well as a general comparison and usage guidelines with secure elements, please refer to the following article.
This article explains commonly heard features in semiconductor hardware security (Secure Element, Secure Enclave, TPM, HSM, TEE, TrustZone, etc.) (Japanese blog).
Estimated time: Approximately 55 minutes (excluding Yocto build)
Using ELE via pkcs11-tool: 10 minutes
Using ELE via openssl: 10 minutes
Creating a PKCS#11 URI PEM file: 5 minutes
Cloud connectivity to Azure IoT Hub: 30 minutes
i.MX Processors Security Japanese Blog
View full article