Author

Topic: Windows PRNG “Seed” registry key (Read 1160 times)

sr. member
Activity: 437
Merit: 260
balance
May 15, 2017, 02:41:56 PM
#5
It's certainly a good question and I don't know the answer off the top of my head. The best I could find relating to Microsoft's decision on this subject was a claim that they follow the NIST guidelines 800-90A outlined in this doc: http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf however given Microsoft's recent track record with security I would say their standards-compliance is questionable. I don't have enough information to determine if it is due to coercion, malice, or negligence.

Luckily Bitcoin running on WIN32 uses OpenSSL in addition to the OS random function to generate a key. Check out this block of code:

Code:
void GetStrongRandBytes(unsigned char* out, int num)
{
    assert(num <= 32);
    CSHA512 hasher;
    unsigned char buf[64];

    // First source: OpenSSL's RNG
    RandAddSeedPerfmon();
    GetRandBytes(buf, 32);
    hasher.Write(buf, 32);

    // Second source: OS RNG
    GetOSRand(buf);
    hasher.Write(buf, 32);

    // Combine with and update state
    {
        std::unique_lock lock(cs_rng_state);
        hasher.Write(rng_state, sizeof(rng_state));
        hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
        ++rng_counter;
        hasher.Finalize(buf);
        memcpy(rng_state, buf + 32, 32);
    }

    // Produce output
    memcpy(out, buf, num);
    memory_cleanse(buf, 64);
}

https://github.com/bitcoin/bitcoin/blob/daf3e7def7b9e5db7a32f5a20b5c4e09e3f0dd18/src/random.cpp#L210-L233

If you follow the code from here you'll see what I'm talking about.

Further reading on RAND_add:

https://wiki.openssl.org/index.php/Manual:RAND_add(3)

legendary
Activity: 3682
Merit: 1580
They could be the phone number that you can call to learn more about Windows' CSPRNG
newbie
Activity: 52
Merit: 0
It says in the quote that only the last 64 bytes are used to seed the CSPRNG so what is there to worry about? The first 12 bytes that remain constant aren't used to seed the CSPRNG. Maybe they serve some other purpose.

Although they aren't used to seed the CSPRNG they must be related to it, or they wouldn't be included in that registry key value. If the twelve bytes represent the differing entropy sources found and used on a particular computer there might be a security risk if an attacker reads them. On the other hand they might represent a unique identifier, in which case it doesn't matter if an attacker reads them.

I'm probably worrying about nothing, but I'd like to know WTF they are for.
legendary
Activity: 3682
Merit: 1580
It says in the quote that only the last 64 bytes are used to seed the CSPRNG so what is there to worry about? The first 12 bytes that remain constant aren't used to seed the CSPRNG. Maybe they serve some other purpose.
newbie
Activity: 52
Merit: 0
The last 64 bytes of the Windows PRNG “Seed” registry key hold a unique hash used to seed the CryptoAPI PRNG. However, that registry key value is 76 bytes long. What do the first 12 bytes hold?

The seed bytes change after every reboot, but the first 12 bytes never change. I tried deleting them and then rebooting, but the system restored exactly the same first 12 bytes. Is there any security risk from an attacker managing to read those 12 bytes? I assume the seed is used in bitcoin private key generation, and those 12 bytes must have some relationship to the seed.

In older versions of Windows the seed was stored in this registry key

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\RNG\Seed

In newer versions of windows the seed now lives here.

HKEY_LOCAL_MACHINE\SYSTEM\RNG

The only information I found from a google was here.

http://illmatics.com/Windows%208%20Heap%20Internals.pdf

Quote
OslpGatherSeedFileEntropy

Gathers entropy by looking up the value of the “Seed” registry key (REG_BINARY) in

HKEY_LOCAL_MACHINE\SYSTEM\RNG.

This key is 76 bytes in size, whereas the last 64 bytes hold a unique hash used to seed the CryptoAPI PRNG
Jump to: