Можно ли стереть otp память

Обновлено: 03.07.2024

Мероприятия:

Глава 8. Программирование OTP чипов

Устройство для записи однократно-программируемых чипов (OTP) фирмы Holtek было специально спроектировано для поддержки линейки OTP МК, позволяя пользователю легко и эффективно программировать такие микропроцессоры. Отличительными особенностями устройства записи являются его малый размер, простота установки и лёгкость использования его функций. Устройство для записи OTP МК встроено во все эмуляторы HT-ICE последней версии, делая их более удобными для разработчика при отладке программы.

Так как устройство записи OTP МК включено в состав HT-ICE, после завершения установки HT-ICE, функции прожига OTP МК готовы к использованию совместно с программой HT-IDE3000 без необходимости установки дополнительного ПО. См. Главу 1 Обзор и установка.

В составе эмулятора HT-ICE поставляется 40-выводная карта адаптера TEXTOOL. Если корпус МК не соответствует карте адаптера, пользователю следует сменить карту адаптера. Дополнительная информация по выбору карт адаптера содержится в технической документации, а также на сайте фирмы Holtek.

Ручное программирование OTP чипов при помощи HT-HandyWriter

  • Option - проверка опций МК
  • Опции (Option)

С помощью этой команды можно распечатать опции, прочитанные из файла либо из самого OTP МК.

    Функции программирования программы HT-HandyWriter

С помощью этой команды можно открыть файл с расширением .OTP, содержимое которого будет загружено в ОЗУ ПК. Эти данные будут использованы при прошивке соответствующего OTP МК. После нажатия кнопки Открыть (Open), появится диалоговое окно, в котором следует выбрать требуемый файл в соответствующей папке. Содержимое открытого файла будет отображено в окне, а контрольная сумма - под кнопкой "Read".

Эта инструкция выполняет два действия. Первое - запись данных из ОЗУ ПК в OTP МК, второе - верификация записанных в OTP МК данных на соответствие тем, которые хранятся в ОЗУ компьютера. Результат проверки выводится на экран в окне программы HT-HandyWriter.

По этой команде читается содержимое OTP МК и сравнивается с данными, содержащимися в ОЗУ компьютера. Результат сравнения выводится на экран в окне программы HT-HandyWriter.

Проверка на отсутствие записанных данных в памяти OTP МК. Результат проверки выводится на экран в окне программы HT-HandyWriter. Если устройство не стёрто, часть памяти, содержащая данные, будет отображена в окне.

Эта команда осуществляет установку защиты на OTP МК, чтение его содержимого в дальнейшем будет невозможно. Эта инструкция используется для защиты содержимого OTP МК после его программирования.

При нажатии этой кнопки будут последовательно выполнены три команды - Проверка на чистоту (Blank Check), Программировать (Program) и Верификация (Verify). Если любая из инструкций вызвала ошибку, дальнейшее выполнение прекращается. Также можно добавить в список выполняемых действий установку защиты. Это следует сделать до нажатия кнопки Авто.

Эта команда осуществляет чтение OTP МК и сохраняет прочитанные данные в оперативной памяти компьютера. Также при этом будет отображена контрольная сумма снизу кнопки "Read". При необходимости, прочитанные данные также можно сохранить в файл с расширением .OTP.

  • Дублирование (Duplicate) - автоопределение и копирование OTP МК

Функция записи серийных номеров позволяет пользователю записывать уникальный серийный номер в каждый МК.

После того, как начальные данные и адрес заданы, следует выбрать команду [S/N]/Enable для активации записи серийных номеров. Когда данная функция активизирована, текущий серийный номер и его адрес отображаются в окне программы внизу справа. В процессе программирования первый из программируемых МК будет содержать предварительно заданные данные по заданному адресу в программной памяти (ПЗУ).

Последующие МК будут содержать серийные номера, увеличенные на единицу на каждое устройство. Для сброса последовательности серийных номеров следует повторно выбрать команду [S/N]/Setup.

    HT-HandyWriter Connect to LPT1/ HT-HandyWriter подключен к LPT1.

Устройство записи OTP МК подключено к порту LPT1.

Возникли проблемы при соединении с программатором OTP МК либо эмулятором HT-ICE.

Программатор OTP МК не поддерживает EV-чип, установленный на HT-ICE. Для корректной работы требуется замена HT-ICE.

Соединение устройства записи OTP МК успешно установлено через HT-ICE.

HT-ICE подсоединён к параллельному порту, но программатор OTP МК не подключен к HT-ICE. Также эта ошибка может возникать при использовании устаревшей версии программатора OTP МК (типа THANDYOTP-A), в этом случае система не сможет установить соединение. В последнем случае, подключайте устройство записи OTP МК непосредственно к ICE.

