(注意: 私は確かに、HAVEGE がその主張に応えているとは主張していません。私はそれらの理論や実装をチェックしていません.)
ランダム性を得るために、HAVEGE や同様のシステムは「物理的なイベント」、特に タイミング をフィードします。 物理的なイベントの。このようなイベントには、ハードウェア割り込みの発生が含まれます (これにより、キー ストローク、マウスの動き、着信イーサネット パケット、ハード ディスクが書き込み要求を完了するまでの時間などに関するデータが収集されます)。 HAVEGE はまた、CPU で発生するすべてのタイプのキャッシュ ミス (L1 キャッシュ、L2 キャッシュ、TLB、分岐予測など) をフィードすると主張しています。これらの要素の動作は、前の数千のクロック サイクルで CPU が行っていたことに依存するため、何らかの「ランダム性」が生じる可能性があります。これは、現在の時刻を非常に正確に (必ずしも正確であるとは限りません) 測定できるかどうかにかかっています。 指示が出ます。クロック サイクルごとにインクリメントされる内部カウンターの現在の内容を返すため、サブナノ秒の精度を提供します。
仮想マシン システムの場合、この命令に関して 3 つの選択肢があります:
<オール>
VM マネージャーが最初のソリューションを選択した場合、17
ハードウェアイベントからエントロピーを収集する目的で、必要なすべての精度を備えており、物理マシン上にあるかのように機能するはずです。ただし、これは仮想マシンであるため、ホスト システム上のアプリケーションです。常に CPU を取得するわけではありません。 25
を使用するゲスト OS の観点から 、これは CPU が時折「盗まれた」ように見えます:2 つの連続した 33
名目上単一のクロックサイクルで区切られた命令は、数百万のカウンターの増加を報告する場合があります .つまり、 46
の場合 ハードウェアに適用されるだけで、ゲスト OS はこれを使用してハイパーバイザーの存在を検出できます。
2 番目のソリューションは、その VM に実際に割り当てられたサイクルを追跡する仮想 VM ごとのサイクル カウンターを維持することによって、エミュレーションをより「完全」にすることを目的としています。利点は 58
です 、ゲストの観点からは、「盗まれたサイクル」効果は表示されなくなります。欠点は、このエミュレーションが CPU 例外のトリガーとトラップによって実行されるため、64
のコストが高くなることです。 数十クロック サイクルのオペコード (CPU ブランドによって異なります。74
を実行するものもあります) 10 サイクル未満、その他の用途では 60 または 70 サイクル) から 1,000 以上 サイクルの。ゲストが多くの 82
を実行しようとした場合 (HAVEGE がそうする傾向があるように)、その後、クロールに遅くなります。さらに、例外処理コードは対策を混乱させます。ハードウェア イベントのタイミングを測定する代わりに、コードは例外ハンドラーの実行時間を測定します。これにより、抽出されたランダム性の品質が低下する可能性があります。
3 番目の解決策 (99
を無効にする) ) は、HAVEGE が適切なランダム性を返すのを単純に防ぎます。内部で PRNG を使用しているため、「ランダムに見える」ことと「予測不可能であること」には大きな違いがあるため、出力は依然として統計分析ツールを欺く可能性があります (統計分析ツールは「ランダムに見える」パスに従いますが、暗号化セキュリティは予測不可能性に依存しています).
VirtualBox のマニュアルでは、VirtualBox はデフォルトで最初の方法 (104
) に従うと主張しています。 無条件に許可され、ハードウェアに直接適用されます) が、2 番目のソリューションを適用するように構成されている場合があります (この場合は望ましくありません)。
VM の動作をテストするには、この小さなプログラムを試すことができます (119
でコンパイルします)。 Linux で; 121
重要です):
#include <stdio.h>
#if defined(__i386__)
static __inline__ unsigned long long rdtsc(void)
{
unsigned long long int x;
__asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#elif defined(__x86_64__)
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
#endif
int
main(void)
{
long i;
unsigned long long d;
d = 0;
for (i = 0; i < 1000000; i ++) {
unsigned long long b, e;
b = rdtsc();
e = rdtsc();
d += e - b;
}
printf("average : %.3f\n", (double)d / 1000000.0);
return 0;
}
非仮想マシンでは、「true」の 134
、これは、CPU ブランドに応じて、10 から 100 の間の値を報告します。報告された値が 0 の場合、またはプログラムがクラッシュした場合、140
無効になっています。値が千単位の場合、154
これは、エントロピー収集が期待どおりに機能しない可能性があることを意味します。
10 から 100 の間の値を取得しても、161
が保証されるわけではないことに注意してください。 VM マネージャーは仮想カウンターを維持しながら、例外ハンドラーの実行に必要な予想時間を減算する可能性があるため、エミュレートされません。最終的には、VM マネージャーのマニュアルと構成をよく確認する必要があります。
もちろん、HAVEGE の前提全体には疑問があります。実用的なセキュリティのためには、暗号的に安全な PRNG でシードとして使用する、200 を超えない数個の「真のランダム」ビットが必要です。 PRNG は、真のランダム性と見分けがつかない数ギガバイトの疑似領域を生成します。これは、すべての実用的な目的には十分です。
すべてのビットでハードウェアに戻ることを主張することは、エントロピーを一種のガソリンと見なし、それを見ると燃え尽きるという欠陥のあるアイデアの新たな発生のように見えます.
polarssl アドバイザリについて:詳細な技術的対応は、最新の debian ソースにあります:
http://bazaar.launchpad.net/~ubuntu-branches/debian/experimental/haveged/experimental/revision/12?start_revid=12#debian/README.Debian
エグゼクティブ サマリーは次のとおりです:polarssl !=haveged !=HAVEGE
embloms.se エミュレーターの実験について:
172
テスト スイート、187
と 195
、ソース ビルドが機能する RNG を生成したことを確認します。仮想環境での実行時の動作を検証するには、実行時テストが必要です。これは、かなり最近 haveged に追加されたものです。
統計テストについて:
204
があるとします。 、 213
、壊れていないことをどのように知っていますか?ハードウェアが壊れます。ドイツの標準化団体には、まさにその問題に対処する仕様 226
があります。 .そのアプローチは haveged によって採用されています。 haveged に適用される RNG の標準に関する (偏った) 議論は、次の場所にあります。
http://www.issihosts.com/haveged/ais31.html
236
の予測不可能性 ベンチマーク ソフトウェアで見られるのとまったく同じメカニズムです。これはタイマーのドリフトによるものではなく、最新のプロセッサにおける非同期動作の集約によるものです。パフォーマンスの変動がキャッシュ ミスによるものか、別のプロセッサに配信されたタイム スライスによるものかは問題ではありません。タイマーの精度も、「適切」であれば問題ありません。それはどのように決定されますか?出力によって。設計による (または設計上のものかもしれません) 240
貧弱な入力データの影響を受けません。設計を覆す唯一の方法は、エントロピー プールに追加されたエントロピーについて嘘をつくことです。 haveged の最新バージョンは、生成された出力に対してランタイム エントロピー推定を実行し、出力が理想的な TRNG と一致することを保証します。
エグゼクティブ サマリー:254
出力は 269
と見分けがつきません 270
を認定するためにドイツの標準化団体が使用するテストによる .そうでない場合は 280
シャットダウンします。
(更新 、gwertz に感謝 292
の現在の作者/メンテナ 、 302
の間の区切りを逃しました と 315
.)
329
は、乱数を生成するための HAVEGE メソッドの明確な実装です。最新であり、維持され、ここで文書化されています:http://www.issihosts.com/haveged/ (また、libhavege を直接使用しなくなりました)。
330
速度と正確さのために誰かが最近 (2009 年) にパッチを当てましたが、あまり最新ではありません (2006 年)。その方法が文書化されておらず、仮想マシンについて言及されておらず、前述のように 341
に (大きく) 依存しているため、注意が必要です。 (または同等のプラットフォーム)。 (ソースコードもぞっとしますが、それはかなり主観的なものです。)
ホスト VM が意図せずゲストに状態を漏らしてはならないことを主張します。そのため、この方法を使用する場合、それはエントロピーの良いソースと見なされるべきではありません。
Linux でのより良いアプローチは、virtio-rng 準仮想化 rng ドライバーを使用した rng-tools です (つまり、ゲストがホストによって収集されたエントロピーにアクセスできるようにし、「ランダムな」イベントのゲスト ビューに関する多くの潜在的な問題を排除します)、またはエントロピーが見つかる場合があります。ブローカーがより便利に。最近の Intel チップでは、RDRAND 命令をゲストに公開して、問題を回避することもできます。
この記事 (LinuxCon Europe 2012 での hpa の講演から) ) を読むと便利です:http://lwn.net/Articles/525459/ 、 353
についても説明しています。 /362
(ただし、ここでも区別は明確ではありません)。
lack を判断する方法については、この質問への回答を参照してください。 ランダム性:擬似乱数データを識別するために使用できる統計は?