web-dev-qa-db-ja.com

仮想マシンのエントロピーのソースとしてhavegedを使用することは適切ですか?

仮想マシンのエントロピープール枯渇の解決策を探しているときに、_ [〜#〜] havege [〜#〜] アルゴリズムに基づくhavegedという興味深いプロジェクトに遭遇しました(ハードウェアの揮発性エントロピーの収集と拡張)。それはかなり素晴らしい主張です。

HAVEGEは、内部CPUハードウェアの状態(キャッシュ、分岐予測子、TLB)の変更を不確実性の原因として利用する乱数ジェネレーターです。初期化フェーズでは、プロセッサのハードウェアクロックサイクルカウンターを使用して、このエントロピーの一部を収集します。平均すると、オペレーティングシステムコールごとに何万もの予測不可能なビットを収集できます。

これが本当にヘッドレス仮想マシンでほぼ無制限の高品質エントロピーを生成する場合、デフォルトですべてのサーバーディストリビューションに含める必要があります!それでも、一部の人々は懸念を表明しています。

「本来、[HAVEGE]はプロセッサの高解像度タイマー(RDTSC命令)に基づくタイミング情報を使用します。この命令は仮想化でき、一部の仮想マシンホストはこの命令を無効にして、0または予測可能な結果を​​返します。」
(出典: PolarSSL Security Advisory 2011-02 polarssl.org)。

さらに、人気のあるNISTおよびENTテストは、意図的に誤って構成されていて実際に乱数を生成していない場合でも、havegedにパスを与えることがあります!

プロセッサのタイムスタンプカウンターを読み取るのではなく、HAVEGEの「HARDTICKS」マクロを定数0(ゼロ)に置き換えました。これはすぐにランダム性テストに失敗しました。ただし、代わりに定数1(1)を使用した場合、entテストに合格しました。そしてnistでさえ、実行された426のテストのうち1つの失敗したテストのみでほぼ合格しました。 (出典: HAVEGEランダムネスの評価 engbloms.seで)。

  • それでは、仮想マシンでhavegedを使用しても安全な仮想化プラットフォーム/ハイパーバイザーはどれですか。
  • また、ランダム性のソースが十分に高品質の数値を生成しているかどうかをテストするために一般に受け入れられているベストプラクティスの方法はありますか?
69
Nic

警告:HAVEGEがその主張に準拠しているとは私は確かに主張していません。その理論や実装については確認していません。)

ランダム性を得るために、HAVEGEおよび同様のシステムは「物理的イベント」、特に物理的イベントのtimingをフィードします。このようなイベントには、ハードウェア割り込みの発生が含まれます(これにより、キーストローク、マウスの動き、着信イーサネットパケット、ハードディスクが書き込み要求を完了するまでの時間などのデータが収集されます)。 HAVEGEは、CPUで発生するすべてのタイプのキャッシュミス(L1キャッシュ、L2キャッシュ、TLB、分岐予測...)にも影響を与えると主張しています。これらの要素の動作は、CPUが前の数千クロックサイクルで何をしているかに依存するため、「ランダム性」が発生する可能性があります。これは rdtsc 命令が関係する大きな精度(必ずしも正確ではない)で現在時刻を測定する可能性にかかっています。各クロックサイクルでインクリメントされる内部カウンターの現在の内容を返すため、サブナノ秒の精度を提供します。

仮想マシンシステムの場合、この命令に関して3つの選択肢があります。

  1. 命令をハードウェアに直接渡します。
  2. 命令をトラップしてエミュレートします。
  3. 命令を完全に無効にします。

VMマネージャーが最初のソリューションを選択する場合、rdtscは必要な精度をすべて備えており、ハードウェアイベントからエントロピーを収集する目的で、物理マシン上にある場合と同様に機能します。ただし、これは仮想マシンであるため、ホストシステム上のアプリケーションであり、常にCPUを取得しているわけではありません。rdtscを使用するゲストオペレーティングシステムから見ると、CPUが「盗まれた」ように見えます"たまに:名目上単一のクロックサイクルで分離された2つの連続するrdtsc命令は、カウンターの増加を数百万報告する場合があります。簡単に言うと、rdtscがハードウェアに単に適用されると、ゲストOSはこれを使用して、ハイパーバイザーの存在を検出できます。

2番目のソリューションは、仮想マシンごとの仮想サイクルカウンターを維持することにより、エミュレーションをより「完全」にすることを目的としています。利点は、ゲストの観点から見ると、rdtscが「盗まれたサイクル」の影響を示さなくなることです。欠点は、このエミュレーションがCPU例外のトリガーとトラップを通じて実行され、数十クロックサイクルからrdtscオペコードのコストが上がることです(CPUブランドによって異なります。一部はrdtscを10サイクル未満で実行し、その他は60または70サイクル)〜サイクル以上。ゲストが多くのrdtscを実行しようとすると(HAVEGEが実行する傾向があるため)、それはクロールまで遅くなります。さらに、例外処理コードは測定を妨害します。コードは、ハードウェアイベントのタイミングを測定する代わりに、例外ハンドラーの実行時間を測定します。これにより、抽出されたランダム性の品質が低下する可能性があります。

