2

Many moons ago, I answered a question about Java blocking due to a lack of entropy in /dev/random. (https://security.stackexchange.com/a/53025/41709)

My main suggestion was to use /dev/urandom, but I also suggested that in VM environments, urandom should be seeded from an external source.

It was obviously pointed out by @CodesInChaos that the lack of true randomness of the clean VM would mean that the randoms required for an SSL connection to the external source could be deduced.

(I'm assuming that Pollinate (https://github.com/dustinkirkland/pollinate) will also be susceptible to such an attack)

I've casually thought of a solution on and off for a few months.

Would encrypting a seed on the server using a public certificate or shared secret allow the encrypted seed to be transfered in the clear without the client requiring any entropy?

(Assuming the private key was copied to the client VM physically)

  • 2
    Since everyone is wondering, it's 29 moons ago. – TTT Nov 24 '15 at 19:08
  • I'd personally question whether a VM environment doesn't produce enough entropy. My understanding is that entropy is gathered from a variety of sources, including packet timing. What makes a VM so special that it won't produce sufficient, or reliable entropy? Can you provide a referenced paper for this, since it seems to be a rather important point if it's actually true. – Steve Sether Nov 24 '15 at 19:44
  • @SteveSether, I'm afraid I only have anecdotal evidence to hand. I've worked with headless physical and VM guests that have been starved of entropy due to insufficient sources, despite there being network traffic. If a VM guest booted during this event, then it would not have a true entropy seed source. I'm also aware of Linux operating systems that save a seed on shutdown, the purpose to avoid this situation. – Alastair McCormack Nov 24 '15 at 19:58
  • 1
    @AlastairMcCormack Thanks for you information. Even anecdotal information is a place to start. I'd be a little shocked if this was common, given how much VMs are used essentially everywhere. If /dev/urandom gives out random data without being seeded properly, that seems like it's a kernel bug. – Steve Sether Nov 24 '15 at 20:10
  • There have been actual router exploits where using /dev/urandom to generate private keys generated predictable keys. At the bottom of 2uo.de/myths-about-urandom there is a discussion that the "ideal" random device would wait once after system boot, but stop blocking alltogether after enough entropy has been gathered to reliably seed the generator. – Michael Karcher Nov 24 '15 at 20:15
2

tl;dr

Use TLS_DHE_PSK_WITH_AES_256_CBC_SHA with a large Pre-Shared Key. Send over Seed.

Objective

Create a secure network session over which we can send some entropy.

Preconditions

Assumption: /dev/urandom is foul. (I agree with @SteveSether, this is a kernel bug.)

Assumption: Any protocol you try to create between client and server will, in the end, rediscover TLS or Kerberos (Public Key or Symmetric Key), therefore, you should just use one of these or one like these.

Caveat: It is impossible to preserve Perfect Forward Secrecy without good entropy on both the server and the client. Although it helps to get entropy to the client, in the end this is a fool's errand. See discussion at the end.

With that caveat, let's dive in.

Requirements

To fetch entropy from server, we require:

  1. Secrecy of the entropy
  2. Server Authentication
  3. #1 & #2 imply: Secure Network Protocol with Perfect Forward Secrecy

Candidate Protocols

  1. TLS w/ DHE and Mutual RSA
  2. TLS w/ DHE and PSK
  3. TLS non-standard extension

TLS with DHE and Mutual Authentication

I had to study TLSv1.2 to figure out this wouldn't work. As noted in the question, the client isn't random, so its ephemeral can be known and Eve can compute the Master Secret. I had hoped TLS used the Client's RSA Key to protect the secrecy of the ephemeral(s). It doesn't.

Rejected.

TLS with DHE and Pre-Shared Key

Some people don't like this class of cipher suites. However, those arguments apply to humans as the holder of the PSK, not a computer. This works just fine for large PSKs. There are some security considerations, the most interesting one worth noting is a dictionary/brute-force attack. From RFC 4279:

For the DHE_PSK ciphersuites, an attacker can obtain the information by getting a valid client to attempt connection with the attacker. Passive eavesdropping alone is not sufficient.

In our case, this could be done as an observation attack due to lack of entropy on client. A sufficiently large PSK should eliminate brute forcing the Master Secret, in any event.

Use this one.

TLS Non-Standard Extension

For fun, I was thinking what if we could extend TLS somehow?

During TLS's mutual authentication step, the client and the server exchange their certificates and proofs. If the client could use an Encryption Cert instead of a Signing Cert (this is easily done, Sign and Decrypt are isomorphic), it would tell the server to modify the DHE exchange. During the DHE exchange, server sends its ephemeral as Sign(Encrypt(B,Key_C),Key_S). Only the client can decrypt the server's ephemeral, only the server could have sent it. This keeps the server's ephemeral secret, which normally doesn't need to be. However, because we are trying to create a secure channel that Eve cannot penetrate and client doesn't have entropy for its ephemeral (a,A), hiding B will do the trick.

In summary, modify TLS_DHE_RSA with Mutual Authentication

  • client uses Encryption Cert
  • client authenticates by Decrypting some Nonce
  • Server hides its DHE ephemeral using Client's Encryption Key.

Know anyone on the IETF committee for TLSv1.3?

Other Options?

As suggested above, any other solution (RSA or Secret key provisioning with Nonces, etc.) recreates TLS or Kerberos, so why bother? You'll be taking on all of the challenges of rolling your own network authentication protocol without the vast analysis these protocols have endured.

Conclusion

Just use TLS with DHE and a Pre-Shared Key and send the Seed over that secure channel. It's a standard protocol, it has all of the properties you require, it's easy to set up and it doesn't suffer from too many problems. See below, however.


Discussion: A Fool's Errand and Broken Promises

We need entropy to make good on the promise of Perfect Forward Secrecy (PFS). The client doesn't have it and can't make it, so we are trying to get it from the server. We can use regular old cryptography (RSA or symmetric) to send the entropy. However, if the RSA Private Key or the Symmetric Key are exposed, Eve can use that Key to decrypt the server packet containing the Seed. How bad is this?

Assume after the client received its entropy, it only ran TLS+DHE+RSA for all communications. That has PFS, right? The problem is that once PRNG(Seed) is exposed, Eve, who was eavesdropping and recorded every network session in and out of the client, knows the secret part of the DH ephemeral produced by the client (B=g^b%P) and can rebuild Master Key from every (g,P,A) by doing K=A^b%P. Boom! PFS is gone.

We can't use PFS to send the Seed to client, because client's first DH exchange has the same exact problem. Once a secret key (RSA or PSK) is exposed, Eve can recompute the DH Master Key protecting the session with the Seed. Any other attempt at creating a secure channel or secret message suffers the same fate.

So, without client entropy we can have Current Secrecy for all algorithms. However, exposing any Key used to protect the transfer of the Seed exposes all sessions built using PRNG(Seed).

Basically, /dev/urandom has to work in a client VM to get Perfect Forward Secrecy.

  • I know it's poor practice, but thank you for such a well composed and well researched answer. It's going to take me a few hours to grok. – Alastair McCormack Nov 25 '15 at 8:52
  • @AlastairMcCormack, you're welcome. You spent a couple of years thinking about the problem, I figured I'd spend a few hours thinking about an answer. Although I already knew DH, it forced me to dig into TLS, which I enjoyed. Open a chat if you want to discuss contents in depth. – Andrew Philips Nov 25 '15 at 15:11
1

In your situation, you do not only need confidentality, which you can obtain using a secret shared key, but you also need authenticity. There is no way for the VM to know from the received data whether it is truely random, so the source must be authenticated in a secure way. This includes resistance against replay attacks. Typically this is achieved by using a client-generated nonce. So you need entropy on the client. On a second thought, you might get away with a trusted high-precision timestamp as nonce, as predictability shouldn't be a problem if uniqueness is ensured.

  • Good point re: authenticity. I guess I could sign the response with the server's key and verify against its public cert, or HMAC with a shared key. Again, I don't think would require entropy – Alastair McCormack Nov 24 '15 at 19:45
  • 1
    A signature doesn't prevent replay. The client could be sent the same authentic entropy repeatedly by a man in the middle. Including a nonce in the requests that needs to be signed is a standard way to exclude this attack. – Michael Karcher Nov 24 '15 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.