GKIカーネルには、暗号化ソフトウェア モジュールのFIPS 140-3要件に準拠するfips140.ko
という Linux カーネル モジュールが含まれています。このモジュールは、GKI カーネルを実行する製品で必要な場合、FIPS 認定のために送信できます。
暗号化ルーチンを使用する前に、特に次の FIPS 140-3 要件を満たす必要があります。
- モジュールは、暗号化アルゴリズムを使用可能にする前に、自身の整合性をチェックする必要があります。
- モジュールは、承認された暗号化アルゴリズムを使用可能にする前に、既知の答えのセルフテストを使用して実行および検証する必要があります。
別のカーネル モジュールを使用する理由
FIPS 140-3 検証は、ソフトウェアまたはハードウェア ベースのモジュールが認定されると、変更されることはないという考えに基づいています。変更された場合は、再認定を受ける必要があります。これは、現在使用されているソフトウェア開発プロセスとは容易には一致しません。この要件の結果として、FIPS ソフトウェア モジュールは一般に、暗号化に関連しない変更が確実に実行されるように、暗号化コンポーネントにできるだけ集中するように設計されています。暗号化の再評価を必要としません。
GKI カーネルは、サポートされている全期間にわたって定期的に更新されることを意図しています。これにより、カーネル全体が FIPS モジュールの境界内にあることは不可能になります。そのようなモジュールは、カーネルの更新ごとに再認定する必要があるためです。また、LTO は重要なセキュリティ機能であるCFIの前提条件であるため、GKI は LTO (Link Time Optimization) を有効にしてコンパイルされます。これにより、カーネルの暗号化コードだけに FIPS モジュールの境界を描くことができなくなります。そのようなコードは、結果のバイナリで明確に定義された場所にないからです。カーネルの更新により、暗号コードも変更される場合があります。
したがって、FIPS 140-3 要件でカバーされるすべてのコードは、ビルド元の GKI カーネル ソースによって公開される安定したインターフェイスのみに依存する別のカーネル モジュールfips140.ko
にパッケージ化されます。これにより、モジュールが同じ世代の異なる GKI リリースで使用できることが保証され、モジュール自体によって実行されるコードで問題が修正された場合にのみ、モジュールを更新して認定のために再提出する必要があります。
モジュールをいつ使用するか
GKI カーネル自体には、FIPS 140-3 カーネル モジュールにもパッケージ化されている暗号化ルーチンに依存するコードが含まれています。したがって、組み込み暗号化ルーチンは、実際には GKI カーネルから移動されるのではなく、モジュールにコピーされます。モジュールがロードされると、組み込みの暗号化ルーチンは Linux CryptoAPI から登録解除され、モジュールによって運ばれるものに取って代わられます。
つまり、 fips140.ko
モジュールは完全にオプションであり、FIPS 140-3 認定が要件である場合にのみ展開する意味があります。さらに、このモジュールは追加機能を提供せず、不必要にロードしてもブート時間に影響を与えるだけで、何のメリットもありません。
モジュールのデプロイ方法
モジュールは、次の手順を使用して Android ビルドに組み込むことができます。
- モジュール名を
BOARD_VENDOR_RAMDISK_KERNEL_MODULES
に追加します。これにより、モジュールがベンダー ramdisk にコピーされます。 - モジュール名を
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
に追加します。これにより、モジュール名がターゲットのmodules.load
に追加されます。modules.load
は、デバイスの起動時にinit
によってロードされるモジュールのリストを保持します。
完全性セルフチェック
FIPS 140-3 カーネル モジュールは、モジュールのロード時に独自の.code
および.rodata
セクションの HMAC-SHA256 ダイジェストを取得し、それをモジュールに記録されたダイジェストと比較します。これは、Linux モジュール ローダーが ELF 再配置処理や CPU エラッタの代替パッチなどの通常の変更をそれらのセクションに加えた後に行われます。ダイジェストを正しく再現できるようにするために、次の追加手順が実行されます。
- ELF 再配置は、HMAC の入力に逆に適用できるように、モジュール内に保持されます。
- 静的キー、したがってトレースポイント、およびベンダー フックを含む、モジュールの他のすべてのコード パッチは無効になります。
既知の答えの自己テスト
FIPS 140-3 要件の対象となる実装アルゴリズムは、使用前に既知の答えの自己テストを実行する必要があります。 FIPS 140-3 実装ガイダンス 10.3.Aによると、暗号化と復号化の両方がテストされる限り、サポートされているキーの長さのいずれかを使用するアルゴリズムごとに 1 つのテスト ベクトルで十分です。
Linux CryptoAPI には、アルゴリズムの優先順位の概念があり、同じアルゴリズムの複数の実装 (特殊な暗号命令を使用する実装や、それらの命令を実装しない CPU のフォールバックなど) が共存する場合があります。したがって、同じアルゴリズムのすべての実装をテストする必要があります。これが必要なのは、Linux CryptoAPI が優先度ベースの選択を回避し、代わりに優先度の低いアルゴリズムを選択できるようにするためです。
モジュールに含まれるアルゴリズム
android13-5.10 ソースからビルドされたときに FIPS 140-3 モジュールに含まれるすべてのアルゴリズムは次のとおりです。
アルゴリズム | 実装 | 承認可能 | 意味 |
---|---|---|---|
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 テンプレートは、 cmac(<aes-impl>) を使用してaes の任意の実装で構成できます。他の実装はスタンドアロンです。 |
ecb(aes) | ecb (テンプレート)、 ecb-aes-neon 、 ecb-aes-neonbs 、 ecb-aes-ce | はい | AES-ECB: すべての AES キー サイズがサポートされています。 ecb テンプレートは、 ecb(<aes-impl>) を使用してaes の任意の実装で構成できます。他の実装はスタンドアロンです。 |
cbc(aes) | cbc (テンプレート)、 cbc-aes-neon 、 cbc-aes-neonbs 、 cbc-aes-ce | はい | AES-CBC: すべての AES キー サイズがサポートされています。 cbc テンプレートは、 ctr(<aes-impl>) を使用してaes の任意の実装で構成できます。他の実装はスタンドアロンです。 |
cts(cbc(aes)) | cts (テンプレート)、 cts-cbc-aes-neon 、 cts-cbc-aes-ce | はい | 暗号文を盗む AES-CBC-CTS または AES-CBC: 使用される規則はCS3 です。最後の 2 つの暗号文ブロックは無条件に交換されます。すべての AES キー サイズがサポートされています。 cts テンプレートは、 cts(<cbc(aes)-impl>) を使用してcbc の任意の実装で構成できます。他の実装はスタンドアロンです。 |
ctr(aes) | ctr (テンプレート)、 ctr-aes-neon 、 ctr-aes-neonbs 、 ctr-aes-ce | はい | AES-CTR: すべての AES キー サイズがサポートされています。 ctr テンプレートは、 ctr(<aes-impl>) を使用してaes の任意の実装で構成できます。他の実装はスタンドアロンです。 |
xts(aes) | xts (テンプレート)、 xts-aes-neon 、 xts-aes-neonbs 、 xts-aes-ce | はい | AES-XTS: すべての AES キー サイズがサポートされています。 xts テンプレートは、 xts(<ecb(aes)-impl>) を使用して ecb ecb(aes) の任意の実装で構成できます。他の実装はスタンドアロンです。すべての実装は、FIPS で必要な弱いキー チェックを実装しています。つまり、前半と後半が等しい XTS キーは拒否されます。 |
gcm(aes) | gcm (テンプレート)、 gcm-aes-ce | いいえ1 | AES-GCM: すべての AES キー サイズがサポートされています。 96 ビット IV のみがサポートされています。このモジュールの他のすべての AES モードと同様に、呼び出し元は IV を提供する責任があります。 gcm テンプレートは、 gcm_base(<ctr(aes)-impl>,<ghash-impl>) を使用してctr(aes) およびghash の任意の実装で構成できます。他の実装はスタンドアロンです。 |
sha1 | sha1-generic 、 sha1-ce | はい | SHA-1 暗号ハッシュ関数 |
sha224 | sha224-generic 、 sha224-arm64 、 sha224-ce | はい | SHA-224 暗号化ハッシュ関数: コードは SHA-256 と共有されます。 |
sha256 | sha256-generic 、 sha256-arm64 、 sha256-ce 、SHA-256 ライブラリ | はい | SHA-256 暗号化ハッシュ関数: 従来の CryptoAPI インターフェイスに加えて、ライブラリ インターフェイスが SHA-256 に提供されます。このライブラリ インターフェイスは、別の実装を使用します。 |
sha384 | sha384-generic 、 sha384-arm64 、 sha384-ce | はい | SHA-384 暗号化ハッシュ関数: コードは SHA-512 と共有されます。 |
sha512 | sha512-generic 、 sha512-arm64 、 sha512-ce | はい | SHA-512 暗号化ハッシュ関数 |
hmac | hmac (テンプレート) | はい | HMAC (Keyed-Hash Message Authentication Code): hmac テンプレートは、 hmac(<sha-alg>) またはhmac(<sha-impl>) を使用して、任意の SHA アルゴリズムまたは実装で構成できます。 |
stdrng | drbg_pr_hmac_sha1 、 drbg_pr_hmac_sha256 、 drbg_pr_hmac_sha384 、 drbg_pr_hmac_sha512 | はい | 名前付きハッシュ関数でインスタンス化され、予測抵抗が有効になっている HMAC_DRBG: ヘルスチェックが含まれます。このインターフェースのユーザーは、独自の DRBG インスタンスを取得します。 |
stdrng | drbg_nopr_hmac_sha1 、 drbg_nopr_hmac_sha256 、 drbg_nopr_hmac_sha384 、 drbg_nopr_hmac_sha512 | はい | drbg_pr_* アルゴリズムと同じですが、予測耐性が無効になっています。コードは、予測耐性のあるバリアントと共有されます。最も優先度の高い DRBG はdrbg_nopr_hmac_sha256 です。 |
jitterentropy_rng | jitterentropy_rng | いいえ | Jitter RNGのバージョン 2.2.0 : このインターフェイスのユーザーは、独自の Jitter RNG インスタンスを取得します。 DRBG が使用するインスタンスを再利用しません。 |
xcbc(aes) | xcbc-aes-neon 、 xcbc-aes-ce | いいえ | |
cbcmac(aes) | cbcmac-aes-neon 、 cbcmac-aes-ce | いいえ | |
essiv(cbc(aes),sha256) | essiv-cbc-aes-sha256-neon 、 essiv-cbc-aes-sha256-ce | いいえ |
ソースからモジュールをビルドする
fips140.ko
モジュールは、次のコマンドを使用して GKI カーネル ソースからビルドできます。
BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
これにより、カーネルとfips140.ko
モジュールで完全なビルドが実行され、その内容の正しい HMAC-SHA256 ダイジェストが埋め込まれます。
Android 14 (AOSP 実験的) 以降では、次のコマンドを使用して、 build/build.sh
の代わりにBazelでビルドします。
tools/bazel run //common:fips140_dist
エンド ユーザー ガイダンス
クリプト オフィサーのガイダンス
カーネル モジュールを操作するには、オペレーティング システムをシングル オペレーター モードの操作に制限する必要があります。これは、プロセッサのメモリ管理ハードウェアを使用して、Android によって自動的に処理されます。
カーネル モジュールを個別にインストールすることはできません。これはデバイス ファームウェアの一部として含まれており、起動時に自動的にロードされます。承認された操作モードでのみ動作します。
Crypto Officer は、デバイスを再起動することで、いつでもセルフテストを実行できます。
ご利用案内
カーネル モジュールのユーザーは、暗号化アルゴリズムを使用する必要がある他のカーネル コンポーネントです。カーネルモジュールは、アルゴリズムを使用する際に追加のロジックを提供せず、暗号操作の実行に必要な時間を超えてパラメーターを保存しません。
FIPS 準拠のためのアルゴリズムの使用は、承認されたアルゴリズムに限定されます。 FIPS 140-3 の「サービス インジケータ」要件を満たすために、モジュールは、アルゴリズムが承認されているかどうかを示す関数fips140_is_approved_service
を提供します。
セルフテストエラー
自己診断テストに失敗した場合、カーネル モジュールが原因でカーネル パニックが発生し、デバイスは起動を続行しません。デバイスを再起動しても問題が解決しない場合は、デバイスを再フラッシュして問題を解決するために、デバイスをリカバリ モードで起動する必要があります。
モジュールの AES-GCM 実装は「アルゴリズムの承認」はできるが、「モジュールの承認」はできないことが予想されます。それらは検証できますが、AES-GCM は FIPS モジュールの観点から承認されたアルゴリズムと見なすことはできません。これは、GCM の FIPS モジュール要件が、独自の IV を生成しない GCM 実装と互換性がないためです。 ↩