Ядро GKI включает модуль ядра Linux под названием fips140.ko, который соответствует требованиям FIPS 140-3 для криптографических программных модулей.
Этот модуль можно отправить на сертификацию FIPS, если это необходимо для продукта, в котором используется ядро GKI.
Прежде чем использовать криптографические процедуры, необходимо выполнить следующие требования FIPS 140-3:
- Модуль должен проверять собственную целостность, прежде чем предоставлять доступ к криптографическим алгоритмам.
- Модуль должен проверить одобренные криптографические алгоритмы с помощью самотестирования, прежде чем сделать их доступными.
Почему используется отдельный модуль ядра
Проверка FIPS 140-3 основана на идее, что после сертификации программного или аппаратного модуля он никогда не меняется. Если вы измените его, вам придется заново пройти сертификацию. Это не соответствует современным процессам разработки ПО. В результате программные модули FIPS обычно разрабатываются так, чтобы они были максимально сосредоточены на криптографических компонентах. Это гарантирует, что изменения, не связанные с криптографией, не потребуют ее повторной оценки.
Ядро GKI должно регулярно обновляться на протяжении всего срока поддержки. Поэтому разместить все ядро в модуле FIPS невозможно, так как такой модуль придется повторно сертифицировать при каждом обновлении ядра. Определение "модуля FIPS" как подмножества образа ядра смягчило бы эту проблему, но не решило бы ее, поскольку двоичное содержимое "модуля FIPS" по-прежнему менялось бы гораздо чаще, чем необходимо.
До версии ядра 6.1 GKI компилировался с включенной оптимизацией во время компоновки (LTO), поскольку она была необходима для проверки целостности потока управления – важной функции безопасности.
Поэтому весь код, на который распространяются требования FIPS 140-3, упакован в отдельный модуль ядра fips140.ko, который опирается только на стабильные интерфейсы, предоставляемые исходным кодом ядра GKI, на основе которого он был создан. Это означает, что модуль можно использовать с разными выпусками GKI одного поколения и что его нужно обновлять и повторно отправлять на сертификацию, только если в коде, который переносится самим модулем, были исправлены какие-либо проблемы.
Когда использовать модуль
Само ядро GKI содержит код, который зависит от криптографических процедур, также упакованных в модуль ядра FIPS 140-3. Таким образом, встроенные криптографические процедуры не удаляются из ядра GKI, а копируются в модуль. При загрузке модуля встроенные криптографические подпрограммы отменяются в Linux CryptoAPI и заменяются подпрограммами, которые переносятся модулем.
Это означает, что модуль fips140.ko является необязательным и его имеет смысл развертывать только в том случае, если требуется сертификация FIPS 140-3. Кроме того, модуль не предоставляет никаких дополнительных возможностей, а его загрузка без необходимости может повлиять на время загрузки системы.
Как развернуть модуль
Чтобы добавить модуль в сборку Android, выполните следующие действия:
- Добавьте название модуля в
BOARD_VENDOR_RAMDISK_KERNEL_MODULES. В результате модуль копируется в RAM-диск поставщика. - Добавьте название модуля в
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. В результате название модуля будет добавлено вmodules.loadна целевом устройстве.modules.loadсодержит список модулей, которые загружаютсяinitпри запуске устройства.
Самопроверка целостности
Модуль ядра FIPS 140-3 во время загрузки модуля создает дайджест HMAC-SHA256 для собственных разделов .code и .rodata и сравнивает его с дайджестом, записанным в модуле. Это происходит после того, как загрузчик модулей Linux уже внес обычные изменения, такие как обработка перемещения ELF и исправление альтернатив для ошибок ЦП. Чтобы обеспечить правильное воспроизведение дайджеста, выполняются следующие дополнительные действия:
- Перемещения ELF сохраняются внутри модуля, чтобы их можно было применить в обратном порядке к входным данным HMAC.
- Модуль отменяет все исправления кода, внесенные ядром для функции Dynamic Shadow Call Stack. В частности, модуль заменяет все инструкции, которые извлекают или помещают данные в теневой стек вызовов, на исходные инструкции кода аутентификации указателя (PAC).
- Для модуля отключено исправление любого другого кода, в том числе статических ключей и, следовательно, точек трассировки, а также хуков поставщика.
Самотестирование криптографического алгоритма
Модуль ядра FIPS 140-3 соответствует требованиям FIPS 140-3 к самотестированию криптографических алгоритмов, поскольку реализует тесты с известными ответами. Реализованные тесты зависят от алгоритма и соответствуют руководству по внедрению FIPS 140-3 10.3.A.
Как правило, для каждого алгоритма достаточно одного тестового вектора. Самопроверки криптографических алгоритмов FIPS предназначены только для проверки базовой функциональности. Комплексное тестирование проводится отдельно с использованием программы проверки криптографических алгоритмов (CAVP) и набора криптографических тестов ядра.
Если алгоритм имеет несколько реализаций, доступных пользователю или используемых сервисами модуля, стандарт FIPS 140-3 требует, чтобы все эти реализации были протестированы самостоятельно. Это важно для стратегии интеграции, традиционно используемой в Linux CryptoAPI, где у каждого алгоритма может быть несколько доступных пользователю реализаций. Например, в ядре android16-6.12 алгоритм SHA-256 реализован тремя способами: sha256-generic, sha256-arm64 и sha256-ce. На процессорах с криптографическими расширениями ARMv8 по умолчанию используется sha256-ce, но пользователи могут явно выбрать другие варианты. Поэтому модуль самостоятельно проверяет все три реализации.
В ядре android17-6.18 и более поздних версий некоторые алгоритмы используют более простую стратегию интеграции. Например, в ядре android17-6.18 у SHA-256 есть одна реализация sha256-lib, которая автоматически выбирает подходящий код для ЦП во время загрузки модуля. Поэтому модуль просто выполняет самотестирование.
sha256-lib
Алгоритмы, включенные в модуль
Ниже перечислены все алгоритмы, входящие в модуль FIPS 140-3.
Это относится к ветвям ядра android12-5.10, android13-5.10, android13-5.15, android14-5.15, android14-6.1, android15-6.6, android16-6.12 и android17-6.18, хотя различия между версиями ядра отмечаются, когда это необходимо.
| Алгоритм | Реализации | Возможность одобрения | Определение |
|---|---|---|---|
aes |
aes-generic, aes-arm64, aes-ce, библиотека AES |
Да | Простой блочный шифр AES без режима работы: поддерживаются все размеры ключей (128, 192 и 256 бит). Все реализации, кроме библиотечной, можно комбинировать с режимом работы с помощью шаблона. |
cmac(aes) |
cmac (шаблон), cmac-aes-neon, cmac-aes-ce |
Да | AES-CMAC: поддерживаются все размеры ключей AES. Шаблон cmac можно создать с помощью любого варианта реализации aes, используя cmac(. Остальные реализации являются автономными. |
ecb(aes) |
ecb (шаблон), ecb-aes-neon, ecb-aes-neonbs, ecb-aes-ce |
Да | AES-ECB: поддерживаются все размеры ключей AES. Шаблон ecb можно создать с помощью любого варианта реализации aes, используя ecb(. Остальные реализации являются автономными. |
cbc(aes) |
cbc (шаблон), cbc-aes-neon, cbc-aes-neonbs, cbc-aes-ce |
Да | AES-CBC: поддерживаются все размеры ключей AES. Шаблон cbc можно создать с помощью любого варианта реализации aes, используя cbc(. Остальные реализации являются автономными. |
cts(cbc(aes)) |
cts (шаблон), cts-cbc-aes-neon, cts-cbc-aes-ce |
Да | AES-CBC-CTS или AES-CBC с заимствованием зашифрованного текста: используется соглашение CS3; последние два блока зашифрованного текста безусловно меняются местами. Поддерживаются все размеры ключей AES. Шаблон cts можно создать с помощью любого варианта реализации cbc, используя cts(. Остальные реализации являются автономными. |
ctr(aes) |
ctr (шаблон), ctr-aes-neon, ctr-aes-neonbs, ctr-aes-ce |
Да | AES-CTR: поддерживаются все размеры ключей AES. Шаблон ctr можно создать с помощью любого варианта реализации aes, используя ctr(. Остальные реализации являются автономными. |
xts(aes) |
xts (шаблон), xts-aes-neon, xts-aes-neonbs, xts-aes-ce |
Да | AES-XTS: в ядре 6.1 и более ранних версиях поддерживаются все размеры ключей AES; в ядре 6.6 и более поздних версиях поддерживаются только AES-128 и AES-256. Шаблон xts можно создать с помощью любого варианта реализации ecb(aes), используя xts(. Остальные реализации являются автономными. Во всех реализациях выполняется проверка на слабый ключ, требуемая стандартом FIPS, то есть ключи XTS, первая и вторая половины которых равны, отклоняются. |
gcm(aes) |
gcm (шаблон), gcm-aes-ce |
Нет 1 | AES-GCM: поддерживаются все размеры ключей AES. Поддерживаются только 96-битные векторы инициализации. Как и в случае с другими режимами AES в этом модуле, за предоставление векторов инициализации отвечает вызывающий объект. Шаблон gcm можно составить с любыми реализациями ctr(aes) и ghash, используя gcm_base(. Остальные реализации являются автономными. |
sha1 |
Ядро 6.12 и более ранние версии: sha1-generic, sha1-ce |
Да | криптографическая хеш-функция SHA-1; Удалено в ядре 6.18 и более поздних версий. |
sha224 |
Ядро 6.18 и выше: sha224-lib. Ядро 6.12 и более ранние версии: sha224-generic, sha224-arm64, sha224-ce |
Да | Криптографическая хеш-функция SHA-224. Код используется совместно с SHA-256. |
sha256 |
Ядро 6.18 и более поздних версий: sha256-lib. Ядро 6.12 и более ранние версии: sha256-generic, sha256-arm64, sha256-ce, библиотека SHA-256 |
Да | криптографическая хеш-функция SHA-256; |
sha384 |
Ядро 6.18 и более поздних версий: sha384-lib. Ядро 6.12 и более ранние версии: sha384-generic, sha384-arm64, sha384-ce |
Да | Криптографическая хеш-функция SHA-384: код используется совместно с SHA-512. |
sha512 |
Ядро 6.18 и более поздних версий: sha512-lib. Ядро 6.12 и более ранних версий: sha512-generic, sha512-arm64, sha512-ce. |
Да | криптографической хеш-функции SHA-512. |
sha3-224 |
Ядро 6.6 и более поздних версий: sha3-224-generic |
Да | криптографическая хеш-функция SHA3-224; |
sha3-256 |
Ядро 6.6 и более поздних версий: sha3-256-generic |
Да | То же, что и выше, но с длиной дайджеста 256 бит (SHA3-256). Для всех длин дайджестов используется одна и та же реализация Keccak. |
sha3-384 |
Ядро 6.6 и более поздние версии: sha3-384-generic |
Да | То же, что и выше, но с длиной дайджеста 384 бита (SHA3-384). Для всех длин дайджестов используется одна и та же реализация Keccak. |
sha3-512 |
Ядро 6.6 и более поздних версий: sha3-512-generic |
Да | То же, что и выше, но с длиной дайджеста 512 бит (SHA3-512). Для всех длин дайджестов используется одна и та же реализация Keccak. |
hmac |
hmac (шаблон) |
Да | Код аутентификации сообщений с хешированием по ключу (HMAC). Шаблон hmac можно составить с любым алгоритмом SHA или реализацией с помощью hmac( или hmac(. |
stdrng |
Все ядра: drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512. Ядро 6.6 и более ранние версии: drbg_pr_hmac_sha1 |
Да | HMAC_DRBG, созданный с помощью именованной хеш-функции и с включенной устойчивостью к прогнозированию. Проверки работоспособности включены. Пользователи этого интерфейса получают собственные экземпляры DRBG. |
stdrng |
Все ядра: drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512. Ядро 6.6 и более ранние версии: drbg_nopr_hmac_sha1 |
Да | То же, что и алгоритмы drbg_pr_*, но с отключенным сопротивлением прогнозированию. Код используется в варианте, устойчивом к прогнозированию. В ядре 5.10 DRBG с наивысшим приоритетом – drbg_nopr_hmac_sha256. В ядре 5.15 и более поздних версиях – drbg_pr_hmac_sha512. |
jitterentropy_rng |
jitterentropy_rng |
Нет | Jitter RNG версии 2.2.0 (версия ядра 6.1 и ниже) или версии 3.4.0 (версия ядра 6.6 и выше). Пользователи этого интерфейса получают собственные экземпляры Jitter RNG. Они не используют экземпляры, которые применяются в DRBG. |
xcbc(aes) |
xcbc-aes-neon, xcbc-aes-ce |
Нет | |
xctr(aes) |
Ядро 5.15 и более поздние версии: xctr-aes-neon, xctr-aes-ce |
Нет | |
cbcmac(aes) |
cbcmac-aes-neon, cbcmac-aes-ce |
Нет | |
essiv(cbc(aes),sha256) |
essiv-cbc-aes-sha256-neon, essiv-cbc-aes-sha256-ce |
Нет |
1. Реализации AES-GCM в модуле могут быть одобрены для алгоритма, но не для модуля. Их можно проверить, но AES-GCM нельзя считать одобренным алгоритмом с точки зрения модуля FIPS. Это связано с тем, что требования FIPS к модулю GCM несовместимы с реализациями GCM, которые не генерируют собственные векторы инициализации.
Сборка модуля из исходного кода
Для Android 14 и более поздних версий (включая android-mainline) соберите модуль fips140.ko из исходного кода, используя следующие команды:
Сборка с помощью Bazel:
tools/bazel run //common:fips140_distПострой объект "
build.sh" (устаревшее):BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
Эти команды выполняют полную сборку, включая ядро и модуль fips140.ko со встроенным содержимым дайджеста HMAC-SHA256.
Руководство для конечных пользователей
Руководство для специалиста по шифрованию
Чтобы использовать модуль ядра, операционная система должна работать в режиме одного оператора. Это происходит автоматически с помощью аппаратного обеспечения управления памятью в процессоре.
Модуль ядра нельзя установить отдельно. Он входит в состав встроенного ПО устройства и загружается автоматически при запуске. Оно работает только в одобренном режиме.
Специалист по шифрованию может запустить самотестирование в любое время, перезапустив устройство.
Руководство пользователя
Пользователями модуля ядра являются другие компоненты ядра, которым необходимо использовать криптографические алгоритмы. Модуль ядра не предоставляет дополнительную логику для использования алгоритмов и не хранит никаких параметров дольше, чем необходимо для выполнения криптографической операции.
Для соответствия требованиям FIPS можно использовать только одобренные алгоритмы. Чтобы соответствовать требованию FIPS 140-3 "индикатор сервиса", модуль предоставляет функцию fips140_is_approved_service, которая указывает, одобрен ли алгоритм.
Ошибки самотестирования
Если самотестирование не пройдено, модуль ядра вызывает панику ядра, и устройство не продолжает загрузку. Если перезагрузка устройства не помогла, его нужно перевести в режим восстановления, чтобы устранить проблему, перепрошив устройство.