S32K314でのSE050E AEAD復号化 様 S32K314 プラットフォームで、SE050E を使用して TLS1.3 を開発しています。 TLS1.3ハンドシェイク中に、 AEAD(AES GCM)キーがトラフィックキーとしてインポートされます。 AEADOneShotコマンド(AES GCM計算)Se05x_API_AeadOneShot()が実行されます。 ただし、SE050 は NACK で I2C にアクセスできません。理由は分かりません。 この問題が発生する前は、I2C は正常に動作していました。S32K314 I2C の問題ですか? それとも SE050 の問題ですか? よろしくお願いします。 チャン < LOG > mbedtls_cipher_aead_decrypt 暗号 ctx(20427388) モード 6 [INF][devtask] 暗号 Aead OneGo 開始:0x204273a8 暗号モード:0xb0、OP タイプ:0x38 [INF][devtask] キーID: 0xef0003b7 [INF][devtask] aadLen: 5 (17 3 3 0...) [INF][devtask] nonceLen: 12 (67 bf 6f e0...) [INF][devtask] タグ長さ: 16 (49 5b 34 3d...) APDU TX 長さ=75: 80 03 11 38 00 00 42 41 04 EF 00 03 B7 42 01 B0 43 10 E0 5E 33 33 D5 52 0D C4 86 51 E8 E7 6E 0C 86 30 44 05 17 03 03 00 20 45 0C CC C3 95 FF 3A 88 9A A0 64 44 F2 52 46 10 97 C5 DA 87 CE F6 98 C9 DB E3 8D 81 F4 C0 A8 3E 00 00 _i2c_write() が失敗しました。最大再試行!!! < SW Code > i2c_error_t axI2CWrite(void *conn_ctx, unsigned char bus, unsigned char addr, unsigned char *pTx, unsigned short txLen)
{
Lpi2c_Ip_StatusType status;
int i;
curr_check_ticks = SYS_TMR_TickCountGet();
{
status = Lpi2c_Ip_MasterSendDataBlocking(
I2C_INSTANCE_1,
pTx,
txLen,
true, /* send STOP */
100000
);
if (status == LPI2C_IP_SUCCESS_STATUS)
{
return I2C_OK;
}
else
{
if (status == LPI2C_IP_RECEIVED_NACK_STATUS)
return I2C_NACK_ON_ADDRESS;
else
{
__printf("%s Failed(0x%x)\\r\\n", __func__, status);
return I2C_FAILED;
}
}
}
}
int phPalEse_i2c_write(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToWrite)
{
unsigned int ret = I2C_OK, retryCount = 0;
int numWrote = 0;
pBuffer[0] = 0x5A; //Recovery if stack forgot to add NAD byte.
do {
/* 1ms delay to give ESE polling delay */
sm_sleep(ESE_POLL_DELAY_MS);
ret = axI2CWrite(pDevHandle, I2C_BUS_0, SMCOM_I2C_ADDRESS, pBuffer, nNbBytesToWrite);
if (ret != I2C_OK) {
T_SMLOG_D("_i2c_write() error : %d ", ret);
if ((ret == I2C_NACK_ON_ADDRESS) && (retryCount < MAX_RETRY_COUNT)) {
retryCount++;
/* 1ms delay to give ESE polling delay */
/*i2c driver back off delay is providing 1ms wait time so ignoring waiting time at this level*/
//sm_sleep(ESE_POLL_DELAY_MS);
T_SMLOG_D("_i2c_write() failed. Going to retry, counter:%d !", retryCount);
continue;
}
if (retryCount == MAX_RETRY_COUNT)
__printf("_i2c_write() failed(0x%x). Max retry !!!(size:%d)\\r\\n", ret, nNbBytesToWrite);
return -1;
}
else {
numWrote = nNbBytesToWrite;
//sm_sleep(ESE_POLL_DELAY_MS);
break;
}
} while (ret != I2C_OK);
return numWrote;
}
smStatus_t DoAPDUTxRx(pSe05xSession_t session_ctx,
const tlvHeader_t *hdr,
uint8_t *cmdBuf,
size_t cmdBufLen,
uint8_t *rspBuf,
size_t *pRspBufLen,
uint8_t length_extended)
{
smStatus_t apduStatus = SM_NOT_OK;
ENSURE_OR_GO_EXIT(hdr != NULL);
if (cmdBufLen > 0) {
ENSURE_OR_GO_EXIT(cmdBuf != NULL);
}
ENSURE_OR_GO_EXIT(pRspBufLen != NULL);
ENSURE_OR_GO_EXIT(rspBuf != NULL);
#ifdef ENABLE_SM_APDU_MUTEX
SM_MUTEX_LOCK(g_sm_apdu_mutex);
#endif
{
if (cmdBufLen > 0) {
if ((cmdBufLen < 0xFF) && !length_extended) {
ENSURE_OR_GO_EXIT((MAX_APDU_BUFFER - 5) >= cmdBufLen);
memmove((cmdBuf + 5), cmdBuf, cmdBufLen);
memcpy(cmdBuf, hdr, 4);
cmdBuf[4] = cmdBufLen;
ENSURE_OR_GO_EXIT((UINT_MAX - 5) >= cmdBufLen);
cmdBufLen += 5;
}
else {
ENSURE_OR_GO_EXIT((MAX_APDU_BUFFER - 7) >= cmdBufLen);
memmove((cmdBuf + 7), cmdBuf, cmdBufLen);
memcpy(cmdBuf, hdr, 4);
cmdBuf[4] = 0x00;
cmdBuf[5] = 0xFFu & (cmdBufLen >> 8);
cmdBuf[6] = 0xFFu & (cmdBufLen);
ENSURE_OR_GO_EXIT((UINT_MAX - 7) >= cmdBufLen);
cmdBufLen += 7;
}
}
else {
memcpy(cmdBuf, hdr, 4);
cmdBufLen = 4;
}
if (length_extended) {
ENSURE_OR_GO_EXIT((MAX_APDU_BUFFER - 2) >= cmdBufLen);
ENSURE_OR_GO_EXIT((UINT_MAX - 2) >= cmdBufLen);
cmdBuf[cmdBufLen++] = 0x00;
cmdBuf[cmdBufLen++] = 0x00;
}
apduStatus = smComT1oI2C_TransceiveRaw(session_ctx->conn_context, cmdBuf, cmdBufLen, rspBuf, pRspBufLen);
if (*pRspBufLen >= 2) {
apduStatus = rspBuf[(*pRspBufLen) - 2] << 8 | rspBuf[(*pRspBufLen) - 1];
}
}
exit:
#ifdef ENABLE_SM_APDU_MUTEX
SM_MUTEX_UNLOCK(g_sm_apdu_mutex);
#endif
return apduStatus;
}
smStatus_t Se05x_API_AeadOneShot(pSe05xSession_t session_ctx,
uint32_t objectID,
SE05x_CipherMode_t cipherMode,
const uint8_t *pInputData,
size_t inputDataLen,
const uint8_t *pAad,
size_t aadLen,
uint8_t *pIV,
size_t IVLen,
uint8_t *pTagData,
size_t *pTagDataLen,
uint8_t *pOutputData,
size_t *pOutputDataLen,
const SE05x_Cipher_Oper_OneShot_t operation)
{
smStatus_t retStatus = SM_NOT_OK;
tlvHeader_t hdr = {{kSE05x_CLA, kSE05x_INS_CRYPTO, kSE05x_P1_AEAD, operation}};
//uint8_t cmdbuf[SE05X_MAX_BUF_SIZE_CMD];
size_t cmdbufLen = 0;
uint8_t *pCmdbuf;
int tlvRet = 0;
//uint8_t rspbuf[SE05X_MAX_BUF_SIZE_RSP] = {0};
uint8_t *pRspbuf;
size_t rspbufLen = MAX_APDU_BUFFER;
SE05x_Result_t result;
uint16_t ivlen16 = 0;
size_t ivlen32 = IVLen;
size_t rspIndex = 0;
pCmdbuf = &session_ctx->apdu_buffer[0];
pRspbuf = &session_ctx->apdu_buffer[0];
if (IVLen > UINT16_MAX) {
goto cleanup;
}
ivlen16 = (uint16_t)IVLen;
tlvRet = TLVSET_U32("objectID", &pCmdbuf, &cmdbufLen, kSE05x_TAG_1, objectID);
if (0 != tlvRet) {
goto cleanup;
}
#if SSS_HAVE_SE05X_VER_GTE_07_02
tlvRet = TLVSET_CipherMode("cipherMode",
&pCmdbuf,
&cmdbufLen,
kSE05x_TAG_2,
((cipherMode == kSE05x_CipherMode_AES_GCM_INT_IV) ? kSE05x_CipherMode_AES_GCM : cipherMode));
#else
tlvRet = TLVSET_CipherMode("cipherMode", &pCmdbuf, &cmdbufLen, kSE05x_TAG_2, cipherMode);
#endif
if (0 != tlvRet) {
goto cleanup;
}
tlvRet = TLVSET_u8bufOptional("inputData", &pCmdbuf, &cmdbufLen, kSE05x_TAG_3, pInputData, inputDataLen);
if (0 != tlvRet) {
goto cleanup;
}
tlvRet = TLVSET_u8bufOptional("AdditionalData", &pCmdbuf, &cmdbufLen, kSE05x_TAG_4, pAad, aadLen);
if (0 != tlvRet) {
goto cleanup;
}
if ((cipherMode == kSE05x_CipherMode_AES_GCM) ||
((cipherMode == kSE05x_CipherMode_AES_GCM_INT_IV) && (operation == kSE05x_Cipher_Oper_OneShot_Decrypt))) {
tlvRet = TLVSET_u8bufOptional("IV", &pCmdbuf, &cmdbufLen, kSE05x_TAG_5, pIV, IVLen);
if (0 != tlvRet) {
goto cleanup;
}
}
else {
tlvRet = TLVSET_U16("IVLen", &pCmdbuf, &cmdbufLen, kSE05x_TAG_5, ivlen16);
if (0 != tlvRet) {
goto cleanup;
}
}
if (operation == kSE05x_Cipher_Oper_OneShot_Decrypt) {
if (pTagDataLen != NULL) {
//__printf("%s tgaDataLen is selected\\r\\n", __func__);
//if (pTagDataLen > 0 ) {
tlvRet = TLVSET_u8bufOptional("tag", &pCmdbuf, &cmdbufLen, kSE05x_TAG_6, pTagData, *pTagDataLen);
if (0 != tlvRet) {
goto cleanup;
}
}
}
//retStatus = DoAPDUTxRx_s_Case4_ext(session_ctx, &hdr, session_ctx->apdu_buffer, cmdbufLen, pRspbuf, &rspbufLen);
retStatus = DoAPDUTxRx(session_ctx, &hdr, session_ctx->apdu_buffer, cmdbufLen, pRspbuf, &rspbufLen, 1);
if (retStatus == SM_OK) {
retStatus = SM_NOT_OK;
if (inputDataLen != 0) {
tlvRet = tlvGet_u8buf(pRspbuf, &rspIndex, rspbufLen, kSE05x_TAG_1, pOutputData, pOutputDataLen);
if (0 != tlvRet) {
goto cleanup;
}
}
if (operation == kSE05x_Cipher_Oper_OneShot_Encrypt) {
tlvRet = tlvGet_u8buf(pRspbuf, &rspIndex, rspbufLen, kSE05x_TAG_2, pTagData, pTagDataLen);
if (0 != tlvRet) {
goto cleanup;
}
}
if (operation == kSE05x_Cipher_Oper_OneShot_Decrypt) {
tlvRet = tlvGet_Result(pRspbuf, &rspIndex, rspbufLen, kSE05x_TAG_2, &result);
if (0 != tlvRet) {
goto cleanup;
}
if (result != kSE05x_Result_SUCCESS) {
goto cleanup;
}
}
if ((operation == kSE05x_Cipher_Oper_OneShot_Encrypt) && (cipherMode == kSE05x_CipherMode_AES_GCM_INT_IV)) {
tlvRet = tlvGet_u8buf(pRspbuf, &rspIndex, rspbufLen, kSE05x_TAG_3, pIV, &ivlen32);
if (0 != tlvRet) {
goto cleanup;
}
}
if ((rspIndex + 2) == rspbufLen) {
retStatus = (smStatus_t)((pRspbuf[rspIndex] << 😎 | (pRspbuf[rspIndex + 1]));
}
}
cleanup:
return retStatus;
}
int sss_se05x_aead_one_go(mbedtls_cipher_context_t *ctx,
const uint8_t *srcData,
uint8_t *destData,
size_t size,
uint8_t *nonce,
size_t nonceLen,
const uint8_t *aad,
size_t aadLen,
uint8_t *tag,
size_t *tagLen)
{
int retval = -1;
smStatus_t status = SM_NOT_OK;
/* Already saved aead cipher ctx */
sss_se05x_aead_t *context = (sss_se05x_aead_t *)ctx->cipher_ctx;
size_t destDataLen = size;
SE05x_CipherMode_t cipherMode =
(context->algorithm == kAlgorithm_SSS_AES_GCM) ? kSE05x_CipherMode_AES_GCM : kSE05x_CipherMode_AES_GCM_INT_IV;
SE05x_Cipher_Oper_OneShot_t OperType =
(context->mode == kMode_SSS_Encrypt) ? kSE05x_Cipher_Oper_OneShot_Encrypt : kSE05x_Cipher_Oper_OneShot_Decrypt;
// Not support decrypt with internal IV.
SMLOG_I("Cipher Aead OneGo Start:0x%x Cipher Mode:0x%x, OP Type:0x%x", context->keyObject, cipherMode, OperType);
SMLOG_I(" Key ID: 0x%x\\r\\n", context->keyObject->keyId);
SMLOG_I(" aadLen: %d (%x %x %x %x...)", (size_t)aadLen , aad[0], aad[1], aad[2], aad[3]);
SMLOG_I(" nonceLen: %d (%x %x %x %x...)", nonceLen, nonce[0], nonce[1], nonce[2], nonce[3]);
SMLOG_I(" tagLen: %d (%x %x %x %x...)", *tagLen, tag[0], tag[1], tag[2], tag[3]);
ENSURE_OR_GO_EXIT(context->keyObject != NULL);
status = Se05x_API_AeadOneShot(context->keyObject->session,
context->keyObject->keyId,
cipherMode,
srcData,
size,
aad,
aadLen,
nonce,
nonceLen,
tag,
tagLen,
destData,
&destDataLen,
OperType);
if (status == SM_ERR_APDU_THROUGHPUT) {
retval = kStatus_SSS_ApduThroughputError;
goto exit;
}
SMLOG_I("Cipher Aead One Go Status: 0x%x\\r\\n", status);
ENSURE_OR_GO_EXIT(status == SM_OK);
retval = 0;
exit:
return retval;
}
int psa_mbedtls_gcm_auth_decrypt( mbedtls_cipher_context_t *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output )
{
int ret = 0;
size_t TAG_SIZE = tag_len; /* should be */
ret = sss_se05x_aead_one_go(
ctx, // AEAD context
input, // srcData (ciphertext)
output, // destData (plaintext)
length, // size
(uint8_t *)iv, // nonce
iv_len, // nonceLen
add, // aad
add_len, // aadLen
(uint8_t *)tag, // tag
&TAG_SIZE // tagLen
);
if (ret != 0) {
ret = MBEDTLS_ERR_GCM_AUTH_FAILED;
}
return( ret );
}
int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t output_len,
size_t *olen, size_t tag_len)
{
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/* AEAD case: check length before passing on to shared function */
if (ilen < tag_len || output_len < ilen - tag_len) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len,
input, ilen - tag_len, output, olen,
input + ilen - tag_len, tag_len);
#else
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
}
Re: SE050E AEAD Decryption in S32K314 こんにちは@Changhawn
S32K3 デバイス用の現在の MbedTLS ミドルウェア スタックは、HSE によって提供されるセキュリティ機能とともに、トランスポート層セキュリティ (TLS) プロトコル バージョン 1.2 をサポートしています。現時点では、TLS 1.3 は S32K3 デバイスではサポートされておらず、その実装はサポートの範囲外となります。
SE050 に関連する問題については、 Secure 認証コミュニティに質問を投稿してください。これらのデバイスの専任サポート チームがさらにサポートします。
BR、ヴェインB
記事全体を表示