Hi @Fjk ,
Thanks for the reaching out! Please have my comments as below:
Q1: Implementation Method & API Guidance:
What is the recommended SSS API implementation method to execute this end-to-end workflow without revealing the plain DEK to the host?
The correct approach uses a two-layer API strategy:
- Key management (KEK store, DEK wrap/unwrap): Use
Se05x_API_ExportObject() / Se05x_API_ImportObject() from se05x_APDU_apis.h. These operate entirely inside the SE051 and are the only way to wrap/unwrap a key using another key stored in SE051 without ever revealing plaintext to the host.
- File encryption/decryption: Use
sss_cipher_one_go() (or sss_cipher_init + sss_cipher_update + sss_cipher_finish for large files) against the transient DEK object created by the import step above.
The SSS high-level layer (sss_key_store_set_key) cannot be used for DEK import-from-wrapped, because it always requires the key in plaintext on the host side. The APDU-level Se05x_API_ImportObject is required for the unwrap step to remain fully inside SE051.
Q2 : Key Unwrapping & Transient Objects:
What specific SSS APIs and policies are required to import a Wrapped DEK, unwrap it within SE051, and hold it as a transient key object for immediate file encryption/decryption?
Phase 1: Key Provisioning & Wrapping
Step 1 — Store the KEK as a persistent object:
// Policy for KEK: allow ENC/DEC and IMPORT_EXPORT (for use as wrapping key)
sss_policy_u kekPolicyList[] = {
{ .type = KPolicy_Sym_Key,
.policy = { .symmkey = { .can_Encrypt = 1, .can_Decrypt = 1,
.can_Import_Export = 1 } } }
};
sss_policy_t kekPolicy = { .nPolicies = 1, .policies = kekPolicyList };
sss_object_t kekObject = {0};
sss_key_object_init(&kekObject, &pCtx->ks);
sss_key_object_allocate_handle(&kekObject, KEK_KEY_ID,
kSSS_KeyPart_Default, kSSS_CipherType_AES,
AES256_KEY_BYTES, kKeyObject_Mode_Persistent);
sss_key_store_set_key(&pCtx->ks, &kekObject,
kekData, kekLen, kekLen * 8, &kekPolicy, sizeof(kekPolicy));
Step 2 — Import the plain DEK into SE051 as a transient object:
// Policy for DEK: allow ENC/DEC and IMPORT_EXPORT (so it can be wrapped for export)
sss_policy_u dekPolicyList[] = {
{ .type = KPolicy_Sym_Key,
.policy = { .symmkey = { .can_Encrypt = 1, .can_Decrypt = 1,
.can_Import_Export = 1 } } }
};
sss_policy_t dekPolicy = { .nPolicies = 1, .policies = dekPolicyList };
sss_object_t dekObject = {0};
sss_key_object_init(&dekObject, &pCtx->ks);
sss_key_object_allocate_handle(&dekObject, DEK_TEMP_ID,
kSSS_KeyPart_Default, kSSS_CipherType_AES,
AES256_KEY_BYTES, kKeyObject_Mode_Transient);
sss_key_store_set_key(&pCtx->ks, &dekObject,
plainDEK, dekLen, dekLen * 8, &dekPolicy, sizeof(dekPolicy));
// plainDEK is the ONLY moment the DEK appears on the host — during initial provisioning only
Step 3 — Export the DEK wrapped by the KEK (entirely inside SE051):
// Se05x_API_ExportObject wraps DEK_TEMP_ID using KEK_KEY_ID — no plaintext leaves SE051
uint8_t wrappedDEK[AES256_KEY_BYTES + 8]; // RFC 3394 adds 8 bytes overhead
size_t wrappedDEKLen = sizeof(wrappedDEK);
pSe05xSession_t se05xSession =
&((sss_se05x_session_t *)&pCtx->session)->s_ctx;
Se05x_API_ExportObject(se05xSession,
DEK_TEMP_ID, // Object to wrap (the transient DEK)
kSE05x_TransientIndicator_TRANSIENT,
wrappedDEK,
&wrappedDEKLen);
// Store wrappedDEK to host persistent storage — safe, never reveals plaintext DEK
//Please note The transient DEK_TEMP_ID object is automatically deleted when the session closes. After exporting the wrapped DEK, the plain DEK is gone from SE051.
Phase 2: Runtime File Protection:
Step 4 — Import wrapped DEK: SE051 unwraps internally using KEK, stores as transient:
// Se05x_API_ImportObject unwraps the wrapped DEK using KEK_KEY_ID INSIDE SE051
// The DEK never appears in plaintext on the host — this is the key security guarantee
Se05x_API_ImportObject(se05xSession,
DEK_RUNTIME_ID, // Target object ID for the unwrapped DEK
kSE05x_RSAKeyComponent_NA, // N/A for symmetric keys
NULL, // Use default policy
0,
wrappedDEK, // Wrapped DEK from host storage
wrappedDEKLen,
kSE05x_TransientIndicator_TRANSIENT, // Store as transient — clears on session end
KEK_KEY_ID); // SE051 uses this key to unwrap internally
Step 5 — Encrypt/Decrypt the file using the transient DEK:
// Get handle to the now-unwrapped transient DEK
sss_object_t dekTransient = {0};
sss_key_object_init(&dekTransient, &pCtx->ks);
sss_key_object_get_handle(&dekTransient, DEK_RUNTIME_ID);
// Encrypt
sss_symmetric_t ctxEncrypt = {0};
sss_symmetric_context_init(&ctxEncrypt, &pCtx->session, &dekTransient,
kAlgorithm_SSS_AES_CBC, kMode_SSS_Encrypt);
sss_cipher_one_go(&ctxEncrypt, iv, ivLen,
plainFileData, encryptedFileData, dataLen);
sss_symmetric_context_free(&ctxEncrypt);
// Decrypt (same pattern, change mode to kMode_SSS_Decrypt)
sss_symmetric_t ctxDecrypt = {0};
sss_symmetric_context_init(&ctxDecrypt, &pCtx->session, &dekTransient,
kAlgorithm_SSS_AES_CBC, kMode_SSS_Decrypt);
sss_cipher_one_go(&ctxDecrypt, iv, ivLen,
encryptedFileData, decryptedFileData, dataLen);
sss_symmetric_context_free(&ctxDecrypt);
// Explicitly erase transient DEK after use (optional, also cleared on session close)
sss_key_store_erase_key(&pCtx->ks, &dekTransient);
sss_key_object_free(&dekTransient);
Q3: Reference Code:
Are there any code samples in Plug & Trust MW v04.00.00 that demonstrate key wrapping/unwrapping combined with symmetric encryption operations inside SE051?
There is no single example that combines key wrapping + symmetric encryption end-to-end, but the following examples should be helpful.
| Purpose |
Path in simw-top/ |
| AES symmetric encrypt/decrypt |
sss/ex/symmetric/ex_sss_symmetric.c |
| Using object policies |
demos/se05x/se05x_policy/ |
| Key export/import at APDU level |
hostlib/hostLib/se05x/src/se05x_APDU_apis.c |
Hope that helps,
Have a great day,
Kan
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------