S32K314 question about TLS API with HSE

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

S32K314 question about TLS API with HSE

Jump to solution
7,992 Views
Changhawn
Contributor IV

In S32K314,
We are using Mbedtls RTM 1.0.0 provided by NXP w/ HSE.

After TLS Handshake, we need to compute shared secret, so we are using mbedtls_ecdh_compute_shared() API,

But that API(mbedtls_ecdh_compute_shared) assign key handle as z value parameter like below picture.

In working operation, we need to derive actual shared secret key value, not key handle value. How can we do that? Please guide.

 

TLS Code)

Changhawn_0-1731469557649.png

application code)

uint8_t sharedSecret[32];
 
~~~
 
        rc = mbedtls_ecdh_compute_shared(&ecdh.grp, &z, &ecdh.Qp, &d, myrand, NULL);
        if (rc != 0)
            SYS_CONSOLE_PRINT("!!! mbedtls_ecdh_compute_shared returned %d\r\n", rc);
 
        tmp_rc = mbedtls_mpi_write_binary(&z, sharedSecret, 32);
        if (tmp_rc != 0)
            SYS_CONSOLE_PRINT("!!! mbedtls_mpi_write_binary returned %d\r\n", tmp_rc);
 
        PrintDumpBytes("sharedSecret", sharedSecret, 32);
 
 

test log)

Private keyHandle 0x20400 | Peer KeyHandle : 0x20500 | Shared Secret KeyHandle 0x20600
Z is 20600
sharedSecret=
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 06 00

0 Kudos
Reply
1 Solution
7,794 Views
Changhawn
Contributor IV

Dear NXP guys.

In KDF,  I know that NIST 800-56A is not supported currently in NXP HSE.

So implemented it without HSE. 

View solution in original post

0 Kudos
Reply
3 Replies
7,795 Views
Changhawn
Contributor IV

Dear NXP guys.

In KDF,  I know that NIST 800-56A is not supported currently in NXP HSE.

So implemented it without HSE. 

0 Kudos
Reply
7,938 Views
Changhawn
Contributor IV
Below is the code written on the Platform where HSE is running, that is, with MBEDTLS_USE_NXP_HSE_CRYPTO enabled, after tls handshaked processing is done.
 
It includes the process of generating a derived key using a certificate and DH public key, decrypting the private key through AES, and assigning it to the ECC context, as well as the signature generation process.
 
That is, an encryption key was created using the certificate and DH public key, and the key was derived using mbedtls_ssl_tls_prf(), and then the private key (output) was created through AES and assigned to the ECC context.
 
But, in the authorization req process, the SignatureValue created is responded with a wrong signature in the authorization res.
 
1. For key derivation, use mbedtls_ssl_tls_prf(), label is correct ? or not?
which one "externed master secret" or "key expansion" ?
 
