Hey everyone,
I’m using STM32F767, following the OTA demo and implemented the required ota_pal.h functions.
The process of downloading the file is working good, but I have a problem with the signature verification. (sha256 ECDSA)
When using a quite small ‘test file’ for the update (~40KB), the verification works as expected.
But when using the new image file (~650KB), the verification fails.
Specifically in the function prvVerifySignature in iot_crypto.c, mbedtls_pk_verify fail with the error MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00
static BaseType_t prvVerifySignature(char *pcSignerCertificate,
size_t xSignerCertificateLength,
BaseType_t xHashAlgorithm,
uint8_t *pucHash,
size_t xHashLength,
uint8_t *pucSignature,
size_t xSignatureLength)
{
BaseType_t xResult = pdTRUE;
mbedtls_x509_crt xCertCtx;
mbedtls_md_type_t xMbedHashAlg = MBEDTLS_MD_SHA256;
CRYPTO_PRINT(("prvVerifySignature"));
memset(&xCertCtx, 0, sizeof(mbedtls_x509_crt));
/*
* Map the hash algorithm
*/
if (cryptoHASH_ALGORITHM_SHA1 == xHashAlgorithm)
{
xMbedHashAlg = MBEDTLS_MD_SHA1;
}
/*
* Decode and create a certificate context
*/
CRYPTO_PRINT(("calling mbedtls_x509_crt_init"));
mbedtls_x509_crt_init(&xCertCtx);
CRYPTO_PRINT(("calling mbedtls_x509_crt_parse"));
if (0 != mbedtls_x509_crt_parse(
&xCertCtx, (const unsigned char *)pcSignerCertificate, xSignerCertificateLength))
{
CRYPTO_PRINT(("mbedtls_x509_crt_parse FAILED"));
xResult = pdFALSE;
}
/*
* Verify the signature using the public key from the decoded certificate
*/
if (pdTRUE == xResult)
{
CRYPTO_PRINT(("calling mbedtls_pk_verify"));
if (0 != mbedtls_pk_verify(
&xCertCtx.pk,
xMbedHashAlg,
pucHash,
xHashLength,
pucSignature,
xSignatureLength))
{
CRYPTO_PRINT(("mbedtls_pk_verify FAILED"));
xResult = pdFALSE;
}
}
/*
* Clean-up
*/
CRYPTO_PRINT(("calling mbedtls_x509_crt_free"));
mbedtls_x509_crt_free(&xCertCtx);
return xResult;
}
The call to prvVerifySignature comes from CRYPTO_SignatureVerificationFinal:
BaseType_t CRYPTO_SignatureVerificationFinal(void *pvContext,
char *pcSignerCertificate,
size_t xSignerCertificateLength,
uint8_t *pucSignature,
size_t xSignatureLength)
{
CRYPTO_PRINT(("CRYPTO_SignatureVerificationFinal."));
BaseType_t xResult = pdFALSE;
if (pvContext != NULL)
{
SignatureVerificationStatePtr_t pxCtx = (SignatureVerificationStatePtr_t)pvContext; /*lint !e9087 Allow casting void* to other types. */
uint8_t ucSHA1or256[cryptoSHA256_DIGEST_BYTES]; /* Reserve enough space for the larger of SHA1 or SHA256 results. */
uint8_t *pucHash = NULL;
size_t xHashLength = 0;
if ((pcSignerCertificate != NULL) &&
(pucSignature != NULL) &&
(xSignerCertificateLength > 0UL) &&
(xSignatureLength > 0UL))
{
/*
* Finish the hash
*/
if (cryptoHASH_ALGORITHM_SHA1 == pxCtx->xHashAlgorithm)
{
CRYPTO_PRINT(("CRYPTO_SignatureVerificationFinal: SHA1."));
(void)mbedtls_sha1_finish_ret(&pxCtx->xSHA1Context, ucSHA1or256);
pucHash = ucSHA1or256;
xHashLength = cryptoSHA1_DIGEST_BYTES;
}
else
{
CRYPTO_PRINT(("CRYPTO_SignatureVerificationFinal: SHA256."));
if (0 != mbedtls_sha256_finish_ret(&pxCtx->xSHA256Context, ucSHA1or256))
{
CRYPTO_PRINT(("mbedtls_sha256_finish_ret FAILED"));
}
pucHash = ucSHA1or256;
xHashLength = cryptoSHA256_DIGEST_BYTES;
}
/*
* Verify the signature
*/
CRYPTO_PRINT(("Verifying signature..."));
xResult = prvVerifySignature(pcSignerCertificate,
xSignerCertificateLength,
pxCtx->xHashAlgorithm,
pucHash,
xHashLength,
pucSignature,
xSignatureLength);
}
else
{
/* Allow function to be called with only the context pointer for cleanup after a failure. */
CRYPTO_PRINT(("CRYPTO_SignatureVerificationFinal: Invalid parameters."));
}
/*
* Clean-up
*/
CRYPTO_PRINT(("CRYPTO_SignatureVerificationFinal: Cleaning up."));
vPortFree(pxCtx);
}
CRYPTO_PRINT(("CRYPTO_SignatureVerificationFinal finished."));
return xResult;
}
Any ideas to understand what can cause this will help.
Thank you.