Два устройства с одинаковым именем но разными префиксами uefi и usb. Устройство файла UEFI BIOS, часть вторая: UEFI Firmware Volume и его содержимое
КАТАЛОГ ТОВАРОВ

Срок доставки товара в течении 1-3 дней !!!

 

ПОЛЬЗОВАТЕЛЬ
КОРЗИНА

Что новые версии UEFI-стандартов нам готовят, часть третья, UEFI 2.5. Два устройства с одинаковым именем но разными префиксами uefi и usb


Что новые версии UEFI-стандартов нам готовят, часть третья, UEFI 2.5 / Хабр

В последней части цикла я постараюсь рассказать о новшествах стандарта UEFI 2.5, первые реализации которого должны появиться примерно через полгода на новых платах с процессорами Intel Skylake и AMD R-Series. В первой и второй частях речь шла о более низкоуровневых (и потому менее интересных неспециалистам) стандартах PI 1.4 и ACPI 6.0, здесь же поговорим об изменениях, напрямую влияющих на работу ОС и возможности загрузки по сети. Если вы хотите узнать, что нового в UEFI 2.5, почему PXE уходит в прошлое и зачем UEFI поддержка WiFi и Bluetooth — искренне прошу под кат. В отличие от своих низкоуровневых собратьев, стандарт UEFI развивается в очень высоком темпе, и с момента выпуска предыдущей версии 2.4 Errata C не успело пройти и полугода. Изменений масса, поэтому я постараюсь отфильтровать мелкие и не слишком важные, вроде исправлений опечаток и правок некоторых частей текста, допускавшего двоякое толкование. Если вас это не устраивает и вам нужны все изменения до последней запятой — оригинал документа к вашим услугам.

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

ESRT и новый способ обновления прошивки
В UEFI 2.5 вводится новая необязательная таблица ESRT, при помощи которой UEFI может сообщить операционной системе типы и версии имеющихся компонентов прошивки, а также статус их последнего обновления. С использованием этой таблицы ОС может инициировать обновление не только всей прошивки целиком (как это было практически на всех произведенных материнских платах с UEFI), но и конкретных независимых друг от друга компонентов, таких как VBIOS/GOP-драйвер, Raid-драйвер, UNDI-драйвер и т.п. Для инициации обновления будет использован стандартный механизм UEFI Capsule Update, а само обновление будет произведено при следующей загрузке. Файлы с обновлениями компонентов защищены от модификации ЭЦП на основе RSA2048/SHA256 и могут быть выпущены только обладателями закрытого ключа, поэтому прошивать модифицированные образы (и не важно, выполнена ли модификация злобным вирусом или опытным пользователем) с помощью Capsule Update не выйдет, так что программатор по прежнему наше всё. ESRT также будет использоваться для доставки обновлений через подсистему обновления компонентов ОС (т.е. Windows Update для Win10 и fwupd для Linux).
SysPrep, OS Recovery и Platform Recovery
Изначально в фазе BDS можно было запустить только один тип EFI-приложений — bootloader, он же EFI-загрузчик. Порядок загрузки задается в переменной BootOrder, а путь и параметры загрузчика сохраняются в переменных Boot####, начиная с Boot0000 и заканчивая BootFFFF. В UEFI 2.3 был добавлен еще один тип — DXE-драйвер, который будет запущен диспетчером BDS до запуска любых загрузчиков из Boot####, и вместе с типом добавились соответствующие переменные DriverOrder и Driver####. В версии 2.4 добавили возможность привязать к EFI-загрузчику из Boot#### горячую клавишу, которая хранится в переменной Key####. В текущей версии и этого оказалось мало, и были добавлены сразу 3 новых типа приложений: SysPrep, OsRecovery и PlatformRecovery.
SysPrep
Иногда получалось, что запускать какой-либо код из Driver#### слишком рано (к примеру, нужна консоль или полностью инициализированное железо), а из Boot#### — слишком поздно (BS-переменные уже недоступны, приходится шаманить с BootOrder'ом, чтобы гарантированно запускаться первым, и есть риск сломать загрузку совсем). Чтобы решить эту проблему, предложен третий тип приложений — System Preparation Application. Такие приложения запускаются после драйверов, но до загрузчиков и имеют доступ к консоли и графическому режиму. К приложениям такого типа могут относиться шифровальщики дисков, эмуляторы IPMI, системы адаптированного UI для людей с ограниченными возможностями и т.п. На SysPrep-приложения распространяются те же ограничения, что и на загрузчики, т.е. для использования их вместе с SecureBoot они должны быть подписаны подходящей ЭЦП. Возможно выглядит весьма полезной, осталось дождаться реализации и попробовать в деле.
OS Recovery
Если ни один из загрузчиков не смог запустить ОС, то ОС может инициировать восстановление загрузчика, для чего используются переменные OsRecoveryOrder и OsRecovery####. Эта возможность доступна только системам с поддержкой SecureBoot и для её использования SecureBoot должен быть активирован. При ее использовании приложения из SysPrep и PlatfromRecovery загружаться не будут.
Platform Recovery
Если ни один из загрузчиков не смог запустить ОС, то UEFI тоже может инициировать восстановление загрузчика, используя данные из PlatfromRecoveryOrder и PlatfromRecovery####. Обе эти переменные недоступны для модификации из ОС, и будут использованы только в случае, когда OS Recovery недоступен. Одна из переменных PlatfromRecovery#### может быть помечена флагом Default Boot Behavior, т.е. именно указанное в ней приложение будет запущено в случае, если ничего другого запустить не удалось. Если обе вышеперечисленные возможности производители прошивок реализуют правильно, то о проблемах вроде этой можно будет наконец забыть.
Безопасность
В новом стандарте появилось несколько новых протоколов, которые предлагается использовать для контроля целостности компонентов прошивки и шифрования. Протокол EFI_PKCS7_VERIFY_PROTOCOL с двумя функциями VerufySignature и VerifyBuffer позволяет проверить целостность как самой ЭЦП (в формате PKCS7 binary DER), как и подписанных ей данных. Протокол EFI_HASh3_PROTOCOL добавляет к уже имеющейся возможности посчитать хеш-сумму от непрерывного буфера заранее заданного размера тройку функций HashInit, HashUpdate и HashFinal, которые позволяют вычислять хеш от потока данных или нескольких буферов на разных концах доступной памяти. Протокол EFI_BLOCK_IO_CRYPTO_PROTOCOL добавляет возможность чтения/записи данных с шифрованием «на лету» Также в стандарт добавлена поддержка использования NX-бита для защиты буферов и областей с данными от исполнения.
NVM
Как и в стандарты более низкого уровня, в UEFI 2.5 добавлена поддержка NVDIMM и других типов Persistent Memory. В основном это разного рода определения в заголовочных файлах, но нашлось место и новому протоколу — EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL, используя который можно общаться с NVMe-устройствами напрямую, передавая «сырые» команды обнаруженным NVMe-устройствам и обрабатывая ответы от них.
Сетевой стек и загрузка по сети
Загрузка по HTTP
Основным новшеством стандарта UEFI 2.5 является добавление загрузки по HTTP в качестве альтернативы уже имевшейся реализации UEFI PXE с использованием протокола TFTP. Для этого понадобилось добавление поддержки протоколов DNSv4, DNSv6 и самого HTTP, поддержки IPv6 драйвером UNDI, предложены изменения для корпоративных DHCP-серверов и некоторые другие улучшения. Окончательная схема загрузки по HTTP по стандарту выглядит вот так: Загрузчик — обычное UEFI-приложение (чтобы отличать удаленные загрузчики от локальных, в стандарте их обозвали NBP), которые для использование совместно с SecureBoot требуется подписать подходящей ЭЦП. NBP может использовать сетевой стек для загрузки следующих стадий, так что написание многостадийных загрузчиков теперь небольшая проблема, в отличие от PXE.
Поддержка WiFi и Bluetooth
Также в новом стандарте появилась поддержка VLAN, WIFI и Bluetooth как компонентов сетевого стека. Вместе с ней появился целый ворох новых протоколов вроде EFI_WIRELESS_MAC_CONNECTION_PROTOCOL или EFI_BLUETOOTH_HC_PROTOCOL, которые, при наличии драйвера для аппаратной части, позволят получить доступ к беспроводным сетям из UEFI-драйверов и приложений. В итоге с прошивкой на базе UEFI 2.5 можно загрузить ОС ноутбука по WiFi с удаленного HTTP(S)-сервера без слишком уж сильного колдунства. Не могу сказать, что мне это очень нужно или меня это сильно радует, мой внутренний параноик немного ворчит, но если сетевая инфраструктура не нужна — ее можно отключить (и проконтролировать, что она действительно отключена) или выпилить совсем, это тоже не очень сложно.
Остальное
Осталась еще масса мелких изменений, о которых почти нечего рассказывать: поддержка устройств чтения смарт-карт, которые могут быть использованы как источники данных для различного-рода криптографии, новый протокол EFI_USBFN_IO_PROTOCOL для низкоуровневого общения с USB-устройствами, новые протокол EFI_REGULAR_EXPRESSION_PROTOCOL и HII-опкод EFI_IFR_MATCh3, который это самый RegExp-протокол будет использовать, несколько новых типов DevicePath-нод — BMC, SD-карта, RAM-диск, и так далее, всего не перечислить.
Заключение
Мое общее впечатление от новых версий UEFI-стандартов — скорее положительное. Не могу сказать, что все изменения ожидаемы или очень нужны простому пользователю, часть сможет «выстрелить» только при грамотной реализации стандарта со стороны разработчиков UEFI-платформ (т.е. AMI, Insyde, Phoenix и т.д.), а некоторые очень понравятся разработчикам (ASL 2.0 FTW!), но в конечном итоге мой вердикт — пойдет. Посмотрим, конечно, получится ли реализовать все, что гладко выглядит на бумаге, но я надеюсь, что через полгода мне не придется писать статью вроде «почему не работает UEFI HTTP Boot и как с этим бороться». Спасибо читателю за потраченное время, и удачных вам прошивок.

habr.com

долгожданный наследник BIOS и заклятый друг Linux / Offсянка

Разработанная свыше тридцати лет назад для персональных компьютеров IBM PC, система BIOS (или «базовая система ввода-вывода») уже лет пятнадцать как считается реликтом древней эпохи. Жизнь, однако, распорядилась так, что подходящих альтернатив не находилось очень долго. Лишь теперь сложились подходящие обстоятельства и, соответственно, пошли разговоры, что BIOS наконец-то начинает сдавать свои доминирующие позиции.

На ее место приходит система UEFI, комплекс спецификаций, появившийся как «загрузочная инициатива Интел» (Intel Boot Initiative) в далеком уже 1998 году. Причиной рождения инициативы послужило то, что ограничения, обусловленные BIOS, стали ощутимо тормозить прогресс вычислительных систем на основе новейших в ту пору интеловских процессоров Itanium. Несколько позже эта же инициатива стала называться EFI, а в 2005 году корпорация подарила свою разработку специально созданному под нее консорциуму UEFI Forum, главными членами которого стали — помимо Intel — такие зубры IT-индустрии, как AMD, Apple, IBM, Microsoft и ряд других.

Логотип UEFI уже сейчас можно встретить на упаковке материнских плат

Не самая благозвучная аббревиатура UEFI расшифровывается как Unified Extensible Firmware Interface и представляет собой весьма радикальное преобразование традиционной для компьютеров процедуры загрузки. Точнее, перемены настолько глубоки, что UEFI не имеет с системой PC BIOS практически ничего общего.

В то время как BIOS по сути своей является весьма жестким и фактически неизменным по содержанию кодом прошивки специального BIOS-чипа, система UEFI — скорее гибко программируемый интерфейс. А расположен этот интерфейс поверх всех аппаратных компонентов компьютера с их собственными прошивками-микрокодами. В отличие от загрузочного кода BIOS, который всегда жестко прошит в соответствующем чипе на системной плате, куда более обширные по размеру коды UEFI находятся в специальной директории /EFI/, место физического расположения которой может быть самым разнообразным — от микросхемы памяти на плате или раздела на жестком диске компьютера и до внешнего сетевого хранилища.

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

UEFI, что и говорить, по сравнению с классическими BIOS выглядит гораздо красивее и понятнее для нормальных людей

Еще более усиливая сходство с ОС, спецификации UEFI включают в себя не только загрузочные, тестовые и рабочие сервисы, но также протоколы коммуникаций, драйверы устройств (UEFI изначально разрабатывалась для работы вне зависимости от операционных систем), функциональные расширения и даже собственную EFI-оболочку, из-под которой можно запускать собственные EFI-приложения. А уже поверх всего этого хозяйства расположен собственно загрузчик, отвечающий за запуск на компьютере основной операционной системы (или нескольких систем).

Хотя UEFI иногда называют псевдо-ОС, она, тем не менее, способна сама получать доступ ко всему аппаратному обеспечению компьютера. То есть уже на уровне UEFI вполне возможно, к примеру, выходить в Интернет или организовывать резервное копирование жестких дисков, причем делать это все в условиях полноценного графического интерфейса под привычным мышиным управлением.

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

Полностью построенная на основе программного кода, UEFI действительно стала объединенной кросс-платформенной системой. Уже сегодня спецификации UEFI предусмотрены в работе почти любой комбинации чипов с 32- и 64-битной архитектурой, выпускаемых AMD, Intel и многочисленными лицензиатами ARM. Единственное, что требуется для обеспечения этой универсальности, это скомпилировать исходный код под требования каждой конкретной платформы.

UEFI уже сейчас вовсю используется в топовых материнских платах крупных производителей, а к концу следующего года найти свежую модель с «просто BIOS» станет практически невозможно

Помимо внушительного множества расширяемых возможностей, реализуемых благодаря гибкому и продвинутому интерфейсу, система UEFI также определяет несколько стандартных особенностей, которые должны быть реализованы в работающем под ней компьютере. В частности, среди таких стандартно обеспечиваемых возможностей упоминаются «безопасная загрузка» (secure boot, о чем в подробностях далее), низкоуровневая криптография, сетевая аутентификация, универсальные графические драйверы и еще немало чего другого...

