5.24. Import External Object Prepare

Import External Object command allows the user to import an external object wrapped with a secure ECKey_Auth context. A session is not required to execute this command, the ECKey_Auth parameters are provided with the wrapped WriteSecureObject command. The applet will use ECKey_Auth parameters and derive session keys to unwrap the command and execute it. ImportExternalObject command works in its own session. It will open an ECKey session, write the secure object and close the session.

In this example, we prepare a complete raw APDU to be sent to SE05x. A WriteSecureObject command needs to be prepared which will be wrapped and sent as a part of ImportExternalObject command. For an example we are preparing WriteSymmKey command as :

/* Symmetric Key */
/* clang-format off */
uint8_t keyValue[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x31};
/* clang-format on */
/* API to create buffer */
pse05xWriteBufferSessionCtx->fp_TXn = &fLogTransmitBufferCreateAPDU;
int index                           = 0;
Se05xPolicy_t policy;
uint8_t policyBuffer[MAX_POLICY_BUFFER_SIZE] = {0};
size_t policyBufferLen                       = sizeof(policyBuffer);

/* Create policy if required */
getWriteOnlyKeyPolicy(policyBuffer, &policyBufferLen);
policy.value     = policyBuffer;
policy.value_len = policyBufferLen;

sm_status = Se05x_API_WriteSymmKey(pse05xWriteBufferSessionCtx,
    &policy,
    SE05x_MaxAttemps_NA,
    __LINE__,
    SE05x_KeyID_KEK_NONE,
    keyValue,
    sizeof(keyValue),
    kSE05x_INS_NA,
    kSE05x_SymmKeyType_AES);
if (sm_status != SM_OK) {
    LOG_E("Failed to create buffer");
    status = kStatus_SSS_Fail;
    goto exit;
}
/* WriteSecureObject API will prepare complete APDU.
 * We need to skip initial CLA INS P1 P2 and use just the TLVs
 *
 * The length is determined by the first length byte. If it
 * is 0x00, the next two bytes are the length, otherwise that
 * byte is the length.
 *
 * Determine the length here and accordingly determine the TLV.
 */
if (gTxBuffer[4] == 0x00) {
    WriteSymmKeyAPDU_len = ((gTxBuffer[5] << 8) && 0xFF00) | ((gTxBuffer[6]) && 0xFF);
    index                = 7;
}
else {
    WriteSymmKeyAPDU_len = gTxBuffer[4];
    index                = 5;
}
if (WriteSymmKeyAPDU_len > sizeof(WriteSymmKeyAPDU)) {
    LOG_E("Insufficient buffer");
    status = kStatus_SSS_Fail;
    goto exit;
}
memcpy(WriteSymmKeyAPDU, &gTxBuffer[index], WriteSymmKeyAPDU_len);
/* This API creates an APDU buffer and stores it to the global buffer */
smStatus_t fLogTransmitBufferCreateAPDU(Se05xSession_t *pwrite_apdubufferctx,
    const tlvHeader_t *hdr,
    uint8_t *cmdBuf,
    size_t cmdBufLen,
    uint8_t *rsp,
    size_t *rspLen,
    uint8_t hasle)
{
    memset(gTxBuffer, 0, sizeof(gTxBuffer));
    size_t i = 0;
    memcpy(&gTxBuffer[i], hdr, sizeof(*hdr));
    smStatus_t ret = SM_OK;
    i += sizeof(*hdr);
    if (cmdBufLen > 0) {
        // The Lc field must be extended in case the length does not fit
        // into a single byte (Note, while the standard would allow to
        // encode 0x100 as 0x00 in the Lc field, nobody who is sane in his mind
        // would actually do that).
        if ((cmdBufLen < 0xFF) && !hasle) {
            gTxBuffer[i++] = (uint8_t)cmdBufLen;
        }
        else {
            gTxBuffer[i++] = 0x00;
            gTxBuffer[i++] = 0xFFu & (cmdBufLen >> 8);
            gTxBuffer[i++] = 0xFFu & (cmdBufLen);
        }
        memcpy(&gTxBuffer[i], cmdBuf, cmdBufLen);
        i += cmdBufLen;
    }
    if (hasle) {
        gTxBuffer[i++] = 0x00;
        gTxBuffer[i++] = 0x00;
    }
    ret          = SM_OK;
    gTxBufferLen = i;

    LOG_AU8_I(gTxBuffer, gTxBufferLen);

    return ret;
}

You can call any of the WriteSecureObject API with your data and create the buffer.

5.24.1. Building

Build the project with the following configurations.

se05x_ImportExternalObjectPrepare

  • Project = se05x_ImportExternalObjectPrepare

  • SCP=SCP03_SSS

  • SE05x_Auth=ECKey or SE05x_Auth=ECKey_PlatfSCP03

5.24.2. How to use

Generate the raw APDU file by running the executable. Run se05x_ImportExternalObjectPrepare as

se05x_ImportExternalObjectPrepare.exe -keyid 0x7DA00003 -file eckey_ecdsa.der -out rawAPDU.der <portName>

where,

  • keyid is the authentication keyId at which ECDSA public key is stored.

  • file is the input ECDSA keypair file (in binary format)

  • out is the output file where the raw APDU will be stored.

  • portName is the name of the port over which to connect (COMPORT in case running over VCOM)

After this executes successfully, you need to send the generated raw APDU to SE05x. Refer to Section 5.25 Import External Object Create