Звоночки розетки
Мне отдали розетку sbdv-00123 для экосистемы сбера «Салют». Она работает по Wi-Fi и управляется через сберовское приложение.
Мне не нравится когда для работы устройств умного дома требуется интернет, так что я захотел прошить её и добавить в Home Assistant. Розетки Xiaomi я уже прошивал, поэтому наивно решил что это приключение на 20 минут.
Спойлер: нет.

Разбирается розетка довольно легко: во внутренней части корпуса спрятан винт под треугольник. Плата внутри никак не закреплена: достаточно выкрутить винт и вытолкнуть внутренности из корпуса, уперев вилку в твёрдую поверхность.
Главная опасность — Wi-Fi антенна. Это тонкий кусок медной фольги на скотче. Перед извлечением платы её лучше отклеить, иначе вместо прошивки розетки придётся паять антенну.

На плате стоит Beken BK7231N — чип, который часто встречается в устройствах Tuya. За измерение энергопотребления отвечает BL0942. Оба поддерживаются ESPHome.
На этом этапе всё по-прежнему выглядело подозрительно просто.

Припаялся к тест-поинтам, подключил PL2303 и снял дамп с помощью bk7231tools.
☝️ Всегда снимайте дамп перед прошивкой. Если программная часть пойдёт не по плану, у вас хотя бы останется путь к отступлению.

Первый звоночек
Анализ дампа с помощью dissect_dump не нашёл контейнеров Tuya. То есть прошивка собрана не на Tuya SDK. Само по себе это ещё не проблема, но именно здесь двадцатиминутное приключение впервые начало подозрительно посматривать на часы.
Я снял карту энтропии скриптом и в разделе конфигурации нашёл распиновку:
| Функция | Пин | Уровень |
|---|---|---|
| Реле | P26 | active-high (rl1_lv:1) |
| Кнопка | P9 | active-low (bt1_lv:0) |
| Светодиод | P6 | active-low (netled1_lv:0) |
| Счётчик мощности | BL0942 (по UART) | — |
По железу всё выглядело вполне обычно. Можно было прошивать.
Второй звоночек
Залил OpenBeken 1.18.298 в раздел приложения по адресу 0×11000. Прошивка записалась без ошибок. Розетка не включилась. UART молчит, точки доступа Wi-Fi нет.
ltchiptool flash info показал нестандартный загрузчик. Следующая гипотеза: возможно, OpenBeken не стартует из-за него. Поэтому я прошил уже комплектом — приложение вместе с загрузчиком.
Снова OK!. Снова тишина.
Третий звоночек
К этому моменту появилась другая гипотеза: Сбер мог использовать собственный ключ шифрования прошивки. С учётом их чрезмерной любви к безопасности вариант выглядел вполне правдоподобно.
Я взял стандартный ключ Beken и попробовал расшифровать им стоковую прошивку и OpenBeken. У OpenBeken после расшифровки получились нормальные ARM-векторы. У стоковой прошивки — какой-то мусор.
Получалось, что аппаратный движок дешифрования действительно настроен на другой ключ. ltchiptool flash info при этом возвращал нули в Encryption Key, то есть eFuse, похоже, защищены от чтения.
На этом месте нормальный человек обычно приходит к выводу, что розетка не стоит затраченных усилий. Но нормальный человек не стал бы уже столько времени прошивать розетку.
В загрузчике и прошивке OpenBeken я заметил семь вхождений слова e59ff014. Значит, появилась точка опоры: известные открытые данные, по которым можно проверять результат дешифрования. Я написал скрипт, который перебирает режимы и решает линейную систему для коэффициентов, а заодно восстановил схему CRC.
Восстановленный ключ: coef0=0x54a00e3c, coef1=0, coef2=0, coef3=0x10001803.
CRC: 32 байта данных + 2 байта crc16(block, init=0xFFFF) big-endian.
Казалось, что защита наконец-то разобрана.
Казалось.
Четвёртый звоночек
Дальше дело остаётся за малым: взять OpenBeken, снять CRC, расшифровать стандартным ключом, зашифровать ключом Сбера, вернуть CRC и прошить результат. Скриптую, прошиваю и… UART снова молчит.
Розетка явно пытается мне что-то сказать.
Финальный звоночек
От отчаяния я решил пройтись по строкам стоковой прошивки и поискать, что ещё вообще может мешать запуску. В бутлодере нашлось вот это:
- rt_ota_custom_verify
- part_fw_hash_verify
- Custom verify RAW firmware failed!
- OTA upgrade failed! Need to recovery factory firmware
А следом обнаружились строки:
- rsaEncryption
- sha256WithRSAEncryption
- ecdsa-with-SHA256
- id-kp-codeSigning
И тут всё наконец сложилось.
Получается, в розетке используется verified boot сразу на нескольких уровнях. Бутлодер проверяет подпись приложения. А поскольку даже корректно зашифрованный сторонний бутлодер не стартует, вероятно ROM дополнительно проверяет подпись бутлодера — то есть secure boot включён на уровне чипа.
Если это так, без приватного ключа дальше ловить нечего.
Моё уважение ребятам из сбера. Это пока самое защищённое от внешнего вмешательства устройство умного дома, которое мне попадалось. Пользоваться им через интернет я, конечно же, всё равно не буду и куплю Zigbee-розетку.
Скрипты и дампы выложил на GitHub.