OtaPalStatus_t otaPal_CheckFileSignature()

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;
}