Зашита от считывания прошивки stm32

stm32
Сегодня мы будем защищать прошивку на stm32 от считывания кул-хакерцами. Дабы не тянуть резину, вот кусок кода:


#ifdef NDEBUG
    if (FLASH_GetReadOutProtectionStatus() == RESET)
    {
        FLASH_Unlock();
        FLASH_ReadOutProtection(ENABLE);
        FLASH_Lock();
    }
#endif  



Как не сложно догадаться, кусок использует библиотеку от stm. Такой кусок кода использовать очень удобно — контроллер сам устанавливает свою защиту при первом запуске, а первый запуск легко организовать после прошивки. Вот она, свобода от тирании фьюзов!

Да, я знаю, насчет холивора насчет «библиотека vs непосредственное обращение к регистрам». Моя позиция тут такова — если нужна большая скорость, или осталось совсем мало памяти, но нужно непосредственное обращение к регистрам. Если и скорость не важна и памяти много, лучше использовать библиотеку — так программа пишется быстрее и получается более читаемая.

Снять защиту
Контроллер то мы защитили. Но вот беда — нужно поправить нашу программу, а при установленной защите ничего с контроллером сделать нельзя — ни прочитать ни записать. Как снять защиту? Сразу предупреждаю — ребята из ST все сделали правильно и вместе с защитой уничтожается вся прошивка.

Для снятия защиты нам понадобится программа st-link utility. Скачать ее можно вот тут.

Запускаем программу и выбираем вот этот пункт, либо просто жмем ctrl-b:


В поле «состояние защиты от чтения выбираем выключено». И нажимаем кнопку Apply:
Стирание защиты

Вместе с битом защиты стирается и вся память:


Защищайтесь, мы за безопасный эмбед.

17 комментариев

avatar
По-моему снятие защиты стиранием прошивки — это гениально, а главное просто.
Осталось пересесть с AVR на ARM, но это уже другая история.
avatar
в контролерах AT91SAM7S такая ж процедура зашиты флеш
avatar
А как работает эта защита в двух словах можно? (Пока не читал просто про нее) В смысле что блокирует? Доступ к флешу извне? Нельзя ли залить в ОЗУ свой код, который сольет нам флеш? Или она отладочный модуль вырубает?
avatar
Естественно, вырубает — ничего не записать ни считать нельзя. Ну и встроенный бутлоадер тоже вырубает во избежание неприятностей.

Прочитать можно вот тут.
Комментарий отредактирован 2013-07-01 10:40:47 пользователем bsvi
avatar
встроенный бутлоадер не отключается. Естественно, прочитать через него содержимое нельзя, но через него можно снять защиту со стиранием всей памяти.
avatar
А подобным образом может ли микроконтроллер сам себя разблокировать выполнив к примеру такой код заранее записанный во флеш ???

FLASH_Unlock();
FLASH_ReadOutProtection(DISABLE);
FLASH_Lock();
Комментарий отредактирован 2013-07-09 11:20:25 пользователем alexns
avatar
Защита снимется, но вместе с ней сотрется и вся прошивка.
avatar
Спасибо за столь быстрый ответ!
avatar
Все не так хорошо, как кажется. Вот есть, например, приложение, в котором собственный загрузчик может позволять пользователю загружать различные прошивки (через USART). Все вроде хорошо, но если пользователь создаст прошивку, которая перехватит управление на себя и через то-же UART сможет передать весь DUMP. В ATMege это сделано запретом чтения flash в секции boot из секции application, а в STM похоже в такой ситуации защиты не получится! Если есть какие-то варианты, то подскажите. Буду признателен!
avatar
Непонятна Ваша логика: если обновление через собственный загрузчик, а не через встроенный, то вероятно он с шифрованием (иначе зачем он нужен?), соответственно пользователь не сможет создать любую прошивку и загрузить её, сможет только тот, кому разрешено это делать (либо пользователю выдаётся софт, генерирующий на выходе уже шифрованную прошивку, тогда этот софт сам должен ограничивать действия пользователя). Поясните ещё раз, что Вы хотите сделать.
avatar
Да, наверное я непонятно выразился. Имеется коммерческий девайс, ценность которого представляет софт. Но он находится у заказчика и должен иметь возможность обновлять прошивку удаленно. То есть прошивка отсылается заказчику и он выполняет обновление. Для этого имеется загрузчик, но который выполняет очень много функций устройства в себе (библиотека функций и является основной ценностью). В АТМеге загрузчик и эта библиотека сидят в bootsection. Выставлены биты зашиты чтения boot из приложения. Прошивка загружаемая должна запускаться и если в прошивке перехватить управление USARTом, то можно попытаться вычитать весь дамп. АТМега не даст вычитать данные из bootsection. На АТМеге все прекрасно работает, но хотелось бы перейти на STM. То есть, в STM загрузив прошивку во флеш, она имеетвозможность вычитать весь флеш. Это не устраивает. Может есть какие-то варианты?
Комментарий отредактирован 2013-08-04 19:45:13 пользователем megauser
avatar
Если пользователь сам не создаёт прошивок, а только обновляет, то собственный бутлоадер с шифрованием решает эту проблему. Прошивка передаётся в зашифрованном виде. Кроме прочего бутлоадер должен проверять целостность прошивки. Алгоритм и ключи шифрования конечный пользователь знать не должен. Дальнейшие рассуждения по поводу защиты отдельных секций теряют смысл.
Комментарий отредактирован 2013-08-04 22:13:18 пользователем Koyodza
avatar
Понял, спасибо. Но в АТМЕГЕ все решается на аппаратном уровне. Буду думать. Ещё раз спасибо.
avatar
А для STM32F050 тот же код защиты?
Кужа его вставлять, в.с или .h?
#include <stm32f0xx_flash.h> в CooCox нужна?
У меня компелируется, но не защищает.
Выдает ошибки компиляции, если пишу в main() только 3 строчки:
FLASH_Unlock();
FLASH_ReadOutProtection(ENABLE);
FLASH_Lock();
Комментарий отредактирован 2014-02-04 13:58:14 пользователем diart
avatar
Я залочил контроллер настраивая ворт… его как-то можно разлочить?
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //включаем тактирование порта GPIOA
GPIO_InitTypeDef gpio;
;GPIO_StructInit(&gpio); // скорее всего комментируя эту строку привеза к залочке
gpio.GPIO_Pin = GPIO_Pin_4;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&gpio);
Имею теперь вечную моргалку на STM, даже две.
avatar
Научился разлочивать.
1. В «St-link utility» в «Settings» установить «Connect Under Reset»
2. Удерживать RESET в 0
3. Нажать «Erase Chip»
4. Отпустить RESET
С подключенным RESET к программатору чип не стирался.
avatar
На russiansemiresearch.com прекрасно считывают прошивки с stm32 без стирания самой программы. Похоже, просто блокируют команду стирания прошивки, но при этом нормально стирают защиту.
Комментарий отредактирован 2017-09-18 13:24:19 пользователем cyber
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.