Идентификатор "power-on ID" в открытом файле равен ADh, идентификатор "software ID" равен 50h.

Открытый файл имеет неверный формат.

Тип OTP МК не совпадает с идентификатором в открытом файле.

Доступный для записи объём ПЗУ в OTP МК равен 400h, содержимое файла имеет размер 800h, таким образом, устройство записи OTP МК может записать в микроконтроллер только 400h данных.

Возникла ошибка при программировании либо верификации. Данные zzzzh по адресу xxxxh в OTP МК не совпадают с данными yyyyh в памяти ПК.

OTP МК не является стёртым, по адресу xxxxh в нём содержатся данные zzzzh, дальнейшее выполнение команд прекращено.

OTP МК, находящийся в устройстве записи не соответствует типу МК, обозначенному в .OTP файле, дальнейшее выполнение команд прекращено.

OTP МК, находящийся в устройстве записи, защищён, дальнейшее выполнение команд прекращено.

Перед выполнением операций Верификация (Verify) либо Программировать (Program), следует загрузить .OTP-файл с помощью инструкции Открыть (Open) программы HT-HandyWriter.


Слышим прекрасно. К сожалению, это не вносит ясности, а лишь вызывает новые вопросы о ее определении.

1. Действительно, в считанном CM2MTK фулле нашлись нестираемые (читал фулл два раза, до формата тела флештулом и после) данные из OTP, в самом его конце (98%). Однако, при чтении OTP отдельно, я дал флештулу дал стартовый адрес 0x0. Как флештул (и модем аппарата) нашли эту зону? Ее адреса не могут быть стандартизированы, ибо во флешке бОльшего размера 98% от ее объема будут находиться по другому адресу. Или Flash Tool-таки работает с OTP спецкомандами, через процесссор или eMMC контроллер, который с завода "выделил" часть ROM1 под OTP и он один знает, где именно? Это объяснило бы крайне медленные чтение и запись (напомню, 1 мегабайт за три минуты!)
2. В чем отличие участка OTP от любого другого пространства ROM1, если оно вообще есть? Эта зона как-то специально выделена на заводе-производителе памяти, или я, как и телефоны, не использующие OTP, могут спокойно стирать-писать туда что угодно? Тогда кто и когда превращает ее в ONE Time Programmable?
3. Каков ее объем в разных флешках, кто и как его устанавливает?
4. И вообще, эта OTP - часть JEDEC или "произвол" процессоров MTK, которые берут и объявляют часть памяти Read Only? Если да, то на колодке я от такой "OTP" ни бита не оставлю.

На эти вопросы ответа по-прежнему нет. Пока что я мучал аппарат по USB, что не вполне корректно: на этом процессоре в считанном фулле присутствует не только ROM1. Там есть и ROM2 c прелоадером, и пустой ROM3. Завтра подкину флеш на колодку, считаю уж точно только ROM1 и проверю, есть ли там данные из OTP и будут ли они стираться при сервисных операциях.

p.s. на практику эта неопределенность не влияет, один аппарат я уже поднял.

dervish


А вот и ответ о длинe OTP в данном аппарате.
Значения более чем 0x400000 флештулом не принимаются, см. фото. Итого OTP в этом аппарате 4 мегабайта. Не факт, что 4 мегабайта. У меня такую ошибку флэштул выдавал при несоответствии размера считываемых блоков 512 байтам. Происходило это во вкладке ReadBack, и происходило потому, что флэштул читает из флэш блоками по 512 байт (0x200) на этой вкладке, не меньше. У Вас на фото стоит размер 0x40000 1 , единичка в конце указывает на блок 1 байт. Попробуйте выставить размер 0x3FFFFF (на 1 байт в меньшую сторону), и если не считается, а выдаст ошибку, то это будет подтверждением моих слов. В этом случае, попробуйте "поиграться" с размером блоков, есть предположение, что этот размер на вкладке Parameter может быть значительно меньше, чем на вкладке ReadBack, вплоть до 4-х байт.
крайне медленные чтение и запись (напомню, 1 мегабайт за три минуты!) Объяснением этому может служить предположение, что флэштул в этом режиме читает маленькими блоками, много меньшими, чем 512 байт в обычном режиме.

Radiotrance


Изначально я и прибавлял кратные значения. Потом уменьшал разброс, чтобы найти "границу".
Единичка - просто для наглядности, длины больше 0x400000 на этом аппарате не принимаются никакие.

0x3FFFFF читается без ошибок.

dervish


Значит на вкладке Parameter минимальный размер блока для чтения - 1 байт. Это здОрово.
Потому и долго читается, думаю.

Вложения

NoName®

Z3x Team


