Шифрование прошивки ESP32

Смещение ПАМЯТИ по умолчанию в PlatformIO:

1. Загрузчик: 0x1000

2. Таблица разделов: 0x8000

3. Прошивка: 0x10000

Мы можем прочитать файл прошивки внутри комплекта esp32 с помощью следующей команды

esptool.py --port PORT --baud 230400 read_flash 0 0x40000 ./trick.bin

Файл прошивки хранится какrick.bin, и вы можете прочитать этот файл, используя любой из плагинов для чтения HEX в VScode.

Этапы шифрования

1. Клонируйте папку Esptool GitHub и выполните следующие команды

$ python setup.py install                 // To install from setup.py file 
$ espefuse.py --port "COM12" Summary       //press the boot button now

Здесь он покажет карту внутренних предохранителей чипа. В основном мы можем сосредоточиться на следующих параметрах.

Внутренние предохранительные предохранители:

FLASH_CRYPT_CNT =0 , FLASH_CRYPT_CONFIG = 0

  • Флэш-ключ шифрования будет храниться в

BLOCK1 (BLOCK1): флэш-ключ шифрования

= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

  • Ключ шифрования безопасной загрузки будет храниться в

BLOCK2 (BLOCK2): безопасный ключ загрузки

= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

2. Скомпилируйте исходный код и создайте файл «firmware.bin», используя любую платформу, например Arduino UNO или PlatformIO.

3. Сгенерируйте ключ флэш-шифрования для esp32

$ espsecure.py generate_flash_encryption_key "<path_to_bin_file_to_store_key>"

eg:
$ espsecure.py generate_flash_encryption_key flash_encryption_key.bin

Этот процесс необратим, делайте это только тогда, когда проект полностью настроен (в производстве)

4. Запишите ключ на свой esp32

Нажмите кнопку загрузки и введите BURN

$ espefuse.py --port PORT burn_key flash_encrytion "<path_to_bin_file_to_store_key>"

eg:
$ espefuse.py --port COM12 burn_key flash_encryption flash_encryption_key.bin

5. Теперь мы снова можем прочитать сводку и увидеть флеш-ключ шифрования

$ espefuse.py --port "COM12" Summary

Теперь блок 1 будет выглядеть примерно так

BLOCK1 (BLOCK1): флэш-ключ шифрования

= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-

6. Включение механизма флэш-шифрования

Нажмите кнопку загрузки и введите BURN

$ espefuse.py --port COM12 burn_efuse FLASH_CRYPT_CNT

7. Настройка флэш-шифрования для использования всех битов адреса вместе с ключом шифрования (максимальное значение 0x0F).

Нажмите кнопку загрузки и введите BURN

$ espefuse.py --port COM12 burn_efuse FLASH_CRYPT_CONFIG 0x0F

8. Теперь еще раз проверьте сводку эспефуза

$ espefuse.py --port "COM12" Summary

Теперь вы можете заглянуть внутрь предохранительных предохранителей -

FLASH_CRYPT_CNT = 1, FLASH_CRYPT_CONFIG = 15

9. Генерируем шифрование для раздела, загрузчика и прошивки

  • Шифрование таблицы разделов
$ espsecure.py encrypt_flash_data --keyfile "<path to key.bin>key.bin" --address 0x8000 --output path to store encrypted partition table.bin>" "<path to unencrypted partition.bin>"

eg:
$ espsecure.py encrypt_flash_data --keyfile flash_encryption_key.bin --address 0x8000 --output partition_table_encrypted.bin build/partition_table/partition-table.bin

Эта команда шифрует двоичный файл таблицы разделов (partition-table.bin) с помощью ключа флэш-шифрования и выводит зашифрованную таблицу разделов в partition_table_encrypted.bin по адресу 0x8000.

  • Шифрование загрузчика
$ espsecure.py encrypt_flash_data --keyfile "<path to key.bin>key.bin" - address 0x1000 --output "<path to store encrypted bootloader.bin>" "<path to unencrypted bootloader.bin>"