3番目のソリューション(rdtscを無効にする)は、HAVEGEが適切なランダム性を返さないようにするだけです。内部では [〜#〜] prng [〜#〜] を使用しているため、「ランダムに見える」と「予測できない」の間に大きな違いがあるため、出力は依然として統計分析ツールをだます可能性があります(統計分析ツールは「ランダムに見える」経路をたどりますが、暗号化セキュリティは予測不可能性に依存しています)。

VirtualBoxマニュアル は、VirtualBoxはデフォルトで最初の方法に従います(rdtscは無条件に許可され、ハードウェアに直接適用されます)が、2番目のソリューションを適用するように構成されている可能性があります(これは望ましくありません) 、 この場合)。

VMが何をするかをテストするには、この小さなプログラムを試すことができます(gcc -W -Wall -O Linux; -O は重要):

#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」rdtscを使用して、CPUブランドに応じて、10〜100の値を報告します。報告された値が0の場合、またはプログラムがクラッシュした場合、rdtscは無効になります。値が千単位の場合、rdtscがエミュレートされます。これは、エントロピー収集が期待どおりに機能しない可能性があることを意味します。

VMマネージャは、仮想カウンタを維持しながら、実行に必要な予想時間を差し引く可能性があるため、10〜100の値を得ても、rdtscがエミュレートされない保証はありません。最終的には、VMマネージャーのマニュアルと設定をよく見る必要があります。


もちろん、HAVEGEの前提全体は疑わしいものです。実用的なセキュリティを実現するには、200以下の「実際のランダム」ビットが必要です。これを 暗号的に安全なPRNG のシードとして使用します。 PRNGは、真のランダム性と区別がつかないギガバイトの疑似aleaを生成します。これは、すべての実用的な目的に十分です。

ハードウェアに少しずつ戻ると主張することは、エントロピーをガソリンの一種と見なす、その欠陥のあるアイデアの別の発生のように見えます。

40
Tom Leek

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エミュレーター実験について:

havegedテストスイート、NISTおよびentは、ソースビルドが機能するRNGを生成したことを確認します。仮想環境での動作が古いことを確認するには、ランタイムテストが必要です。これは、hagedにかなり最近追加されたものです。

統計検定について:

hardware RNGTRNG、壊れていないことをどうやって確認しますか?ハードウェアが壊れる。ドイツの標準化団体は、まさにその問題に対処する仕様を持っていますAIS31。そのアプローチは老人によって採用されています。高齢者に適用されるRNGの標準に関する(偏った)議論は、次の場所にあります。

http://www.issihosts.com/haveged/ais31.html

HAVEGEの予測不可能性は、ベンチマークソフトウェアで見られるメカニズムとまったく同じです。これはタイマーのドリフトによるものではなく、最近のプロセッサーにおける非同期動作の集約によるものです。パフォーマンスの変動がキャッシュミスによるものか、別のプロセッサに配信されるタイムスライスによるものかは、実際には関係ありません。タイマーの精度も、「適切」である限り問題になりません。それはどのように決定されますか?出力によって。設計上(または設計上)/dev/randomは不十分な入力データの影響を受けません。設計を覆す唯一の方法は、エントロピープールに追加されたエントロピーについて嘘をつくことです。 hasgedの最新バージョンは、出力が理想的なTRNGと一致することを保証するために、生成された出力に対してランタイムエントロピー推定を実行します。

エグゼクティブサマリー:havegedの出力は、ドイツの標準化団体がTRNGを認定するために使用したテストによると、TRNGと区別がつきません。そうでない場合、havegedはシャットダウンします。

11
gwuertz

更新gwuertzのおかげで、havegedの現在の作成者/管理者、HAVEGEhavegedの分離に失敗しました。)

havegedは、乱数を生成するためのHAVEGEメソッドの個別の実装であり、現在、維持され、ここに文書化されています。 http://www.issihosts.com/haveged/ (そしてlibhavegeを直接使用しなくなりました) 。

HAVEGEはあまり最新ではありませんが(2006年)、速度と正確さのために誰かが パッチを当てた より最近(2009年)にしています。その方法が文書化されておらず、仮想マシンについても言及されておらず、前述のとおり、RDTSC(または同等のプラットフォーム)に(大きく)依存しているため、注意が必要です。 (また、ソースコードは私を震えさせますが、それはかなり主観的です。)

私は、ホストVMが意図せずにゲストに侵入することはない 状態の漏出 であってはならない)と主張します。

Linuxでのより良いアプローチは rng-tools with virtio-rng 準仮想化されたrngドライバー(つまり、ゲストがホストによって収集されたエントロピーにアクセスできるようにし、ゲストは「ランダムな」イベントを表示します)、または Entropy Broker の方が便利な場合があります。最近のIntelチップでは、ゲストに [〜#〜] rdrand [〜#〜] 命令を公開して、問題を回避することもできます。

この記事( hpaの講演LinuxCon Europe 2012から)は、次の参考文献として役立ちます: http://lwn.net/Articles/525459/HAVEGE/havegedについても説明します(ここでも区別は明確ではありません)。

ランダム性の欠如を判断する方法についての考えについては、この質問への回答を参照してください。 疑似ランダムデータを識別するためにどの統計を使用できますか?

9
mr.spuratic