Request for AES-GCM Example with SE052F

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Request for AES-GCM Example with SE052F

1,115 Views
JaeHoLee1811
Contributor I

Hello,

I am currently working with the EdgeLock SE052F secure element and would like to use the AES-GCM mode for encryption and authentication.
According to the SE052F specifications, AES-GCM should be supported. However, after searching through the SIMW-TOP package and its documentation, I was unable to find any example or reference implementation for AES-GCM.

Could you please help clarify the following points?

  1. Is there any example code or API usage guide demonstrating AES-GCM encryption/decryption (including tag generation and verification) for SE052F?

  2. If such examples exist within SIMW-TOP or another middleware package (e.g., Plug & Trust Middleware), could you please point me to the exact location or documentation?

  3. Are there any specific considerations or limitations when using AES-GCM on SE052F (e.g., supported key sizes, IV/nonce handling, tag length, etc.)?

 

void se_test(void)
{
    sss_status_t st = ex_sss_entry(PCONTEXT);
    if (st != kStatus_SSS_Success) {
        ESP_LOGE("SE-GCM", "ex_sss_entry failed (0x%X)", st);
        return;
    }
    log_se_applet_version(&PCONTEXT->session);
    se_delete_object(PCONTEXT, USER_TEMPLATE_AES_KEY_ID);
    se_list_ids(PCONTEXT, kSE05x_SecObjTyp_AES_KEY);

    vTaskDelay(pdMS_TO_TICKS(500));

    sss_status_t status = kStatus_SSS_Success;
    sss_algorithm_t algorithm;
    sss_mode_t mode;
    /* clang-format off */
    uint8_t srcData[16] = { 0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x31 }; /*HELLOHELLOHELLO1*/
    uint8_t keystring[16] = { 0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x31 }; /*HELLOHELLOHELLO1*/
    uint8_t destData[16] = {0,};
    size_t destDataLen = sizeof(destData);
    uint8_t iv[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x15, 0x71, 0x99, 0x32, 0xd3, 0x56, 0x90};
    size_t ivlen = sizeof(iv);
    uint32_t keyId = USER_TEMPLATE_AES_KEY_ID;
    sss_key_part_t keyPart;
    sss_cipher_type_t cipherType;
    size_t keyByteLenMax = 16;
    sss_object_t key = { 0 };
    sss_aead_t ctx_aead_encrypt = { 0 };
    size_t TAG_SIZE = 16;
    uint8_t tag[TAG_SIZE];
    uint8_t  *aad =(uint8_t*)"Extra authentication data";
    size_t aadSize = strlen((char*)aad);

    // === 1) Symmetric Key Policy: GCM 허용 + 외부 IV 금지 ===
    static const sss_policy_sym_key_u gcm_symm = {
        .can_Sign = 0,
        .can_Verify = 0,
        .can_Encrypt = 1,              // GCM Encrypt 허용
        .can_Decrypt = 1,              // GCM Decrypt 허용
        .can_Import_Export = 0,        // 필요 시 1
        .forbid_Derived_Output = 0,
        .can_TLS_KDF = 0,
        .allow_kdf_ext_rnd = 0,
        .can_TLS_PMS_KD = 0,
        .can_HKDF = 0,
        .can_PBKDF = 0,
        .can_Wrap = 0,
        .can_Desfire_Auth = 0,
        .can_Desfire_Dump = 0,
        .can_Desfire_KD = 0,
        .forbid_external_iv = 1,       // ★ AN13904: 외부 IV 금지
        .can_usage_hmac_pepper = 0,
        .can_KA = 0,
        .can_KD = 0,
        .can_Write = 0,                // (공통 정책에서 R/W/Delete 처리)
        .can_Gen = 0,
    };

    // === 2) Common Policy: Read/Write/Delete 허용 + Secure Messaging 강제 ===
    static const sss_policy_common_u common = {
        .forbid_All = 0,
        .can_Read   = 1,               // 읽기 허용
        .can_Write  = 1,               // 쓰기 허용
        .can_Delete = 1,               // 삭제 허용
        .req_Sm     = 1,               // ★ SCP03 등 보호채널(암호/무결성) 강제
        .req_pcr_val = 0,
    };

    // === 3) Policy Wrapper ===
    static const sss_policy_u pol_sym = {
        .type = KPolicy_Sym_Key,
        .auth_obj_id = 0,
        .policy.symmkey = gcm_symm,
    };
    static const sss_policy_u pol_common = {
        .type = KPolicy_Common,
        .auth_obj_id = 0,
        .policy.common = common,
    };

    // === 4) Policy Array (두 정책 동시 적용) ===
    static const sss_policy_t key_policy = {
        .policies = { &pol_sym, &pol_common },
        .nPolicies = 2,
    };

    algorithm =  kAlgorithm_SSS_AES_GCM;
    keyPart    = kSSS_KeyPart_Default;
    cipherType = kSSS_CipherType_AES;
    mode       = kMode_SSS_Encrypt;

    /* doc:start ex_sss_symmetric-allocate-key */
    /* Pre-requisite for encryption Part*/
    ENSURE_OR_GO_CLEANUP(kType_SSS_SE_SE05x == ((PCONTEXT)->session).subsystem);
    status = sss_key_object_init(&key, &(PCONTEXT)->ks);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_object_allocate_handle(&key, keyId, keyPart, cipherType, keyByteLenMax, kKeyObject_Mode_Persistent);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    // status = sss_key_store_set_key(&(PCONTEXT)->ks, &key, keystring, sizeof(keystring), sizeof(keystring) * 8, NULL, 0);
    status = sss_key_store_set_key(&(PCONTEXT)->ks, &key, keystring, sizeof(keystring), sizeof(keystring) * 8, &key_policy, sizeof(key_policy));
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
    /* doc:end ex_sss_symmetric-allocate-key */
    se_list_ids(PCONTEXT, kSE05x_SecObjTyp_AES_KEY);
    se_dump_free_memory(PCONTEXT);
    /* doc:start ex_sss_aead-encrypt */

    status = sss_aead_context_init(&ctx_aead_encrypt, &(PCONTEXT)->session, &key, algorithm, mode);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    LOG_I("Do Encryption");
    LOG_MAU8_I("iv", iv, ivlen);
    LOG_MAU8_I("srcData", srcData, sizeof(srcData));
    /*Do Encryption*/

    status = sss_aead_one_go(&ctx_aead_encrypt,srcData,destData, destDataLen, iv, ivlen, aad, aadSize, tag, &TAG_SIZE);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
    /* doc:end ex_sss_aead-encrypt */

    LOG_MAU8_I("encrypted data", destData, destDataLen);
    LOG_I("Encryption successful !!!");

cleanup:
    ex_sss_close((PCONTEXT));
}
 