Значит на вкладке Parameter минимальный размер блока для чтения - 1 байт. Это здОрово.
Потому и долго читается, думаю.
Из выложенного документа следует - размер OTP раздела HC_WP_GRP_SIZE*512K блоков. Ищется по мэджику OTP из выше указанных исходников.

Radiotrance


Всегда после замены флеши на алкателях с otp imei 0/0 и "сеть" будет, при условии что модем в настройках отображается

IMEI будет неверным. Сети не будет.

В аттаче скриншоты с 6037Y до прописывания OTP и после. Кроме записи OTP никаких действий с аппаратом не производилось.

Вложения

before-1.jpg

before-2.jpg

after-1.jpg

after-2.jpg

NoName®

Z3x Team


IMEI будет неверным. Сети не будет.

В аттаче скриншоты с 6037Y до прописывания OTP и после. Кроме записи OTP никаких действий с аппаратом не производилось.

Radiotrance


Итак, я изнасиловал новый Alcatel 4033D.

eMMC KMN5X000ZM-B209, OTP прописана и залочена.
Форматирую тело через FT, снимаю флеш, ставлю на колодку, читаю образ ROM1 EasyJTAG'ом.

Никаких GP-разделов, как видим, на ней нет. Таблицы софтовых разделов MBR тоже нет, она стерта. А вот OTP-область действительно есть и находится внутри ROM1 по адресам 0x0E5000000 - 0x0E57FFFFF, (8 мегабайт), см. скриншоты 1-3. Там имеются IMEI платы и туда невозможно ничего стереть/записать - Block verify fail! За пределами этого участка все пишется-читается, см. скриншот 4.


Начинаю мучения:
1. Выполняю MoviNAND Format + Reset и читаю этот блок еще раз. Данные из OTP пропали! Кроме того, теперь этот блок стал прописываться тестовым файлом без ошибок: вся OTP-область исчезла как не бывало. Стало быть, с завода ее там не было, появилась позже.

2. Ставлю eMMC обратно на плату, вливаю фулл, считанный с нее до формата, читаю OTP через флештул - и вижу что IMEI на месте. Содержимое OTP влилось из фулла, а ее адреса флештул получил из scatter:

. однако, этот 0xFFFF0200 мало того что не соответствует 0xE5000000 даже близко, так еще и находится за пределами 3728Мб, имеющихся в ROM1. Равно как и размер 0x2B00000 (43Mb) не совпадает с экспериментально найденным 8Mb. Эти адреса в скаттере явно не прямые. Кстати, OTP-область теперь не залочена и принимает файлы на запись.

3. Меняю этот адрес на 0xFFFF0100, выбираю в FT новый скаттер, пишу туда некий блок данных, читаю - совпадает. Кажись, я только что создал новую OTP-зону. "Старая" OTP при этом на месте и читается при выборе старого scatter.

4. Делаю Format Whole Flash - данные из обеих (незакрытых) OTP исчезли.

5. Повторяю пункты 3-4, но закрыв обе OTP после записи (закрывались они независимо друг от друга, то есть, после закрытия первой, вторая еще давала себя переписывать - похоже, создались две совершенно разные зоны). Теперь данные из обеих OTP остались.

6. Залил фулл, включил тело. IMEI на месте, то есть мусорные данные из "второй OTP" модемом игнорируются.

7. Проверяю эту ерунду с адресами. Снова снимаю eMMC и на колодку, посмотрим, где теперь окажутся обе OTP.
Первая - на прежнем месте и прежней длины. Вторая нашлась по адресам 0x0E7000000 - 0xE7800000 (снова 8 мегабайт). То есть, несмотря на то что я уменьшил адрес второй OTP в скаттере на 0x100, по факту она оказалась на 32 мегабайта дальше первой. Похоже, тамошний адрес еще и инвертированный, отсчитывается от конца ROM1.

8. Теперь посмотрим, не попадают ли эти зоны в какой-нибудь из логических разделов телефона. Адрес 0xE5000000 это 3664-й мегабайт, то есть самый конец ROM1, за 64 мегабайта до границы раздела. Последний раздел USERDATA по scatter имеет адрес 0x5D680000 и длину 0x88200000, то есть оканчивается на 0xE5880000. Однако, из этого числа нужно вычесть 8,5 мегабайт (0x880000) т.к. вначале идут ROM2(4Мб) + ROM3(4Мб) + RPMB(512к). 0xE5880000 - 0x880000 = 0xE500000. Получается, OTP-зоны начинаются байт-в-байт сразу за Userdata и расположены дальше, в небольшом "зазоре" между ней и границей ROM1.


