- PVSM.RU - https://www.pvsm.ru -
В февралe 2020 года на Хабре появилась увлекательная статья [1] про преобразованию программатора ST-Link v2 в аппаратный ключ шифрования. Уже тогда в комментариях появились жалобы на то, что результат не удаётся повторить, но они остались без ответа.
За прошедшее время до меня дошла пара посылок с Aliexpress и теперь, самостоятельно пройдя весь путь, я попытаюсь представить более или менее полную инструкцию с комментариями, которая поможет неспециалисту перепрошить микропроцессор в китайском клоне ST-Link v2. Постараюсь не повторять уже известное, поэтому про пайку контактов и использование GPG с аппаратным ключом смотрите в исходной статье.
Первое, на что нужно обратить внимание ещё до покупки, — это комментарии к товару на Aliexpress. Скорее всего, кто-нибудь уже написал про марку микропроцессора из серии STM32***, который установлен в изделие у данного конкретного продавца. Впрочем, мой опыт показал, что комментарии не помогают, и даже у одного продавца могут попадаться программаторы с разной начинкой.
Главное отличие микропроцессоров с нашей точки зрения — это объём флэш памяти размещённой на кристалле. На одном из форумов попадалось мнение, что китайцы могут выпустить программатор на дешёвом процессоре без аппаратной поддержки USB и эмулировать USB программно, дёргая одну из ножек процессора, но это, маловероятно, поскольку требует существенной доработки исходного кода программатора.
Оригинальный ST-Link v2 от фирмы STMicroelectronics базировался на чипе STM32F103 той же фирмы, имеющего 128 Кбайт флэш памяти.
В первой посылке мне пришёл программатор на китайском клоне STM32F103 — CKS32F103C8*. В интернете не очень много информации по этому чипу. Его обзывают то CS32F то CKS32F. Даже даташит на китайском куда-то пропал, так что сообщаю, что на моём чипе всего 64 Kбайт флэш памяти. Вроде бы, процессоры CKS32F103CB* имеют 128 Kбайт флэша, но это только слухи из интернета.
Во второй посылке оказались изделия на основе STM32GC102CB. Что это такое, похоже, не знает ни кто [2], но в нём опять 64 Kбайт флэш памяти (и, к счастью, есть аппаратный USB).
Фокус в том, что прошивка программатора в минимальной конфигурации укладывается в эти 64 Кбайт и китайцы явно пытаются сэкономить копеечку. Про обновление прошивки ST-Link v2 в качестве программатора можно почитать в статье на хабре [3].
Проще всего собрать комплект ПО под каким-нибудь Linux, основанном на Debian. В моём случае это был antiX Linux и репозитории Debian 9 Stretch.
make и git у меня были, так что мне хватило установки специфических пакетов:
sudo apt install gcc-arm-none-eabi
sudo apt install libnewlib-arm-none-eabi
sudo apt install openocd
Плюс к этому, установилась несколько зависимостей.
Почему-то мне не удалось найти пакеты c Arm Embedded Toolchain в стандартных репозиториях CentOS. Может искал не по тем ключевым словам.
Под Windows всё придётся настраивать самостоятельно:
Сам так и не попробовал, но вдруг кому пригодится.
Ещё раз напоминаю, что для дальнейших шагов вам потребуется подпаять проводки от программатора на целевую плату, взятую из другого программатора. Смотрим оригинальную статью [1].
Хочу обратить внимание на то, что у разных программаторов разная разводка контактов. Получив вторую посылку я почти убедил себя, что пришли бракованные программаторы, просто потому, что переткнул пучок проводов из одного программатора в другой, не меняя их раскладку. В интернете попадаются жалобы, что на плате идёт одна маркировка выводов, а на корпусе нарисована другая. Маркировка на плате более достоверна.
Будем считать, что нашим основным инструментом управления программатором является OpenOCD.
Для начала нам необходимо разблокировать доступ к флэш памяти на целевой плате, поскольку изначально он закрыт и на запись и на чтение (для сохранения в тайне содержимого текущей прошивки).
Ситуация 1: целевая плата с микросхемой ST32F1**
$ openocd -f interface/stlink-v2.cfg -f target/st32f1x.cfg -c 'init; reset halt; stm32f1x unlock 0; reset halt;exit'
...
Info : device id = 0x20036410
Info : flash size = 64kbytes
stm32x unlocked.
INFO: a reset or power cycle is required for the new settings to take effect.
Ситуация 2: целевая плата с микросхемой CKS32F1**
$ openocd -f interface/stlink-v2.cfg -f target/st32f1x.cfg -c 'init; reset halt; stm32f1x unlock 0; reset halt;exit'
...
Info : STLINK v2 JTAG v29 API v2 SWIM v7 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.174295
Warn : UNEXPECTED idcode: 0x2ba01477
Error: expected 1 of 1: 0x1ba01477
Файлы interface/stlink-v2.cfg и target/st32f1x.cfg — это скрипты на языке OpenOCD, настраивающие параметры программатора и целевой платы. Разработчики китайского клона назначили ID своего процессора 0x2ba01477, а у STM321F1*** было 0x1ba01477. В принципе, в стандартной поставке OpenOCD есть несколько конфигураций с нужным ID, но я решил, что во всём остальном клон должен быть похож именно на STM321F1**, и просто скопировал файл конфигурации к себе и поправил ID в команде set _CPUTAPID 0x1ba01477.
mkdir ~/.openocd/{target}
cp /usr/share/openocd/scripts/target/stm32f1x.cfg ~/.openocd/target/cks32f1x.cfg
sed -i 's/0x1ba01477/0x2ba01477/' /.openocd/target/cks32f1x.cfg
В дальнейшем, при прошивке плат с процессором CKS32F1** я просто указываю опцию -f target/cks32f1x.cfg.
Теперь можно проверить объём памяти. Можно, например, сгенерировать случайный файл размером 128 Кбайт и попытаться записать его во флэш память. Тогда OpenOCD выдаст ошибки примерно такого вида:
Error: checksum mismatch - attempting binary compare
diff 0 address 0x08010000. Was 0x00 instead of 0x7d
diff 1 address 0x08010001. Was 0x50 instead of 0x40
Я просто попытался разблокировать второй банк памяти:
$ openocd -f interface/stlink-v2.cfg -f target/cks32f1x.cfg -c 'init; reset halt; stm32f1x unlock 1; reset halt;exit'
...
Error: flash bank 1 does not exist
...
Если моя методика неверна — пишите, перепроверю чипы другим способом.
Когда мы определились с объёмом флэш памяти на чипе, можно выбрать версию прошивки GNUK [7], которая и обеспечивает функциональность нашей платы как аппаратного ключа шифрования.
Если удариться в историю, то в 2003 году некая компания g10code [8] написала спецификации протокола для взаимодействия программы, соответствующей спецификации OpenPGP, с аппаратным ключом шифрования, реализованным по стандарту смарткарты ISO/IEC 7816. Ещё одна компания — ZeitControl
написала проприетарный код, реализующий необходимые алгоритмы, для своей Card OS (и своей смарт-карты). Нынче получившуюся игрушку для гиков можно купить в интернет магазине
FLOSS-Shop [9] под названием OpenPGP Smart Card по несколько завышенной цене в 17,90 €. Не забудьте, что кроме смарт-карты, вам потребуется купить ещё и считыватель для неё.
Несколько позже в игру вступила некоммерческая организация Free Software Initiative of Japan [10] — этакая национальная ячейка FSF. Именно они разработали прошивку GNUK для процессоров STM32*, которая эмулирует считыватель смарт-карт со вставленной в него OpenPGP Smart Card.
На настоящий момент существует две стабильные версии GNUK — 1.0 и 1.2, отличающиеся базовой ОС и набором алгоритмов шифрования. Я бы порекомендовал брать их из дебиановского репозитория [11], где они находятся в бранчах STABLE-BRANCH-1-0 и STABLE-BRANCH-1-2 соответственно.
В части шифрования обе версии базируются на библиотеке PolarSSL, а в аппаратной части версия 1.0 базируется на ChibiOS_2.0.8, а версия 1.2 на библиотеке chopstx.
Для нас важно, что версия 1.0 компилируется в исполняемый код объёмом 62 Кбайт, а версия 1.2 — в 112 Кбайт.
Итак, если у нас есть 128 Кбайт флэша, то компилируем версию 1.2
git clone https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
cd gnuk
git checkout STABLE-BRANCH-1-2
cd src
# --target определяет ножки процессора, на которые привязан светодиод и управление USB
# Значение --target по умолчанию - FST_01 - не совместимо с ST-LINK v2
# --vidpid="234b:0000" соответствует USB считывателю смарт-карт
# --enable-factory-reset - возможность программного обнуления ключа при забытом PIN
./configure --target=ST_DONGLE --vidpid="234b:0000" --enable-factory-reset
make
Если у нас есть только 64 Кбайт флэша, то мы компилируем версию 1.0
git clone https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
cd gnuk
git checkout STABLE-BRANCH-1-0
cd src
# На удивление, значение по умолчанию в этой версии - OLIMEX_STM32_H103 - совместимо с ST-LINK v2
# --enable-keygen - включает внутреннюю генерацию секретного ключа
./configure --vidpid="234b:0000" --enable-keygen
make
Я даже перенёс конфигурацию ST_DONGLE из chopstx в ChibiOS, но это оказалось лишним.
Заливаем прошивку в чип. Не забываем выбрать правильный cfg файл и помним, что в версии 1.2 образ прошивки лежит в src/build/gnuk.elf, а в версии 1.0 в src/gnuk.elf
# загружаем прошивку
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c 'program build/gnuk.elf verify reset exit'
# и запрещаем доступ к флэшу
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "stm32f1x lock 0" -c reset -c exit
Поскольку у меня все процессоры с 64 Кбайт флэш памяти я не смог проверить, надо ли применять команду stm32f1x lock 1, чтобы заблокировать доступ ко второму банку памяти.
Ну вот и всё. У меня получилось. Надеюсь, что и у вас получится.
Автор: aragont
Источник [17]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/stm32/352101
Ссылки в тексте:
[1] увлекательная статья: https://habr.com/ru/post/487748/
[2] не знает ни кто: https://www.radiokot.ru/forum/viewtopic.php?f=59&t=132053
[3] хабре: https://habr.com/ru/post/442290/
[4] GNU Arm Embedded Toolchain: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads
[5] OpenOCD: http://www.freddiechopin.info/en/download/category/4-openocd
[6] CNUWin32: http://gnuwin32.sourceforge.net/
[7] GNUK: https://wiki.debian.org/GNUK
[8] g10code: http://www.g10code.com/p-card.html
[9] FLOSS-Shop: https://www.floss-shop.de/
[10] Free Software Initiative of Japan: http://www.fsij.org/
[11] дебиановского репозитория: https://salsa.debian.org/gnuk-team/gnuk/gnuk
[12] OpenOCD: руководство пользователя: http://www.microsin.net/programming/ARM/openocd-manual-part2.html
[13] Обсуждение CS32F103C8T6: https://www.eevblog.com/forum/beginners/unexpected-idcode-flashing-bluepill-clone/msg2107822/
[14] История реверс инжиниринга клона ST-Link 2015-2018: https://github.com/blacksphere/blackmagic/issues/62
[15] Первая англоязычная инструкция по переделке ST-Link в ключ 08.02.2018: https://nx3d.org/gnuk-st-link-v2/
[16] Вторая англоязычная инструкция по переделке ST-Link в ключ 26.02.2018: https://blog.danman.eu/2-usb-crypto-token-for-use-with-gpg-and-ssh/
[17] Источник: https://habr.com/ru/post/496946/?utm_source=habrahabr&utm_medium=rss&utm_campaign=496946
Нажмите здесь для печати.