Перейти к содержанию

Как защитить прошивку ATmega328P от чтения?

Обновлено Редакция GAW

Байт защиты ATmega328P задаёт, что программатор и загрузчик могут делать с памятью. Как и у фьюзов, «0» означает «запрограммирован», а вернуть биты в «1» можно только полным стиранием кристалла.

Байт защиты

БитыИмяЧто ограничивает
5:4BLB12, BLB11доступ к разделу загрузчика
3:2BLB02, BLB01доступ к разделу приложения из загрузчика
1:0LB2, LB1доступ программатора ко всей памяти

Режим LB 3 (LB2 = LB1 = 0) запрещает программатору и проверку, то есть чтение, и запись флеш-памяти и EEPROM, а заодно блокирует фьюзы и биты BLB (DS40002061B, табл. 28-2). Подробная расшифровка — в термине «Биты защиты».

Кристалл без загрузчика

Достаточно режима LB 3. Наш расчёт в записи, которую использует Arduino (неиспользуемые биты 7:6 — нули): 0x0F у Uno — это 0000 1111; обнулив два младших бита, получаем 0x0C. Команда avrdude — с ключом -U lock:w:0x0C:m, после записи прошивки и фьюзов.

Кристалл с загрузчиком Arduino

Загрузчик работает изнутри кристалла и читает флеш командой LPM — биты LB ему не мешают. Табл. 28-3 даташита задаёт для этого режимы BLB0:

Режим BLB0BLB02 BLB01Загрузчик читает приложениеЗагрузчик пишет приложение
11 1дада
40 1нет, но новая программа прочитаетда
30 0нетнет

Наш вывод: режим 4 не защищает. Запрет в табл. 28-3 касается только команд LPM, выполняемых из раздела загрузчика, а запись разрешена. Загрузка скетча в Arduino идёт без стирания кристалла (ключ -D), optiboot стирает и пишет флеш по страницам — значит, можно загрузить маленькую программу, которая займёт первые страницы, прочитает остальную флеш-память из раздела приложения и выдаст её по UART. Защищает только режим 3 (BLB02 = BLB01 = 0): наш расчёт — с BLB1 как у Uno и LB = 00 это байт 0x00, но загрузчик тогда больше не обновит прошивку. Второй вариант — стереть загрузчик и прошивать по ISP с байтом 0x0C.

Порядок записи

  1. Прошивка и EEPROM.
  2. Фьюзы — проверьте их в калькуляторе фьюзов AVR.
  3. Биты BLB, затем биты LB.

Сигнатура у защищённого кристалла по-прежнему читается — по ней программатор опознаёт модель.

Похожие вопросы

Можно ли снять защиту и вернуть кристалл к жизни?

Да, полным стиранием (Chip Erase, ключ -e в avrdude): оно возвращает биты защиты в единицы, и стирает флеш-память, а EEPROM — только если не запрограммирован фьюз EESAVE (DS40002061B, 28.7.3, прим. 1). Прошивку прочитать нельзя — её больше нет, но при включённом EESAVE данные EEPROM переживут снятие защиты, поэтому секреты там с EESAVE не хранят (наш вывод). После стирания кристалл программируется как новый.

Почему после записи защиты не меняются фьюзы?

В режимах LB 2 и 3 фьюзы заблокированы для программатора. Поэтому Microchip требует сначала записать фьюзы и биты BLB, а биты LB — последними. Исправить фьюзы потом можно только после Chip Erase.

Защищает ли это от любого копирования?

Защита закрывает чтение через ISP, а с BLB0 в режиме 3 — и путь через загрузчик. Сигнатуру кристалла по-прежнему можно прочитать — так задумано. От атак на сам кристалл в лаборатории биты защиты не рассчитаны; это наш вывод, Microchip в этом даташите таких гарантий не даёт.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — табл. 28-1 — байт защиты: биты 5:4 BLB12/BLB11, 3:2 BLB02/BLB01, 1:0 LB2/LB1; табл. 28-2 — режим LB 3 (00): запрещены программирование и проверка флеш и EEPROM, заблокированы фьюзы и BLB; прим. 1 — фьюзы и BLB программируют до LB; табл. 28-3 — BLB0 режим 4 (01): LPM из раздела загрузчика не читает раздел приложения, режим 3 (00) — к этому SPM не пишет в приложение; 28.3 — сигнатура читается и у защищённого кристалла; 28.7.3 — биты защиты стираются только Chip Erase вместе с флеш и EEPROM
  2. Arduino. ArduinoCore-avr, boards.txt (коммит 11b9130) — uno.bootloader.unlock_bits=0x3F, uno.bootloader.lock_bits=0x0F

Нашли ошибку?