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

Автономный микропрограмматор BootProg для прошивки boot-а (а может и не только)

Новости по результатам реализации нового варианта прошивальщика. Это когда шьётся не только загрузчик, но и сразу весь остальной код целевого девайса (либо весь код без загрузчика).

Отличие возникает в следующем (помимо того, что контроллер взял с большей памятью - ATMega168):

1. Прошиваемый код может иметь (и скорее всего) несколько кусков кода, которые никак не стыкуются своим началом и/или концом друг с другом в адресном пространстве флеш памяти, а могут и отстоять друг от друга всего на несколько байт, в т.ч. в пределах одной страницы флеш-памяти.

2. В основном коде может оказаться нечётное количество байтов. В загрузчике такого быть не могло, т.к. там только коды команд, а здесь могут быть, например, строковые константы.

3. Надо (скорее всего) прошивать ещё и EEPROM.

4. Шьётся boot-загрузчик + код, так что для загрузчика с контролем CRC надо, чтобы в итоге получилось правильное содержимое флеша, чтобы CRC при проверке была равна 0, иначе загрузчик не стартует основное приложение.

 

Сразу скажу, что последнюю проблему я решил просто - переделал boot-загрузчик, чтобы он не проверял CRC (в AES-загрузчике от Атмела такая возможность есть).

Для исправления отл.3, я добавил процедуру прошивки EEPROM в код прошивальщика.

Из-за отл.1 и 2, при засовывании в проект загрузчика вместе с основным кодом, прошивальщик работал неправильно. Первый кусок шился кроме последнего байта (из-за нечётности), а второй неправильно (из-за малого "отступа" от первого при наличии страничности).

Для исправления отл.2 я вставил в ispProgramFlash() загрузку байта 0xFF в последнее слово в случае, если оказывалось нечётное количество байт в массиве (любом) для прошивки флеша. Кстати, эта "ошибка" по-моему есть в коде всех доморощенных программаторов. Но их спасает, видимо, то, что Студия формирует массивы для прошивки нужным образом - с чётным количеством байт (при прошивке флеша).

А вот с отл.1 оказалось всё сложнее. Поскольку флеш прошивается странично, то пришлось учесть то, как разные непрерывные куски кода прошивки ложатся в память: начальные адреса, конец куска добить до целой страницы, но при этом учесть, чтобы он не залез на следующий кусок (у меня, например, получалось два куска, между которыми был всего один байт "пустоты") и т.д. Опять же Студия, по всей видимости, всё это учитывает сама и выдаёт по протоколу STK500 блоки данных с нужным выравниванием и размером (потому и моя реализация STK500 для программатора Dimoniprog работает). Но в этом случае ведь никакой Студии нет, шьётся всё автономно! Проблему пришлось решать. Я не стал исправлять код прошивальщика, а сделал так, чтобы массивы для прошивания уже были "как надо". Для этого модифицировал программу Hex2Src. Теперь она формирует массивы в исходниках выровненные на границу страницы и размером с целое количество страниц. "Лишние" байты вставлены кодом 0xFF. Взаимное положение кусков кода тоже учтено. Если при выравнивании куски "состыкуются", то они в итоге станут одним целым куском. При запуске программы Hex2Src теперь надо в командной строке перед именем файла (.hex) задать цифрами размер страницы флеш памяти целевого кристалла (не контроллера прошивальщика!), например:

Hex2Src 128 mega16.hex

После такой подготовки массивов кодов для прошивки, решение проблемы с нечётным количеством байт стало неактуальным. Но я его оставил на всякий пожарный.

Поскольку теперь программа Hex2Src формирует выходные файлы сразу в "пригодном" виде, то я их стал добавлять в main.c директивой include. Только надо всё же поправить имена констант и массивов - я правил для boot-а (в boot.c) и eeprom-а (в eeprom.c), т.к. они скорее всего в процессе разработки не поменяются, а вот имена флеш массивов оставил как есть, так что при изменении прошиваемого кода просто перекидываю в проект загрузчика обновлённый файл code.c (название, понятно, условное) с новым кодом.

При наличии двух и более кусков, зашиваемых во флеш, надо добавить соответственно строчки (в main.c) с вызовами ispAddress() и ispProgramFlash() для этих кусков. Думаю это понятно.

Добавил зажигание светодиода на четверть секунды в начале при старте. Теперь ведь шьётся дольше, так что надо было как-то проинформировать, что "началось".

Ещё немного задержки увеличил на всякий пожарный. Лучше подольше, но наверняка.

 

Исходники нового "расширенного" BootProg и новой версии программы Hex2Src прилагаются. В исходняках, понятное дело, содержимое файлов boot.c, code.c удалено, оставлены начало и конец для наглядности. Файл eeprom.c секретности не несёт, так что его оставил как есть.

BootProg.rar

