The Go Blog

FIPS 140-3 Go暗号モジュール

Filippo Valsorda (Geomys), Daniel McCarney (Geomys), and Roland Shoemaker (Google)
2025年7月15日

FIPS 140は暗号実装の標準であり、必ずしもセキュリティを向上させるものではありませんが、FIPS 140準拠は、Goの採用が増加している特定の規制された環境では必須要件となっています。これまで、FIPS 140準拠はGoユーザーにとって大きな摩擦源であり、安全性、開発者エクスペリエンス、機能性、リリース速度、コンプライアンスの問題を抱えるサポートされていないソリューションを必要としていました。

Goは、この高まるニーズに対応するため、標準ライブラリとgoコマンドにFIPS 140ネイティブサポートを組み込み、GoをFIPS 140に準拠する最も簡単で安全な方法にしています。FIPS 140-3検証済みのGo暗号モジュールは、昨年2月にリリースされたGo 1.24に含まれるGo暗号モジュールv1.0.0を皮切りに、Goの組み込み暗号ライブラリの基盤となっています。

v1.0.0モジュールは、暗号アルゴリズム検証プログラム(CAVP)証明書A6650を取得し、暗号モジュール検証プログラム(CMVP)に提出され、5月には処理中モジュールリスト(MIPリスト)に掲載されました。MIPリスト上のモジュールはNISTのレビュー待ちであり、すでに特定の規制環境で展開可能です。

Geomysは、Goセキュリティチームとの共同で実装を主導し、Goコミュニティのために広範に適用可能なFIPS 140-3検証を進めています。Googleおよびその他の業界関係者は、特定の動作環境を証明書に含めるためにGeomysと契約関係にあります。

モジュールの詳細については、ドキュメントをご覧ください。

一部のGoユーザーは現在、FIPS 140準拠戦略の一部として、Go+BoringCrypto GOEXPERIMENTまたはそのフォークに依存しています。FIPS 140-3 Go暗号モジュールとは異なり、Go+BoringCryptoは公式にはサポートされておらず、Googleの内部ニーズのためにのみ作成されたため、開発者エクスペリエンスに大きな問題がありました。Googleがネイティブモジュールに移行すると、将来のリリースで削除される予定です。

ネイティブな開発者エクスペリエンス

モジュールはGoアプリケーションに完全に透過的に統合されます。実際、Go 1.24でビルドされたすべてのGoプログラムは、すべてのFIPS 140-3承認アルゴリズムにすでにこのモジュールを使用しています!モジュールは、crypto/ecdsacrypto/randなどのパッケージが公開する操作の実装を提供する、標準ライブラリのcrypto/internal/fips140/...パッケージの別名にすぎません。

これらのパッケージにはcgoが含まれていません。つまり、他のGoプログラムと同様にクロスコンパイルでき、FFIのパフォーマンスオーバーヘッドがなく、Go+BoringCryptoとそのフォークとは異なり、メモリ管理のセキュリティ問題に悩まされることもありません。

Goバイナリを起動する際、fips140=on GODEBUGオプションを使用してモジュールをFIPS 140-3モードに設定できます。これは環境変数として、またはgo.modファイルを介して設定できます。FIPS 140-3モードが有効になっている場合、モジュールはNIST DRBGを乱数に、crypto/tlsはFIPS 140-3承認済みのTLSバージョンとアルゴリズムのみを自動的にネゴシエートし、初期化時および鍵生成時に必須の自己テストを実行します。それだけです。他に動作の違いはありません。

また、実験的なより厳格なモードであるfips140=onlyもあり、これにより承認されていないすべてのアルゴリズムはエラーを返すかパニックを引き起こします。これはほとんどのデプロイメントには柔軟性に欠ける可能性があると理解しており、ポリシー施行フレームワークがどのようなものになるかについてフィードバックを求めています