2. Is there anything wrong in the code below?
 
 
certificationInstatllResponse
{
/* omission */
 
    {
        mbedtls_pk_context oem_key;
        mbedtls_ecp_keypair *oem_ecp;
 
        mbedtls_pk_init(&oem_key);
        mbedtls_mpi_init(&d);
 
        rc = mbedtls_pk_parse_key(&oem_key, PKI_1_CRT_OEM_LEAF_VALID_key, PKI_1_CRT_OEM_LEAF_VALID_key_len,
                                  gq_cert_passphrase, gq_cert_passphrase_len);
        if (rc != 0)
            SYS_CONSOLE_PRINT("!!! failed - mbedtls_pk_parse_key(oem_key) - 0x%x\r\n", -rc);
 
        oem_ecp = mbedtls_pk_ec(oem_key);
        rc = mbedtls_mpi_copy(&d, &oem_ecp->d);
        if (rc != 0)
            SYS_CONSOLE_PRINT("!!! mbedtls_mpi_copy returned %d\r\n", rc);
 
        mbedtls_pk_free(&oem_key);
    }
 
    /* DHpublickey */
    /* ContractSignatureEncryptedPrivateKey */
    {
 
        /* Initialize a group of ecdh structures with a SECP256R1 curve. */
        rc = mbedtls_ecp_group_load(&ecdh.grp, MBEDTLS_ECP_DP_SECP256R1);
        if (rc != 0)
            SYS_CONSOLE_PRINT("!!! mbedtls_ecp_group_load returned %d\r\n", rc);
 
        /* Read and apply public keys from other systems in binary data format to ecdh.Qp */
        bytes = res->DHpublickey->CONTENT->bytes;
        bytesLen = res->DHpublickey->CONTENT->bytesLen;
 
        SYS_CONSOLE_PRINT("%s DHpublickey (%x %x %x %x... len %d)\r\n", __func__, bytes[0], bytes[1], bytes[2], bytes[3], bytesLen);
        {
            temp_shared = pvPortMalloc(bytesLen);
            if (temp_shared)
            {
                memcpy(temp_shared, bytes, bytesLen);
                rc = mbedtls_ecp_point_read_binary(&ecdh.grp, &ecdh.Qp, temp_shared, bytesLen);
                //rc = nxp_hse_ecp_point_read_binary(&ecdh.grp, &ecdh.Qp, temp_shared, bytesLen);
                if (rc != 0)
                    SYS_CONSOLE_PRINT("!!! mbedtls_ecp_point_read_binary %d\r\n", rc);
            }
            else
            {
                SYS_CONSOLE_PRINT(LABEL_ISO "!!! memalloc failed -> anyway go\r\n");
                rc = mbedtls_ecp_point_read_binary(&ecdh.grp, &ecdh.Qp, bytes, bytesLen);
                if (rc != 0)
                    SYS_CONSOLE_PRINT("!!! mbedtls_ecp_point_read_binary %d\r\n", rc);
            }
        }
        isoPrintDumpBytes("DHpublickey", bytes, bytesLen);
 
        /* Verify that the d value is a valid private key in SECP256R1 */
        rc = mbedtls_ecp_check_privkey(&ecdh.grp, &d);
        if (rc != 0)
        {
            SYS_CONSOLE_PRINT("Invalid private key: -0x%04X\n", -rc);
        }
 
        /* Verify that the public key is within the valid range of SECP256R1 */
        rc = mbedtls_ecp_check_pubkey(&ecdh.grp, &ecdh.Qp);
        if (rc != 0)
        {
            SYS_CONSOLE_PRINT("DHpublickey is not valid: -0x%04X\n", -rc);
        }
 
 
        /* Calculate the shared secret key, where d is the private key generated in the previous step. */
        rc = mbedtls_ecdh_compute_shared(&ecdh.grp, &z, &ecdh.Qp, &d, myrand, NULL);
        if (rc != 0)
            SYS_CONSOLE_PRINT("!!! mbedtls_ecdh_compute_shared returned %d\r\n", rc);
 
 
        /* Use the shared secret, label, and other info to derive the key */
        rc = mbedtls_ssl_tls_prf(
            MBEDTLS_SSL_TLS_PRF_SHA256,                      /*  Hash function (usually SHA-256 for TLS) */
            &z, //&keyhandle,                     /* Secret data (shared secret) */
            32,                             /* Length of the shared secret */
            "externed master secret", //"extended master secret",   //"master secret",  //"key expansion"
            otherInfo,                   /* Additional data (optional) */
            (int)sizeof(otherInfo),               /* Length of additional data */
            key,                   /* Output buffer for derived key */
            (int)sizeof(key)                /* Desired length of derived key, key handle */
        );
        if (rc != 0)
        {
            SYS_CONSOLE_PRINT("!!! mbedtls_ssl_tls_prf() failed with error -0x%04X\n", -rc);
        }
 
        tmp_rc = mbedtls_aes_setkey_dec(&aes, key, 128);
        if (tmp_rc != 0)
        {
            SYS_CONSOLE_PRINT("!!! mbedtls_aes_setkey_dec returned %d\r\n", tmp_rc);
        }
 
        bytes = res->ContractSignatureEncryptedPrivateKey->CONTENT->bytes;
        bytesLen = res->ContractSignatureEncryptedPrivateKey->CONTENT->bytesLen;
        gq_memcpy(iv, bytes, 16);
        input = bytes + 16;
        bytesLen -= 16u;
 
        {
            uint8_t *temp_input;
            temp_input = pvPortMalloc(bytesLen);
            if (temp_input)
            {
                memcpy(temp_input, input, bytesLen);
                tmp_rc = mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, bytesLen, iv, temp_input, output);
                if (tmp_rc != 0)
                {
                    SYS_CONSOLE_PRINT("!!! mbedtls_aes_crypt_cbc returned %d\r\n", tmp_rc);
                }
                vPortFree(temp_input);
            }
            else
            {
                SYS_CONSOLE_PRINT(LABEL_ISO "!!! mbedtls_aes_crypt_cbc memalloc failed\r\n");
            }
        }
 
        pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
        mbedtls_pk_init(&iso->contract_key);
        rc = mbedtls_pk_setup(&iso->contract_key, pk_info);
        if (rc < 0)
        {
            SYS_CONSOLE_MESSAGE("!!! failed-mbedtls_pk_setup\r\n");
        }
 
        ec = mbedtls_pk_ec(iso->contract_key);
        rc = mbedtls_ecp_group_load(&ec->grp, MBEDTLS_ECP_DP_SECP256R1);
        if (rc < 0)
        {
            SYS_CONSOLE_MESSAGE("!!! failed-mbedtls_ecp_group_load\r\n");
        }
 
        isoPrintDumpBytes("PrivateKey", output, bytesLen);
        {
            uint8_t *uds_buf = (uint8_t *)get_gq_uds_buffer();
            memset(uds_buf, 0, 64);
            memcpy(uds_buf+64, output, bytesLen);
 
            no = pki_get_index(KEY_CONTRACT_LEAF);
            if(no < 0)
                pki_add(KEY_CONTRACT_LEAF, uds_buf, bytesLen+64);
            else
                pki_replace(no, KEY_CONTRACT_LEAF, uds_buf, bytesLen+64);
            /* Release the uds buffer */
            put_gq_uds_buffer();
        }
 
        rc = mbedtls_mpi_read_binary(&ec->d, output, bytesLen);
        if (rc < 0)
        {
            SYS_CONSOLE_MESSAGE("!!! failed-mbedtls_mp_read_binary\n");
        }
 
        if (temp_shared != NULL)
        {
            vPortFree(temp_shared);
        }
        mbedtls_mpi_free(&z);
        mbedtls_aes_free(&aes);
        mbedtls_ecdh_free(&ecdh);
    }
 
