Hi,
I plan to sell an app to my customers.
Customers have or buy their own ESP32 card, then they burn the app and start to use it.
But, I need to protect the code from reading (copy prevention already done with gumroad generated licence keys api).
What is for you the best process ?
1. My customers are "normal" people, they cannot use IDE.
2. May be they can download the app and burn it on ESP with ESP-launchpad ? (encryption supported?)
3. Or they burn a simple not encrypted app that then update from server OTA ?
4. Customers must be able to upgrade app later. As I understood, it is only possible with OTA because of eFuse ?
I have read the encryption (boot and flash) but did not find an example how to implement it from A to Z (from IDE to customer flash )
Any help would be appreciated, thanks
Distribute a protected app to customers
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Distribute a protected app to customers
FWIW, in your use case it's not possible to protect the firmware against reverse engineering (including 'cracking', where one user buys your firmware, then modifies it so it can be flashed without issue on any ESP32). For that, you would need to distribute an encrypted application where only the target ESP32 has the key info to decrypt the application. Given that the customer brings their own ESP chips, there's way to securely get your key info in there. In other words: enabling flash encryption and secureboot is utterly useless here since an attacker can simply get the firmware via 'the front door'.
For the initial flash: if your customers have a browser that is compatible (anything derived from Chrome, usually), you can use esptool-js to flash the firmware straight from a webpage.
For the initial flash: if your customers have a browser that is compatible (anything derived from Chrome, usually), you can use esptool-js to flash the firmware straight from a webpage.
Re: Distribute a protected app to customers
Thank you for your clear answer.
Then, is it possible to use this process to keep the code confidential ?
1. The user buy his own ESP32
2. He download a binary loader app I provide(code not encrypted)
3. He burn the ESP32 with this binary (using esptool-js)
4. Then after restarting ESP32, the binary loader connect to internet, download the encrypted app and install it OTA, with encryption.
Then, is it possible to use this process to keep the code confidential ?
1. The user buy his own ESP32
2. He download a binary loader app I provide(code not encrypted)
3. He burn the ESP32 with this binary (using esptool-js)
4. Then after restarting ESP32, the binary loader connect to internet, download the encrypted app and install it OTA, with encryption.
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Distribute a protected app to customers
No. It is impossible from a theoretical cryptographic level as you do not have a root of trust. For instance, with your scheme above, the binary loader can be modified to skip over the encryption step. You'd flash the modified loader to an ESP32, let it download and install the OTA, then simply read out the flash. Alternatively, someone could run the binary loader in an emulator, let it do its thing, then use the emulator debug features to dump the firmware.leodm05 wrote: ↑Mon Sep 02, 2024 10:06 amThank you for your clear answer.
Then, is it possible to use this process to keep the code confidential ?
1. The user buy his own ESP32
2. He download a binary loader app I provide(code not encrypted)
3. He burn the ESP32 with this binary (using esptool-js)
4. Then after restarting ESP32, the binary loader connect to internet, download the encrypted app and install it OTA, with encryption.
Generally, the 1st step of whatever process you need to come up with involves flashing a binary that you provide into the ESP32, and that binary must be unencrypted and cannot be verified as being not tampered with by the ESP32 it's flashed to. Because of that, it's pretty easy to reverse engineer it and modify it. That means that you can change it to skip verification and encryption of any step after it as well. An attacker can simply keep doing that until they reached your actual firmware, then dump that.
The only way around that that I can imagine is to not have the actual important bits of whatever you are making in the firmware. If you do that on a server on the Internet, you can make sure that only one license has access to that at one time. If someone copies your firmware then, without a license they still cannot do the thing they intended. Downside is that this requires always-on WiFi (meaning the thing you're making won't work when there's no Internet connectivity), and the things you do on the server must not be so trivial that someone can easily create a replacement server from scratch.
Re: Distribute a protected app to customers
Thanks !
But:
"You'd flash the modified loader to an ESP32, let it download and install the OTA, then simply read out the flash."
The downloaded file is encrypted, so it is not readable, no?
Here is what I get from ChatGPT, could you tell me what is wrong in that pattern with a single key for all products ?
Option 1 involves using a single AES key to encrypt the firmware, which will be shared among all the ESP32s you distribute. This approach simplifies the process since you only need to manage one key, but it's crucial to protect this key carefully. Here are the detailed steps to implement this option:
1. Preparation of the Encryption Key
Generate the AES Key:
Generate a 256-bit AES key (32 bytes) that will be used to encrypt your firmware. You can use tools like OpenSSL to generate this key securely.
bash
openssl rand -hex 32
Store this key in a secure location. Ideally, use a digital safe or a secret management solution.
2. Firmware Encryption
Develop the Application:
Develop your application as usual using your preferred IDE (ESP-IDF or Arduino IDE).
Configure Encryption:
With ESP-IDF, configure the project to enable flash encryption.
In the sdkconfig file, enable flash encryption:
plaintext
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y
CONFIG_FLASH_ENCRYPTION_ENABLED=y
Encrypt the Firmware:
Use ESP-IDF to compile your application. The build process will generate an encrypted .bin firmware file using the AES key you configured.
3. Provisioning the ESP32
Initial Step: Flash the Key:
For each ESP32, you need to inject the unique AES key before flashing the encrypted firmware.
Create a simple provisioning firmware or use a script to flash the AES key onto the ESP32. This provisioning firmware does not need to be encrypted.
Using esptool.py to Flash the Key:
You can use the esptool.py tool to inject the AES key into the ESP32:
bash
esptool.py --chip esp32 --port /dev/ttyUSB0 burn_key flash_encryption my_aes_key.bin
Here, my_aes_key.bin is a binary file containing your unique AES key.
Enable Flash Encryption:
Once the key is flashed, flash encryption is activated. The ESP32 will then only be able to read firmware encrypted with this key.
4. Firmware Distribution and Installation
Prepare the Distribution Package:
Create a package containing:
The encrypted binary file (.bin).
An installation script (install_firmware.bat or install_firmware.sh).
Necessary drivers for connecting the ESP32 to the PC (if needed).
A simple user guide.
Create an Automated Installation Script:
Write a script that detects the ESP32’s serial port and automatically flashes the encrypted firmware:
bash
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 firmware_encrypted.bin
This script can be customized for Windows (a .bat file) or macOS/Linux (a .sh file).
Instructions for the Client:
Provide simple instructions to the client on how to connect the ESP32, run the installation script, and verify that the installation was successful.
5. Firmware Update
Update:
For any updates, you must provide a new encrypted firmware file using the same AES key.
The client can use the same installation script to flash the new firmware version.
6. Security and Management
Protect the Key:
Ensure the AES key is securely stored.
Avoid sharing the key directly with clients or making it accessible over the network.
Recovery Process:
If an ESP32 device is corrupted or the key is compromised, you may need to erase and reprovision the chip.
Advantages and Disadvantages of Option 1
Advantages:
Simplicity in management and deployment.
Managing a single key reduces complexity.
Disadvantages:
High risk if the single key is compromised.
All devices share the same key, so if one device is compromised, the others are as well.
This method is suitable if you have a relatively small number of ESP32s to manage or if you can guarantee the security of the single key. For more critical or large-scale deployments, it may be necessary to switch to a method with unique keys per device (Option 2).
But:
"You'd flash the modified loader to an ESP32, let it download and install the OTA, then simply read out the flash."
The downloaded file is encrypted, so it is not readable, no?
Here is what I get from ChatGPT, could you tell me what is wrong in that pattern with a single key for all products ?
Option 1 involves using a single AES key to encrypt the firmware, which will be shared among all the ESP32s you distribute. This approach simplifies the process since you only need to manage one key, but it's crucial to protect this key carefully. Here are the detailed steps to implement this option:
1. Preparation of the Encryption Key
Generate the AES Key:
Generate a 256-bit AES key (32 bytes) that will be used to encrypt your firmware. You can use tools like OpenSSL to generate this key securely.
bash
openssl rand -hex 32
Store this key in a secure location. Ideally, use a digital safe or a secret management solution.
2. Firmware Encryption
Develop the Application:
Develop your application as usual using your preferred IDE (ESP-IDF or Arduino IDE).
Configure Encryption:
With ESP-IDF, configure the project to enable flash encryption.
In the sdkconfig file, enable flash encryption:
plaintext
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y
CONFIG_FLASH_ENCRYPTION_ENABLED=y
Encrypt the Firmware:
Use ESP-IDF to compile your application. The build process will generate an encrypted .bin firmware file using the AES key you configured.
3. Provisioning the ESP32
Initial Step: Flash the Key:
For each ESP32, you need to inject the unique AES key before flashing the encrypted firmware.
Create a simple provisioning firmware or use a script to flash the AES key onto the ESP32. This provisioning firmware does not need to be encrypted.
Using esptool.py to Flash the Key:
You can use the esptool.py tool to inject the AES key into the ESP32:
bash
esptool.py --chip esp32 --port /dev/ttyUSB0 burn_key flash_encryption my_aes_key.bin
Here, my_aes_key.bin is a binary file containing your unique AES key.
Enable Flash Encryption:
Once the key is flashed, flash encryption is activated. The ESP32 will then only be able to read firmware encrypted with this key.
4. Firmware Distribution and Installation
Prepare the Distribution Package:
Create a package containing:
The encrypted binary file (.bin).
An installation script (install_firmware.bat or install_firmware.sh).
Necessary drivers for connecting the ESP32 to the PC (if needed).
A simple user guide.
Create an Automated Installation Script:
Write a script that detects the ESP32’s serial port and automatically flashes the encrypted firmware:
bash
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 firmware_encrypted.bin
This script can be customized for Windows (a .bat file) or macOS/Linux (a .sh file).
Instructions for the Client:
Provide simple instructions to the client on how to connect the ESP32, run the installation script, and verify that the installation was successful.
5. Firmware Update
Update:
For any updates, you must provide a new encrypted firmware file using the same AES key.
The client can use the same installation script to flash the new firmware version.
6. Security and Management
Protect the Key:
Ensure the AES key is securely stored.
Avoid sharing the key directly with clients or making it accessible over the network.
Recovery Process:
If an ESP32 device is corrupted or the key is compromised, you may need to erase and reprovision the chip.
Advantages and Disadvantages of Option 1
Advantages:
Simplicity in management and deployment.
Managing a single key reduces complexity.
Disadvantages:
High risk if the single key is compromised.
All devices share the same key, so if one device is compromised, the others are as well.
This method is suitable if you have a relatively small number of ESP32s to manage or if you can guarantee the security of the single key. For more critical or large-scale deployments, it may be necessary to switch to a method with unique keys per device (Option 2).
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Distribute a protected app to customers
Sure, but where does the key for the encrypted downloaded file come from? You cannot send it to the ESP32 in a secure fashion, which means that an attacker can snatch it up and decrypt your OTA update.
Again, how are you going to get that key into the ESP32 without someone being able to grab it? ChatGPTs scenario assumes you can do the first (unsecure) firmware flash while you have the ESP32 in your ownership (e.g. when you manufacture a widget containing an ESP32 that then is sold to users) but that doesn't apply to your case. Note that its instructions literally tell you to generate a file with the key in it and flash that to the ESP32; if you let the end user do that, it's trivial to intercept that step and grab that key for themselves.Here is what I get from ChatGPT, could you tell me what is wrong in that pattern with a single key for all products ?
Re: Distribute a protected app to customers
Thank you for your patience , understood !
Then the only way to it is :
- flashing myself with encryption on
- ask the manufacturer to do it (giving him the key)
Am I right ?
Then the only way to it is :
- flashing myself with encryption on
- ask the manufacturer to do it (giving him the key)
Am I right ?
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Distribute a protected app to customers
This is correct
What would usually happen is that you give the manufacturer a bootloader, partition table and 'factory' app. If you compile those with SecureBoot + flash encryption enabled, the bootloader on first boot will encrypt the flash and burn the fuses for SecureBoot. Then a new firmware flash can only happen through any facility you built into the factory app (e.g. ota updates) and the factory app can use whatever method you want to verify the firmware is correct. Check the docs for more info.- ask the manufacturer to do it (giving him the key)
Who is online
Users browsing this forum: No registered users and 276 guests