static sss_status_t select_applet(ex_sss_boot_ctx_t *pCtx)
{
    sss_session_t *pSession                 = &pCtx->session;
    pCtx->se05x_open_ctx.skip_select_applet = 0;
    pCtx->se05x_open_ctx.connType           = kType_SE_Conn_Type_T1oI2C;
    sss_status_t status = sss_session_open(pSession, kType_SSS_SE_SE05x, 0, kSSS_ConnectionType_Encrypted, &pCtx->se05x_open_ctx);
    if (status == kStatus_SSS_Success) {
        LOG_I("Applet selection successful!");
    }
    else {
        LOG_E("Applet selection failed!");
    }

    status = sss_key_store_context_init(&pCtx->ks, pSession);
    if (kStatus_SSS_Success != status) { LOG_E("SE keystore init fail (0x%X)", status);}

    status = sss_key_store_allocate(&pCtx->ks, 1U);
    if (kStatus_SSS_Success != status) { LOG_E("SE keystore alloc fail (0x%X)", status);}

    return status;
}

static sss_status_t test_random(ex_sss_boot_ctx_t *pCtx)
{
    sss_rng_context_t rng;
    uint8_t rndData[256] = {0};

    sss_status_t status = sss_rng_context_init(&rng, &pCtx->session);
    ENSURE_OR_GO_CLEANUP(kStatus_SSS_Success == status);
    status = sss_rng_get_random(&rng, rndData, 32);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
    status = sss_rng_context_free(&rng);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

cleanup:
    return status;
}

