Go標準暗号ライブラリにおけるFIPS 140-2およびFIPS 140-3実装の構造

FIPS 140 (Federal Information Processing Standard Publication 140)
FIPS 140は、米国NISTが制定した暗号モジュールのセキュリティ認証標準です。この標準は、特定の暗号モジュールやライブラリがNISTの定めたセキュリティ要件を満たしているかを評価します。したがって、FIPS 140認証を取得したということは、当該モジュールが公式に信頼できるセキュリティ性を備えていることを意味し、金融、医療、国防など、セキュリティが重要な分野で利用できることを意味します。
FIPS 140は1994年に最初に制定されて以降、2001年にはFIPS 140-2へ、2019年にはFIPS 140-3へと改定されました。現在も多くのシステムやアプリケーションでは、FIPS 140-2またはFIPS 140-3の認証を要求しています。
FIPS 140とプログラミング言語
このような理由から、FIPS 140認証を受けた暗号モジュールは、多くのプログラミング言語や環境において事実上の標準として利用されています。代表的なものにOpenSSL、BoringSSL、LibreSSL、NSSなどがあり、これらはセキュリティが重要なアプリケーションで最も広く活用されているモジュールです。
FIPS 140認証モジュールの大部分はCまたはC++で書かれています。このため、PHP、Python、JavaScriptなどの言語では、これらのモジュールを直接利用するのではなく、外部のProviderモジュールを介して連携させることでFIPS環境を構成します。しかし、このようなアプローチにはいくつかの限界があります。
バージョン不一致の問題
FIPS 140認証は特定のバージョンに対してのみ付与されます。したがって、最新バージョンのモジュールを使用するには再度認証の過程を経る必要があり、この過程でアプリケーションが使用するモジュールとFIPS認証モジュールの間にバージョンの不一致が生じることがあります。承認されていないバージョンを使用した場合、当該環境はもはやFIPS認証環境とはみなされなくなります。
動的ロードと性能低下
ほとんどの言語は、FIPS 140認証モジュールを動的ライブラリの形式でロードして使用します。この方式は初期化および実行過程で性能低下を引き起こすことがあり、実行時に問題が発生した場合、アプリケーション全体の安定性に直接影響を及ぼすおそれがあります。
セキュリティ脆弱性
前述のとおり、OpenSSL Providerのように外部モジュールを連携させる構造では、当該モジュールのセキュリティ脆弱性がアプリケーションに直接伝播するおそれがあります。また、アプリケーションと外部モジュールの間の通信レイヤー自体が追加の攻撃対象領域となり、これを保護するための別途のセキュリティレイヤーが必要となります。これは複雑性を増大させ、予期しない脆弱性を生じさせるおそれがあります。
FIPS 140とGolang
このような理由から、Golangは別の戦略を採用しました。Goは、FIPS 140認証を外部ツールに依存するのではなく、公式の暗号ライブラリで直接サポートする方式を選択しました。したがって開発者は、別途Providerをインストールしたり設定したりする必要がなく、標準のcryptoパッケージをそのまま使用しながら、FIPS認証モード(GOFIPS=1)を有効にするだけで済みます。この過程で外部モジュールとの通信境界が除去されることによりセキュリティ性が強化され、静的コンパイルされた単一のバイナリのみを配布すればよいため、運用も簡素化されます。
FIPS 140-2とGolang
これを実現するため、GolangはBoringSSLから派生したBoringCryptoモジュールをGoランタイムに組み込み、FIPS 140-2認証を取得しました。BoringCryptoはGo 1.19バージョン以降、特定のディストリビューションにおいて有効化することができ、これによりGoアプリケーションは別途の外部モジュールなしでもFIPS 140-2認証環境を構成できるようになりました。
ただし、BoringCryptoはOpenSSLベースであるため、依然としてC言語への依存性が存在します。したがって、Goアプリケーションは完全に独立したバイナリとしてビルドされるわけではなく、必要なCライブラリを併せて配布しなければならないという制約がありました。
FIPS 140-3とGolang
Goチームは、このような限界を克服するため、既存のGo標準cryptoライブラリをFIPS 140-3規格に適合するよう改善しました。この改良されたモジュールはGo 1.21バージョンから実験的に提供され始め、現在NISTのFIPS 140-3認証審査が進行中です。NIST FIPS 140-3審査進行中のモジュール一覧
これはGo暗号ライブラリの成熟度を示すものであり、これによりGoは完全に独立した単一のバイナリとしてFIPS 140-3認証環境を提供できるようになりました。
また、Goチームは単にFIPS 140-3標準を満たすにとどまらず、独自にセキュリティ性を強化しました。
Fail Fast
GoのFIPS モードはFail Fastセキュリティモデルを適用しており、非認証アルゴリズムを呼び出すとpanicによって直ちに実行を中断します。これは、フォールバックの可能性を残す他言語のProviderベースのモデルとは異なり、セキュリティおよび規制遵守の観点からより厳格で明確な保証を提供します。
Hedged Signature
FIPS 140-3標準では、ECDSA署名時にRFC6979方式が推奨されています。しかしGoはこれに加えてHedged方式を導入し、署名過程で発生しうるサイドチャネル攻撃により強力に対応します。
強化された乱数生成器
Goの乱数生成器はユーザー空間のDRBG(Deterministic Random Bit Generator)を使用しながらも、オペレーティングシステムのカーネルに対してエントロピーを追加で注入することで、ユーザー空間だけでなくカーネル空間においても高品質の乱数を生成します。これにより、乱数生成器のセキュリティ性がさらに強化されます。