А. А. Корнев г. Москва, ФГУП «НПЦ «Дельта» ОПЕРАЦИОННАЯ СИСТЕМА ДЛЯ ПОСТРОЕНИЯ СПЕЦИАЛИЗИРОВАННЫХ КОМПЛЕКСОВ ДОВЕРЕННОЙ ОБРАБОТКИ ИНФОРМАЦИИ. В статье рассматривается проблема создания операционной системы для построения специализированных комплексов доверенной обработки информации. Доверенная обработка подразумевает отсутствие возможности несанкционированного вывода информации во внешнюю среду, так называемых «утечек» информации, через какие-либо каналы ввода-вывода. Рассматривается концепция и практическая реализация системы с минимальным ядром как базового компонента комплекса обработки информации. Ключевые слова: операционная система, информационная безопасность, доверенная обработка информации. А. А. Kornev OPERATING SYSTEM FOR CONSTRUCTING SPECIALIZED TRUSTED INFORMATION PROCESSING SYSTEMS The paper describes the problem of building an operating system for specialized trusted information processing system development. Trusted treatment implies the absence of the possibility of unauthorized information output to the external environment, the so-called "leakage" of information, through any input-output channels. The concept and practical implementation of the system with a minimal kernel as a basic component of the information processing system is described. Keywords: operating system, information security, trusted information processing. Одной из основных угроз информационной безопасности является утечка информации. Под утечкой будем понимать несанкционированный вывод информации во внешнюю среду через какие-либо каналы ввода-вывода. Опасность утечки информации существует во многих широко применяемых операционных системах и в вычислительных комплексах, работающих под их управлением. Именно к операционным системам мы предъявляем наибольшие требования по безопасности как к модулям, имеющим наивысший уровень привилегий по исполнению операций, по доступу к данным и устройствам. В работе рассматриваются две типичные ситуации, потенциально приводящие к образованию каналов утечки. Первая ситуация связана с наличием недокументированных или неуправляемых механизмов ввода-вывода в операционной системе. Подобная опасность сохраняется во многих широко распространенных операционных системах, в том числе, в системах с открытым кодом. Учитывая большой объем таких систем, даже наличие открытого кода не дает возможности гарантировать отсутствие каких-либо скрытых механизмов взаимодействия вычислительного комплекса с внешней средой. Вторая ситуация связана с наличием алгоритмических ошибок в программном коде и, как следствие, возникновением сбоев, потенциально способных привести к образованию каналов утечки. Наличие ошибок является свойством программных продуктов. Исследования [1] показывают, что среднее число ошибок оценивается как 6 на 1000 строк кода, причем это оценка снизу. Кроме того, количество ошибок увеличивается с увеличением объема кода. Дополнительные проблемы возникают при использовании в разработках стороннего кода, который также априори содержит ошибки. Даже если удалось обнаружить ошибку в чужом коде и локализовать, исправление ее без непосредственного участия автора может иметь непредсказуемые последствия с появлением целого спектра новых ошибок. Отметим, что обе описанные ситуации представляют наибольшую угрозу, когда они возникают в модулях, работающих на высоком уровне привилегий. Как правило, это достигается в ядре операционной системы. Заметим, что отладка модулей, работающих в режиме ядра, является существенно более трудоемкой, чем отладка прикладных модулей. Многие широко применяемые операционные системы состоят из большого количества модулей (здесь, в первую очередь, речь идет о драйверах), работающих в режиме ядра ОС. Они фактически представляют собой составные части ядра монолитной системы. В таких системах объем потенциально опасного кода велик. Добавим здесь, что в больших системах принципиально невозможно проведение экспертного анализа одним экспертом. Такие системы анализируются по частям разными специалистами, в ущерб анализу системы в целом. В качестве пути решения этих проблем предлагается создание минимальной операционной системы, а точнее системы с минимальным ядром. По мере возможности, все компоненты и, в первую очередь, драйверы устройств, должны быть вынесены на прикладной уровень. Сформулируем основные требования к операционной системе. 1. Отказ от использования сторонних разработок. 2. Минимизация кода, работающего на высоком уровне привилегий. 3. Модульная организация. 4. Централизация управления ресурсами. 5. Прозрачность алгоритмов и их реализации. Требование по модульной организации преследует две цели. Во-первых, обеспечить эффективную изоляцию ошибок внутри каждого модуля. Сбой в работе одного модуля не должен приводить к сбою в работе остальных модулей. Во-вторых, обеспечить гибкость конфигурирования системы под конкретную задачу. Специализированная вычислительная система должна содержать минимально необходимый и достаточный функционал. В соответствии с требованиями разработана архитектура операционной системы и ядро как основной ее элемент. Ядро ориентировано на платформу Intel x86 c использованием защищенного 32-х разрядного режима процессора и состоит из 8 основных функциональных компонентов, как показано на рис. 1. В системе реализуется два кольца защиты: нулевое для ядра и третье для всех остальных программ. Ядро (80 Кб) Драйверы и приложения Менеджер объектов Процесс 1 Менеджер ресурсов шины PCI Процесс 2 Менеджер памяти Планировщик процессов Процесс 3 Процесс N API Диспетчер сообщений Криптомодуль Видео подсистема Кольцо 3 Кольцо 0 Рис. 1. Архитектура операционной системы. Менеджер объектов является основным инструментом реализации требования по централизации управления ресурсами. Он обеспечивает управление и поддержание целостности таблицы некоторых структур, так называемых объектов ядра, служащих для управления мультипрограммной средой и организации взаимодействия между программами (процессами). Объекты ядра характеризуются своим идентификатором, типом, владельцем и содержат некоторые служебные данные, состав которых определяется типом объекта. Определим следующие 9 типов объектов ядра. 1. Процесс – это объект, представляющий программу. Процесс определяет указатель на каталог страниц виртуальной памяти (CR3), указатель на блок сегментов состояния задачи (TSS), указатель на первую страницу кучи, указатель на главный поток. Процесс содержит виртуальные указатели на блок исполняемого кода и блок данных, а также их размеры. Процесс является владельцем всех ресурсов, используемых программой. 2. Поток – это объект, представляющий контекст выполняемой функции. Поток обладает блоком служебных страниц, в которых располагаются стеки, буферы для сообщений и запросов. Поток содержит указатель на TSS, виртуальные указатели чтения и записи в буфере сообщений. Каждый процесс является владельцем, по крайней мере, одного (главного) потока. 3. Набор физических страниц (НФС) – это объект, представляющий непрерывный набор последовательно расположенных в физической памяти страниц и служащий для обмена данными между процессами. НФС характеризуется указателем на первую страницу, количеством выделенных страниц и статусом использования. ОС выделяет физические страницы при создании объекта НФС и освобождает их при уничтожении. Перед использованием НФС должен быть спроецирован в АП процесса (заблокирован), после использования должен быть разблокирован. НФС может быть спроецирован в АП как владельца, так и другого процесса. При проецировании НФС в АП происходит его блокировка, так что никакие два процесса не могут одновременно владеть проекциями одного и того же НФС. 4. Устройство – это объект, представляющий некий абстрактный компонент, способный выполнять какие-либо функции по принципу «черного ящика». Функциональным компонентом может являться как физическое устройство (например, жесткий диск), так и логическое (например, программный архиватор). Устройство характеризуется кодом производителя (в случае с физическим устройство это код Vendor/Product), кодом класса, определяющим функционал устройства (например, класс «Устройства хранения данных», «Сканеры» или «Программные кодеки»). Код производителя и код класса используются как драйверами для выявления поддерживаемых ими устройств в системе, так и приложениями для выявления наличия требуемого функционала в других программах. Создавая в ОС объекты-устройства, одна программа может предоставлять другим программам часть своего функционала для использования. Программу, создающую в ОС объекты-устройства, предлагается условно называть драйвером. Программу, не создающую объекты-устройства, но, возможно, использующую «чужие» устройства, предлагается называть приложением. 5. Сервис – это объект, обеспечивающий доступ к устройствам. Для того, чтобы использовать устройство, программа должна создать соответствующий ему сервис (открыть устройство). Далее все операции с устройством осуществляются через созданный сервис. Сервис содержит указатель на устройство и статус устройства. Указатель на устройство становится недействительным (равным нулю) при уничтожении устройства. 6. Файл – это объект, обеспечивающий доступ к дисковым файлам. Файл содержит указатель на сервис, связанный с устройством класса "Логический том". Функции по работе с файлами инициируют запросы к соответствующему устройству драйвера файловой системы. 7. Таймер – это объект, обеспечивающий измерение временных интервалов. Единицей измерения является 1/1024 с. Таймер циклически посылает сообщения создавшей его программе через указанный временной интервал. Таймер характеризуется величиной измеряемого интервала и временем, прошедшим с момента последней регистрации события. 8. Окно – это объект, определяющий прямоугольную область экрана, через которую программа выводит графическое изображение. Окно характеризуется двумерными координатами левого верхнего и правого нижнего угла (в пикселах), буфером для изображения, определенным как НФС и спроецированным в АП процессавладельца окна. Окно может быть видимым и невидимым. Все окна в ОС сортируются по глубине: окна с меньшей глубиной перекрывают окна с большей глубиной, нулевая глубина соответствует окну, находящемуся сверху. Глубина может стать отличной от нуля только в случае наличия пересечений окон. 9. Криптографический преобразователь – это объект, определяющий вычислитель по алгоритму ГОСТ 28147-89. Состояние преобразователя определяется загруженным ключом, 11-ю масками и таблицей замен. Таблица замен хранится в развернутом виде (декартово произведение строк). Ключ и 11 масок хранятся в развернутом виде последовательно и раздельно для базовых циклов зашифрования и расшифрования [2]: (К0К1К2К3К4К5К6К7К0К1К2К3К4К5К6К7К0К1К2К3К4К5К6К7К7К6К5К4К3К2К1К0) ×12 (К0К1К2К3К4К5К6К7К7К6К5К4К3К2К1К0К7К6К5К4К3К2К1К0К7К6К5К4К3К2К1К0) ×12, где Кi – 4-байтовый элемент ключа (маски). Менеджер ресурсов шины PCI обеспечивает ограничение доступа к устройствам. В целях повышения уровня безопасности предполагается минимально использовать устройства, непосредственно подключаемые к шине PCI, отдавая предпочтение аналогичным USB-устройствам (если это возможно). Наличие возможности у PCIустройств осуществлять прямой доступ к физической памяти является дополнительным источником угрозы безопасности: например, ошибка при настройке параметров прямого доступа в драйвере PCI-устройства может привести к фатальному сбою системы или, что в нашем случае более опасно, выводу во внешнюю среду содержимого защищаемых областей физической памяти. Полностью отказаться от применения PCI-устройств не удается; как минимум, требуется обеспечить взаимодействие с USB-контроллерами типа UHCI/EHCI. Менеджер ресурсов шины PCI обеспечивает разделение доступа программ (драйверов) к конфигурационным пространствам устройств, к проекциям (mapping) памяти устройств и пространству ввода-вывода. Менеджер памяти обеспечивает формирование изолированных виртуальных адресных пространств для всех программ, а также, при необходимости, разделяемых областей памяти на основе страничного механизма. Он играет свою роль в изоляции и отладке ошибок, так как основная масса программных ошибок связана именно с некорректным использованием памяти. Отличительной чертой организации динамической памяти является то, что связный список областей доступной и занятой памяти («куча») поддерживается на уровне ядра для каждой программы. В «куче» находят свое отражение как операции выделения и освобождения памяти, так и операции проецирования разделяемых физических страниц. Реализация «кучи» в защищенных страницах ядра позволяет избежать сложные в отладке ошибки, при которых вследствие некорректной работы с памятью происходит повреждение служебных страниц самой «кучи». Кроме того, это позволяет производить диагностику наличия «утечек» памяти непосредственно ядром при отладке программ. Полагаем, что «утечкам» памяти следует уделять самое пристальное внимание как явлению, косвенно свидетельствующему о некорректном использовании памяти программой. Заметим, что само ядро реализовано исключительно на статической памяти в целях повышения его надежности. Планировщик реализует механизм вытесняющей многозадачности, исключая блокировку системы каким-либо процессом. Планирование процессов производится по принципу равноправия прикладных программ и приоритета потока ядра на основе значений семафоров, отображающих текущее состояние потоков: готовность к выполнению, ожидание завершения обработки запроса, ожидание поступления сообщения, ожидание истечения заданного интервала времени, ожидание уничтожения. Диспетчер сообщений обеспечивает взаимодействие процессов через механизмы посылки коротких асинхронных сообщений, а также выполнения синхронных или асинхронных запросов. Запросы отличаются от сообщений тем, что ориентированы на передачу больших объемов данных между программами и наделены средствами контроля их обработки адресатом. Диспетчеризация сообщений вместе с применением объектов ядра типа «Устройство» и «Сервис» позволяют строить многозвенные цепочки драйверов, реализующих многоуровневые протоколы. Криптомодуль реализует функционал объекта ядра типа «Криптографический преобразователь» и служит для контроля целостности загружаемых программ, а также как вспомогательное средство шифрования для ряда прикладных задач. Видео подсистема обеспечивает поддержку работы видеоадаптера в графическом режиме с двойной буферизацией, программной обработкой курсора, а также поддержкой непрямого доступа приложений к видеопамяти через оконный механизм. Заметим, что реализация непосредственно графических элементов управления не входит в подсистему, обеспечивается лишь синхронизация оконных буферов с «задним» буфером, а также «заднего» буфера с кадровым. Взаимодействие программ с ядром осуществляется через интерфейс программирования приложений (API), реализованный на основе механизма программных прерываний и насчитывающий 85 функций. Разработанная по сформулированным принципам построения операционная система позволит в работающих под ее управлением вычислительных комплексах проводить доверенную обработку информации. Размер ядра, обеспечивающего описанный выше функционал, составляет около 80 Кб или 7300 строк программного кода на языке С. Базовый комплект драйверов включает в себя: драйверы контроллеров UHCI/EHCI и IDE/SATA, драйвер устройств хранения данных типа USB Mass Storage Device, драйверы файловых систем FAT16/32 и ISO-9660. Размер операционной системы с установленным базовым комплектом драйверов не превышает 500 Кб. Дополнительно могут быть установлены драйверы других периферийных устройств, а также драйверы виртуальных устройств типа кодеков, архиваторов, СУБД и т. д. Разработанная операционная система соответствует сформулированным выше требованиям. Она позволяет строить на ее основе вычислительные комплексы с минимальным объемом привилегированного кода, модульные, гибко конфигурируемые, с обеспечением изоляции сбоев и возможностью загрузки практически с любого носителя, в том числе с отчуждаемого непосредственно по окончании загрузки. Такая система позволит в работающих под ее управлением вычислительных комплексах проводить доверенную обработку информации. БИБЛИОГРАФИЧЕСКИЙ СПИСОК 1. Ostrand T., Weyuker E., Bell R. Where the Bugs Are. In Proc. of the 2004 ACM SIGSOFT Int’l Symp. on Software Testing and Analysis, P 86–96. ACM, 2004. 2. Винокуров А. Алгоритм шифрования ГОСТ 28147-89, его использование и реализация для компьютеров платформы Intel x86 [Электронный ресурс] // http://www.enlight.ru/crypto/articles/vinocurov/gost_i.htm.