sss_status_t s_alloc_Scp03key_Host(sss_object_t *keyObject, sss_key_store_t *pKs, uint32_t keyId)
{
    sss_status_t status = kStatus_SSS_Fail;
    status              = sss_key_object_init(keyObject, pKs);
    if (status != kStatus_SSS_Success) {
        return status;
    }

    status = sss_key_object_allocate_handle(keyObject,
        keyId,
        kSSS_KeyPart_Default,
        kSSS_CipherType_AES,
        SCP03_MAX_AUTH_KEY_SIZE,
        kKeyObject_Mode_Transient);
    return status;
}

sss_status_t s_platform_prepare_host(sss_session_t *pHostSession,
    sss_key_store_t *pHostKs,
    SE_Connect_Ctx_t *se05x_open_ctx,
    uint8_t *ENC_KEY,
    uint8_t *MAC_KEY,
    uint8_t *DEK_KEY,
    size_t key_length)
{
    sss_status_t status = kStatus_SSS_Fail;

    NXSCP03_StaticCtx_t *pStatic_ctx = se05x_open_ctx->auth.ctx.scp03.pStatic_ctx;
    NXSCP03_DynCtx_t *pDyn_ctx       = se05x_open_ctx->auth.ctx.scp03.pDyn_ctx;

    pStatic_ctx->keyVerNo = PF_KEY_VERSION_NO;

    /* Init Allocate ENC Static Key */
    status = s_alloc_Scp03key_Host(&pStatic_ctx->Enc, pHostKs, __LINE__);
    if (status != kStatus_SSS_Success) {
        return status;
    }
    /* Set ENC Static Key */
    status = sss_key_store_set_key(pHostKs, &pStatic_ctx->Enc, ENC_KEY, key_length, key_length * 8, NULL, 0);
    if (status != kStatus_SSS_Success) {
        return status;
    }

    /* Init Allocate MAC Static Key */
    status = s_alloc_Scp03key_Host(&pStatic_ctx->Mac, pHostKs, __LINE__);
    if (status != kStatus_SSS_Success) {
        return status;
    }
    /* Set MAC Static Key */
    status = sss_key_store_set_key(pHostKs, &pStatic_ctx->Mac, MAC_KEY, key_length, key_length * 8, NULL, 0);
    if (status != kStatus_SSS_Success) {
        return status;
    }

    /* Init Allocate DEK Static Key */
    status = s_alloc_Scp03key_Host(&pStatic_ctx->Dek, pHostKs, __LINE__);
    if (status != kStatus_SSS_Success) {
        return status;
    }
    /* Set DEK Static Key */
    status = sss_key_store_set_key(pHostKs, &pStatic_ctx->Dek, DEK_KEY, key_length, key_length * 8, NULL, 0);
    if (status != kStatus_SSS_Success) {
        return status;
    }

    /* Init Allocate ENC Session Key */
    status = s_alloc_Scp03key_Host(&pDyn_ctx->Enc, pHostKs, __LINE__);
    if (status != kStatus_SSS_Success) {
        return status;
    }

    /* Init Allocate MAC Session Key */
    status = s_alloc_Scp03key_Host(&pDyn_ctx->Mac, pHostKs, __LINE__);
    if (status != kStatus_SSS_Success) {
        return status;
    }
    /* Init Allocate DEK Session Key */
    status = s_alloc_Scp03key_Host(&pDyn_ctx->Rmac, pHostKs, __LINE__);

    return status;
}

sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx)
{
    /** Prepare Host for SCP03 connection, KCs will be set in ex_sss_entry **/
    SE05x_Connect_Ctx_t *pConnectCtx = &pCtx->se05x_open_ctx;
    // Hardcode the connection to T1oI2C
    pConnectCtx->connType = kType_SE_Conn_Type_T1oI2C;
    // Auth type is Platform SCP03
    pConnectCtx->auth.authType              = kSSS_AuthType_SCP03;
    pConnectCtx->auth.ctx.scp03.pStatic_ctx = &pCtx->ex_se05x_auth.scp03.ex_static;
    pConnectCtx->auth.ctx.scp03.pDyn_ctx    = &pCtx->ex_se05x_auth.scp03.ex_dyn;
    pConnectCtx->auth.ctx.scp03.pStatic_ctx->key_len = AUTH_KEY_SIZE;

    sss_status_t status = sss_host_session_open(&pCtx->host_session, kType_SSS_mbedTLS, 0, kSSS_ConnectionType_Plain, NULL);
    if (kStatus_SSS_Success != status) {
        LOG_E("Failed to open Host Session");
        goto cleanup;
    }
    status = sss_host_key_store_context_init(&pCtx->host_ks, &pCtx->host_session);
    if (kStatus_SSS_Success != status) {
        LOG_E("Host: sss_key_store_context_init failed");
        goto cleanup;
    }
    status = sss_host_key_store_allocate(&pCtx->host_ks, __LINE__);
    if (kStatus_SSS_Success != status) {
        LOG_E("Host: sss_key_store_allocate failed");
        goto cleanup;
    }

    status = s_platform_prepare_host(&pCtx->host_session,
        &pCtx->host_ks,
        &pCtx->se05x_open_ctx,
        SCP03_KEY_ENC,
        SCP03_KEY_MAC,
        SCP03_KEY_DEK,
        AUTH_KEY_SIZE);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    /* Open the SCP03 session with the applet selected */
    status = select_applet(pCtx);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    /* Test RNG */
    // status = test_random(pCtx);
    // ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
    // LOG_I("Random test was successful from secure application");

cleanup:
    return status;
}
Labels (2)
0 Kudos
Reply
4 Replies

