in components/ota_pal/source/ota_pal.c [500:582]
OtaPalStatus_t otaPal_CheckFileSignature(OtaFileContext_t *const pFileContext)
{
OtaPalStatus_t result;
uint32_t ulSignerCertSize;
void *pvSigVerifyContext;
const uint8_t *pucSignerCert = 0;
static spi_flash_mmap_memory_t ota_data_map;
uint32_t mmu_free_pages_count, len, flash_offset = 0;
esp_err_t ret = 0;
/* Verify an ECDSA-SHA256 signature. */
if (CRYPTO_SignatureVerificationStart(&pvSigVerifyContext, cryptoASYMMETRIC_ALGORITHM_ECDSA,
cryptoHASH_ALGORITHM_SHA256) == pdFALSE)
{
LogError(("Signature verification start failed"));
return OTA_PAL_COMBINE_ERR(OtaPalSignatureCheckFailed, 0);
}
pucSignerCert = otaPal_ReadAndAssumeCertificate((const uint8_t *const)pFileContext->pCertFilepath, &ulSignerCertSize);
if (pucSignerCert == NULL)
{
LogError(("Cert read failed"));
return OTA_PAL_COMBINE_ERR(OtaPalBadSignerCert, 0);
}
mmu_free_pages_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
len = ota_ctx.data_write_len;
while (len > 0)
{
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser.
* 0x0000FFFF is mmap aligned mask for 64K boundary */
uint32_t mmu_page_offset = ((flash_offset & 0x0000FFFF) != 0) ? 1 : 0;
/* Read the image that fits in the free MMU pages */
uint32_t partial_image_len = MIN(len, ((mmu_free_pages_count - mmu_page_offset) * SPI_FLASH_MMU_PAGE_SIZE));
const void *buf = NULL;
if (prvIsPatchFile((char *)pFileContext->pFilePath))
{
ret = esp_partition_mmap(ota_ctx.patch_partition, flash_offset, partial_image_len,
SPI_FLASH_MMAP_DATA, &buf, &ota_data_map);
}
else
{
ret = esp_partition_mmap(ota_ctx.update_partition, flash_offset, partial_image_len,
SPI_FLASH_MMAP_DATA, &buf, &ota_data_map);
}
if (ret != ESP_OK)
{
LogError(("Partition mmap failed %d", ret));
result = OTA_PAL_COMBINE_ERR(OtaPalSignatureCheckFailed, 0);
goto end;
}
CRYPTO_SignatureVerificationUpdate(pvSigVerifyContext, buf, partial_image_len);
spi_flash_munmap(ota_data_map);
flash_offset += partial_image_len;
len -= partial_image_len;
}
if (CRYPTO_SignatureVerificationFinal(pvSigVerifyContext, (char *)pucSignerCert, ulSignerCertSize,
pFileContext->pSignature->data, pFileContext->pSignature->size) == pdFALSE)
{
LogError(("Signature verification failed"));
result = OTA_PAL_COMBINE_ERR(OtaPalSignatureCheckFailed, 0);
}
else
{
result = OTA_PAL_COMBINE_ERR(OtaPalSuccess, 0);
}
end:
/* Free the signer certificate that we now own after prvReadAndAssumeCertificate(). */
if (pucSignerCert != NULL)
{
vPortFree(( void* )pucSignerCert);
}
return result;
}