В принципе, в каждой из основных на сегодня операционных систем (Windows, OS X, Linux) уже имеется поддержка загрузки через UEFI. Но следует также отметить, что пока UEFI все еще является очень молодой системой и реально очень немногие ОС пользуются всеми ее преимуществами, перечисленными выше.

Linux определенно поддерживает UEFI, однако это скорее поверхностное знакомство, чем эффективное партнерство. Система Mac OS X продвинулась несколько дальше и отчасти использует UEFI со своим загрузочным менеджером Bootcamp. В линейке Microsoft реальная поддержка UEFI появится в Windows 8, и когда она будет запущена в 2012 году, эта операционная система, вероятно, станет первой из «главных» ОС, где будут весьма интенсивно задействованы преимущества UEFI, включая функции восстановления, обновления, безопасной загрузки и, вполне возможно, что-то еще.

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

⇡#Мягкое выдавливание конкурентов

В сентябре компьютерное сообщество взбудоражила новость о том, что корпорация Microsoft станет требовать поддержки безопасной загрузки UEFI от систем, официально сертифицированных под Windows 8. Вроде бы ничего страшного, но такой подход может с очень большой вероятностью привести к полному блокированию загрузки ОС Linux на Windows-сертифицированных системах.

Кое-где угроза была воспринята настолько серьезно, что, например, в Австралии Linux-сообщество тут же запустило процедуру подачи официальной жалобы в ACCC, Австралийскую комиссию по честной конкуренции и правам потребителей.

Однако, как говорят сведущие в технических и юридических тонкостях специалисты, именно из этого разбирательства Microsoft практически наверняка сумеет выбраться без всяких проблем. Просто потому, что в описании процесса безопасной загрузки UEFI или, точнее, в словах о необходимости такого процесса корпорацией не упоминаются иные операционные системы. Суть проблемы, с которой сражается Microsoft (очень тщательно и аккуратно подбирая выражения), — это борьба с вредоносными кодами, а безопасная загрузка тем и хороша для работы Windows, что такой процесс перекрывает еще один опасный канал для проникновения вредоносных программ.

Есть ощущение, что с выходом Windows 8 увидеть на экране какой-то другой интерфейс станет посложнее. По крайней мере, для людей, не умеющих собирать компьютеры самостоятельно

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

Начиналось все так. В конце сентября один из ведущих разработчиков дистрибутива Red Hat Мэтью Гаррет (Matthew Garrett) в своем блоге отметил, что, согласно новым правилам относительно присвоения машинам логотипа «Windows 8», все компьютеры, совместимые с этой ОС, должны будут иметь для загрузки уровень UEFI вместо устаревшего уровня BIOS.

Причем речь шла не просто о любом уровне спецификаций UEFI (реализованных в разных версиях достаточно давно), а конкретно о безопасном UEFI. Что означает более жесткий контроль за процессом загрузки системы. Конкретнее, это ужесточение означает то, что «все микрокоды прошивки и программное обеспечение, участвующее в процессе загрузки, должны быть криптографически подписаны доверяемым органом сертификации (CA)» — согласно слайдам презентации о загрузочном процессе UEFI в одном из официальных докладов Ари ван дер Ховена (Arie van der Hoeven), главного менеджера программ Microsoft (здесь, наверное, стоит привести и английскую версию названия этой почти непереводимой должности, Principal Program Manager Lead. — прим. редакции).

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

Судя по всему, коварство Microsoft всерьез потрясло Мэтью Гаррета, так что на всех новых фотографиях он выглядит одинаково удивленным

Ну, к словесным баталиям деятелям мира Linux не привыкать. Однако процедура оказывается чрезвычайно запутанной и трудозатратной — даже для линуксоида со стажем — сразу в двух аспектах: юридическом и практическом.

Во-первых, юридическая сторона. По свидетельству Гаррета, самый распространенный линуксовский загрузчик GRUB 2 лицензирован на условиях лицензии GPLv3. Это вроде бы может означать, что ключи должны быть предоставлены поставщиком вместе с исходным кодом программы. Однако в действительности это весьма мутный момент. Лицензия GPLv3 требует, чтобы ключи цифровой подписи выпускались, когда аппаратное обеспечение продается вместе с ПО, созданным под GPLv3 (и криптографически подписанным). Но если это же подписанное ПО просто используется на чьем-то еще аппаратном обеспечении, тогда ключи не требуются. И хотя уже это выглядит запутанно, ситуация еще более сложна, когда речь идет о GPLv2, лицензии для первоначального загрузчика GRUB (существенно отличающейся в своих требованиях от GPLv3). Для того чтобы полностью избавиться от всех этих юридических неясностей, Гаррет рекомендует просто использовать иной загрузчик, не связанный условиями лицензии GPL.

Вот только гарретовский рецепт, как бы сомнительно он ни выглядел, в реальности может оказаться еще опаснее. Процедура загрузки ОС — это один из сервисов, которые уже встроены в ядро Linux. А ядро этой ОС является кодом, работа с которым определяется лицензией GPLv2, причем ситуацию эту даже не собираются менять — из неких принципиальных соображений и несогласия с GPLv3.

Благодаря заботе Microsoft, многие дистрибутивы Linux могут окончательно утратить имидж user-friendly

И наконец, есть еще один — практический — аспект, о котором упоминает Гаррет. Кто именно будет заниматься тем, чтобы отслеживать и убеждать всех OEM-изготовителей компьютеров, чтобы они предоставляли соответствующие криптоключи, необходимые для безопасной загрузки Linux? Конечно же, многие компании предоставят такие ключи для Windows 8 — коль скоро они хотят иметь возможность продавать свои машины на новой операционной системе Microsoft. Однако в природе не существует никаких правил, которые диктовали бы им, что они обязаны предоставлять такие же ключи кому-то еще. И, учитывая долю рынка Linux, убедить их может оказаться делом непростым…

Между тем ни о какой нечестной конкуренции речи-то не идет. Официальные лица Microsoft уже вполне резонно парировали нападки линуксоидов тем, что с их стороны речь идет исключительно об укреплении безопасности в работе ОС Windows. И они никоим образом не пытаются влиять на то, как именно изготовители аппаратного обеспечения распоряжаются своими криптоключами. Microsoft никак не препятствует выдачам таких же ключей другим операционным системам. А если у индейцев возникают проблемы с третьей стороной, причем тут шериф?

Если пытаться судить объективно, позицию Microsoft здесь никак нельзя называть неправой. Просто реальная ситуация на рынке такова, что небольшого смещения акцентов под здравые, в общем, требования Microsoft оказалось достаточно, чтобы вся ответственность перенеслась на действия (точнее, вероятное бездействие) OEM-изготовителей.

Linux уверенно побеждает Windows только в творчестве фанатов. Если бы кому-то пришло в голову нарисовать истинное положение дел, картинка выглядела бы слишком шокирующе даже для нашего либерального портала

В финальных комментариях на данный счет Мэтью Гаррет говорит следующее: «Microsoft имеет возможности потребовать от поставщиков железа предоставления своих ключей. Их конкуренты таких возможностей не имеют. Всякая система, которая продается с ключами подписи только для Microsoft и никого другого, будет не способна выполнять безопасную загрузку любой операционной системы, отличающейся от Windows. Ни один другой поставщик ПО или аппаратного обеспечения не имеет такой же позиции власти над поставщиками железа. У Red Hat нет возможностей гарантировать, что каждый OEM обеспечит для этой ОС ключи подписи. Нет такой возможности у Canonical (ОС Ubuntu). Нет у Nvidia, или у AMD, или любого другого изготовителя компьютерных компонентов. В этой области влиятельность Microsoft даже больше, чем у корпорации Intel».