1,089 Views
JaeHoLee1811
Contributor I

The logs are as follows

App :INFO :PAL open: use existing I2C port 0, addr 0x48
I (28832) pwr: button_state = 1
I (28832) pwr: button_state = 0
sss :INFO :atr (Len=35)
01 A0 00 00 03 96 04 03 E8 00 FE 02 0B 03 E8 00
01 00 00 00 00 64 13 88 0A 00 65 53 45 30 35 31
00 00 00
sss :INFO :Newer version of Applet Found
sss :INFO :Compiled for 0x70200. Got newer 0x70216
App :INFO :Applet selection successful!
App :WARN :#################### SE Applet Version ####################
App :INFO :Applet Major = 7
App :INFO :Applet Minor = 2
App :INFO :Applet Patch = 22
App :INFO :SecureBox = FFFF
App :WARN :###########################################################
App :INFO :Deleted object 0x20000004
App :INFO :ID[0] = 0x20000003
App :INFO :ID[1] = 0x20000002
App :INFO :ID[2] = 0xF0003394
App :INFO :ID[3] = 0x7FFF100A
App :INFO :ID[4] = 0x7FFF0207
App :INFO :>> filter=0x09 : 5 object(s)
App :INFO :ID[0] = 0x20000004
App :INFO :ID[1] = 0x20000003
App :INFO :ID[2] = 0x20000002
App :INFO :ID[3] = 0xF0003394
App :INFO :ID[4] = 0x7FFF100A
App :INFO :ID[5] = 0x7FFF0207
App :INFO :>> filter=0x09 : 6 object(s)
App :INFO :Free Persistent (NVM): 83948 bytes
App :INFO :Free Transient-RESET (RAM): 1077 bytes
App :INFO :Free Transient-DESELECT (RAM): 1072 bytes
App :INFO :Do Encryption
App :INFO :iv (Len=16)
00 00 00 00 00 00 00 00 FD 15 71 99 32 D3 56 90
App :INFO :srcData (Len=16)
48 45 4C 4C 4F 48 45 4C 4C 4F 48 45 4C 4C 4F 31
sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:7839 Function:sss_se05x_TXn
sss :WARN :APDU Transaction Error: Conditions not satisfied (0x6985)

sss :WARN :nxEnsure:'status == SM_OK' failed. At Line:6697 Function:sss_se05x_aead_one_go
App :WARN :nxEnsure:'status == kStatus_SSS_Success' failed. At Line:902 Function:se_test
App :INFO :phPalEse_i2c_close()

0 Kudos
Reply

1,089 Views
JaeHoLee1811
Contributor I

Hi,
I'm working in VSCode with an ESP32 custom board.

0 Kudos
Reply

907 Views
carlos_o
NXP TechSupport
NXP TechSupport

Apologies the late reply, 

There are not any examples to use AES-GCM on the SE052F,

I recommend you review the Plug & Trust MW Documentation there you could review how to configure the sss_aead functions to accomplish it. 


0 Kudos
Reply

1,093 Views
carlos_o
NXP TechSupport
NXP TechSupport

Hi @JaeHoLee1811 

Thanks for your post.

Could you please share in which environment are you working on this? (Linux, Visual Studio, or a specific board)

0 Kudos
Reply