I want to encrypt my ESP32 firmware with espsecure.py and then update my devices with OTA. Strangely, espsecure.py requires me to pass the partition address:
python espsecure.py encrypt_flash_data --keyfile encryption_key.bin --address 0x100000 --output firmware_encrypted.bin firmware.bin
As OTA holds the firmware at two redundant locations, does this mean, that I have to provide two different firmware files to my customer and that the customer has to "guess" the correct file depending on which OTA partion is the currently active firmware partition? The device provides a webserver which allows uploading files (i.e., the device does not download its updates from some remote server, otherwise, it could deduct the correct file and draw only this one from the Update Server)
This command creates a raw pre-encrypted image which gets written to Flash directly using a JTAG programmer or the ROM bootloader. Generally you would only do this once when initially programming the device in factory (e.g. generate device keys and write into device, pre-encrypt the golden image using device keys and flash into device).
For subsequent OTA operations you don't need a pre-encrypted firmware image. On the contrary, ESP-IDF OTA client requires an unencrypted image, which it will encrypt on the fly while flashing into the unused slot. Note that you can download the image to device using any encrypted channel or format you choose (HTTPS, MQTTS, custom encryption, etc) but you'd have to unencrypt it locally before handing it over to OTA client.
Last time I solved OTA downloads by securing the HTTPS channel with mTLS (server was authenticated to client using a certificate signed by PKI root certificate, client was authenticated to server using a unique device certificate also signed by the same PKI root certificate). Since the download of image was authenticated, authorized and encrypted, I didn't bother encrypting the image in transit any further.