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_ImportExternalObjectPrepareSCP=SCP03_SSSSE05x_Auth=ECKeyorSE05x_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
