Как защитить прошивку ATmega328P от чтения?
Обновлено Редакция GAW
Байт защиты ATmega328P задаёт, что программатор и загрузчик могут делать с памятью. Как и у фьюзов, «0» означает «запрограммирован», а вернуть биты в «1» можно только полным стиранием кристалла.
Байт защиты
| Биты | Имя | Что ограничивает |
|---|---|---|
| 5:4 | BLB12, BLB11 | доступ к разделу загрузчика |
| 3:2 | BLB02, BLB01 | доступ к разделу приложения из загрузчика |
| 1:0 | LB2, 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:
| Режим BLB0 | BLB02 BLB01 | Загрузчик читает приложение | Загрузчик пишет приложение |
|---|---|---|---|
| 1 | 1 1 | да | да |
| 4 | 0 1 | нет, но новая программа прочитает | да |
| 3 | 0 0 | нет | нет |
Наш вывод: режим 4 не защищает. Запрет в табл. 28-3 касается только команд LPM, выполняемых из раздела загрузчика, а запись разрешена. Загрузка скетча в Arduino идёт без стирания кристалла (ключ -D), optiboot стирает и пишет флеш по страницам — значит, можно загрузить маленькую программу, которая займёт первые страницы, прочитает остальную флеш-память из раздела приложения и выдаст её по UART. Защищает только режим 3 (BLB02 = BLB01 = 0): наш расчёт — с BLB1 как у Uno и LB = 00 это байт 0x00, но загрузчик тогда больше не обновит прошивку. Второй вариант — стереть загрузчик и прошивать по ISP с байтом 0x0C.
Порядок записи
- Прошивка и EEPROM.
- Фьюзы — проверьте их в калькуляторе фьюзов AVR.
- Биты 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 в этом даташите таких гарантий не даёт.
Источники
- 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
- Arduino. ArduinoCore-avr, boards.txt (коммит 11b9130) — uno.bootloader.unlock_bits=0x3F, uno.bootloader.lock_bits=0x0F
Нашли ошибку?
Смотрите также
- Биты защиты AVR (lock bits)Запрет чтения прошивки и защита загрузчика от перезаписи
- Фьюзы AVRБиты фьюзов, заводские значения и avrdude
- AVRDUDEПрошивка AVR из командной строки: ключи, Arduino, USBasp, фьюзы, ошибки
- Сигнатура AVR (signature bytes)Три заводских байта, по которым программатор опознаёт кристалл