Итого выяснено:
1. OTP-зона является частью стандарта JEDEC и создается/читается флештулом по спецадресам в scatter-файле прошивки. Новые eMMC такой зоны не имеют.
2 У OTP-зоны отсутствуют какие-либо сигнатуры: она начинается сразу с записанных в нее данных. До и после этих данных сплошные нули.
3. Под нее отводится самый хвост раздела ROM1; логические разделы прошивок намеренно обходят это место.
4. OTP-зона может быть определена только в scatter и не создаваться в виде отдельного логического раздела, то есть отсутствовать в MBR/EBR/GPT/PMT аппарата.
5. На одной eMMC можно создать несколько OTP-зон с независимыми состояниями. Модем аппарата ищeт нужную по вшитым в него адресам, совпадающим с адресами в scatter.
6. Закрытая OTP-зона может быть стерта форматом либо обновлением прошивки контроллера на eMMC Samsung. Недавно введенный Universal Format для флешек других производителей еще предстоит проверить.

Осталось выяснить:
1. Как адрес 0xFFFF0200 из scatter переводится в "отступить 64 мегабайта от границы ROM1"?
2. Каким образом определяется размер создаваемой OTP-зоны? Длина в scatter не соответствует фактически создаваемой, равно как и формулe HC_WP_GRP_SIZE * 512k. Пока что встречались значения 4Мб и 8Мб.
3. Как и какими средствами внутри eMMC прописываются границы OTP-зоны? Какими регистрами и где? Можно ли их сбросить?


Восстановление и уничтожение данных — две стороны одной медали. Чтобы знать, когда и как можно вернуть себе информацию, надо понимать и как она может быть уничтожена безвозвратно. А в некоторых ситуациях бывает просто необходимо: например, уничтожение корпоративной информации при утилизации оборудования, уничтожение ваших личных данных при передаче диска в пользование друзьям или продаже, а может быть вы раз и навсегда хотите удалить историю переписки с любовницей ;) Считается, что лучшие специалисты по восстановлению данных работают в спецслужбах, поэтому мы сформулировали вопрос именно таким образом: как уничтожить информацию с диска так, чтобы её не восстановили ни копы из отдела «К», ни Q из Джеймса Бонда, ни даже наши специалисты из StoreLab.

Уничтожение данных программным методом

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

Полная перезапись диска

Существует много алгоритмов для уничтожения данных через полную перезапись диска. Но все они сводятся к N-кратному форматированию и записи на него двоичных единиц, нулей и псевдослучайных чисел. Так как скорость записи на диск обычно не превышает 70 MB/s, то вооружившись калькулятором мы посчитаем, сколько нам потребуется времени?
Формула достаточно простая: Объём диска (MB) / Скорость записи * Количество циклов = Секунды;
500000 / 70 * 7 = 50000 (сек.).
Из этого мы можем сделать вывод, что диск объёмом в 500 GB будет “стираться” около 13 часов. Но стоит ли нам использовать 7 циклов перезаписи? Современные носители информации не оставляют остаточной намагниченности после перезаписи данных. Поэтому нам хватит и одного цикла. Значит времени нам понадобится не 13 часов, а всего лишь 1.5.
Операционные системы имеют инструменты для полного удаления файлов.

Вместо "c:" необходимо указать букву логического раздела.
Для Windows Vista и старше, предыдущие поколения Windows удаляют только служебную информацию.

Вместо "/dev/sda" необходимо указать адрес устройства для форматирования.

Частичная перезапись данных

Используя прямое подключение к жёсткому диску на нижнем уровне через API драйвера диска или собственный драйвер, можно быстро испортить информацию, перезаписывая промежутки данных псевдослучайными числами. Напрямую указывая адрес памяти, в который выполнять запись, мы не нуждаемся в полной перезаписи диска. Также через API драйвера диска можно получить адреса, в которых хранится информация, и перезаписывать только эту область памяти. Данный способ самый сложный в своём исполнении, но с другой стороны позволяет быстро уничтожить только конфиденциальную информацию, сохраняя работоспособность диска.
Работа с драйвером предполагает 2 стадии. Первая — это получение адреса и длину данных, обычно один файл записан в разных местах на диске, поэтому мы получим массив адресов и массив длин. Второй шаг — это запись псевдослучайных чисел в данные области памяти, запись необходимо производить также через драйвер, для того, чтобы операционная система не заблокировала или не перенаправила запись данных в другую область диска.

Уничтожение данных вместе с диском

Усложним задачу: представим, что у нас нет времени на безопасное для диска уничтожение данных. В таком случае единственное что вам может помочь — уничтожение самого диска. А если быть точным, то нужно уничтожить только блины, на которые записывается информация.

Механическое уничтожение данных



На картинке показан жёсткий диск после помещения его в устройство для давления жётских дисков (EDR Solutions) .
Раз и навсегда уничтожить данные получится, если испортить блины жёсткого диска. Сложно и зачастую невозможно восстановить данные с поцарапанных дисков, не забудьте держать рядом с собой отвёртку, ведь вам придётся снять крышку жёсткого диска и ею же можно жёсткий диск поцарапать. Естественно, данные будут стёрты в тех местах, где была проведена царапина и смежных с ней. В остальных местах данные можно будет восстановить в лаборатории. Не жалейте свои силы на царапины, лёгкие полоски не уничтожат данные даже в местах, где побывала ваша отвёртка. А если погнуть блин, как показано на картинке, то ваши данные уже точно никем никогда не будут восстановлены.

Но уронить диск на пол будет недостаточно. Да, он не определится компьютером, но данные успешно восстановят в лаборатории. HDD диск не переживёт падения со стола, причём в выключенном состоянии высота безопасного падения больше, чем во время работы диска. SSD были разработаны с расчётом на такой случай, даже падение из окна первого-второго этажа не убьёт диск. Это достигается за счёт того, что в SSD нет подвижных элементов, все действия выполняет контроллер. Информация по прежнему может быть прочитана программным или непрограммным способом.

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

Физически


«То, что не убивает нас, делает нас сильнее.» Логично будет предположить и обратное: то, что не делает нас сильнее, убивает нас. Из предыдущей статьи вы могли узнать, что охлаждение диска отрицательно влияет на его работу. Но можно ли его так убить? Положив в морозильную камеру ваш носитель важной информации, вы его не убиваете. В ваших руках “бомба” замедленного действия — диск будет работать и с него можно будет прочитать информацию программным способом. Когда же диск сломается, то все данные без особого труда восстанавливаются в “чистой комнате”.
А что диски думают о нагревании? Среди всех устройств диска нас интересуют только блины. Материал, которым покрыт блин, способен размагничиваться при температуре 450 °C. При нагревании магнитный слой должен окисляться и становиться зелёного цвета. Ещё один негативный для диска, но положительный для нас результат даёт температура более 660 °C.
При такой температуре начинает плавиться алюминий — основа блина жёсткого диска. Температуру в 750 °C в домашних условиях можно получить от пламени свечи или горящей спички. Для достижения максимальной температуры необходимо пламя подставить самым краем к блину.
Также размагнитить диск можно с помощью электромагнита, воздействуя на блин переменным магнитным полем с увеличением расстояния от магнита до диска. Для таких целей было разработано специальное оборудование «Устройства уничтожения информации». Воздействуя импульсами на жёсткие диски, они полностью размагничивают диск, что приводит к невозможности восстановить какие-либо данные на нём. Данные устройства уничтожают всё за 2-3 секунды.

Химически

Как вы уже, наверное, поняли, чтобы уничтожить данные — нужно уничтожить магнитный слой блина жёсткого диска. На диск достаточно вылить любой жидкости, которая способна изменять свойства ферромагнетиков. Чтобы изменить строение оксида хрома (ферромагнетик, которым покрывают блины жёстких дисков, — магнитный слой диска), необходимо вылить на него соляную кислоту или воду при температуре 100 °C.

В микроконтроллере 1986ВК01 реализованы три ядра: два Cortex-M4, и одно специальное - криптографический модуль (сопроцессор), построенный на базе Cortex-M0.
В материале Начало работы с криптоядром микроконтроллера «Электросила» подробно рассказано о том, как начать работать с криптоядром и загрузить в него программу для запуска из внутренней памяти, через отладочный интерфейс SWD.
В данной статье рассмотрим, как загружать в криптоядро программу для исполнения с помощью основного ядра M4, то есть именно так, как в «Release» версии программы для микроконтроллера.

СТРУКТУРА ВЗАИМОДЕЙСТВИЯ. ШЛЮЗ

На рисунке 1 приведена общая схема микроконтроллера, которая показывает, что всё взаимодействие между ядрами M4 и защищенным M0 осуществляется через шлюз обмена данных.


Рисунок 1 – Структурная схема микроконтроллера 1986ВК01

Стоит отметить, что на данной схеме не отражены отладочные интерфейсы. Как отмечено было ранее, в защищенном криптомодуле реализован отладочный интерфейс SWD. Он доступен на следующих портах ввода – вывода:

Но в «Release» варианте программы пользоваться отладчиком возможности нет, поэтому в первую очередь рассмотрим взаимодействие через шлюз. Шлюз представляет собой:

16 входных/выходных регистров (8 входных и 8 выходных. Следовательно, входной с одной стороны является выходным с другой),

2 FIFO данных: от открытого ядра к защищённому, и от защищённого ядра к открытому, шириной данных 32 бита и объёмом 16 слов.

Реализовано по 3 служебных регистра: для FIFO и для входных/выходных регистров. Они необходимы для контроля и настройки взаимодействия обмена данными по шлюзу. Подробная карта регистров блока шлюза представлена в таблице 1.

Таблица 1 – Карта регистров блока Шлюза


Рисунок 2 – Общий алгоритм загрузки программы для криптоядра с помощью шлюза

Подготовить программу для работы сопроцессора M0.

Конвертировать программу в массив данных.

К этому массиву необходимо добавить Hash и наложить гамму.

Рассчитывать хэш-функцию загрузчика пользовательского ПО необходимо по алгоритму RIPEMD-160.

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

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

Предварительно систему криптомодуля необходимо проинициализировать, а именно, записать серийный номер, записать гамму для расшифровки получаемой программы. Этот процесс осуществляется с помощью UART – загрузчика, выведенного на выводы:
PD[2] / UARTTX
PD[3] / UARTRX

СТАРТ И ИНИЦИАЛИЗАЦИЯ КРИТПОЯДРА

После разрешения тактирования со стороны M4, ядро M0 запускает внутреннюю бутовую программу. Как уже было отмечено, для взаимодействия с микроконтроллером в загрузочной программе ядра M0 используется модуль UART. Поэтому для анализа данных, получаемых от микроконтроллера, можно воспользоваться любой терминальной программой.


Необходимо запустить программу в M4, чтобы она разрешила тактирование криптоядра. При этом в качестве источника тактирования лучше использовать генератор HSE для обеспечения стабильной работы UART, поскольку подстройки скорости во внутреннем boot не реализовано, а генератор HSI неточный (f_HSI=6-10МГц) - его частота может варьироваться от образца к образцу.

После старта загрузочная программа ядра Cortex-M0 начинает выполнять чтение статуса из OTP памяти по определенному адресу (0x1010C0000) и анализирует его:

    если статус = 0x0, загрузчик приступает к процедуре преинициализации OTP;

если статус = 0x0000A55A, загрузчик приступает к процедуре инициализации OTP;

если статус = 0x75A9A55A, загрузчик понимает, что OTP инициализирована и приступает к процедуре обработки данных, полученных через шлюз от ядра M4.

Таким образом, есть 3 фазы работы встроенного загрузчика:

1. Фаза преинициализации - запись в одноразово-записываемую память (OTP) уникального серийного номера. Серийный номер имеет длину 8 байт. Запись серийного номера строго однократна. После завершения записи фаза жизненного цикла изменяется и этот функционал более никогда не будет доступен. Записанный серийный номер защищается контрольной суммой CRC32, ошибка контрольной суммы серийного номера при дальнейшей работе трактуется как угроза безопасности и приводит к блокированию дальнейшей работы защищённого ядра.

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

3. Фаза работы - загрузчика защищённого ядра обеспечивает загрузку прошивки ядра из памяти незащищённой части через шлюз.

Выполняется проверка целостности серийного номера и его отправка в незащищённое ядро.

Выполняется проверка целостности серийного номера и гаммы, после чего серийный номер отправляется через шлюз в незащищённое ядро.

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

Загрузчик защищённого ядра проверяет целостность зашифрованной прошивки, сравнивая её CRC32. Если проверка выполнена успешна, то происходит расшифровывание прошивки в оперативной памяти путём её сложения с гаммой по модулю 2.

Целостность расшифрованной прошивки определяется путём расчёта и сравнения с расшифрованным значения хэш-функции RIPEMD-160.

Если целостность прошивки подтверждена, выставляется флаг готовности и управление передаётся расшифрованной прошивке в оперативной памяти

Рассмотрим каждую процедуру по отдельности.

Преинициализация

По сути, данная процедура запускается всегда, когда OTP-память пустая. Первым этапом происходит настройка UART:

UART настраивается на скорость 9600 бод при условии, что частота тактирования микроконтроллера 8 МГц.


Рисунок 3 – Окно терминала, получение статуса готовности преинициализации

Ниже приведены все расшифровки статусов загрузчика:

// Base CM0 UART/GATE statuses

Затем ядро M0 ожидает приём по UART 8 байт серийного номера и 4 байта контрольной суммы CRC данного номера. После получения этих данных МК самостоятельно рассчитывает CRC от полученного серийного номера и сравнивает со значением, полученными по UART. В случае если значения не сошлись, то загрузчик возвращает статус CM0_PREINIT_FAIL. На рисунке 4 показан пример ввода серийного номера SN и некорректно рассчитанной к нему контрольной суммы CRC, в результате чего получен ожидаемый статус о неудачной процедуре преинициализации.


Рисунок 4 – Загрузчик вернул статус неудачной преинициализации

После возвращения статуса PREINIT_FAIL микроконтроллер зависает в бесконечном цикле, повторно дублируя данный статус в шлюз к ядру M4 через 15 регистр. Требуется выполнить сброс, чтобы повторно провести процедуру преинициализации с корректно рассчитанной контрольной суммой. При отправке корректной контрольной суммы микроконтроллер выдаст статус PREINIT_DONE – рисунок 5.


Рисунок 5 – Получение статуса об успешной преинициализации

После выдачи статуса об успешной процедуре преинициализации микроконтроллер записывает во внутреннюю OTP-память статус 0x0000A55A, и CRC, рассчитанное от статуса и серийного номера, после чего вновь зависает. Важно отметить, что в результате успешной или неуспешной процедуры преинициализации микроконтроллер безальтернативно зависает. Разница состоит в том, что, когда процедура выполняется успешно, происходит запись статуса в OTP-память, который анализируется при старте загрузчика. То есть наличие данных 0x0000A55A в статусе позволяет перейти к процедуре инициализации.

Инициализация

После сброса процессор, прочитав измененный статус во внутренней OTP-памяти, приступил к процедуре инициализации, сообщив об этом по UART, выдавая статус INIT_READY – рисунок 6. Дополнительно в 8 и 9 регистры шлюза загрузчик отправил серийный номер, записанный в его OTP-памяти во время преинициализации.



Рисунок 7 - Выдача серийного номера, в случае получения статуса GAMMA_READY


После успешной выдачи серийного номера микроконтроллер ожидает принять гамму размером 16364 байта. Это обязательное условие загрузчика. В рассматриваемом случае, к примеру, в качестве гаммы было выбрано число 42.


Рисунок 9 - Отправка гаммы

После принятия гаммы загрузчик микроконтроллера ожидает получить контрольную сумму CRC для переданной гаммы, после чего её проверяет. Если контрольная сумма не сошлась, в ответ загрузчик вернет статус INIT_FAIL – рисунок 10.


Рисунок 10 - Некорректный ввод CRC для гаммы

В случае передачи корректной CRC микроконтроллер приступает к прошивке гаммы во внутреннюю OTP-память, затем изменяет и переписывает в памяти OTP основной статус, который опрашивается при старте процессора на OTP_INIT 0x75A9A55A. После чего рассчитывает новое значение CRC от статуса, серийного номера и гамма, и выдает в UART статус INIT_DONE, что свидетельствует об окончании процесса инициализации – рисунок 11. И, как было отмечено ранее, микроконтроллер опять зависнет даже в случае успешной инициализации и вновь потребует сброса.


Рисунок 11 - Завершение процесса инициализации

После окончания процесса инициализации при последующем сбросе, загрузчик прочитает статус из своей памяти OTP_INIT 0x75A9A55A, что говорит о том, что он готов принимать зашифрованную по прописанной гамме программу, для последующей расшифровки и записи.

Если подключиться с помощью отладчика к ядру M0, то можно посмотреть, как выглядят записанные данные в OTP-памяти – рисунок 12.


ЗАПУСК ПРОГРАММЫ НА КРИПТОЯДРЕ

Закончив этап подготовки, взаимодействуя с защищенной системой с помощью uart – загрузчика, была прошита OTP-память. Криптоядро подготовлено к работе. Теперь каждый раз при старте, как уже отмечалось чуть выше, ядро M0 будет анализировать записанные в его память данные, после чего в регистр 15 шлюза выставит статус WORK_READY. Затем ядро может начать загружать прошивку через шлюз, куда её передает ведущее ядро M4.

Подготовка

Алгоритм взаимодействия между ядрами с помощью шлюза приведен выше на рисунке 2. В рамках демонстрации рассмотрим его на конкретном примере: будем накладывать гамму и HASH на прошивку для ядра M0 внутри программы для M4. Это отображено на измененной схеме алгоритма на рисунке 13.


Рисунок 13 - Алгоритм, реализованный на примере в приложении

Запуск

К данной статье приложено два проекта:

1) Loader – проект с программой для ведущего ядра Cortex-M4, в котором разрешается тактирование криптоядра, а затем шифруется по гамма и передается через шлюз программа для исполнения ядром Cortex-M0;

2) CryptoHello – программа для исполнения ядром Cortex-M0.

Во втором проекте (CryptoHello) конфигурируется модуль UART и отправляется приветствие. Затем включается блок генератора случайных чисел, который генерирует число и отправляет его всё по тому же UART, а также дублирует его в 14 регистр шлюза.

После того как программа для Cortex-M0 была написана, необходимо сгенерировать файл ramCode.h. В приложенном проекте после процесса компиляции выставлена опция запуска файла формата *.bat для генерации файла ramCode.h (рисунок 14).


Рисунок 14 - Выставление настройки для генерации массива после процесса компиляции

То есть программа для исполнения ядром M0 была конвертирована в массив данных. Полученный файл ramCode.h необходимо добавить в проект для ядра Cortex-M4.

Теперь можно перейти к запуску первого проекта (Loader). Стоит вновь обратить внимание на разрешение тактирования криптоядра:

Затем в проекте происходит наложение HASH и Gamma на массив чисел из файла ramCode.h, который был добавлен в проект. После чего в основном цикле программы проверяется 15-ый регистр шлюза, куда криптоядро, как отмечено ранее, должно выставить статус WORK_READY.


Рисунок 15 - Выставление статуса WORK_READY (REG15) и ключа (REG08 и REG09) в шлюз

Теперь ядро M0 готово принимать защищенную по гамма прошивку. Анализируя готовность, ядром M4 отправляется через шлюз подготовленный заранее код.

Время до готовности M0 запускать программу составляет порядка 3

4 сек на частоте 8 МГц. Данное время тратится на отработку загрузчика.


С помощью выводов UART криптоядра наблюдаем работу программы – рисунок 16.


Рисунок 16 - Демонстрация работы программы критпоядра

Приложение 1. Алгоритм расчёта CRC

Для расчёта CRC для ключа и гамма использовался алгоритм CRC32. Функция расчёта приведена ниже, а также приложена во вложении к материалу.
crc = 0;
crc = crc32(crc, (uint8_t*)sn, 8); //sn - serial nember


uint32_t crc32(uint32_t ctx, const uint8_t* buf, uint32_t sz)
ctx = ctx ^ 0xFFFFFFFF;

while (sz--)
ctx = crc32_tab[(ctx ^ *(buf++)) & 0xFF] ^ (ctx >> 8);
>

return ctx ^ 0xFFFFFFFF;
>

Приложение 2. Блокировка отладочного интерфейса криптоядра

OtpData* const gOtpMem = (OtpData*)OTP_MEM;

typedef struct
OtpUserData UData; /*< User space */
OtpServiceData SData; /*< Service space */
uint32_t Gamma[SZ_GAMMA]; /*< Gamma arrea */
> OtpData;

typedef struct
uint32_t Special; /*< Special word */
uint32_t NotUsed[255]; /*< Testing arrea */
uint32_t User[12032]; /*< User space */
> OtpUserData;

По данному адресу записывается SecurityWord = (0xFFFFFF<<8)|(0xFF<<0). То есть в исполняемой (конечной) программе для ядра M0 можно предусмотреть алгоритм проверки. Сама проверка заключается в чтении защитного слова. В случае если оно не записано, то происходит его запись и, соответственно, блокировка интерфейса SWD.

Если защищенное слово записано в OTP-памяти, блокировка отладочного интерфейса SWD происходит сразу при подаче питания, что реализует 100% защиту.

Следовательно, после отработки основного алгоритма исполняемой программы в лабораторных условиях необходимо запустить алгоритм записи SecurityWord, что приведет к блокировке отладочного интерфейса защищенной подсистемы. В следующих циклах запуска работы системы при успешном чтение SecurityWord дополнительное обращение к OTP-памяти происходить не будет. Ниже приведён пример алгоритма блокировки интерфейса, который может быть встроен в программу для ядра M0 (проект CryptoHello). В конечное решение о том, как организовать блокировку отладочного интерфейса защищенной подсистемы, разработчик изделия принимает самостоятельно.

if ( readOtpWord == SecurityWord)
uartWrite ("\r\n JTAG is already blocked! \r\n", 30);
else
otpWrite(&gOtpMem->UData.Special, &SecurityWord, 1);
uartWrite ("\r\n JTAG blocked! \r\n", 15);
>
.
>

Временная блокировка SWD-интерфейса криптоядра

Выводы CRPT_SWD совмещены с выводами PC[31:30], при этом после подачи тактирования на защищённую подсистему в регистре CRPT_CLK_CTRL (асинхронный тип регистра), выводы PC[31:30] полностью переходят под управление интерфейса SWD (Cortex-M0) и не могут управляться контроллером портов ввода-вывода и другими периферийными блоками из открытой подсистемы. На время отладки ПО, помимо блокировки SWD через OTP, есть возможность отключить в защищенной подсистеме интерфейс SWD, чтобы выводы PC[31:30] снова стали доступны для управления из открытой подсистемы. Для этого в ПО для Cortex-M0 необходимо сбросить бит 7 (DEBUG_EN) регистра SYS->CTRL:

(1<<7);
После сброса бита DEBUG_EN выводы PC[31:30] снова перейдут под управление открытой подсистемы (Cortex-M4F). Чтобы снова включить интерфейс SWD ядра Cortex-M0 необходимо выполнить сброс МК, программным способом установить бит DEBUG_EN для включения SWD нельзя.

Читайте также: