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 */
}