/* omission */
}
 
createSignature
{
/* omission */
            rc = mbedtls_pk_sign(&iso->contract_key, MBEDTLS_MD_SHA256, hash2, 32, asn, &siglen, mbedtls_ctr_drbg_random,
                                 &ctr_drbg);
       
            if (rc != 0)
            {
                 SYS_CONSOLE_PRINT("mbedtls_pk_sign failed %d\r\n", rc );
            }
 
            /*-----------------------------------------------------------------------------------*/
            /* Signature->SignatureValue 내용 채우기 */
            /*-----------------------------------------------------------------------------------*/
            SignatureValue->Id_isUsed = 0;
            /* SignatureValue->CONTENT 할당 */
            requiredLen = sizeof(struct iso1SignatureValueType_CONTENT);
            retalloc = iso1AllocZCodecEncBuffer(requiredLen);
            if (retalloc != NULL)
            {
                GQ_ISO_MEMCPY(&(SignatureValue->CONTENT), &(retalloc), sizeof(void *));
 
                /* SignatureValue->CONTENT 값 */
                SignatureValue->CONTENT->bytesLen = 64;
                /* MISRA_C_2012_17_07 */
                pasn1 = &asn[4];
            s_index = 37;
            if (asn[3] == 33)
            {
            pasn1++;
            s_index++;
            }
            memcpy(&SignatureValue->CONTENT->bytes[0], pasn1, 32);
 
            pasn1+= 32 + 2;
            if (asn[s_index] == 33)
            pasn1++;
            memcpy(&SignatureValue->CONTENT->bytes[32], pasn1, 32);
 
            }
/* omission */
}
0 Kudos
Reply
7,961 Views
Changhawn
Contributor IV