最後に、アプリケーションはGOFIPS140環境変数を使用して、crypto/internal/fips140/...パッケージの古い検証済みバージョンに対してビルドできます。GOFIPS140GOOSGOARCHと同様に機能し、GOFIPS140=v1.0.0に設定すると、プログラムはCMVPに検証のために提出されたパッケージのv1.0.0スナップショットに対してビルドされます。このスナップショットは、lib/fips140/v1.0.0.zipとしてGo標準ライブラリの残りの部分とともに出荷されます。

GOFIPS140を使用する場合、fips140 GODEBUGはデフォルトでonになるため、すべてをまとめると、FIPS 140-3モジュールに対してビルドし、FIPS 140-3モードで実行するために必要なのはGOFIPS140=v1.0.0 go buildだけです。それだけです。

ツールチェインがGOFIPS140を設定してビルドされた場合、生成されるすべてのビルドはその値にデフォルトで設定されます。

バイナリのビルドに使用されたGOFIPS140バージョンは、go version -mで確認できます。

Goの将来のバージョンは、次のバージョンがGeomysによって完全に認証されるまで、Go暗号モジュールv1.0.0の出荷と連携を継続しますが、古いモジュールに対してビルドする場合、一部の新しい暗号機能は利用できない場合があります。Go 1.24.3以降、GOFIPS140=inprocessを使用して、Geomys検証が「処理中」段階に達した最新のモジュールを動的に選択できます。Geomysは、FIPS 140ビルドが大きく遅れないように、そしてモジュールの脆弱性が呼び出し側の標準ライブラリコードで軽減できない場合はいつでも、少なくとも毎年新しいモジュールバージョンを検証する予定です。

妥協のないセキュリティ

モジュールの開発における最優先事項は、既存のGo標準ライブラリ暗号パッケージのセキュリティに合致するか、それを上回ることでした。驚くかもしれませんが、FIPS 140セキュリティ要件への準拠を達成し、実証する最も簡単な方法は、それらを超えないことです。私たちはそれを受け入れませんでした。

たとえば、crypto/ecdsa常にヘッジ署名を生成していました。ヘッジ署名は、秘密鍵、メッセージ、およびランダムバイトを組み合わせてnonceを生成します。決定論的ECDSAと同様に、乱数生成器の障害から保護し、そうでなければ秘密鍵が漏洩するでしょう。決定論的ECDSAとは異なり、APIの問題フォルト攻撃にも耐性があり、メッセージの等価性を漏洩させません。FIPS 186-5はRFC 6979決定論的ECDSAのサポートを導入しましたが、ヘッジECDSAは導入しませんでした。

FIPS 140-3モードで(またはさらに悪いことに、モード間で)通常のランダム化または決定論的ECDSA署名にダウングレードする代わりに、ヘッジアルゴリズムを変更し、多数のドキュメントを接続して、新しいものがDRBGと従来のECDSAの準拠した構成であることを証明しました。その際、決定論的署名のオプトインサポートも追加しました

もう1つの例は乱数生成です。FIPS 140-3は暗号論的乱数がどのように生成されるかについて厳格な規則を設けており、本質的にユーザー空間のCSPRNGの使用を強制しています。逆に、私たちはカーネルがセキュアなランダムバイトを生成するのに最適であると考えています。なぜなら、カーネルはシステムからエントロピーを収集し、プロセスや仮想マシンがクローンされたとき(これは「ランダムなバイト」の再利用につながる可能性があります)を検出するのに最適な位置にあるからです。そのため、crypto/randはすべての読み取り操作をカーネルにルーティングします。

この問題を解決するために、FIPS 140-3モードでは、AES-256-CTRに基づく準拠したユーザー空間NIST DRBGを維持し、すべての読み取り操作でカーネルから取得した128ビットをそれに注入します。この追加のエントロピーはFIPS 140-3の目的では「信頼されていない」追加データと見なされますが、実際には、たとえ遅くても、カーネルから直接読み取るのと同じくらい強力にします。

最後に、Go暗号モジュールv1.0.0のすべてがTrail of Bitsによる最近のセキュリティ監査の対象であり、唯一の非情報的な発見による影響を受けませんでした。

Goコンパイラとランタイムが提供するメモリ安全性の保証と相まって、GoをFIPS 140準拠のための最も簡単で安全なソリューションの1つにするという目標を達成していると信じています。

広範なプラットフォームサポート

FIPS 140-3モジュールは、テスト済みまたは「ベンダー確認済み」の動作環境、つまりオペレーティングシステムとハードウェアプラットフォームの組み合わせで動作する場合にのみ準拠します。可能な限り多くのGoユースケースを可能にするために、Geomys検証は業界で最も包括的な動作環境セットの1つでテストされています。

Geomysのラボでは、様々なLinuxフレーバー(Podman上のAlpine Linux、Amazon Linux、Google Prodimage、Oracle Linux、Red Hat Enterprise Linux、SUSE Linux Enterprise Server)、macOS、Windows、およびFreeBSDを、x86-64(AMDおよびIntel)、ARMv8/9(Ampere Altra、Apple M、AWS Graviton、およびQualcomm Snapdragon)、ARMv7、MIPS、z/ Architecture、およびPOWERの組み合わせでテストし、合計23のテスト環境で検証しました。

これらのいくつかは関係者によって支払われ、その他はGoコミュニティのためにGeomysによって資金提供されました。

さらに、Geomysの検証では、広範な汎用プラットフォームをベンダー確認済み動作環境としてリストしています。

  • x86-64およびARMv7/8/9上のLinux 3.10+
  • Apple Mプロセッサ上のmacOS 11–15
  • x86-64上のFreeBSD 12–14
  • x86-64上のWindows 10およびWindows Server 2016–2022、および
  • x86-64およびARMv8/9上のWindows 11およびWindows Server 2025。

包括的なアルゴリズムカバレッジ

驚くかもしれませんが、サポートされている動作環境でFIPS 140-3モジュールによって実装されたFIPS 140-3承認アルゴリズムを使用するだけで、必ずしも準拠に十分ではありません。アルゴリズムは、検証の一部としてテストによって具体的にカバーされている必要があります。そのため、GoでFIPS 140準拠アプリケーションを可能な限り簡単に構築できるように、標準ライブラリのすべてのFIPS 140-3承認アルゴリズムはGo暗号モジュールによって実装され、デジタル署名からTLSキー生成まで、検証の一部としてテストされました。

Go 1.24で導入されたポスト量子ML-KEM鍵交換(FIPS 203)も検証されており、これによりcrypto/tlsはX25519MLKEM768でFIPS 140-3準拠のポスト量子セキュア接続を確立できます

場合によっては、同じアルゴリズムを複数の異なるNIST指定の下で検証し、異なる目的で完全に準拠して使用できるようにしました。例えば、HKDFは_4つ_の名前でテストおよび検証されています:SP 800-108 フィードバックKDF、SP 800-56C 2段階KDF、実装ガイダンスD.PワンステップカウンタなしKDF、およびSP 800-133セクション6.3 KDF。

最後に、CMACカウンタKDFなどのいくつかの内部アルゴリズムも検証し、XAES-256-GCMなどの将来の機能を公開できるようにしました。

全体として、ネイティブFIPS 140-3モジュールは、Go+BoringCryptoよりも優れたコンプライアンスプロファイルを提供しつつ、FIPS 140-3制限されたアプリケーションにより多くのアルゴリズムを利用可能にします。

新しいネイティブGo暗号モジュールが、Go開発者にとってFIPS 140準拠のワークロードをより簡単かつ安全に実行できるようにすることを期待しています。

次の記事:Go 1.25がリリースされました
前の記事:ジェネリックインターフェース
ブログインデックス