/dev/random への書き込みが /dev/random の並列読み取りを高速化しないのはなぜですか。

/dev/random への書き込みが /dev/random の並列読み取りを高速化しないのはなぜですか。

通常、読み取り操作は/dev/random100〜500バイトを生成し、エントロピーが収集されるのを待つブロックを生成します。

/dev/random他のプロセスに情報を書き込んで読み取る速度が速くないのはなぜですか?必要なエントロピーを提供してはいけませんか?

gpg再起動してすべてを再入力することなく、ロック解除または同様のソフトウェアのロックを解除したり、初級秘密鍵ではなくキーを生成したりするのに役立ちます。

答え1

/dev/random追加のランダムバイトを提供する方法の一部なので、書くことができますが、/dev/randomそれだけでは不十分です。また、追加のエントロピーがあることを呼び出してシステムに通知する必要がありますioctl()

私のテストにも同じ機能が必要です。スマートカード設定プログラムこれは、マウス/キーボードが各テスト実行に対して複数の呼び出しを実行するのに十分なコンテンツを生成するのを待たないためですgpg。私がすることは、テストと同時にPythonプログラムを実行することです。当然そうです。いいえランダム文字列はまったくランダムではないため、実際のgpgキー生成に適しています(システムで生成されたランダム情報は依然としてインターリーブされます)。文字列を設定する外部ソースがある場合は、random高いエントロピーを持つことができるはずです。以下を使用してエントロピーを確認できます。

cat /proc/sys/kernel/random/entropy_avail

プログラム:

#!/usr/bin/env python
# For testing purposes only 
# DO NOT USE THIS, THIS DOES NOT PROVIDE ENTROPY TO /dev/random, JUST BYTES

import fcntl
import time
import struct

RNDADDENTROPY=0x40085203

while True:
    random = "3420348024823049823-984230942049832423l4j2l42j"
    t = struct.pack("ii32s", 8, 32, random)
    with open("/dev/random", mode='wb') as fp:
        # as fp has a method fileno(), you can pass it to ioctl
        res = fcntl.ioctl(fp, RNDADDENTROPY, t)
    time.sleep(0.001)

(完了したらプログラムを終了することを忘れないでください。)

答え2

通常、カーネル開発者が設計し、次の文書に文書化されていますman 4 random

Writing to /dev/random or /dev/urandom will update the entropy pool
with the data written, but this will not result in a higher entropy
count.  This means that it will impact the contents read from both
files, but it will not make reads from /dev/random faster.

答え3

/dev/randomAnthonyは、書き込みがエントロピー数を増やさないと説明し、RNDADDENTROPY ioctlを実演しました(参照:ランダム(4)) を使用してエントロピーを計算できます.明らかに実際には安全ではないので、ハードウェア乱数ジェネレータを使用できるようになれば代替になります。

次の実装では、エントロピープールから512バイト(4096ビット)のランダム性を取得し、/dev/hwrngそれをエントロピープールに渡します。各バイトには4ビットのエントロピーが与えられ、これは私がランダムに選択したものです。その後は呼び出されます。選択(2)エントロピープールがいっぱいになるとブロックするシステムコール(で説明されています)ランダム(4)マンページ)。

Pythonバージョン:

import fcntl, select, struct
with open('/dev/hwrng', 'rb') as hw, open('/dev/random') as rnd:
    while True:
        d = hw.read(512)
        fcntl.ioctl(rnd, 0x40085203, struct.pack('ii', 4 * len(d), len(d)) + d)
        select.select([], [rnd], [])

Arch Linux isoにはPythonがインストールされていないため、Perlバージョンもあります。

open my $hw, "</dev/hwrng" and open my $rnd, "</dev/random" or die;
for (;;) {
    my $l = read $hw, my $d, 512;
    ioctl $rnd, 0x40085203, pack("ii", 4 * $l, $l) . $d or die;
    vec(my $w, fileno $rnd, 1) = 1;
    select undef, $w, undef, undef
}

これは rngd プログラムの一部である可能性があります。RNGツール)はすでに一般的に利用可能なツール(PythonまたはPerl)を使用していること以外は確認されていません。

関連情報