i.MX93 Key Import and Key Exchange Example#
This documentation covers the key import and key exchange operations for the i.MX93 EdgeLock Secure Enclave, specifically focusing on the combined key agreement and key derivation functionality used to establish secure key import capabilities.
1. Prerequisites#
SPSDK is needed with examples extension.
pip install spsdk[examples](Please refer to the installation documentation.)This demo was tested with i.MX93 EVK board
Obtain an NXP_PROD_KA_PUB key
1.1 NXP Production Key#
The EdgeLock Secure Enclave provides a built-in production key for key agreement:
Key ID: 0x70000000 (NXP PROD MANUFACT KEY AGREEMENT)
Purpose: Enables consistent OEM_IMPORT_xxx keys across devices with same SRKH
Availability: Same key across all lifecycles
Public Key Export: Available via Public key export API (0x32)
This ensures that devices with the same Super Root Key Hash (SRKH) can use identical import keys, simplifying key management across device populations.
2 Key Exchange Operation#
2.1 Purpose#
The key exchange operation performs a combined key agreement and key derivation to create symmetric keys stored in the EdgeLock Secure Enclave key storage. This operation is primarily used to establish OEM Master Keys for secure key import operations.
2.2 Key Features#
Combined Operation: Performs both key agreement (ECDH) and key derivation (HKDF) in a single operation
Symmetric Key Creation: Only symmetric keys can be created through this operation
Secure Storage: Derived keys are stored in EdgeLock Secure Enclave key storage
OEM Signed Content: Input parameters are protected by OEM signed messages for integrity
2.3 Key Exchange Signed Message Configuration#
message:
command:
KEY_EXCHANGE_REQ:
# Key storage configuration
key_store_id: 0x454C4500
# Algorithm selection
key_exchange_algorithm: HKDF SHA256 # Options: HKDF SHA256, HKDF SHA384
# Salt configuration for HKDF process
salt_flags: 0 # Bit 0: Salt source, Bit 1: ELE import salt
# Derived key attributes
derived_key_grp: 0 # Group ID (0-99)
derived_key_size_bits: 256 # Key size: 128/192/256
derived_key_type: OEM_IMPORT_MK_SK # Key type for import operations
derived_key_lifetime: PERSISTENT # VOLATILE/PERSISTENT/PERMANENT
derived_key_usage: # Permission list
- Derive
derived_key_permitted_algorithm: HKDF SHA256
derived_key_lifecycle: CURRENT # Lifecycle restrictions
derived_key_id: 0x1 # Key identifier
# ECDH configuration
private_key_id: 0x70000000 # NXP PROD MANUFACT KEY AGREEMENT
oem_private_key: oem_private_key.pem # OEM private key for ECDH
nxp_prod_ka_pub: nxp.pub # NXP production public key
2.4 OEM Master Key Generation#
The key exchange operation generates an OEM_IMPORT_MK_SK (OEM Import Master Secret Key) with specific requirements:
Required Attributes#
Type: OEM_IMPORT_MK_SK
Usage: Derive (Cache usage set by default)
Permitted Algorithm: HKDF SHA256 (0x08000109)
Size: 256 bits
Lifecycle: User-defined
Lifetime: User-defined (PERSISTENT recommended)
Derived Keys#
From the OEM_IMPORT_MK_SK, two additional keys are derived:
OEM_IMPORT_CMAC_SK
Used to verify Key Import signed TLV buffers
Type: AES, Size: 256 bits
No key identifier (derived on-demand)
OEM_IMPORT_WRAP_SK
Used to decrypt wrapped keys in Key Import operations
Type: AES, Size: 256 bits
No key identifier (derived on-demand)
2.5 Generation of signed message and key derivation#
The command generates the signed message for the key exchange. If the -w/–assets option is specified, also generates the assets - OEM_IMPORT_MK_SK key is derived.
nxpimage -v signed-msg export -c inputs/key_exchange.yaml
%! nxpimage -v signed-msg export -c inputs/key_exchange.yaml -w workspace/assets
nxpimage -v signed-msg export -c inputs/key_exchange.yaml -w workspace/assets
INFO:spsdk.image.ahab.signed_msg:Calculated input_peer_public_key_digest from OEM private key during config loading 3d164eb2e8c2c8566be458bdbdae6715f4484c8ffbacb14f248e20c3811def9b
INFO:spsdk.image.ahab.signed_msg:ECDH shared secret: 1ae9e13162f15e3b0baa0b7b959852e4d8a5c573cc0a4072e0d3a6666c728cbd
INFO:spsdk.image.ahab.signed_msg:Derived OEM_Import_MK_SK: c7e7436ed876b0176d775a658c3e9bcf59c940a41a2673b0552b7d7df504d194
INFO:spsdk.image.ahab.signed_msg:Derived OEM_Import_Wrap_SK: f2fa66b83ed82acbe4dddb5c60966cabad61cf3116b542115f10f06cf6aee825
INFO:spsdk.image.ahab.signed_msg:Derived OEM_Import_CMAC_SK: dc202a1160b4a5d11c088514e99e298b45aba12867543236fcd8774227f3e15c
INFO:spsdk.image.ahab.signed_msg:ECDH key derivation completed during configuration loading
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:Created Signed message Image:
Name: Signed Message Image
Starts: 0x0
Ends: 0x23f
Size: Size: 576 B
Alignment: 8 B
Execution Start Address: Not defined
Pattern:zeros
Signed Message Image for mimx9352, Revision: latest
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:Created Signed message Image memory map:
┌──0x0000_0000─ Signed Message Image ──┐
│ Size: 576 B │
│ Signed Message Image for mimx9352, │
│ Revision: latest │
│ Pattern: zeros │
│┌──0x0000_0000─ Signed Message ──────┐│
││ Size: 576 B ││
││Signed Message for KEY_EXCHANGE_REQ ││
│└──0x0000_023f───────────────────────┘│
└──0x0000_023f─────────────────────────┘
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:SRK hash:cb2cc774b2dcec92c840eca0646b78f8d3661d3a43ed265a490a13aca75e190a
INFO:spsdk.image.ahab.signed_msg:Exported shared_secret to workspace/assets/shared_secret.bin
INFO:spsdk.image.ahab.signed_msg:Exported oem_import_mk_sk to workspace/assets/oem_import_mk_sk.bin
INFO:spsdk.image.ahab.signed_msg:Exported oem_import_wrap_sk to workspace/assets/oem_import_wrap_sk.bin
INFO:spsdk.image.ahab.signed_msg:Exported oem_import_cmac_sk to workspace/assets/oem_import_cmac_sk.bin
Performing post export
workspace/assets/shared_secret.bin
workspace/assets/oem_import_mk_sk.bin
workspace/assets/oem_import_wrap_sk.bin
workspace/assets/oem_import_cmac_sk.bin
Success. (Signed message: workspace/signed_msg_key_exchange_hkdf.bin created.)
3. Key Import Operation#
3.1 Purpose#
The key import operation allows secure importation of symmetric keys or private keys from asymmetric key pairs into the EdgeLock Secure Enclave key storage.
3.2 Key Features#
Encrypted Import: All imported keys must be encrypted (except specific cases like SRKH)
Multiple Key Types: Supports AES, HMAC, ECC, and other key types
Flexible Wrapping: Supports RFC3394 and AES-CBC wrapping algorithms
Signed TLV Format: Uses signed TLV (Type-Length-Value) format for integrity
3.3 TLV Blob generation#
Example of the configuration of TLV blob for importing the AES-256 key.
command:
KEY_IMPORT:
# Key identification
key_id: 0 # Key store ID
# Permitted algorithm
permitted_algorithm: "ALL CIPHER" # Hash algorithm for verification
# Key attributes
key_type: AES # Key type and hash
key_size_bits: 256 # Key size: 128/192/224/256/384/512
key_lifetime: ELE_KEY_IMPORT_PERSISTENT # Persistence level
key_lifecycle: OPEN_CLOSED # Lifecycle restrictions
key_usage: # Permission list
- Encrypt
- Decrypt
# Wrapping configuration
oem_mk_sk_key_id: 1 # OEM_IMPORT_MK_SK key ID
key_wrapping_algorithm: RFC3394 # RFC3394 or AES_CBC
signing_algorithm: CMAC # Signature algorithm
# Key data (two options)
# Option 1: Pre-wrapped key and signature
# wrapped_key: "0x00000000"
# signature: "0x00000000000000000000000000000000"
# Option 2: Raw key with master key (automatic wrapping)
import_key: aes256.bin # Raw key file
oem_import_mk_sk_key: "0xc7e7436ed876b0176d775a658c3e9bcf59c940a41a2673b0552b7d7df504d194" # Taken from the key exchange operation
# Optional SRKH for salt derivation
srkh: "0x00000000000000000000000000000000"
3.4 Supported Key Types#
Key Type |
Value |
Supported Sizes (bits) |
|---|---|---|
AES |
0x2400 |
128, 192, 256 |
HMAC |
0x1100 |
224, 256, 384, 512 |
Derived key |
0x1200 |
256, 384 |
OEM_IMPORT_MK_SK |
0x9200 |
128, 192, 256 |
ECC NIST |
0x7112 |
128, 192, 256, 384, 521 |
3.5 Key Usage Permissions#
Permission |
Value |
Description |
|---|---|---|
Cache |
0x00000004 |
Cache in secure memory (default) |
Encrypt |
0x00000100 |
Encryption operations |
Decrypt |
0x00000200 |
Decryption operations |
Sign message |
0x00000400 |
Message signing (MAC/asymmetric) |
Verify message |
0x00000800 |
Message verification |
Sign hash |
0x00001000 |
Hash signing (asymmetric) |
Verify hash |
0x00002000 |
Hash verification |
Derive |
0x00004000 |
Key derivation operations |
3.6 Export of TLV blob#
nxpimage -v signed-msg tlv export -c inputs/tlv_import_aes256.yaml
YamlDiffWidget("inputs/tlv_import_aes256.diffc").html
3.6.1 TLV blob - AES256#
%! nxpimage -v signed-msg tlv export -c inputs/tlv_import_aes256.yaml
nxpimage -v signed-msg tlv export -c inputs/tlv_import_aes256.yaml
INFO:spsdk.image.ahab.tlv:The Import key Signed message created with raw key and OEM_IMPORT_MK_SK key.
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_WRAP_SK: f2fa66b83ed82acbe4dddb5c60966cabad61cf3116b542115f10f06cf6aee825
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_CMAC_SK: dc202a1160b4a5d11c088514e99e298b45aba12867543236fcd8774227f3e15c
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV blob size: 141 bytes
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV details:
TLV
Key ID value: 0x00000000, 0
Key import algorithm value: ALL CIPHER
Key usage value: ['Encrypt', 'Decrypt']
Key type value: AES
Key bit size value: 0x00000100, 256
Key life time value: ELE_KEY_IMPORT_PERSISTENT
Key life cycle value: OPEN_CLOSED
OEM Import MK SK key ID value: 0x00000001, 1
Key wrapping algorithm: RFC3394
Initial vector value: 00000000000000000000000000000000
Key signing algorithm: CMAC
Import key wrapped data: 8551f75b2dd95752084cfbc196a8ae1102eab2e1821fbcaf70a9f5b4e7dc3a130441cc3272524bf0
Signature: a63e4e71b1dae995c8a484a12e6f811b
Success. (TLV blob: inputs/tlv.bin created.)
3.6.2 TLV blob - ECC384#
YamlDiffWidget("inputs/tlv_import_ecc384.diffc").html
%! nxpimage -v signed-msg tlv export -c inputs/tlv_import_ecc384.yaml
nxpimage -v signed-msg tlv export -c inputs/tlv_import_ecc384.yaml
INFO:spsdk.image.ahab.tlv:The Import key Signed message created with raw key and OEM_IMPORT_MK_SK key.
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_WRAP_SK: f2fa66b83ed82acbe4dddb5c60966cabad61cf3116b542115f10f06cf6aee825
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_CMAC_SK: dc202a1160b4a5d11c088514e99e298b45aba12867543236fcd8774227f3e15c
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV blob size: 157 bytes
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV details:
TLV
Key ID value: 0x00000000, 0
Key import algorithm value: ECDSA SHA384
Key usage value: ['Sign hash', 'Verify hash']
Key type value: ECC NIST
Key bit size value: 0x00000180, 384
Key life time value: ELE_KEY_IMPORT_PERSISTENT
Key life cycle value: OPEN_CLOSED
OEM Import MK SK key ID value: 0x00000001, 1
Key wrapping algorithm: RFC3394
Initial vector value: 00000000000000000000000000000000
Key signing algorithm: CMAC
Import key wrapped data: 8b3fa3a1a659ae4c4b5a120cb5eebb2ae3fd33ecbd9b3e2cc7c3b4566848cc40aa33601469fa82750ef1acc9d37800f03c381e86ec560513
Signature: e7d995f27ac05e7336a800a5924d38e0
Success. (TLV blob: inputs/tlv.bin created.)
3.6.3 TLV blob - ECC521#
YamlDiffWidget("inputs/tlv_import_ecc521.diffc").html
%! nxpimage -v signed-msg tlv export -c inputs/tlv_import_ecc521.yaml
nxpimage -v signed-msg tlv export -c inputs/tlv_import_ecc521.yaml
INFO:spsdk.image.ahab.tlv:The Import key Signed message created with raw key and OEM_IMPORT_MK_SK key.
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_WRAP_SK: f2fa66b83ed82acbe4dddb5c60966cabad61cf3116b542115f10f06cf6aee825
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_CMAC_SK: dc202a1160b4a5d11c088514e99e298b45aba12867543236fcd8774227f3e15c
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV blob size: 199 bytes
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV details:
TLV
Key ID value: 0x00000000, 0
Key import algorithm value: ECDSA SHA512
Key usage value: ['Sign hash', 'Verify hash']
Key type value: ECC NIST
Key bit size value: 0x00000209, 521
Key life time value: ELE_KEY_IMPORT_PERSISTENT
Key life cycle value: OPEN_CLOSED
OEM Import MK SK key ID value: 0x00000001, 1
Key wrapping algorithm: AES_CBC
Initial vector value: 00000000000000000000000000000000
Key signing algorithm: CMAC
Import key wrapped data: 917b068704098f0685083f3056a08b1a95d0f49cff49806103a04c7cad2a57859b1a16a74e82fb193db3a6aeb1726c6d9190c501c19a3bd4613406010b8a010b7a12435e56bec4a7df52e9fec126e6d3
Signature: db088ca226029d74b52cb97b88f86d8b
Success. (TLV blob: inputs/tlv.bin created.)
3.6.3 TLV blob - RSA4096#
YamlDiffWidget("inputs/tlv_import_rsa4096.diffc").html
%! nxpimage -v signed-msg tlv export -c inputs/tlv_import_rsa4096.yaml
nxpimage -v signed-msg tlv export -c inputs/tlv_import_rsa4096.yaml
INFO:spsdk.image.ahab.tlv:The Import key Signed message created with raw key and OEM_IMPORT_MK_SK key.
INFO:spsdk.image.ahab.tlv:RSA key loaded: 4096 bits, modulus: 512 bytes, exponent: 512 bytes
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_WRAP_SK: f2fa66b83ed82acbe4dddb5c60966cabad61cf3116b542115f10f06cf6aee825
INFO:spsdk.image.ahab.tlv:Derived OEM_IMPORT_CMAC_SK: dc202a1160b4a5d11c088514e99e298b45aba12867543236fcd8774227f3e15c
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV blob size: 1135 bytes
INFO:spsdk.apps.nxpimage_apps.nxpimage_signed_msg:TLV details:
TLV
Key ID value: 0x00000000, 0
Key import algorithm value: RSA PKCS1 ALL
Key usage value: ['Sign hash', 'Verify hash']
Key type value: RSA
Key bit size value: 0x00001000, 4096
Key life time value: ELE_KEY_IMPORT_PERSISTENT
Key life cycle value: OPEN_CLOSED
OEM Import MK SK key ID value: 0x00000001, 1
Key wrapping algorithm: RFC3394
Initial vector value: 00000000000000000000000000000000
Key signing algorithm: CMAC
Import key wrapped data: 897ef5802e89080fb176798992bbe954b2ce3e6b31afe2c6d151e171487b76cfca004a70f83dbaf3b7d7a7dc4b1187bc57c8da4d9d6a0663cad30f1156806fc8973cf391aa4df68450392292539a782c400f33f03c7703e709816752f71cd8db836be26cf7e5814ee3d0e3bb9ee67b633630cc34497c395f510d1dd357975e9d55add77475b1ac52031e6db64be8decf234dfe05fbe439d1e0a8c8eea8d66b6c9fc746d7640860384692d913dfecafc1cefc79d3ce4f2b932724891ff0ad01e46667b44a5259901fedcda603318ea989e052e6b9a8fc60af1303bae83d36c12b5e538a9f561d34e441e8cfd7e6533222a1f79a57831d6ac00c465880a9b7e01c9a05e2f0b0f4651a5b26b1f889ba5964ee52495d3746a458a7cd83ba2bff43633f8e9d3eb1f48d8b266176f68f933f02cffde1bd7dd4c1636b133bc1d2ae48b9d3dacef71512a902960b44abd53bdee6b5e6fdb3b125be55a24d278c9bf351e57c258fd5725a91a09a6b7b616eb8c9935af44c1f78d70e6fce8cc5f8f808cb920bb1c8860d108bc5887cdcbe14e84355ad941c5cb5b1e2ec706c7a08292a03a733cb7975518e8bc023728fbf0ebf827728550a20c216dde511b362d579f6f515bfbc16f912efcffed2e076ecb72f503a584a702823bc8218c38305bf88ca8d015dd30219471dd0bad0c629e712dac5bf5ec72773be2855b7836b7dd49420bb6fe34b0ec977639ac64ec70ed190e6e45f6b4ffc55bf734e6daddf8acd6eb3fe36a6b3bf46d9f5c6ba34226e4886decc9674e10595e331ff625373eb2eac16cb19fa87ed1e99f9132bf63c2af243c1e530568004e6665e4c251dadb04cef6d9ab9e3b3535c59a628a7ec3863c372e6d61728e4a671b8b5cd8bb0072e10c615b908207afb0d3f9ee9d8f7061bbb932c9cf6279966a553e3b38868eb2ac045fe3fba5ff2861c4c9f1b02ed4293475a89a3e291ad95bd029c9a47a9afc228be51ba60159a7773621e3e1bf9f37a90554e5d74ee2b467d74e172ff46c412b837e784fa361bb6389a1737e8ddae1296b0e585ba119d4eacc8cdf9a9747366b34f1ab5136597216478897b777ae3b94ed2e3dcf1180f6fa3cb84e437d26c8f477a6978d3d98f1bff290f9b465a6d6bfe2746fff21a658671ec50705ea140ea64399adcac4118fb1fe1fc8f800764ca095396cdccd90b592a533a82039bb817451cfa382c27b23bf9a1b0bb293f4b91cad702372678229d2d5404488efbd544ed28cfce3aa1fce533c6d2924512334d3c436d04081364949f2c0f32b36466c534eb764435a5724bfe5173e6dee905e2f646faa36cabc3ebf79fefbeaeaa513dc67b032e76d2de1bd78aead20e24745ffc3d9ac7a3e248a14577fef24cd98ccca4cad1334380d577d7d6f8e5d80567131f18eb1c9fff51c62743c2eb2ad070fa6a560cba26ac0e6ca152cb2db3
Signature: 6458344257179e589d2acb7e102743b9
Success. (TLV blob: inputs/tlv.bin created.)