Dear

About problem, program copy an additional key handler through the key handler and exported it to obtain the key value, and  implemented the program as follow sw. I have two questions.
 
1. When I execute the following, HSE_MY_KeyDeriveCopyKey() returns HSE_SRV_RSP_INVALID_PARAM. Can you tell me what is wrong?
2. Can I obtain the Shared secret (used by DH key exchange protocols) value normally like this?
 
 
static hseSrvResponse_t HSE_KeyDeriveCopyKeyContent
(
    hseKeyHandle_t      targetKeyHandle,
    hseKeyInfo_t        keyInfo,
uint16_t *pPubKeyLength,
uint8_t *pPubKey
)
{
    uint8_t u8MuChannel;
    hseSrvResponse_t srvResponse = -5;
 
    /* Get a free channel on u8MuInstance */
    u8MuChannel = Hse_Ip_GetFreeChannel(APP_MU_INSTANCE_U8);
    if(HSE_IP_INVALID_MU_CHANNEL_U8 == u8MuChannel)
    {
    goto exit;
    }
 
/*note: which MU channel need to specify?*/
    hseSrvDescriptor_t *pHseSrvDesc = &Hse_aSrvDescriptor[u8MuChannel];
    hseExportKeySrv_t*  pExportKeyReq = &pHseSrvDesc->hseSrv.exportKeyReq;
    memset(pHseSrvDesc, 0, sizeof(hseSrvDescriptor_t));
    pHseSrvDesc->srvId = HSE_SRV_ID_EXPORT_KEY;
    pExportKeyReq->targetKeyHandle = targetKeyHandle;
 
    pExportKeyReq->pKey[0] = (HOST_ADDR)pPubKey;
    pExportKeyReq->pKeyLen[0] = (HOST_ADDR)pPubKeyLength;
 
    pExportKeyReq->cipher.cipherKeyHandle = HSE_INVALID_KEY_HANDLE;
    pExportKeyReq->keyContainer.authKeyHandle = HSE_INVALID_KEY_HANDLE;
 
/* Build the request to be sent to Hse Ip layer */
    HseIp_aRequest[u8MuChannel].eReqType   = HSE_IP_REQTYPE_SYNC;
    HseIp_aRequest[u8MuChannel].u32Timeout = TIMEOUT_TICKS_U32;
 
    /*note: which MU channel need to specify?*/
    srvResponse = Hse_Ip_ServiceRequest(APP_MU_INSTANCE_U8, u8MuChannel, &HseIp_aRequest[u8MuChannel], pHseSrvDesc);
 
exit:
 
    return srvResponse;
}
 
