2217379_ja-JP

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

2217379_ja-JP

2217379_ja-JP

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

Tags (1)
No ratings
Version history
Last update:
‎11-24-2025 02:01 AM
Updated by: