Летом 2015 года перед нами, разработчиками «Кода безопасности», встала задача реализации защищенного хранилища под Android с шифрованием по стандартам, признанным российским законодательством. До этого у нас уже было решение на планшете, к которому имелись исходники Android. И это позволило нам выпустить обновленное ядерное шифрование (dm-crypt) под поддержку ГОСТ 89, добавить в /system/lib ГОСТ-библиотеки, пропатчить cryptofs подсистему демона vold. В итоге в нашем распоряжении оказалось решение, которое подходило лишь для определенной модели планшета, и не являлось универсальным. Узнав, что в Android версии 4.4 (API уровня 19) появился API, позволяющий осуществлять доступ к данным после регистрации и реализации своего кастомного DocumentsProvider, мы решили создать решение, использующее GOST-шифрование в userspace с использованием данного API, которое не зависело бы от модели устройства.
Для тех, кто заитересовался — добро пожаловать под кат.
Как в Android данные шифруются
Кратко опишу процесс шифрования Android-устройства. Активируется шифрование следующим образом: Settings > Security > Encrypt tablet/phone, реализуется средствами linux kernel > dev-mapper > dm-crypt. При активации данной функциональности устройство запросит пароль, а также попросит сохранить и зашифровать данные из /data (или просто удалит все данные по желанию пользователя). После перезагрузки устройства появится окно ввода пароля, в системных настройках переменная ro.crypto.state будет установлена в состояние encrypted.
Стандартное шифрование разделов в Android базируется на модели FDE (full-disk encryption). Модель является обычной подсистемой ядра Linux – device mapper и обеспечивает прозрачное шифрование. Доступ к данным (например, к разделу /data) предоставляется через виртуальное блочное устройство /dev/block/dm-0, которое каждый io-request шифрует или расшифровывает в режиме AES-CBC на 128-битном секторном ключе, который вычисляется от IV (инициализационного вектора).
Рис. 1: Логическая схема шифрования Android
На схеме представлена последовательность запроса Pin от ключевого контейнера и установки master-key через syscall ioctl в ядерную часть dm-crypt.
Access framework (SAF)
Для применения приложения в java-space мы используем Storage Access Framework (SAF), или платформу доступа к хранилищу. На сайте developer.android.com довольно подробно описаны все свойства и нюансы использования этой платформы, здесь мы отметим лишь основные моменты.
Итак, SAF появилась в Android версии 4.4 (API уровня 19) и она облегчает пользователям поиск и открытие документов, изображений и других файлов в хранилищах всех поставщиков. Стать поставщиком этих файлов мы можем, реализовав класс DocumentsProvider и использовав несколько его методов (об этом ниже).
Вся платформа SAF состоит из следующих элементов:
1) «Клиент» – приложение, которое хочет получить доступ к файлу или создать новый файл. Для всей Android-системы это возможно с помощью интентов с флагами ACTION_OPEN_DOCUMENT и ACTION_CREATE_DOCUMENT соответственно.
2) «Поставщик документов» – наше приложение, которое, как упоминалось выше, является подклассом класса DocumentsProvider и реализует доступ к файлам через API (об этом далее).
3) «Элемент выбора» – системный пользовательский интерфейс, обеспечивающий пользователям доступ к файлам всех поставщиков, удовлетворяющих критериям поиска.
Теперь подробнее. Поставщик документов предоставляет один или несколько корневых каталогов, являющихся отправными точками при обходе дерева документов. Каждый корневой каталог имеет уникальный идентификатор COLUMN_ROOT_ID и указывает на документ (каталог), представляющий содержимое на уровне ниже корневого. Корневые каталоги динамичны по своей конструкции, что обеспечивает поддержку различных вариантов использования: нескольких учетных записей, временных хранилищ на USB-накопителях, возможности входа/выхода в систему/из системы.
Каждый сервер хранилища показывает отдельные файлы и каталоги, ссылаясь на них с помощью уникального идентификатора COLUMN_DOCUMENT_ID (в нашем случае, это полный путь от корня файловой системы до самого файла). Идентификаторы документов должны быть уникальными и не меняться после присвоения, поскольку они используются для выдачи постоянных URI, не зависящих от перезагрузки устройства.
Документ – это либо открываемый файл (имеющий конкретный MIME-тип), либо каталог, содержащий другие документы (с MIME-типом MIME_TYPE_DIR). Каждый документ может иметь различные свойства, описываемые флагами COLUMN_FLAGS, такими как FLAG_SUPPORTS_WRITE, FLAG_SUPPORTS_DELETE и FLAG_SUPPORTS_THUMBNAIL.
Рис. 2: Модель данных поставщика документов
Модель данных поставщика документов основана на традиционной файловой иерархии. Однако физический способ хранения данных остается на усмотрение разработчика при условии, что к ним можно обращаться через API-интерфейс DocumentsProvider. Например, можно использовать для данных облачное хранилище на основе тегов.
Обратите внимание на следующий рисунок:
Рис. 3: Модель взаимодействия поставщика документов и клиента
На платформе SAF поставщики и клиенты не взаимодействуют напрямую. Клиент запрашивает разрешение на взаимодействие с файлами (на их чтение, редактирование, создание или удаление).
Взаимодействие начинается, когда приложение (в нашем примере – обрабатывающее фотографии) активирует намерение ACTION_OPEN_DOCUMENT или ACTION_CREATE_DOCUMENT. Намерение может включать в себя фильтры для уточнения критериев, например, «предоставить открываемые файлы с MIME-типом image».
Когда намерение срабатывает, системный элемент выбора переходит к каждому зарегистрированному поставщику и показывает пользователю корневые каталоги с контентом, соответствующим запросу. Элемент выбора предоставляет пользователю стандартный интерфейс, даже если поставщики документов значительно различаются.
В Android версии 4.3 и ниже приложение для получения файла от другого приложения должно активировать намерение, например, ACTION_PICK или ACTION_GET_CONTENT. После этого пользователь должен выбрать одно из приложений, а оно должно предоставить пользователю интерфейс, с помощью которого он сможет выбирать и получать файлы.
Рис. 4: Диалог выбора поставщика документов
Рис. 5: Диалог выбора получателя документа
Регистрация как document provider
Следующим шагом в разработке собственного поставщика документов является создание подкласса абстрактного класса DocumentsProvider. Как минимум необходимо реализовать следующие методы:
queryRoots ()
queryChildDocuments ()
queryDocument ()
OpenDocument ()
Реализация данных методов строго обязательна, однако для реализации полнофункционального приложения придется реализовать и другие. Подробности приводятся в описании класса DocumentsProvider.
JNI
Следующая логическая часть – это JNI-реализация прослойки между нашей реализацией SAF и открытой библиотекой файловой системы для встраиваемых систем FATFS. Последняя была пропатчена на чтение-запись на файл (в нашем случае он выступает томом) поблочно. Таким образом, на IO-запрос мы получаем номер сектора и количество секторов, отсюда можно вычислить IV и секторный ключ, а затем зашифровать и расшифровать конкретный блок на файле. В итоге у нас получается аналог dm-crypt в userspace.
Рис. 6: Проброс методов SAF в нативную часть и обратно
Далее мы реализовали методы для работы с томами и файлами. Для работы с томами используем следующие функции:
Java_com_securitycode_fatfslib_FatFs_createVolume (...);
Создает файл тома через библиотеку файловой системы и создает внутри этого файла пустую шифрованную FS.
Рис. 7: Создание защищенного хранилища
Java_com_securitycode_fatfslib_FatFs_getVolumeFreeSpace (...);
Передав в функцию определенный том, мы получаем количество свободного места в этом томе.
Java_com_securitycode_fatfslib_FatFs_mount (...);
При монтировании тома мы устанавливаем мастер-ключ, с помощью которого будет происходить шифрование-расшифрование блоков FS.
Рис.8: Монтирование защищенного хранилища
Java_com_securitycode_fatfslib_FatFs_unMount (...);
Очистка ресурсов и завершение операций ввода-вывода.
Для работы с файлами:
Java_com_securitycode_fatfslib_FatFs_createFile (...);
На нашей файловой системе создается объект пустого файла с заданными размером и типом (необходим для SAF).
Java_com_securitycode_fatfslib_FatFs_getFile (...);
Данная функция необходима для SAF-метода queryDocument (...).
В функции мы возвращаем id файла, его тип, корневой узел, содержащий текущий файл и имя файла.
Java_com_securitycode_fatfslib_FatFs_readFile (...);
В данной функции создается Java-stream, который используется в SAF и в качестве URI передается потребителю.
Java_com_securitycode_fatfslib_FatFs_writeFile (...);
Аналогично предыдущей функции, только в данном случае потребителем становимся мы.
Рис.9: Общий экран приложения
Рис.10: Содержимое хранилища
Заключение
В результате всех вышеперечисленных действий мы получили криптодиск с поддержкой ГОСТ-шифрования и электронной подписи в userspace.
Будем рады ответить на ваши вопросы и более подробно рассказать обо всех этапах проекта.
Источники:
1) Nikolay Elenkov. Android Security Internals, Chapter 10: Device Security.
2) Шифрование диска в Android
source.android.com/security/encryption
3) Documents Provider и SAF
developer.android.com/intl/ru/guide/topics/providers/document-provider.html
4) FatFs — Generic FAT File System Module
elm-chan.org/fsw/ff/00index_e.html
Комментарии (36)
SannX
30.03.2016 08:02Для инфо: вот тут описаны особенности FDE в Android разных версий и примеры взлома/брутфорса паролей/ПИНов. Например, в версии 4.4, если ПИН короткий (4 симв.), то взломать можно за 5 мин. Так что длина пароля имеет значение, а просто наличие шифрования не обеспечивает достаточную защиту.
icoz
30.03.2016 08:44Ссылка на исходники где? Или хотя бы сертификат регулятора?
IgnisFatuus
30.03.2016 08:50Во-первых продукт сейчас в бета-тестировании. Выкладывать его в таком виде немного преждевременно. Во-вторых комментарии выше я указал, что сертификация на данный продукт пока не начиналась (но есть в планах).
kpoxxx
30.03.2016 09:33А бета-тестером как стать? Или это внутреннее бета-тестирование?
IgnisFatuus
30.03.2016 09:36+1Сейчас проходит внутреннее тестирование, но в будущем возможно и открытое тестирование. По таким вопросам можно смело обращаться к нам через наш официальный сайт — что-нибудь придумаем!
amarao
30.03.2016 11:04-2Криптопродукт без открытых сырцов? Ну-ну.
IgnisFatuus
30.03.2016 11:32+1Цель статьи — рассказать о том как можно реализовать свой кастомный криптодиск в userspace. Как я уже упоминал — сейчас идет закрытый бета-тест. Повторюсь — если Вы хотите получить исходный код или поучаствовать в тестировании/опробовать продукт — добро пожаловать на наш официальный сайт — мы всегда охотно идем на сотрудничество.
bonv
30.03.2016 14:57+1А много Вы знаете криптопровайдеров с открытым кодом с поддержкой ГОСТ и сертифицированные ФСБ?
amarao
30.03.2016 15:14+1Каким образом сертификация ФСБ улучшает критографическую стойкость продукта?
Есть два типа криптографии: чтобы защищать информацию, и чтобы пилить бабло. Первое подразумевает публичный аудит и надёжность, второе — сертификаты, сертификаты, сертификаты.bonv
30.03.2016 15:44Каким образом сертификация ФСБ улучшает критографическую стойкость продукта?
Я этого не утверждал.
Сертификат дает право использовать это ПО для юридически значимого документооборота и не более.
IgnisFatuus
30.03.2016 15:56Не думаю, что сертификация ФСБ как-то негативно скажется на проекте с ГОСТ-шифрованием. Это даже будет плюс. Сертификат в купе с открытостью ГОСТ-алгоритмов как раз и обеспечивает безопасность.
milabs
31.03.2016 14:05Ну как бы, опыт OpenSSL говорит о том, что открытость и возможность аудита не являются критерием надёжности.
amarao
31.03.2016 15:57Как раз является. Потому что в другом софте оно бы так и осталось непопатченным и неотслеженным.
Опенсорс не является панацеей от багов, но точно прикрывает "NSA sponsored random". Кстати, сертификация ФСБ вызывает у меня аналогичные вопросы — какие именно требования по наличию бэкдоров предъявляет ФСБ к сертифицируемым продуктам?milabs
31.03.2016 18:19+1Это важный фактор, но не решающий. Так же, как и сертификация в ФСБ. Что значит — требования по "наличию бекдоров", поясните? Криптоалгоритмы открытые, есть желание изучать и искать закладки — пожалуйста. С другой стороны, в задачи сертификаторов входит проверка корректности применения этих самых алгоритмов, что на самом деле представляет собой бОльшую угрозу безопасности, чем те же самые невидимые бекдоры. Я считаю, что сертификация в ФСБ по СКЗИ имеет смысл, в отличии от сертификации ФСТЕК.
amarao
04.04.2016 12:33См Dual EC DRBG, с "закладочным" рандомом"
А искать закладки куда комфортнее при открытых исходных текстах. Закрыли исходные тексты? Значит, не хотите, чтобы их кто-то читал.milabs
04.04.2016 12:36Ну и много "закладок" нашли в OpenSSL?
amarao
04.04.2016 14:38Ну, Dual EC DRBG нашли же.
milabs
04.04.2016 14:40Ну так там же Сноуден поучаствовал. А что с хертблидом и компанией? Нет инсайда => не разоблачений? Эй, а как же опенсорс?))
amarao
04.04.2016 14:41Нет, опасения высказывали много раньше, Сноуден просто подтвердил. Heartbleed был найден (по сырцам или по бинарному тестированию) — не знаю.
milabs
04.04.2016 14:44Ну, знаете, высказать опасение не значит найти уязвимость. Я выскажу опасение, что задача дискретного логарифмирования, возможно, не такая уж вычислительно сложная. Такое опасение ставит под сомнение существующую криптографию на эллиптических кривых. Но что толку с моего опасения?
amarao
04.04.2016 14:57Перевожу на русский язык: открывать исходный текст криптоалгоритмов не нужно. Верьте нам, мы там не xor'им.
milabs
04.04.2016 16:31Тексты криптоалгоримов — это мизерная доля от общей кодовой базы продуктов. Открытость текстов не даст вам уверенности в том, что весь продукт безопасен. Ну убедитесь вы, что там не XOR. Ну и что? Так обвязка может всё шифрование на нет свести. Кстати, при сертификации в ФСБ как раз этот вопрос чаще всего и всплывает — реализация хорошая, только используется не правильно :-) Но вот эти 99,9% кода могу составлять "коммерческую тайну" и быть интеллектуальной собственностью компании. Что же теперь по вашей логике — весь код открывать?
amarao
04.04.2016 18:08Тайна так тайна. Только не предлагайте остальным верить, что эта тайна делает что-то, кроме XOR'а, который очень стыдно показать и который потому и тайна, что стыдно.
milabs
04.04.2016 18:41Ну как же, если есть сертификат ФСБ, то "верьте мне", там не XOR :-))))
amarao
04.04.2016 20:21Там есть сертификат, что есть то, что нужно ФСБ. А что нужно ФСБ знает только ФСБ, и уж точно это ортогонально интересам пользователя ПО.
milabs
04.04.2016 23:28Ну что вы за пользователя говорите. Вам нужна открытость — пользуйтесь PGP. Нужен ГОСТ в продакшене — пожалуйте под крыло ФСБ. И вот только не надо говорить, в развитых странах так не принято. И что требования регуляторов открытые для всех жедающих, вспоминая при этом пресловутые фипсы. Это верхушка айсберга, и очень хорошо, что подводную часть хоть как-то, но берегут)
Flemon
04.04.2016 16:24Может вы в курсе, каким именно образом проходят проверки в ФСБ при сертификации по СКЗИ? Как они это выполняют технически? Что за тесты они выполняют? Есть ли какое — то покрытие или еще что — то в этом духе.
Kolyuchkin
07.04.2016 13:39Если описать вкратце, то еще до процесса сертификации нужно согласовать ТЗ на изделие (СКЗИ, например) с соответствующими отделами ФСБ (в этом ТЗ отражены не только технические требования к изделию, но и специальные, в которых прописаны классы (уровни) защищенности и ФСБ-шные требования к изделию). Далее, после завершения разработки и испытаний изделия, наступает этап специальных и инженерно-криптографических исследований (в специализированной организации, имеющей соответствующую лицензию от ФСБ), результат которых и направляется в соответствующий отдел ФСБ. На основании этих результатов и выдается сертификат.
Короче, процесс этот не легкий.
Если Вы занимаетесь разработкой СКЗИ, то у вашей организации должны быть соответствующие лицензии и, соответственно, не должно возникать таких вопросов. Если же Вы спрашиваете из праздного любопытства, чтобы, например, убедиться в объективности сертификата ФСБ, то смогу Вас уверить (здесь уже субъективно), что СКЗИ с сертификатом ФСБ можно верить и доверять (при условии, что Вы соблюдаете правила пользования и условия эксплуатации).Flemon
08.04.2016 01:14Спасибо за ответ. Вопрос: что происходит на этапе специальных и инженерно-криптографических исследований?
Kolyuchkin
08.04.2016 09:46Проверка на «правильность» реализации криптографических алгоритмов. Проверка на выполнение требований ТЗ, в особенности подраздела «Специальные требования». Проведение экспериментальных проверок.
raiSadam
Отличная статья. И на злобу дня, учитывая судебный иск к apple на взлом.
Как на счет сертификации этого решения в контролирующих органах (ФСТЭК, МО или ФСБ)?
IgnisFatuus
В данный момент полным ходом идет сертификация других продуктов компании, для данного продукта сертификация тоже предусмотрена, но позже.
Abir4eg
А под какой класс планируете? КС1?
Будет интересно ключи хранить где-нибудь на синеглазом Рутокене.
IgnisFatuus
С Рутокен-устройствами работаем сейчас в одном из проектов. Столкнулись с тем, что при включении, (говорю по памяти, точные цифры надо утчнять)- на многих девайсах Рутокен очень долго инициализирует связь/обмен ключами и прпр. Очень долго — это примерно от 40 секунд до 2 минут. В проекте, который описан в статье это может и не так критично -один раз инициализировал, получил ключи и работай (какое-то время), но есть некоторые use-case в которых это может доставлять пользователям существенные неудобства