hseSrvResponse_t HSE_MY_KeyDeriveCopyKey
(
    hseKeyHandle_t      keyHandle,
    uint16_t            startOffset,
    hseKeyHandle_t      targetKeyHandle,
    hseKeyInfo_t        keyInfo
)
{
    uint8_t u8MuChannel;
    hseSrvResponse_t srvResponse = HSE_SRV_RSP_GENERAL_ERROR;
 
    /* Get a free channel on u8MuInstance */
    u8MuChannel = Hse_Ip_GetFreeChannel(APP_MU_INSTANCE_U8);
    if(HSE_IP_INVALID_MU_CHANNEL_U8 == u8MuChannel)
    {
    goto exit;
    }
 
/*note: which MU channel need to specify?*/
    hseSrvDescriptor_t *pHseSrvDesc = &Hse_aSrvDescriptor[u8MuChannel];
 
    hseKeyDeriveCopyKeySrv_t *pExtractKeySrv = &(pHseSrvDesc->hseSrv.keyDeriveCopyKeyReq);
 
    memset(pHseSrvDesc, 0, sizeof(hseSrvDescriptor_t));
    pHseSrvDesc->srvId = HSE_SRV_ID_KEY_DERIVE_COPY;
 
    pExtractKeySrv->keyHandle = keyHandle;
    pExtractKeySrv->startOffset = startOffset;
    pExtractKeySrv->targetKeyHandle = targetKeyHandle;
    pExtractKeySrv->keyInfo = keyInfo;
 
/* Build the request to be sent to Hse Ip layer */
    HseIp_aRequest[u8MuChannel].eReqType   = HSE_IP_REQTYPE_SYNC;
    HseIp_aRequest[u8MuChannel].u32Timeout = TIMEOUT_TICKS_U32;
 
    /*note: which MU channel need to specify?*/
    srvResponse = Hse_Ip_ServiceRequest(APP_MU_INSTANCE_U8, u8MuChannel, &HseIp_aRequest[u8MuChannel], pHseSrvDesc);
 
exit:
    return srvResponse;
}
 
int32_t gq_getComputeSharedKey(uint32_t keyHandle, uint8_t *keyBuf)
{
    /* uint8_t keyBuf[32]; */
    uint16_t keyBufLen = 32; 
hseKeyInfo_t KeyInfo;
hseSrvResponse_t srvResponse;
int32_t ret = 0;
uint32_t copykeyslot = HSE_INVALID_KEY_HANDLE;
/* uint8_t export_key[32]={ 0, }; */
 
key_import_param_t key_import_param_shared;
 
memset(&key_import_param_shared, 0x00, sizeof(key_import_param_t));
 
/* copy shared secret key */
key_import_param_shared.key_type = HSE_KEY_TYPE_SHARED_SECRET;
key_import_param_shared.key_catalog = HSE_KEY_CATALOG_ID_RAM;
key_import_param_shared.key_param.sym_key_param.size = 256u;
 
KeystoreMgmt_FindAllocateSlot(&key_import_param_shared, &copykeyslot);
 
memset(keyBuf, 0, keyBufLen);
 
srvResponse = HSE_GetKeyInfo(keyHandle, &KeyInfo);
if(srvResponse == HSE_SRV_RSP_OK)
{
KeyInfo.keyFlags = (HSE_KF_USAGE_ENCRYPT | HSE_KF_USAGE_DECRYPT | HSE_KF_USAGE_SIGN | HSE_KF_USAGE_VERIFY | HSE_KF_USAGE_DERIVE);
KeyInfo.keyType = HSE_KEY_TYPE_SHARED_SECRET;
 
printf("copykeyslot=0x%08x\n", copykeyslot);
/* copykeyslot = 0x00020601; */
srvResponse = HSE_MY_KeyDeriveCopyKey(keyHandle, 0, copykeyslot, KeyInfo);
if(srvResponse != HSE_SRV_RSP_OK)
{
ret = srvResponse;
}
else
{
printf("HSE_KeyDeriveCopyKey() is ok\r\n");
srvResponse = HSE_KeyDeriveCopyKeyContent(copykeyslot, KeyInfo, &keyBufLen, keyBuf);
if(srvResponse != HSE_SRV_RSP_OK)
{
ret = srvResponse;
}
else
{
printf("HSE_KeyDeriveCopyKeyContent() is ok\r\n");
}
}
}
else
{
ret = -2;
}
 
return ret;
}
0 Kudos
Reply