Обновить
8K+
320
Николай Шлей@CodeRush

Firmware Security Engineer

29,1
Рейтинг
692
Подписчики
Отправить сообщение
Там и у основной прошивки, и у МЕ есть области NVRAM, в которых хранятся переменные, способные меняться при каждой загрузке, так что эти отличия — это нормально вполне.
Опять у нас и safety переводят как «безопасность», и security, в итоге получается совершенно непонятно без контекста, о какой именно безопасности речь.
По теме же — все вот эти декларации о намерениях и комитеты начальников штабов — яйца не стоят выеденного без реальных продуктов, и могут закрыться так же быстро, как и собраться (вспоминается история с FlexRay, у которой в комитете тоже были звезды первой величины, и даже выпустили десяток автомобилей с ним, но потом все само по себе сошло на нет, потому что дорогущая шина оказалась мало кому нужна).
Добавлю про многозадачность еще: давно уже есть возможность использовать простаивающие при обычном запуске прошивки ядра для параллельного выполнения задач (к примеру, на Маках таким образом работает Internet Recovery, т.е. загрузка и проверка хешей кусков образа по 10Мб сделана параллельно и задействует все доступные ядра ЦП) через EfiMpServiceProtocol. В UEFI 2.7 похожий протокол добавили в PEI.

Ну и в качестве вишенки на торт: современные реализации EFI используют IOMMU, виртуальную память и разделение на ring-0 и ring-3 для изоляции опасных с точки зрения внешних атак драйверов, OptionROM'ов и приложений (слайды с презентации с BH).

Я сам не стал бы называть EFI полноценной ОС общего назначения (потому что чтобы стать таковой ей нужен EFI Shell), но не называть ее ОС совсем уже давно не получается даже с натяжкой. Я по прежнему считаю, что прошивка должна быть «создана, чтобы умирать», и потому большая часть нынешней спецификации UEFI в ней совершенно лишняя, и может быть без особых проблем заменена на Линукс или другую полноценную ОС, но у индустрии давно уже свое мнение на этот счет, не совпадающее с моим.
Добавлю тоже со своей колокольни, что язык если использовать по назначению — он доучится до нужного уровня самостоятельно, и если вам понадобится его улучшать (например, дорастете до позиции, в которой вся работа уже не с техникой, а с людьми, и где нужно много и правильно говорить и писать на английском, иначе успеха не добиться) — вы его улучшите неминуемо.
Я не советую останавливаться на B1, потому что это слишком низкий уровень для правильного восприятия культуры (а ее на английском сейчас очень много), т.е. серьезные научные статьи, взрослые книги и фильмы, театральные постановки и прочий контент не получится потреблять непосредственно, а только в адаптированном виде (все эти кошмарные сериалы с одноголосой озвучкой и кривым переводом вида «Рабинович напел»). Даже по нынешним переводным статьям на Хабре понятно, насколько «пережеванным дважды» получается результат такой адаптации…
Короче, учите английский до состояния «читаю реддит также легко, как пикабу, хакерсньюз также легко как хабр, смотрю фильмы в оригинале без субтитров», и откроете для себя огромный кусок информационного пространства, который раньше был доступен только в виде переводов кривых.
Товарищ, уберите все это кошмарное выделение жирно-синим, невозможно читать же!
Еще есть интересный кейс — для безопасности. На устройстве, на которое прошивка заливается каждый раз при перезагрузке, невозможно закрепиться, и его не получится использовать как плацдарм для последующих персистентных атак. Более того, схема load-FW/lock-until-reset отлично заменяет другие, более сложные схемы безопасной загрузки. По сути, вместо переизобретения СекуреБута для каждого чипа нужно сделать его один раз нормально для главного чипа, и грузить прошивки в периферию уже из доверенной среды.
Если вносить неправильно, то толку от них в смысле безопасности не будет, только производительность упадет.

Вычислять, понятно, все равно придется, но нужно делать это так, чтобы количество (а значит и время) вычислений не зависело от значения байтов секрета (точнее, не было заметно, потому что совсем убрать эту зависимость сложно). Вот отличная подборка техник от известного криптолога, автора книги Serious Cryptography Жана-Филлипа Омассона.
По постоянной (т.н. black-box mitigation) тоже есть работы, но они по большей части требуют использования hard-RTOS, почитайте пункт 5.3.2 вот этого анализа.

Про спец-проц: кто вам сказал, что это он? Intel fTPM — это программная реализация, исполняемая на синтезированном из верилога аналоге i586 (т.н. Minute IA). Что внутри у STMicro я не знаю, не не удивлюсь какому-нибудь 8051, MIPS или ARCompact'у. Специальные вычислительные ядра делать дорого и долго, а бизнесу нужно дешево и вчера.
Вот это максимальное время может быть очень сложным концептом. Как его вычислить, не перебирая всех возможных nonce? Как гарантировать, что это время именно максимальное? Как замерять время, если источника качественных часов у тебя нет? Пробовали задержки, и где-то они даже работают относительно как-то, но консенсус у авторов крипто-библиотек сейчас в том, что задержки — это только малая часть общего решения, и смысл в них если и есть, то не очень много.
Про задержку написал выше, идея эта крайне плохая, т.к. внесение случайной задержки требует наличия источника и очень хорошей случайности, и «хороших» в некотором смысле задержек (слишком маленькая задержка удаляется из данных статистикой, за слишком большую не пропустят, т.к. она очень заметно снижает производительность).

Про прописные истины: оглянитесь вокруг, среди ваших коллег много специалистов по криптоанализу? И если завтра к вам придет начальство и скажет «а давайте сделаем свой TPM», вы ляжете костьми, но специалиста такого наймете? Ну вот. Людям дали микроконтроллер и библиотеку на С, и сказали, чтобы за полгода-год они сделали из этого TPM, не не простой, а проходящий все сертификации. Они его сделали, выпустили, и продают успешно, а что там они подвержены простейшим атакам — это надо сначала дождаться, чтобы кто-то атаковать пришел, будучи при этом достаточно умелым.

Ну вот к ним и пришли теперь люди, которые там в академической среде имеют и массу времени, и достаточно знаний, и сильное желание сломать и опубликовать результаты (потому что диссертация им нужна намного сильнее, чем ключи какие-то). Реальный же атакующий (который за ключами пришел как раз) раскрывать суть успешной атаки не станет никогда (потому что ее тут же закроют), поэтому любым подобным сообщениям производители должны радоваться (потому что для них бесплатно сделали дорогой аудит).
Сложно сделать эти случайности достаточно непредсказуемыми, чтобы их нельзя было отфильтровать статистикой. Намного лучше будет использовать вычисления, устойчивые к этой атаке, т.е. такие, в котором секретное значение (nonce) не влияет на скорость вычисления результата. Таких "устойчивых к тайминг-атакам" крипто-библиотек уже разработано немало, но сама по себе задача написания такого кода очень нетривиальная, и зачастую практически невозможная без активной поддержки со стороны разработчиков и процессора, и компилятора. Пока что дальше предложений дело не пошло, поэтому так и приходится очень осторожно писать на ассемблере и тестировать непрерывно.
Все можно подсмотреть осциллографом, если TPM живет на шине LPC, но обсуждаемый в статье Intel fTPM находится внутри чипсета или SoC'а, а туда просто так осциллограф уже не подсунешь.
Графики с этой новости совсем не те, которые нужны, оригинальная статья намного лучше поясняет, в чем именно проблема.

А проблема в том, если в используемых для генерации ключей затравочных однократно используемых значений (nonce) оказывается много нулей в начале, то генерация такого ключа выполняется быстрее (т.к. при наивной реализации на 0 быстрее умножать, чем на число, и умножение на число с большим количеством ведущих нулей оказывается быстрее, чем с небольшим. Мозг человека тоже уязвим, т.к. умножать в уме на 0007 легче, чем на 0183, а на 0183 легче, чем на 2749.).

В результате авторы, замеряя время генерации ключа, и собирая сгенерированные ключи, смогли накопить достаточно материала для lattice-атаки. По сути атака сводится к решению большой СЛАУ, которую получается составить только если можно каким-то образом отличить «уязвимые» ключи от «обычных». Там где у авторов это получилось, они смогли достать приватные ключи из устройств, специально сделаных для того, чтобы ключи из них достать было максимально непросто.
Разница в таймингах при этом оказалась настолько заметная, что ее можно замерять даже с удаленной машины.

Вот графики зависимости времени генерации ключа от количества ведущих нулей в nonce на уязвимых реализациях:
Intel — зависимость ступенчатая.

STMicro — зависимость линейная.

Приведенный тут график для Infinion — это то, как выглядит неуязвимая к данной атаке реализация.

Короче, и интересующимся, и особенно автору посоветую оригинальную публикацию прочитать все же, а не переводить новости из источников, которые только звон слышали, и то где-то далеко, и картинки прикрепляют почти случайные.
Это именно единственный источник отопления, а котел — общий на весь дом (небольшой, 3 этажа, 9 квартир). Там действительно не нужно управление толком, потому что либо отопление не нужно совсем (большую часть года), либо его можно один раз включить утром и один раз выключить перед сном.
Есть, водяные, в трех комнатах, по одному регулятору на комнату.
Точнее сказать, были в Германии, теперь в Калифорнии теплые полы не очень нужны, и большую часть года нужен кондиционер.
Можно регулировать прямо на месте, но простым регулятором вроде такого:

Автоматизация, на мой взгляд, нужна там, где она либо экономит кучу времени на монотонную, но необходимую работу (стиральная, посудомоечная и кофе-машины, робот-пылесос — прекрасные примеры), либо если работа должна быть выполнена без участия человека по каким-то причинам. А тут автоматизируется действие «встать с дивана три-пять раз в день», которое само по себе полезно для здоровья, и времени отнимает от силы минуты две. Взамен предлагается устройство, за которым надо следить, обновлять ему прошивку, защищать его от атак, бороться с его глюками и зависаниями, и по итогу может оказаться, что потраченное на его выбор, установку, программирование и поддержку время больше, чем сэкономленное им же за весь период эксплуатации. Simplicity that is the ultimate of sophistication plus practicality, и все вот это вот.
Очень не хватает вариантов вроде «предпочту механические системы электронным». Не нужны мне эти блютусы-вайфаи-тачскрины, вполне хватит не очень страшного крана не посреди комнаты, в крайнем случае — простейшего регулятора под выключателем света. Мне не трудно встать и покрутить, в случае необходимости, и внедрять сложные системы туда, где отлично работают простые, я не стану.
Никак, к сожалению, тут кроме как на себя надеятся больше не на кого. Ну или писать на Расте обертки и работать с ними уже…

Еще можно попробовать брать указатель на указатель первым параметром всех функций, и ставить его в NULL при успехе, т.е. если все сработало, вот вам указатель нового типа, а старый мы вам занулили автоматически, спасибо.
Даже на чистом С можно выразить, выглядит страшно, но работает.
Можно сделать структуру вроде такой:
typedef struct {
    const uint8_t state[STATE_SIZE];
    WRITE* configure_for_writing(...);
    READ* configure_for_reading(...); 
    //UNINITIALIZED* reset(...);
    void* reserved_do_not_use_0(...);
    //STATUS write(...);
    STATUS reserved_do_not_use_1(...);
    //STATUS read(...);
    STATUS reserved_do_not_use_2(...)
} UNINITIALIZED;

Т.е. в момент ее создания там есть состояние (структура которого скрыта, и писать в него напрямую тоже не стоит), и функции, которые возвращают указатель на ту же самую структуру, только уже не с reserved_do_not_use_*(...), а с функциями, которые доступны на данный момент.
typedef struct {
    const uint8_t state[STATE_SIZE];
    void* reserved_do_not_use_0(...);
    void* reserved_do_not_use_1(...);
    UNINITIALIZED* reset(...);
    STATUS reserved_do_not_use_2(...);
    STATUS read(...);
    ...
} READ;

typedef struct {
    const uint8_t state[STATE_SIZE];
    void* reserved_do_not_use_0(...);
    void* reserved_do_not_use_1(...);
    UNINITIALIZED* reset(...);
    STATUS write(...);
    STATUS reserved_do_not_use_2(...)
    ...
} WRITE;

Получается такой себе фасад, за которым на конкретном этапе доступны только те функции, которые имеют на нем смысл. Понятно, что можно вручную кастовать что угодно к чему угодно, и все порушить, но даже такая защита сильно лучше, чем никакой, потому что случайно уже вызвать не ту функцию не получится.
Через типы-состояния, может быть?
Т.е. действие «сконфигурировать на запись» возвращает тип, у которого нет функции чтения.

Информация

В рейтинге
294-й
Дата рождения
Зарегистрирован
Активность

Специализация

Инженер встраиваемых систем, Системный инженер
Ведущий