ESP32 Secure Boot V2 |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||
Этот документ (перевод документации [1]) относится к версии безопасной загрузки Secure Boot V2, которая поддерживается следующими чипами: ESP32 (начиная с ECO3), ESP32-S2, ESP32-S3, ESP32-C3 (начиная с ECO3) и ESP32-C2. Исключение составляет ESP32 он поддерживает только Secure Boot версии 1 (для ESP32 до ECO3 обращайтесь к [2]). Рекомендуется использовать версию V2, если есть в наличии поддерживающий эту версию чип. Secure Boot V2 безопаснее и более гибкая, чем Secure Boot V1. Secure Boot V2 использует верификацию приложения и загрузчика на основе RSA-PSS. Этот документ также может использоваться как руководство для подписывания приложений с использованием схемы RSA-PSS без подписи загрузчика. Опции Secure Boot V2 и схемы подписи RSA (App Signing Scheme) доступны для ESP32 начиная с ECO3. Для использования этих опций в menuconfig установите CONFIG_ESP32_REV_MIN в значение, большее или равное Rev 3. Secure Boot защищает устройство от запуска любого не авторизованного (т. е. не подписанного) кода путем проверки подписи каждой части загружаемого программного обеспечения. Для ESP32 эти части включают загрузчик второй стадии [3] и каждый двоичный образ приложения. Обратите внимание, что загрузчик первой стадии не требует подписи, поскольку он находится в ROM, и поэтому его код не может быть изменен. Новая схема верификации Secure Boot, основанная на RSA (Secure Boot V2), была введена на чипах ESP32 (начиная с ECO3), ESP32-S2, ESP32-S3 и ESP32-C3 (начиная с ECO3). Процесс Secure Boot на ESP32 включает следующие шаги: 1. Когда загрузчик первой стадии загружает загрузчик второй стадии, то для загрузчика второй стадии проверяется подпись RSA-PSS. Если проверка была успешной, то производится запуск загрузчика второй стадии. Достоинства Secure Boot V2: • Публичный ключ RSA-PSS сохраняется в устройстве. Соответствующий ему приватный ключ RSA-PSS находится в секретном месте, и к нему нет никакого доступа со стороны устройства. Примечание: под программным загрузчиком подразумевается загрузчик второй стадии [2]. [Процесс Secure Boot V2] Здесь дается обзор процесса Secure Boot V2. Инструкции по разрешению Secure Boot предоставлены в разделе "Как разрешить Secure Boot V2". Secure Boot V2 проверяет образ программного загрузчика и двоичные образы приложений, используя выделенный блок сигнатуры. Каждый образ имеет отдельно сгенерированный блок сигнатуры, который прикрепляется в конец образа. В ESP32 ECO3 может быть прикреплен только один блок сигнатуры к загрузчику или к образу приложения. Каждому блоку сигнатуры предшествует образ кода, а также соответствующий публичный ключ RSA-3072. Более подробно про формат см. далее раздел "Формат блока сигнатуры". Цифровая подпись публичного ключа RSA-3072 сохраняется в eFuse [4, 5]. Образ приложения проверяется не только при каждой загрузке, но также и при каждом обновлении по радиоканалу (OTA, см. [6]). Если текущий выбранный образ OTA app не может быть проверен, то загрузчик выполнит откат назад в поиске другого корректно подписанного образа приложения. Процесс Secure Boot V2 выполняет следующие шаги: 1. В момент запуска (startup) код ROM проверяет бит Secure Boot V2, находящийся в eFuse. Если конфигурация Secure Boot запрещена, то выполняется нормальный процесс загрузки. Если конфигурация Secure Boot разрешена, то будет выполняться защищенная загрузка из следующих шагов. [Формат блока сигнатуры] Образы загрузчика и приложения дополняются до следующей границы блока из 4096 байт, так что сигнатура занимает отдельный сектор SPI flash. Сигнатура вычисляется от всех байт образа, включая дополняющие байты. Содержимое каждого блока сигнатуры показано в таблице 1. Таблица 1. Содержимое Signature Block.
Примечание: R и M’ используются для аппаратно поддерживаемого алгоритма Монтгомери (hardware-assisted Montgomery Multiplication). Хвост сектора сигнатуры оставляется чистым (заполненным байтами 0xFF), что позволяет записать другие блоки сигнатуры за предыдущим блоком. [Проверка Signature Block] Блок сигнатуры считается допустимым (valid), если первый байт равен 0xe7, и его корректная CRC32 сохранена со смещением 1196. Иначе блок сигнатуры считается ошибочным. Проверка образа. Образ считается проверенным (verified), если публичный ключ, сохраненный в любом блоке сигнатуры, является допустимым для этого устройства, и если сохраненная сигнатура подходит для данных образа, считанных из flash. 1. Сравнивается хэш подписи SHA-256 публичного ключа, строенный в блок сигнатуры загрузчика, с подписью (подписями), сохраненными в битах eFuse. Если хеш публичного ключа не соответствует ни одному из хэшей из eFuse, то проверка завершается неудачей. Размер загрузчика. Разрешение безопасной загрузки (secure boot) и/или шифрования SPI flash (flash encryption) увеличит размер кода загрузчика, что может потребовать обновления для смещения таблицы разделов (см. раздел "Размер загрузчика" в документации [3]). Использование eFuse. ESP32-ECO3: ABS_DONE_1 - разрешает защиту Secure Boot при загрузке. Ключ (ключи) должен иметь возможность чтения, чтобы программа могла получить к нему доступ. Защита от чтения для ключа (ключей) активна, что программа прочитает ключ как нули, в результате процесс верификации потерпит неудачу, и процесс загрузки будет оборван. [Как разрешить Secure Boot V2] 1. Откройте меню конфигурации проекта [7], в "Security features" установите "Enable hardware Secure Boot in bootloader", чтобы разрешить Secure Boot. 2. Для ESP32, конфигурация Secure Boot V2 доступна только начиная с ESP32 ECO3. Чтобы просмотреть опцию "Secure Boot V2", ревизия чипа должна быть изменена на revision 3 (ESP32- ECO3). Чтобы поменять ревизию чипа, установите "Minimum Supported ESP32 Revision" на Rev 3 в "Component Config" -> "ESP32- Specific". 3. Укажите путь до ключа подписи (Secure Boot signing key) относительно корневой директории проекта. 4. Выберите желаемый режим загрузки UART ROM в "UART ROM download mode". По умолчанию UART ROM download mode остается разрешенным для целей отладки, и следует иметь в виду, что это потенциально небезопасно. Рекомендуется запретить UART download mode для устройств, находящихся в производстве, что улучшит защиту кода. 5. Установите другие опции menuconfig (по мере необходимости). В особенности уделите внимание опциям "Bootloader Config", потому что прошить загрузчик Вы сможете только один раз. После этого выйдите из menuconfig и сохраните конфигурацию. 6. При первом запуске idf.py build, если ключ подписи не был найден, то будет выведено сообщение об ошибке с предложением создать ключ подписи (signing key) командой espsecure.py generate_signing_key. Важные замечания: ключ подписи, генерируемый таким способом, будет использовать самый лучший доступный источник случайных чисел для операционной системы и её инсталляции Python (/dev/urandom на OSX/Linux и CryptGenRandom() на Windows). Если этот источник случайных чисел нестойкий, то приватный ключ будет ненадежным. Для целей производства рекомендуется генерировать пару ключей с использованием openssl или другой программы, соответствующую индустриальным стандартам. Подробности см. далее в разделе "Генерация Secure Boot Signing Key". 7. Запустите команду idf.py bootloader для сборки загрузчика с разрешенной функцией Secure Boot. Вывод сборки будет включать приглашение для команды прошивки с использованием esptool.py write_flash. 8. Когда Вы будете готовы прошить загрузчик, запустите эту указанную команду (Вам будет нужно ввести её самостоятельно, система сборки не будет выполнять этот шаг) и подождите завершения прошивки. 9. Запустите idf.py flash для сборки и прошивки таблицы разделов и только что собранного образа приложения (app image). Образ приложения будет подписан с помощью signing key, который был сгенерирован на шаге 4. Замечание: idf.py flash не прошивает загрузчик, если разрешена конфигурация Secure Boot. 10. Сбросьте устройство ESP32, и оно запустит прошитый Вами загрузчик. Программный загрузчик разрешит Secure Boot на чипе, и затем проверит сигнатуру образа приложения и запустит это приложение. Вы должны наблюдать сообщения в выводе консоли ESP32, чтобы проверить, что конфигурация Secure Boot разрешена, и при сборке этой конфигурации не было никаких ошибок. Замечания: безопасная загрузка (secure boot) будет разрешена только после того, как будет прошита правильная таблица разделов и корректный образ приложения. Это необходимо для предотвращения аварий до момента полной настройки системы. Если устройство ESP32 было сброшено, или был сбой по питанию во время первой загрузки, то процесс запустится снова при следующей загрузке. 11. При последующих загрузках аппаратура Secure Boot будет проверять, что программный загрузчик не был изменен, и программный загрузчик будет проверять подписанный образ приложения (используя проверенную часть публичного ключа добавленного signature block). [Ограничения после разрешения Secure Boot] • Любой обновленный загрузчик или приложение должны быть подписаны ключом, который подходит к цифровой подписи, которая была сохранена в eFuse. [Генерация Secure Boot Signing Key] Система сборки выдаст приглашение ввести команду для генерации нового signing key с помощью espsecure.py generate_signing_key. Параметр --version 2 будет генерировать приватный ключ RSA 3072 для конфигурации Secure Boot V2. Надежность ключа подписи пропорциональна (a) качеству генератора случайных чисел, и (b) корректности используемого алгоритма шифрования. Для устройств, находящихся в производстве, рекомендуется использовать генерацию ключей подписи на основе качественного генератора энтропии, применяя лучшие на сегодняшний день утилиты генерации ключей RSA-PSS. Например, для генерации ключа подписи с помощью openssl, используйте команду: openssl genrsa -out my_secure_boot_signing_key.pem 3072 Помните, что безопасность системы Secure Boot зависит от надежности хранения в секрете приватной части ключа подписи. [Дистанционная подпись образов] Для сборок процесса производства хорошей практикой будет использовать удаленный сервер подписи (remote signing server) вместо того, чтобы держать ключ подписи в компьютере, на котором выполняется сборка (которая является конфигурацией безопасной загрузки ESP-IDF по умолчанию). Утилита командной строки espsecure.py на удаленной системе может использоваться при подписи образов приложения и данных таблицы разделов для Secure Boot. Чтобы использовать дистанционное подписывание, запретите опцию "Sign binaries during build". Приватный ключ подписи не должен находиться на системе сборки. После того, как были собраны образ приложения и таблица разделов, система сборки выведет шаги для их подписи с использованием espsecure.py: espsecure.py sign_data --version 2 --keyfile PRIVATE_SIGNING_KEY BINARY_FILE Показанная выше команда добавит образ сигнатуры к существующему двоичному бинарнику. Вы можете использовать аргумент –output, чтобы записать подписанный бинарник в отдельный файл: espsecure.py sign_data --version 2 --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE [Рекомендуемая практика использования Secure Boot] • Генерируйте ключ подписи на системе, где присутствует качественный источник энтропии (надежный генератор случайных чисел). [Технические подробности Secure Boot] Следующие разделы содержат низкоуровневые справочные описания различных элементов безопасной загрузки. Команды, вводимые вручную. Технология Secure Boot интегрирована в систему сборки ESP-IDF, так что запуск idf.py build выполнит подпись образа приложения, и запуск idf.py bootloader сгенерирует подписанный загрузчик, если при сборке была включена защита подписью двоичных файлов. Однако можно использовать утилиту espsecure.py для создания отдельных сигнатур и цифровых подписей. Для подписи двоичного образа: espsecure.py sign_data --version 2 --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin Здесь keyfile это файл в формате PEM, содержащий приватный ключ RSA-3072. [Secure Boot и Flash Encryption] Если Secure Boot используется без Flash Encryption, то есть возможность запустить атаку взлома типа "time-of-check to time-of-use", где содержимое flash подменяется после того, как образ проверен и запущен. Таким образом, рекомендуется одновременно включить обе эти опции защиты. [Проверка подписи приложения без Hardware Secure Boot] Сигнатура Secure Boot V2 может быть проверена в процессе обновления OTA, без разрешения опции аппаратной безопасной загрузки (hardware Secure Boot). Эта опция использует такую же схему подписи приложения, какая применяется для Secure Boot V2, однако в отличие от hardware Secure Boot отключение безопасной загрузки не дает защиты от возможности для атакующего что-либо записать код в память flash и обойти защиту сигнатурой. Отключение безопасной загрузки может понадобиться в случаях, когда неприемлема задержка по времени, которая уходит на процесс верификации Secure Boot, и/или когда модель угрозы не включает возможность физического доступа для атакующего, чтобы он мог подменить загрузчик или образ приложения в памяти SPI flash. В этом режиме публичный ключ, который присутствует в signature block работающего в настоящий момент приложения, будет использован для проверки сигнатуры нового кода для обновляемого приложения (сигнатура работающего приложения в процессе обновления не проверяется, поскольку подразумевается, что она корректна). Таким образом, система создает цепочку доверия от запущенного приложения к новому обновляемому приложению. По этой причине важно, чтобы первоначальное приложение, прошитое в устройство, также было подписано. Проверка подписи выполняется при запуске приложения (app startup), и запуск приложения будет оборван, если подпись не была найдена. Это делается для предотвращения ситуации, когда обновление невозможно. Приложение должно иметь только один корректный блок сигнатуры в первой позиции. Обратите внимание, что в отличие от hardware Secure Boot V2, сигнатура работающего приложения при загрузке не проверяется. Система проверяет только блок сигнатуры в первой позиции, и игнорирует любые другие добавленные сигнатуры. Замечание: как правило, рекомендуется использовать полную конфигурацию hardware Secure Boot за исключением случаев, когда отключение Secure Boot достаточно для обеспечения безопасности приложения. Как разрешить верификацию подписи приложения (Enable Signed App Verification): 1. Откройте меню конфигурации проекта -> Security features. Предупреждение: очень важно, чтобы все прошиваемые приложения были подписаны либо вручную после сборки, либо автоматически во время сборки. [Дополнительные возможности] Отладка JTAG. По умолчанию, когда разрешена конфигурация Secure Boot, отладка JTAG через eFuse запрещается. Загрузчик прошивает этот eFuse во время первой загрузки, одновременно с прошивкой eFuse, который разрешает Secure Boot. См. "JTAG with Flash Encryption or Secure Boot" в советах [8] для дополнительной информации по использованию отладки JTAG, когда разрешена конфигурация Secure Boot, или разрешена проверка подписанного приложения. [Словарик] OTA Over The Air, технология загрузки (обновления) по радиоканалу. PEM Privacy Enhanced Mail, текстовый файл, содержащий сертификат подписи или ключ шифрования в виде ASCII-текста. RSA аббревиатура от фамилий Rivest, Shamir и Adleman, криптографический алгоритм с открытым ключом, основывающийся на вычислительной сложности задачи факторизации больших целых чисел (из Википедии). RSA-PSS RSA Signature Scheme with Probabilistic Signature Scheme, асимметричный алгоритм цифровой подписи (см. Википедию). [Ссылки] 1. ESP32 Secure Boot V2 site:docs.espressif.com. |