CDFは、暗号ソフトウェアの正しさとセキュリティを自動的にテストするツールです。CDFは実装エラー、コンプライアンス違反、サイドチャネル漏洩などを検出できます。
CDFは、ユニットテストと「差分ファジング」(同じプリミティブの異なる実装の動作を、エッジケースやコードカバレッジを最大化する値を与えて比較するアプローチ)を組み合わせて実装しています。
汎用のファザーやテストソフトウェアとは異なり、CDFは以下の特徴を持ちます:
スマート:CDFはテストしているアルゴリズムの種類を認識し、テスト対象の関数に適応します
高速:CDFはテストすべきものだけをテストし、可能な限りテストを並列化します
多用途:CDFは特定の言語やAPIに依存せず、任意の実行可能プログラムやスクリプトをサポートします
ポータブル:CDFはGoで書かれており、プラットフォーム固有の依存関係がないため、UnixまたはWindowsの任意のプラットフォームで動作します
CDFの目的は、開発者やセキュリティ研究者に、テストベクターよりも効果的で、正式検証の手動監査よりも低コストな、より効率的なテストツールを提供することです。
CDFは2017年のBlack Hat USAで初めて発表されました。プレゼンテーションのスライドをご覧いただけます。スライドには、CDFの背景と設計に関する一般的な情報が含まれています。
CDFはGoで書かれており、現在のバージョンはGo 1.8を使用して開発されています。Goの標準ライブラリ以外の依存関係はありません。
ただし、CDFでテストするためのサンプルプログラムを提供しており、これらはC、Python、C++、Java、Goで書かれており、実行には特定の暗号ライブラリが必要です。現在必要なライブラリは以下の通りです:
make で cdf バイナリがビルドされます。
多数のサンプルプログラムはexampleにあります。make examples-all ですべてのサンプルをビルドし、make examples-go でGoのサンプルのみをビルドします。
make test で(CDFの)ユニットテストが実行されます。
まずは cdf -h を実行して使用情報を確認するとよいでしょう。
次に、rsaenc インターフェースをRSA OAEPのGoとCryptoPPのサンプルに対して試すことができます。CryptoPPをリファレンスとして、Go実装を以下のようにテストできます:
cdf rsaenc /examples/oaep_rsa2048_go /examples/oaep_rsa2048_cryptopp
このコマンドは、rsaenc インターフェースに特有のさまざまなテストを実行します。
この例では、CDFはGo実装がサポートする公開指数の最大サイズについて警告します。そのコードを見ると、公開指数が通常の整数として保存されているのに対し、CryptoPP(および他のほとんどの実装)では大きな整数として保存されています。しかし、これは設計によるものであり、変更されることはおそらくないでしょう。
パラメータはconfig.jsonで定義されています。ほとんどのパラメータは説明不要です。rsaenc と ecdsa の秘密鍵を設定する必要があるかもしれません(これらのインターフェースは固定鍵でテストされますが、指数などの一部の鍵パラメータは一部のテストで変更されます)。
seed パラメータは、CDFの擬似乱数生成器で使用されるシードを変更します。(ただし、テスト対象プログラムはOAEPの例のように別の方法でシードされたPRNGを使用している可能性があります。)concurrency パラメータは、プログラムをフォークするときにCDFが生成する同時ゴルーチンの数を設定します。この数を実際のコア数より低く保つことが最善です。verboseLog パラメータを true に設定すると、成功したテストも含めてすべてのプログラムの入力と出力が log.txt ファイルに書き込まれます。
CDFを使用してソフトウェアをテストするには、CDFインターフェースに準拠して入力を受け取り出力を書き込み、内部的にテスト対象プログラムを呼び出すプログラムを作成する必要があります。CDFインターフェースは、任意の実装のブラックボックステストを可能にするための暗号機能の抽象化です。
例えば、ECDSA署名スキームを実装した場合、プログラムはecdsa インターフェースを満たす必要があり、メッセージに署名する場合はそれぞれ4つまたは5つの引数を入力として受け取り、署名を検証する場合は同様に引数を受け取ります。これらの引数は、公開X座標、公開Y座標、秘密Dの大きな整数、署名したいメッセージであり、出力は各行に大きな整数RとSのみを出力する必要があります。または、メッセージを検証するには、X、Y、R、S、メッセージを受け取り、TrueまたはFalseのみを出力する必要があります。インターフェースの仕様は以下で詳しく説明します。
インターフェース実装の例が、独自の実装を作成するのに役立ちます。
エラー処理はテスト対象プログラムに委ねられますが、CDFで意味のあるエラーを得るには、失敗時に終了し、エラーコードを返し、エラーメッセージを出力するのが最善です。
インターフェースプログラムは任意の言語で記述可能で、CDFインターフェースに準拠した実行可能ファイルである必要があります。インターフェースプログラムは通常、テスト対象プログラムと同じ言語で書かれますが、必須ではありません(Javaプログラムの場合は別の言語のラッパーでも構いません)。
CDFは現在、以下のインターフェースをサポートしています。パラメータは、特に説明がない限り、16進ASCII文字列としてエンコードされます:
dsaインターフェースは、デジタル署名アルゴリズム(DSA)の実装をテストします。署名と検証の操作をサポートする必要があります:
| 操作 | 入力 | 出力 |
|---|---|---|
| 署名 | p q g y x m | r s |
| 検証 | p q g y r s m | 真理値 |
ここで、p、q、gはDSAパラメータ、yは公開鍵、xは秘密鍵、mはメッセージ、rとsは署名を形成し、改行で区切って返す必要があります。真理値は「true」または「false」の文字列で表されます。
dsaインターフェースはオプションのテストをサポートしています:-h フラグを使用すると、ハッシュ処理をバイパスし、署名するハッシュ値を直接提供できます。これにより、CDFはオーバーフローやハッシュの切り詰めなどのチェックなど、より多くのテストを実行できます。
ecdsaインターフェースは、楕円曲線デジタル署名アルゴリズム(ECDSA)の実装をテストします。署名と検証の操作をサポートする必要があります:
| 操作 | 入力 | 出力 |
|---|---|---|
| 署名 | x y d m | r s |
| 検証 | x y r s m | 真理値 |
ここで、xとyは公開ECDSA鍵の座標、dは秘密鍵、mはメッセージ、rとsは署名を形成し、改行で区切って返す必要があります。真理値は「true」または「false」の文字列で表されます。
フラグ -h はdsaと同じ目的で機能します。
現在の設計では、テスト対象プログラムで定義された固定曲線を想定していることに注意してください。
これらのテストで再現性のある結果を得て、CDFの検出能力をすべて活用するには、乱数生成器を固定シードでシードするか、決定論的ECDSAバリアントを使用する必要があります。そうしないと、CDFは同じタグの問題などを自動的に検出できません。
encインターフェースは、対称暗号化と復号化の操作をテストします。通常はブロック暗号で行われます(ストリーム暗号はprfインターフェースでテストできます)。暗号化と復号化をサポートする必要があります:
| 操作 | 入力 | 出力 |
|---|---|---|
| 暗号化 | k m | c |
| 復号化 | k c | r |
ここで、kは鍵、mはメッセージ、cは暗号文、rは復元された平文です。
prfインターフェースは、鍵付きハッシュ(擬似ランダム関数、MAC)、およびストリーム暗号をテストします:
| 操作 | 入力 | 出力 |
|---|---|---|
| 計算 | k m | h |
ここで、kは鍵、mはメッセージ(ストリーム暗号の場合はナンス)、hはPRF計算の結果です。このインターフェースは固定鍵サイズと可変入力長を想定しています。特定の鍵を指定する必要がある場合は、テスト対象プログラムが鍵入力を無視するか、xofインターフェースの方が適切かもしれません。
rsaencはRSA暗号化と復号化をテストします。 OAEP(PKCS 2.1)とPKCS 1.5の両方に対応します:
| 操作 | 入力 | 出力 |
|---|---|---|
| 暗号化 | n e m | c |
| 復号化 | p q e d c | r |
ここで、nは法、eは公開指数(一部のライブラリとの互換性のため、復号化にもeが必要)、mはメッセージ、pとqはnの因数(p > q、ライブラリで一般的に必要)、dは秘密指数、rは復元された平文です。
xofインターフェースは、ハッシュ関数、拡張可能出力関数(XOF)、決定論的乱数ビット生成器(DRBG)をテストします:
| 操作 | 入力 | 出力 |
|---|---|---|
| 計算 | m | h |
ここで、mはメッセージ、hは結果です。
CDFは、JP Aumassonの初期アイデアに基づいており、WarCon 2016で初めて公開され、コードの大部分はYolan Romaillerによって書かれました。
CDFの著作権は (c) 2016-2017 Nagravision SA に帰属し、すべての権利は留保されています。
CDFはGPLv3の下でリリースされています。