eg:
$ espsecure.py encrypt_flash_data --keyfile flash_encryption_key.bin --address 0x1000 --output bootloader_encrypted.bin build/bootloader/bootloader.bin

Эта команда шифрует двоичный файл загрузчика (bootloader.bin) с помощью ключа шифрования флэш-памяти, хранящегося в flash_encryption_key.bin. Затем зашифрованный загрузчик выводится на bootloader_encrypted.bin по адресу 0x1000.

  • Шифрование встроенного ПО:
$ espsecure.py encrypt_flash_data --keyfile "<path to key.bin>key.bin" --address 0x10000 --output "<path to store encrypted firmware.bin >" "<path to unencrypted firmware.bin>"

eg:
$ espsecure.py encrypt_flash_data --keyfile flash_encryption_key.bin --address 0x10000 --output firmware_encrypted.bin firmware.bin
  • Эта команда шифрует двоичный файл микропрограммы (firmware.bin) с помощью ключа шифрования флэш-памяти и выводит зашифрованную микропрограмму в firmware_encrypted.bin по адресу 0x10000.

Эти команды демонстрируют, как использовать espsecure.py для шифрования определенных разделов микропрограммы с помощью предоставленного ключа шифрования флэш-памяти. Полученные зашифрованные файлы затем можно прошить на устройство ESP32.

Перед выполнением этих команд убедитесь, что у вас есть необходимый ключ шифрования (flash_encryption_key.bin) и соответствующие двоичные файлы (bootloader.bin, partition-table.bin и firmware.bin) в указанных местах.

10. Наконец, запишите эти файлы на плату esp32, используя следующую команду, и нажмите кнопку загрузки.

$ python esptool.py --chip esp32 --port COM8 --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 "<path to encrypted bootloader.bin file>" 0x10000 "<path to encrypted firmware.bin file >" 0x8000 "<path to encrypted partition.bin file>"

eg:
$ esptool.py -p PORT -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 bootloader_encrypted.bin 0x8000 partition_table_encrypted.bin  0x10000 firmware_encrypted.bin

11. Проверьте, работает ли добавленный зашифрованный механизм, используя следующий код Arduino.

Сгенерируйте файл прошивки и убедитесь, что он закодирован ранее сгенерированным ключом

# include "esp_flash_encrypt.h"
void setup() {
  Serial.begin(115200);
}

void loop() {
  if (esp_flash_encryption_enabled())
    Serial.println("Encryption Enabled");
  else
    Serial.println("Encryption not Enabled");
}

→ Чтобы перепрограммировать плату, мы должны создать новый файл прошивки и зашифровать его с помощью существующего файла KEY.bin (flash_encryption_key.bin), а затем загрузить код в модель

→ Мы должны создать новый файл flash_encryption_key.bin для каждого модуля esp32.

Если после загрузки зашифрованного тестового кода вы получите этот вывод в последовательном терминале, поздравляем 👏👏👏, вы успешно включили механизм шифрования на своей плате esp32.

Обратите внимание на следующие параметры при создании файла загрузчика

Мы можем использовать ESP-IDF для создания файла bootloader.bin. Выполните следующие шаги для установки IDF. Используйте программу Hello_world для создания файла bootloader.bin и установите следующие параметры в меню-конфигурации.

  1. Установите уровень детализации журнала загрузчика (без вывода) — это уменьшит размер загрузчика, поэтому вы сможете включить флэш-шифрование без изменения смещения таблицы разделов в PlatformIO и в IDF.

2. Включить Flash Encryption (для тестирования процедуры установите режим использования только для разработки)

3. Дважды проверьте схему разделов и смещение таблицы разделов по адресу 0x8000.

Общие проблемы

Если вы получаете что-то вроде этой ошибки в последовательном терминале после загрузки нового кода, это означает, что вы не зашифровали прошивку с помощью ранее сгенерированного ключа.