sha256 calc of SPIFFS fails with encrypted flash

dmaxben
Posts: 108
Joined: Thu Nov 16, 2017 6:04 pm

sha256 calc of SPIFFS fails with encrypted flash

Postby dmaxben » Mon Dec 13, 2021 9:10 pm

There appears to be a problem with esp_partition_get_sha256 when requesting the sha256 hash of a SPIFFS partition on an ESP32 that has flash encryption enabled.

Yes, I know that even with flash encryption enabled, SPIFFS encryption is not supported.

That is fine, however I believe the problem is when flash encryption is enabled, the esp_partition_get_sha256 function assumes that its calculating the hash of an encrypted partition? This is NOT the case if you request the hash of a SPIFFS partition. So its 'decrypting' a partition that wasnt even encrypted in the first place, thus giving an incorrect hash calculation.

I have verified on two identical units (one with flash encryption enabled, the other with encryption disabled), with the same contents/image stored in SPIFFS......the unit with flash encryption disabled calculates the SPIFFS hash correctly. The unit with flash encryption enabled calculates SPIFFS hash incorrectly.

Can this be fixed.....?

dmaxben
Posts: 108
Joined: Thu Nov 16, 2017 6:04 pm

Re: sha256 calc of SPIFFS fails with encrypted flash

Postby dmaxben » Mon Dec 13, 2021 11:17 pm

My suspicion was confirmed as correct.

I read out the [unencrypted] SPIFFS from the encrypted unit, then I manually encrypted that SPIFFS bin using espsecure.py with the same key I used to encrypt the app-flash, then flashed that encrypted SPIFFS bin back into the ESP32.

Then I asked the ESP32 to calc the sha256 hash of the SPIFFS partition, and sure enough, this time it gave the correct hash.

So how do we force an ESP [with flash/app encryption enabled] to *not* automatically treat the SPIFFS partition as if it were encrypted, when we use the esp_partition_get_sha256() API?

This seems like kind of an oversight in the IDF API's. SPIFFS will never be encrypted, so why is that esp_partition_get_sha256 function just assuming/defaulting onto the encryption status of the running app?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: sha256 calc of SPIFFS fails with encrypted flash

Postby WiFive » Tue Dec 14, 2021 5:18 am

Yes that api uses memory mapped reads which are always tied to flash encryption, so it would have to be reworked to use raw flash reads for unencrypted partitions.

dmaxben
Posts: 108
Joined: Thu Nov 16, 2017 6:04 pm

Re: sha256 calc of SPIFFS fails with encrypted flash

Postby dmaxben » Tue Dec 14, 2021 12:55 pm

WiFive wrote:
Tue Dec 14, 2021 5:18 am
Yes that api uses memory mapped reads which are always tied to flash encryption, so it would have to be reworked to use raw flash reads for unencrypted partitions.
Is there any documentation or sample code on using the SHA hardware engine for raw hardware reads?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: sha256 calc of SPIFFS fails with encrypted flash

Postby WiFive » Tue Dec 14, 2021 7:53 pm

Mbedtls Sha functions will use hardware as long as it is enabled in menuconfig. esp_partition functions should use raw reads automatically based on partition flags. Then you just need to decide how big a buffer you want to use and how much delay you want between reads since raw flash reads are cache blocking.

dmaxben
Posts: 108
Joined: Thu Nov 16, 2017 6:04 pm

Re: sha256 calc of SPIFFS fails with encrypted flash

Postby dmaxben » Mon Jan 10, 2022 5:39 pm

Finally had a chance to mess around with this...in case anyone else is curious...

code is sloppy and could be condensed...and of course be sure add your own stuff to check return/error codes.

Also this code assumes your SPIFFS partition size is a multiple of 1024 obviously, otherwise you can add an extra bit of code to 'automatically' nibble until you reach the end of your exact partition size.

Code: Select all

#define HASH_LEN 32
#define bufSize 1024
 uint8_t sha_256[HASH_LEN] = {0};
 char hash_print[HASH_LEN * 2 + 1];

const esp_partition_t *_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL);

if (!esp_flash_encryption_enabled()) // if flash is encrypted, dont use regular hash calc API because it assumes SPIFFS is also encrypted
    {
        mbedtls_sha256_context ctx;
        mbedtls_sha256_init(&ctx);
        mbedtls_sha256_starts_ret(&ctx, 0);
        char *partBuf[bufSize];
            for (int addrToRead = 0; addrToRead < _partition->size; addrToRead = addrToRead + bufSize)
            {
                err = esp_partition_read_raw(_partition, addrToRead, partBuf, bufSize);
                mbedtls_sha256_update_ret(&ctx, (const uint8_t *)partBuf, bufSize);
            }
         mbedtls_sha256_finish_ret(&ctx, sha_256);
         mbedtls_sha256_free(&ctx);
    }
    else
    {
        esp_partition_get_sha256(_partition, sha_256);
    }
    for (int i = 0; i < HASH_LEN; ++i)
    {
        sprintf(&hash_print[i * 2], "%02x", sha_256[i]);
    }
    ESP_LOGI(TAG, "SPIFFS hash: %s", hash_print);
   

Who is online

Users browsing this forum: Majestic-12 [Bot] and 92 guests