На рынке серверов ситуация с Linux будет совершенно не такой, как в продажах настольных систем. В серверном пространстве такие поставщики, как IBM, HP, и Dell, уже инвестировали слишком много и в Linux-системы вообще, и в облачные или виртуальные системы в частности, чтобы у Linux не появлялось никаких проблем с установкой на новых машинах.

Однако в мире настольных систем, где ныне почти никто из OEM не продает компьютеры с предустановленной Linux, совершенно неясно, какие стимулы могут быть у изготовителей железа для раздачи своих криптоключей всем этим разнообразным дистрибутивам Linux. Единственное, что можно прогнозировать наверняка, — Microsoft «разруливанием» данной проблемы заниматься не будет точно.

⇡#Другая сторона медали

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

В конце сентября в американском городе Орландо, штат Флорида, проходила специализированная выставка-конференция под названием NSA Trusted Computing, организованная Агентством национальной безопасности США.

Главный комплекс зданий Агентства национальной безопасности США. По всем признакам, людей там хватает

На этом мероприятии доклад об угрозах компьютерам со стороны BIOS и о путях укрепления защиты на этом направлении сделал Эндрю Регеншайд (Andrew Regenscheid), сотрудник подразделения компьютерной безопасности в составе NIST, американского Национального института стандартов и технологий. Именно это ведомство в тесном сотрудничестве с АНБ занимается подготовкой и изданием технических федеральных стандартов на защиту информации.

В апреле текущего года НИСТ выпустил специальный документ SP 800-47 с рекомендациями о том, каким образом производители компьютеров и использующие их структуры должны работать с BIOS для максимального предотвращения заражений и атак. Одним из главных соавторов данного документа и был Эндрю Регеншайд.

По свидетельству этого эксперта, несмотря на весьма ограниченную роль BIOS в современных компьютерах (где, как принято полагать, функции устаревшей системы сводятся лишь к загрузке ОС), реально BIOS на сегодняшний день представляет собой «нарастающий вектор угроз» для компьютеров и их пользователей. Ощутимый прогресс в защите операционных систем заставил злоумышленников изобретательно искать в компьютерах новые уязвимости. При этом специалисты, занимающиеся безопасностью, о BIOS долгое время забывали. А в совокупности все это стало означать, что креативные злодеи с заметным успехом ныне могут эксплуатировать уязвимости и в кодах прошивки микросхем.

Случаи атак через BIOS уже есть. Так, в начале сентября китайская антивирусная фирма обнаружила в компьютерах весьма опасный руткит, получивший название Mebromi, который успешно заражает своим шпионским компонентом память BIOS-чипов AWARD. Проникнув в BIOS и попутно подменяя MBR, главную загрузочную запись жесткого диска, эта вредоносная программа прописывается в машине так основательно, что удалить ее стандартными средствами не представляется возможным. Просто потому что антивирусные программы не занимаются лечением BIOS.

Как сказал об этом Регеншайд, «если злоумышленник способен проникать в BIOS и модифицировать его код, он получает возможности не только «убить» систему, не допуская ее загрузки, но и внедрить свое шпионское ПО на чрезвычайно высоких по привилегиям уровнях работы системы».

И вот теперь, существенно усложняя общий «ландшафт угроз» для компьютерной безопасности в аспектах BIOS, на сцене появляется UEFI BIOS. То есть следующее поколение системы, в своих спецификациях добавляющее множество новых возможностей как для администраторов и конечных пользователей, так и для злоумышленников.

Совершенно очевидно, что, в отличие от традиционных BIOS, система UEFI способна на много, много большее, чем просто процесс загрузки. Эндрю Регеншайд, в частности, в своем докладе особо подчеркнул набор рабочих сервисов, которые можно вызывать даже в таких условиях, когда основная ОС уже давно загружена и, как принято обычно считать, полностью управляет компьютером. Эта специфическая особенность, а также другие свойства UEFI BIOS, по свидетельству Регеншайда, очень ощутимо расширяют пространство возможных атак на систему.

В дополнение к этому, сказал докладчик, стандарт UEFI BIOS намного более подробно документирован, нежели предыдущие спецификации BIOS. Это, да в сочетании с тем, что систему UEFI понадобится обновлять через сеть куда более часто, чем BIOS, открывает широкий простор для создания и внедрения самых разнообразных вредительских и шпионских закладок.

Странная история получается, правда? С одной стороны, во имя безопасности происходит изменение правил игры, существенно осложняющее жизнь «маленьким» участникам. А с другой — уже сейчас, на старте, есть существенные сомнения в том, что этой самой безопасности всерьез прибавится.

Зато никому долго не будет скучно.

Если Вы заметили ошибку — выделите ее мышью и нажмите CTRL+ENTER.

3dnews.ru

О безопасности UEFI, часть третья / Хабр

Продолжаем разговор о безопасности UEFI. На этот раз речь пойдет об опубликованной в конце 2014 года серьезной уязвимости в реализации ACPI S3 (Sleep Mode), ее эксплуатации и последствиях. Основная «фишка» этой уязвимости в том, что она вскрыла целый класс проблем безопасности UEFI, вообще не считавшихся до этого проблемами, и потому и заслуживает отдельной статьи. Тем, кто не читал предыдущие статьи цикла — раз и два, предлагаю прочесть сначала их, остальных жду под катом.
Часть третья. ACPI S3
Еще немножечко ликбеза
В отличие от SMM, о котором обычный пользователь чаще всего даже не подозревает, про ACPI S3, т.е. режим сна, знает любой обладатель ноутбука или ПК, выпущенного в последние 10 лет. Стандарт ACPI, об изменениях в последней версии которого я недавно писал, определяет набор т.н. состояний сна, в одном из которых может находиться система, следующим образом:
  • S0 — Working, т.е. обычная работа, все устройства включены. Внутри этого состояния производители систем имеют право определять кучу других состояний: P-states, C-states, T-states и т.п., расскажу о них как-нибудь в другой раз.
  • S1 — Sleeping with Processor Context Maintained, оно же Power on Suspend, т.е. все ядра процессора выполнили команду HLT и стоят, но все кэши и RAM валидны и обновляются, питание со всех все линий S0-only снято. Возврат из этого состояния занимает приблизительно 10 мс, из которых ~90% — ожидание установившихся режимов после подачи питания на линии S0-only. Никакие регистры ни у CPU, ни у чипсета, ни у устройств в этом состоянии не сбрасываются, так что нас в этой статье оно интересовать не будет.
  • S2/S3 — Suspend to RAM, т.е. содержимое памяти остается валидным и обновляется, а процессор и часть чипсета отключаются полностью с потерей контекста и содержимого практически всех регистров. Разница между S2 и S3 минимальная, и чаще всего S2 вообще не выделяют в отдельное состояние. После пробуждения из S3 процессор начинает выполнять код с ResetVector'а, т.е. чтобы правильно «проснуться», ему нужно восстановить весь контекст для себя и чипсета. Вот на этом этапе разработчиков прошивки и подстерегает несколько подводных граблей, о которых мы и поговорим в этой статье.
  • S4 — Suspend to Disk, т.е. содержимое памяти сбрасывается на диск и система отключает все устройства и подачу питания. После включения система стартует как обычно, и с точки зрения UEFI между S4 и S5 разницы практически нет (а если отключить FastBoot, то совсем нет).
  • S5 — Soft-Off, т.е. система отключена, но дежурное питание присутствует. Из S4/S5 система может быть выведена по сигналу RTC, либо по Wake-сигналу от устройства, либо по нажатию кнопки питания.
Как реализован S3 в UEFI
Чтобы восстановить контекст при «просыпании», сначала его нужно где-то сохранить. При этом желательно не слишком привязываться к конкретным особенностям архитектуры процессора и чипсета, а таже сделать хранение и восстановление контекста максимально прозрачным, чтобы не умереть потом в отладке. Т.к. работоспособность S3 — очень важная характеристика практически любого современного ПК, за исключением серверов с годами аптайма, то технология сохранения и восстановления контекста была разработана инженерами Intel очень рано, в 2004 году, и получила название EFI S3 BootScript. С тех пор спецификация многократно дорабатывалась, последняя версия теперь находится в томе 6 спецификации UEFI PI. Суть ее такова: после исполнения фазы PEI, в которой происходит инициализация базовых устройств, т.е. процессора, кэшей и оперативной памяти, система определяет текущий режим загрузки. 1. Если этот режим отличается от S3 Resume, загрузка продолжается как обычно, PEI заканчивается запуском диспетчера DXE, который создает новый пустой S3 BootScript и запускает все доступные DXE-драйверы. Каждый такой драйвер выполняет финальную инициализацию того устройства, за которое он отвечает, и затем добавляет в S3 BootScript команды, которые необходимо выполнить, чтобы повторить инициализацию устройства при возврате из S3. Команды могут быть примерно такими (список взят из спецификации PI 1.4, но в конкретных реализациях могут встречаются и нестандартные):
  • IO_WRITE — записать указанное значение в указанный CPU IO-порт
  • IO_READ_WRITE — изменить значение в указанном CPU IO-порту согласно указанной маске
  • IO_POLL — выполнять чтение из указанного IO-порта, пока не будет выполнено указанное условие, но не дольше указанного времени ожидания
  • MEM_WRITE — записать указанное значение по указанному физическому адресу
  • MEM_READ_WRITE — изменить значение по указанному физическому адресу согласно указанной маске
  • MEM_POLL — выполнять чтение по указанному адресу, пока не будет выполнено указанное условие, но не дольше указанного времени ожидания
  • PCI_CONFIG_WRITE — записать указанное значение по указанному адресу в конфигурационном пространстве указанного PCI-устройства
  • PCI_CONFIG_READ_WRITE — изменить значение по указанному адресу в конфигурационном пространстве указанного PCI-устройства согласно указанной маске
  • PCI_CONFIG_POLL — выполнять чтение по указанному адресу в конфигурационном пространстве указанного PCI-устройства, пока не будет выполнено указанное условие, но не дольше указанного времени ожидания
  • SMBUS_EXECUTE — передать указанную команду указанному устройству на шине SMBus
  • STALL — подождать указанное число микросекунд
  • DISPATCH — выполнить код по указанному адресу
Вышеуказанных команд вполне достаточно, чтобы повторно инициализировать любое устройство, особенно с учетом последней команды, просто передающей управление PEI-драйверу, который и выполняет всю инициализацию, но нужно это только для особо сложных случаев, когда остальными командами обойтись не получилось. После окончания фазы DXE диспетчер сохраняет получившийся S3 BootScript в памяти типа AcpiNVS, в которой находятся ACPI-таблицы и другие данные, необходимые ОС для правильной работы ACPI в ней. 2. Если же при загрузке выяснилось, что система находится в S3 Resume, вместо диспетчера DXE запускается PEI-модуль с красивым именем BootScriptExecutor, который выполняет BootScript, бережно хранящийся в памяти со времен прошлой нормальной загрузки, а затем передает управление на ОС, которая успешно стартует и радует пользователя. Словами, вроде бы, пояснил, теперь тоже самое — картинкой из спецификации:
Подводные грабли
Это все успешно работало около 10 лет, и практически никто не видел подвоха, пока в конце 2014 года широко известные в узких кругах товарищи Rafal Wojtczuk and Corey Kallenberg не представили атаку, которая оказалась одновременно очевидной и крайне опасной. Оказалось, что область памяти (типа AcpiNVS), которой хранится S3 BootScript, никак не защищена от модификации. Да, ОС воспринимает ее как служебную и не испортит содержимое самостоятельно, а вот атакующий с правами администратора — еще как. Модификации могут быть весьма различными, но т.к. большая часть защитных механизмов, обеспечивающих защиту как от прошивки произвольно кода в микросхему SPI, так и от несанкционированного доступа в SMM, настраиваются через регистры процессора и чипсета, то для успешного обхода этих механизмов достаточно найти BootScript в памяти (это нетрудно), найти в нем нужный нам регистр (тоже никаких сложностей) и изменить его так, чтобы при следующем S3 Resume защита не смогла включиться. Меняем, засыпаем, просыпаемся — оп, а король-то голый! Чем грозит снятие защиты с микросхемы SPI и с SMM — я уже писал в прошлых частях, повторяться не буду, но ничем хорошим это определенно не закончится. Интересно, что инженеры Intel предвидели эту атаку и заранее реализовали защиту от нее — т.н. SmmLockBox. Защита очень простая — после того, как составление скрипта закончится, он копируется целиком в SMRAM, при этом оригинальный BootScript не удаляется. При восстановлении из S3 вызывается обработчик SMI, который проверяет, что оригинальный BootScript совпадает с копией в SMRAM, а если нет — либо переписывает измененный BootScript копией, либо перезагружает машину (это безопаснее, но пользователь теряет все данные из RAM). Проблема оказалась в том, что SmmLockBox просто не успели вовремя внедрить, и когда Rafal и Corey тестировали найденную уязвимость, оказалось, что единственная неуязвимая к атаке плата — Intel'овский UEFI Development Kit. После обнародования атаки IBV начали в спешке внедрять либо оригинальный SmmLockBox, либо свои аналоги, основанные на той же идее, но это внедрение часто буксовало по разным причинам. К примеру, на системах с процессором AMD инициализация SMM проводилась в фазе DXE, и потому вызов обработчика SMI из PEI при S3 Resume заканчивался неудачей и S3 переставал работать вообще. Тем не менее, на данный момент все вендоры, слышавшие о безопасности хотя бы краем уха, уже решили эту проблему каким-либо способом, и если ваша прошивка новее июня 2015 года, а производитель вашей системы не мудак — скорее всего ваша система прямой атаке на изменение S3 BootScript'а уже не подвержена.
Свинья от производителей платформ
После того, как паника немного улеглась, и BootScript успешно затолкали в SMRAM (понятно, что теперь надо хранить его как зеницу ока, но я об этом уже в прошлой части писал), неожиданно выяснилось, что инженеры Intel и AMD, сами того не зная, подложили обладателям своих платформ порядочную свинью в лице нескольких PEI-модулей, которые а) копировались в память прямо рядом с BootScript'ом, б) вызывались из него командой DISPATCH десятки раз и в) были достаточно большими, чтобы в SMRAM на их копии места не хватало. Таким образом, выполнение произвольного кода можно было организовать без модификации самого BootScript'а вообще, вместо этого модифицировав точку входа одного из таких модулей. Удалить такие модули без нарушения работы S3 не получалось, но решение нашлось — вместо копирования в память их перенесли на неупакованную часть DXE-тома, и исправили команды DISPATCH так, чтобы код вызывался прямо с микросхемы SPI. Это оказалось немного медленнее, чем из RAM, зато свинью удалось таки выгнать. Я не знаю, сколько сейчас систем, которые можно атаковать этим способом, но подозреваю, что очень много.
Господа забывчивые
Человек не застрахован от ошибок, и разработчики DXE-драйверов — тоже человеки, и иногда могут банально забыть написать добавление какого-нибудь важного регистра в BootScript, и после S3 в этом регистре окажется его оригинальное значение. Чаще всего такая забывчивость приводит только к мелким глюкам после S3, но законы Мерфи говорят нам, что если какой-либо важный регистр может быть забыт — он обязательно будет забыт, что и происходит. Последний громкий пример забывчивости — опубликованная в конце мая этого года уязвимость в прошивках ноутбуков Apple, где инженеры забыли добавить в S3 BootScript запись в PR-регистры, и после S3 защита микросхемы SPI от прошивки снималась самостоятельно. Очень удобно ведь, закрыл-открыл крышку — и можно доставать flashrom и писать свой код в BIOS, Apple вновь радует простой и юзабилити. Если вы думаете, что случай единичный — советую запустить на своем ПК утилиту Chipsec и сравнить отчеты, сделанные до и после S3. Заодно и сюрприз может получиться.
Отключу S3 и трава не расти
Примерно это, только более экспрессивно и немного более матом, я воскликнул, когда столкнулся с проблемой впервые. К сожалению, этот вариант не всегда возможен (хотя S4 на SSD мало отличается по скорости, зато сильно отличается по надежности, никаких танцев со скриптами и экзекуторами не нужно), более того, если вы не отключили S3 намертво путем модификации прошивки, атакующий, способный запустить на вашей системе UEFI Shell, банально включит S3 обратно. В следующей части я постараюсь рассказать, как избежать такой незавидной судьбы, но коротко — включайте и пользуйтесь SecureBoot, он вовсе не зло, если уметь его готовить.
Кризис доверия
Вся эта история с S3 BootScript вскрыла одну интересную проблему, которую после 10 беззаботных лет разработки в UEFI серьезно начали решать только сейчас. Проблема состоит в том, что «безопасная» прошивка не может доверять ничему, к чему имеет или имела доступ ОС. Устройства нужно сбросить и инициализировать самостоятельно, память очистить и ничего из нее не использовать (не дай рандом вызывать оттуда код!), свои же Runtime-сервисы после события ReadyToBoot компонентам прошивки использовать нельзя (их уже хукнул атакующий, иногда по нескольку раз), в общем, сплошное минное поле, чуть оступился — и вот у тебя уже полный BIOS чужого кода, бэкдор на бэкдоре, честным драйверам в SMRAM места нет. Поэтому производители платформ ищут спасения в аппаратных решениях, кто-то внедряет validated boot, кто-то хранит S3 BootScript в Security Coprocessor'е, кто-то разрабатывает свой собственный крипточип, кто-то просто забил и ждет, пока ему решение UEFI Forum сверху спустит. Вот и Intel добавила в Skylake интересную технологию SGX, которую можно использовать для изоляции отдельных кусков кода и данных от всего остального в системе, такой себе аналог SMM, только всем и даром, чтобы никто не ушел обиженным. Технология выглядит достаточно вкусно, но, во-первых, сложна в программировании, а во-вторых — есть только у Intel и только на Skylake. Со стороны «безопасной» ОС — такой же точно уровень недоверия к прошивке, и тут может пригодиться технология STM, о которой разговоры велись с 2009 года, но представили ее официально только недавно, и «в бою» она еще не опробована. Когда дойдут руки попробовать обе — постараюсь про это написать.
Заключение
Ну вот, проблемы с S3 BootScript позади, в следующей части поговорим об атаках на NVRAM и SecureBoot, а также о том, почему пароль на BIOS — от честных людей. По доброй традиции, посоветую знатокам английского языка вот эту статью тов. d_olex на ту же тему. Там серьезность, глубина, код, и картинки, не то что мое словоблудие тут. Спасибо тебе за внимание, читатель, безопасных тебе прошивок.

habr.com

UEFI Firmware Volume и его содержимое / Хабр

Позади уже полторы (первая, полуторная) части этой статьи, теперь наконец пришло время рассказать о структуре UEFI Firmware Volume и формате UEFI File System.
Введение
Сразу скажу, что в этой части статьи я буду описывать форматы файлов версии 2, т.к. именно они используются во всех существующих BIOS'ах. В последних версиях стандарта PI добавлено описание форматов версии 3, но они нужны для файлов размером более 16 Мб, которых пока нет ни на одной плате, хотя Gigabyte уже вплотную подобралась к этому рубежу на своих платах на Z87. Регион Descriptor на всех современных платах Intel поддерживает не более 2 микросхем емкостью не более 16 Мб, поэтому применение форматов версии 3 откладывается до очередной смены поколений чипсетов Intel, как минимум.

В качестве примера возьмем регион BIOS из файла версии 229 для Zotac Z77-ITX WiFi. Нам понадобятся следующие программы:

  • Hex-редактор на ваш вкус, я буду использовать HxD
  • Утилита PhoenixTool v2.xx, которую можно скачать из темы на форуме MDL
Firmware Volume
Структура Firmware Volume и формат PI FFS описаны в Volume 3 документации по UEFI Platform Initializaton. Firmware Volume — это логическое представление содержимого flash, имеющее следующие атрибуты:
  1. Name: в качестве имени FV и всех его частей выступает их GUID
  2. Size: включает в себя все данные, заголовки и свободное место
  3. Format: тип файловой системы внутри FV, различные типы имеют различные GUID'ы
  4. Allignment: требует, чтобы первый байт FV был выровнен по указанной границе, кратной степени 2. Выравнивание FV не должно быть слабее выравнивания всех файлов внутри него, кроме случая, когда в заголовке установлен флаг EFI_FVB_WEAK_ALIGNMENT. В этом случае выравнивание может быть сделано по любой степени 2, но этот FV нельзя больше перемещать
  5. Атрибуты защиты от чтения, записи, самостоятельного отключения защиты от чтения или записи
  6. OEM-атрибуты, выставляемые на усмотрение производителя
Независимо от используемой внутри FV файловой системы, заголовок FV стандартизирован и имеет следующий вид:typedef struct { UINT8 ZeroVector[16]; UINT8 FileSystemGuid[16]; UINT64 FvLength; UINT32 Signature; UINT32 Attributes; UINT16 HeaderLength; UINT16 Checksum; UINT16 ExtHeaderOffset; UINT8 Reserved[1]; UINT8 Revision; EFI_FV_BLOCK_MAP BlockMap[]; } EFI_FIRMWARE_VOLUME_HEADER; typedef struct { UINT32 NumBlocks; UINT32 Length; } EFI_FV_BLOCK_MAP ZeroVector: в начале FV зарезервировано 16 байт для совместимости с процессорами, reset vector которых находится по нулевому адресу. По присутствию чего-то отличного от нулей в этом блоке можно безошибочно выделить Boot Firmware Volume среди остальных.FileSystemGuid: определяет используемую внутри этого FV файловую систему.FvLength: размер FV с учетом всех заголовков.Signature: используется для поиска FV и по стандарту всегда равна 0x4856465F, т.е. {'_','F','V','H'}.Attributes: те самые атрибуты, о которых мы говорили выше. Их там достаточно много, но самые главные для нас это вышеупомянутый EFI_FVB_WEAK_ALIGNMENT, делающий FV неперемещаемым в случае его установки, один из набора EFI_FVB_ALIGNMENT от EFI_FVB_ALIGNMENT_1 до EFI_FVB_ALIGNMENT_2G и EFI_FVB_ERASE_POLARITY, указывающий, каким именно битом производится стирание микросхемы flash. Остальные нужны коду, который работает с FV как областью памяти, и для нас бесполезны, поэтому не станем их перечислять.HeaderLength: размер заголовка без учета extended header'а, о котором ниже.Checksum: 16-битная контрольная сумма заголовка. Корректный заголовок должен суммироваться в 0x0000.ExtHeaderOffset: смещение начала extended header'а. В нем могут быть указаны GUID описываемого FV, список OEM-типов файлов вместе с их GUID'ам, а также электронная подпись. В данный момент я не встречал ни одного FV с заполненным extended header'ом, поэтому мы не будем его рассматривать. Если дополнительного заголовка у FV нет — в этом поле 0x0000.Reserved: зарезервированное поле, всегда 0x00.Revision: стандарт PI описывает структуру только одной ревизии — второй, поэтому в этом поле всегда 0x02. BlockMap: карта блоков, хранящаяся в виде списка структур EFI_FV_BLOCK_MAP, заканчивающегося такой же структурой о нулями в обоих полях. Т.к. все современные микросхемы flash однородны (т.е. имеют блоки одинакового размера), то весь список состоит обычно всего из двух записей.

Проверим наш пример на соответствие вышеописанному. Откроем наш файл BIOS'а в hex-редакторе и перейдем на смещение 0x500000, в начало региона BIOS. Видим, что 16 нулей в начале имеются, GUID файловой системы имеется, размер этого FV — 0x020000, сигнатура на месте, атрибуты выставлены, заголовок имеет размер 0x48 байт, контрольная сумма посчитана, расширенного заголовка не имеется, зарезервированные поля на месте, а внутри этого FV имеется 20 блоков по 0x1000, что в сумме как раз и дает указанный в поле FvLength размер. Чаще всего, в BIOS'е имеется несколько различных FV, предназначенные для разных целей, хотя это и не обязательно и можно упаковать все в один. Чемпион по степени вложенности FV и файлов друг в друга среди всех производителей UEFI BIOS'ов — Intel, там вложенность до 12 уровней встречается. Хотя теоретически для FV могут использоваться различные файловые системы, на практике используется только одна — PI FFS, о которой мы сейчас поговорим.

Firmware File System
Это плоская файловая система без каталогов и иерархии, все файлы которой находятся в коневом каталоге. Получение списка файлов требует прохода по ФС от начала до конца. Все файлы должны иметь определенный стандартом заголовок. Файлы должны быть выровнены по восьмибайтовой границе относительно начала ФС, для выравнивания по большим границам предусмотрен специальный файл-заполнитель. Также в стандарте описан специальный файл VTF, который обязан присутствовать в конце каждого FV, но на практике он присутствует только в конце последнего FV в образе BIOS и расположен так, что его последний байт является также последним во всей микросхеме. В нем находится код начальной загрузки, необходимой для фазы SEC.
Заголовок файла
Заголовок файла FFS устроен следующим образом:typedef struct { UINT8 Name[16]; UINT8 HeaderChecksum; UINT8 DataChecksum; UINT8 Type; UINT8 Attributes; UINT8 Size[3]; UINT8 State; } EFI_FFS_FILE_HEADER;Name: GUID файла, выступающий в роли имени. В одном FV не может быть двух файлов с одинаковым GUID, если это не PAD-файлы, о которых ниже.HeaderChecksum: восьмибитная контрольная сумма заголовка, исключая поле DataChecksum. Корректный заголовок должен суммироваться в 0x00.DataChecksum: восьмибитная контрольная сумма содержимого файла без учета заголовка. Расчет ее требуется не всегда, а только если установлен атрибут FFS_ATTRIB_CHECKSUM, иначе это поле устанавливается в 0xAA.Type: тип файла. Стандарт определяет 13 стандартных типов файлов (0x01 — 0x0D), 32 пользовательских типа для файлов OEM-производителей (0xC0 — 0xDF), 16 пользовательских типов для отладки (0xE0 — 0xEF) и 16 типов, специфичных для текущей версии FFS (0xF0 — 0xFF), из которых сейчас используется только 0xF0 — EFI_FV_FILETYPE_FFS_PAD для файла-заполнителя. Этот специальный файл может иметь любой, в том числе нулевой GUID, нулевые атрибуты, стандартное состояние и любой размер. По стандарту файл обязан быть пустым, т.е. все его биты, кроме битов заголовка, должны быть установлены в значение EFI_FVB_ERASE_POLARITY. Используется он для выравнивания следующего за ним файла по границе, большей стандартных 8 байт. Минимальный размер PAD-файла равен размеру заголовка — 24 байта. К стандартным типам файлов мы еще вернемся.Attributes: важными для нас атрибутами являются FFS_ATTRIB_FIXED, указывающий на неперемещаемость файла внутри FV и набор FFS_ATTRIB_DATA_ALIGNMENT, указывающих на выравнивание данных (не заголовка) файла по какой-либо границе. Size: размер файла вместе с заголовком, хранится как 24-битный UINT.State: состояние файла. Это поле используется после загрузки FV в память и при операциях с файлами внутри FV. Состояние всех валидных файлов внутри образа BIOS — 0xF8.

Вернемся теперь к типам файлов. Тем, кто еще не читал полуторную часть этой статьи рекомендую сходить и почитать, иначе рискуете ничего не понять. Как мы уже знаем, определено 13 стандартных типов файлов, вот они:

Название Тип Описание
RAW 0x01 Структура такого файла полностью определяется его пользователем, и о ней заранее ничего не известно
FREEFORM 0x02 Такой файл имеет секционную структуру, но о содержимом секций заранее ничего не известно
SECURITY_CORE 0x03 Ядро Security, выполняющее код в фазе SEC
PEI_CORE 0x04 Ядро PEI, оно же PEI Foundation
DXE_CORE 0x05 Ядро DXE, оно же DXE Foundation
PEIM 0x06 Модуль PEI
DRIVER 0x07 Драйвер DXE
COMBINED_PEIM_DRIVER 0x08 Гибридный модуль PEI/DXE
APPLICATION 0x09 Приложение. От драйвера DXE отличается тем, что его запускает не диспетчер DXE, а пользователь. Приложениями являются UEFI Setup, UEFI Shell, BIOS Update и т.п.
SMM 0x0A Модуль SMM
FIRMWARE_VOLUME_IMAGE 0x0B Образ FV. Это специальный файл, позволяющий вложить один FV в другой
COMBINED_SMM_DXE 0x0C Гибридный модуль SMM/DXE
SMM_CORE 0x0D Ядро SMM, оно же SMM Init
Проверим вышеуказанное на нашем файле: Первые 0x48 байт заголовка FV нас уже не интересуют, а интересует то, что сразу за ними. Видно, что там находится файл с GUID CEF5B9A3-476D-497F-9FDC-E98143E0422C, контрольной суммой заголовка 0x36, контрольной суммой данных 0xAA, что указывает на снятый атрибут FFS_ATTRIB_CHECKSUM, типа RAW (0x01), без атрибутов, размера 0x1FFB8 и в стандартном состоянии. Похоже на правду.

Теперь о секциях. Все файлы FFS, кроме RAW, должны быть разделены на секции, выравненные по границе 4 байта от начала области данных файла. К каждому типу файлов со стороны стандарта предъявляются свои требования к количеству и типу секций, но списка требований в этой статье не будет — он слишком длинный и слишком скучный. А вот заголовки секций, их назначение и типы мы сейчас рассмотрим.

Заголовок секции
Минимальный заголовок секции выглядит так: typedef struct { UINT8 Size[3]; UINT8 Type; } EFI_COMMON_SECTION_HEADER; Size: размер секции в том же формате, что и в заголовке файла.Type: тип секции. Секции делятся на два подкласса — encapsulation и leaf. В первых могут содержатся секции других типов, а вторые содержат непосредственно данные. Секции некоторых типов имеют расширенные заголовки, но начало всегда совпадает с общим. Для encapsulation-секций определено 3 типа содержимого: 0x01 — EFI_SECTION_COMPRESSION, указывает на то, что секция сжата по какому либо алгоритму. Полностью заголовок EFI_COMPRESSION_SECTION (слова в названии не перепутаны, именно так) выглядит так:typedef struct { UINT8 Size[3]; UINT8 Type; UINT32 UncompressedSize; UINT8 CompressionType; } EFI_COMPRESSION_SECTION;UncompressedSize: размер распакованных данных.CompressionType: применяемый алгоритм сжатия. В данный момент встречаются 2 алгоритма сжатия — Tiano (0x01) и LZMA (0x02). Если секция была распакована без изменения структуры, то в качестве типа сжатия установлен 0x00, а размер секции совпадает с размером упакованных данных. Алгоритм Tiano — это комбинация LZ77 и кода Хаффмана за авторством Intel, код сжатия и распаковки можно взять из файлов проекта TianoCore под BSDL. Алгоритм LZMA слишком известен, чтобы рассказывать о нем еще раз, код сжатия и распаковки — в LZMA SDK.

Продолжим о типах encapsulation-секций: 0x02 — EFI_SECTION_GUID_DEFINED, указывает на то, что содержимое секции должно рассматриваться пользователем файла в соответствии с GUID, записанным в нем. Именно в такой секции могут храниться различные данные OEM, а также электронная подпись секции или всего файла. 0x03 — EFI_SECTION_DISPOSABLE, указывает на секцию, данные в которой не важны для работы файла и могут быть удалены при пересборке для экономии места. В реальных файлах BIOS не встречается. Для leaf-секций определено 12 типов содержимого:

Название Тип Описание
PE32 0x10 64-битный исполняемый код в формате PE32+ со всеми его заголовками. Основной формат исполняемого кода в UEFI.
PIC 0x11 64-битный исполняемый код, не зависящий от позиции. Используется только некоторыми модулями PEI, формат совпадает с PE32+, только информация о relocation обрезана.
TE 0x12 64-битный исполняемый код, используемый модулями и ядром PEI. От PE32+ отличается заголовком, который уменьшен для экономии места в кэше процессора. Его описание читайте в полуторной части этой статьи.
DXE_DEPEX 0x13 Секция, описывающая зависимости драйвера DXE, в котором она находится. Формат этой секции описан в Volume 2
VERSION 0x14 Содержит версию файла и опционально Unicode-строку с полной версией. Встречается довольно редко.
USER_INTERFACE 0x15 Содержит Unicode-сроку с именем файла. Очень удобно искать файлы по содержимому этой секции. Используется часто, но встречаются и BIOS'ы без единого файла с такой секцией.
COMPATIBILITY16 0x16 16-битный исполняемый код для совместимости со старыми системами.
FIRMWARE_VOLUME_IMAGE 0x17 Секция с образом FV. Внутри этого FV может быть еще файл с такой секцией, и так далее, пока место в микросхеме не закончится.
FREEFORM_SUBTYPE_GUID 0x18 Секция содержит данные, интерпретация которых зависит от записанного ее начало GUID. Используется редко.
RAW 0x19 Секция с сырыми данными. Что с ними делать — определяет тот, кто этот файл открыл.
PEI_DEPEX 0x1B Секция, описывающая зависимости модуля PEI, в котором она находится. Формат этой секции описан в Volume 1.
SMM_DEPEX 0x1C Секция, описывающая зависимости драйвера SMM, в котором она находится, формат совпадает с DXE_DEPEX.
Проверим вышеуказанное на нашем примере. Рассматриваемый в прошлый раз файл типа RAW никаких секций не содержит, поэтому возьмем другой файл, а именно — модуль PEI по имени PchUsb, находящийся по смещению 0x7AD210: Видно, что это действительно PEIM (тип файла — 0x06), который содержит две секции. Первая секция размера 0x3A и типа PEI_DEPEX (0x1B) содержит информацию о его зависимостях. Вторая секция (выровненная по границе 4 байта) имеет размер 0x31A и тип COMPRESSED_SECTION (0x01), а данные в ней упакованы алгоритмом LZMA (0x02) и после распаковки имеют размер 0x558. Если вы умеете распаковывать LZMA в уме, вы уже догадались, что внутри у этой секции, если же нет, я вам расскажу. Там еще 2 секции: PE32 с исполняемым кодом модуля и USER_INTERFACE с именем файла. Спрашиваете, откуда я это знаю, если не умею распаковывать LZMA в уме? There's an app for that!
PhoenixTool и заключение
Называется это приложение PhoenixTool и основная его задача — это добавление SLIC в файлы UEFI BIOS, но мы люди законопослушные и SLIC в наш BIOS добавлять не станем. Из всех функций программы нас будет интересовать кнопка Structure, доступная после указания BIOS, с которым мы будем работать. Структура открывается в отдельном окне и представляет образ UEFI BIOS'а в виде дерева. По каждому компоненту справа отображается информация о нем и доступные действия. Рассмотренный в примере выше файл в этом окне выглядит так: Программа позволяет ограниченное редактирование структуры файла, но лучше всего её не изменять, во избежание.

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

Литература
UEFI Platform Initialization Specification 1.2.1 Errata A, Documents by UEFI Forum

habr.com