Hex2Src.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, эта "ошибка" по-моему есть в коде всех доморощенных программаторов.

...

Поскольку флеш прошивается странично, то пришлось учесть то, как разные непрерывные куски кода прошивки ложатся в память:

Обижаешь... :) Нет у меня такой ошибки :(

И байты - а пусть фрагменты (любое количество на странице) не только заканчиваются на нечётных байтах, а и начинаются на них, даже пусть хоть только одни нечётные байты в HEX-е прописаны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обижаешь... :) Нет у меня такой ошибки :(

И байты - а пусть фрагменты (любое количество на странице) не только заканчиваются на нечётных байтах, а и начинаются на них, даже пусть хоть только одни нечётные байты в HEX-е прописаны.

Имелась в виду embedded составляющая, которой у вас нет. Так что прошу не обижаться :beer:

Я уже писал где-то, что лучше AvReal софта не видел. Но теперь хочется от него поддержки STK500.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте! Возникла необходимость собрать похожий девайс, но со своей спецификой. Допустим, имеется

заказчик (или несколько), который собирает железо, а программировать его некому. Программист (я) находится

в другом городе. По предоплате заказчик работать отказывается, предлагает проценты от продаж железа.

По опыту такие заказчики платят проценты только пока программа нуждается в доработках. Поэтому нужно

собрать автономный программатор со счетчиком числа прошивок и защищенной передачей на целевой кристалл,

чтобы нельзя было скопировать прошивку. Должна быть возможность "пополнения" числа прошивок

или вообще работы с другими прошивками после соответствующей оплаты.

 

По этой теме есть следующие соображения:

 

 

1. Загружаем с компа и храним зашифрованную прошивку на борту в отдельной флеш-микросхеме.

На целевой кристалл шьем AES бутлодер и затем уже через него - основную программу.

 

ДЫРА: 2. Для того чтобы расшифровать прошивку, бутлодер должен знать ключ. Бутлодер должен

зашиваться незашифрованным в чистый контроллер. Его можно перехватить по SPI во время программирования.

Как тогда сохранить в секрете ключ?

 

Временное решение. Сделать бутлодер трудно-поддающимся дизассемблированию (КАК?) и прошивать

в чистый микроконтроллер незащищенным. Но никому об этом не сказать. )))

 

3. В прошивке должны быть идентификатор(ID прошивки) и число допустимых программирований

этой прошивки - все это зашифровано. ID прошивки нужен для того, чтобы вести список прошивок и какую

сколько раз зашивали.

 

4. Список и счетчики прошивок храним внутри контроллера-программатора.

 

ДЫРА: Если у программатора

снесет крышу и придется его перепрограммировать - потеряется таблица прошивок, тогда можно будет повторно

использвать прошивки, которые до этого могли быть уже прошиты максимальное число раз.

 

РЕШЕНИЕ: Программа-обновлялка для ПК, которая загружает новую прошивку на борт программатора - работает только

при наличии связи через сеть интернет. Сначала отсылает программисту (мне) таблицу прошивок из контроллера.

А потом только передает программатору новую прошивку. Тогда при новых компиляциях программы загрузчика

можно сразу туда включать эту таблицу.

 

5. В клиентских программах, также как и в программаторе, выставляем фьюзы на запрет чтения и записи

и внутри программы периодически их проверяем!

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

их контролировать - можно попытаться стереть саму себя в случае обнаружения попытки взлома.

 

ДЫРА: Если сбить

фьюзы и сразу войти в режим программирования (подтянут ресет), т.е. не дать проге запуститься - то она не

успеет сама себя удалить и может быть считана!

 

НЕ РЕШЕНА! Остается надеяться, что в последних версиях контроллеров фьюзы нормально переносят фокусы

с питанием, а также надежно спрятаны от лазеров/ножыков во внутренних слоях кристалла.

 

ДЫРА: 6. Можно прошивать одновременно несколько контроллеров, включив их параллельно!

 

РЕШЕНИЕ: Можно перед прошивкой проверять серийный номер контроллера (а у AVR он есть?) Бутлодеры, у которых

серийник не совпал - просто перестанут принимать данные. Если серийника нет - по тихому загружать его в составе

бутлодера, каждый раз инкрементируя. Опять-же надо контролировать чтобы не шили параллельно несколько кристаллов.

 

:1111493779: Какие еще тут есть дыры (уязвимости, а не технологические отверстия) и способы их решения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:1111493779: Какие еще тут есть дыры (уязвимости, а не технологические отверстия) и способы их решения?

Почитайте теорию криптографии, хотя бы обзорно.

Представьте себе: банкоматы связаны с банками по открытым каналам, с карточки информацию тоже снять ноупроблем.

Казалось бы, любой дурак может обчистить банкомат...

 

В качестве ключа для сеанса связи можно использовать какой-нибудь случайный параметр (например, время заряда до порога компаратора какого-нибудь неприметного конденсатора на плате)

 

Ну или почитайте про системы с открытыми ключами

 

В большинстве реализаций криптография с открытыми ключами используется для засекречивания и распространения сеансовых ключей, которые используются симметричными алгоритмами для закрытия потока сообщений. Иногда такие реализации называются смешанными (гибридными) криптосистемами:

 

1. Боб посылает Алисе свой открытый ключ

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

EB(K).

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

DB(EB(K))=K.

4. Оба участника шифруют свои сообщения с помощью одного сеансового ключа.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь Боб - это программатор, Алиса - ваш девайс с прошитым загрузчиком и случайно сгенерированным сеансовым ключом.
Спасибо. На примере стало понятно. Тоесть для решения проблемы №2 с голым бутлодером используем ассиметричный алгоритм для получения сеансового ключа, а потом этот ключ используем в симметричном AES. Тогда программатор должен будет каждый раз перепаковывать бинарник с новым ключем перед передачей. Ну ладно. Надо будет посмотреть сколько это у него времени займет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

их контролировать - можно попытаться стереть саму себя в случае обнаружения попытки взлома.

Лично Вы это можете сделать? Нет? Так откуда уверенность, что уровень спеца который это сможет сделать будет ниже Вашего? А если так, то как думаете - кто меньше потребует ;) ?

По предоплате заказчик работать отказывается, предлагает проценты от продаж железа.

Изюминка в том, что доход зависит не только от Вашей работы, но и от его умения продавать. Причем некоторые товары еще и сезонные - начаться продажи через год с момента старта...

ЗЫ. Я бы посоветовал все-же оговорить с заказчиком как минимум гонорар за завершение проекта. Синица в руках все-же лучше журавля в небе...

 

В качестве ключа для сеанса связи можно использовать какой-нибудь случайный параметр (например, время заряда до порога компаратора какого-нибудь неприметного конденсатора на плате)

Результат биений двух таймеров с разными источниками тактирования. Например таймер от основного RC плюс прерывание от WDT...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Результат биений двух таймеров с разными источниками тактирования. Например таймер от основного RC плюс прерывание от WDT...
И от блин температуры будет блин зависеть блин непонятно как. У основного RC и у WDT-шного могут быть разные знаки температурного коэффициента, могут буть одинаковые, у каких-то при определённх напряжениях пиатния у WDT вообще немонотонная характеристика частот от температуры. В любом случае с температурой это дело плыть будет атмел знает как.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И от блин температуры будет блин зависеть блин непонятно как.

Дык для генератора случайных чисел это хорошо. Чем больше "непонятно как" - тем лучше генератор... В простейшем виде это 8 битный таймер который крутится(многократно) до срабатывания прерывания WDT или програмный счетчик инкрементирующий ячейку памяти до сброса по WDT(если не хочется использовать прерывание вачдога).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну если нужно порсто случайное число, то да.

Мне показалось, что нужно число случайное от кристалла к кристаллу, но постоянное у каждого конкретного кристалла — чтобы сделать привязку. Спутал с какой-то параллельной темой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Лично Вы это можете сделать? Нет? Так откуда уверенность, что уровень спеца который это сможет сделать будет ниже Вашего? А если так, то как думаете - кто меньше потребует ;) ?
В сети есть несколько сообщений о том что достаточно на короткое время сделать переполюсовку и фьюзы слетают. Для этого спецом достаточно быть ващще никаким. Ну а с подрезкой фузов лазером или напильником - это конечно редкостное извращение. ))) Это меня не беспокоит.

 

Я бы посоветовал все-же оговорить с заказчиком как минимум гонорар за завершение проекта. Синица в руках все-же лучше журавля в небе...

 

Результат биений двух таймеров с разными источниками тактирования. Например таймер от основного RC плюс прерывание от WDT...

Спасибо! Все советы полезные!

 

Мне показалось, что нужно число случайное от кристалла к кристаллу, но постоянное у каждого конкретного кристалла — чтобы сделать привязку. Спутал с какой-то параллельной темой.
Не спутали! Серийник AVR-кам тоже бы очень пригодился! Но поскольку его нет, я думаю придется самому генерить его и прошивать вместе с бутлодером.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. На примере стало понятно. Тоесть для решения проблемы №2 с голым бутлодером используем ассиметричный алгоритм для получения сеансового ключа, а потом этот ключ используем в симметричном AES. Тогда программатор должен будет каждый раз перепаковывать бинарник с новым ключем перед передачей. Ну ладно. Надо будет посмотреть сколько это у него времени займет.

Не совсем так.

Сначала прошиваете в голый кристалл открытый бутлодер по открытому каналу.

Затем указанным алгоритмом прошиваете закрытый бутлодер с ключом AES, а уж потом спокойно заливаете/обновляете основную программу, как обычно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...