4
$\begingroup$

Let's say I need to generate a key, I have these three options as to where to get random data:

  • Yubikey (gpg-connect-agent 'SCD RANDOM 16384' /bye)
  • /dev/random
  • Combine bytes from the 2 sources

My question is: how do I determine which source is better?

P.S.

Also, any information about how Yubikeys generate random data is appreciated... I guess it has to be some true random number generator based on some physical process (?)

$\endgroup$
5
  • 1
    $\begingroup$ It sounds like that command for the YubiKey only works on the YubiKey 5 Series. A brief search didn't lead me to how it's generating random numbers. The YubiKey 5 Series Technical Manual doesn't mention 'random number generator' or similar at all. An old manual from 2014 mentions a built in LFSR fed from the touch sensor/USB traffic. I would stick to the OS CSPRNG and not bother combining anything with it. That's what most software will be doing plus it works without buying a YubiKey. $\endgroup$ Commented Apr 7 at 11:09
  • $\begingroup$ One of the reasons why I ask the question is to understand what is "better": generate key in the OS and then move it to Yubikey or make Yubikey generate it for me internally. 1st approach leaves key "exposed" to OS, 2nd approach hinges upon Yubikey RNG... $\endgroup$
    – DimanNe
    Commented Apr 7 at 13:24
  • 5
    $\begingroup$ Oh, well that's a completely different question all together. I suggest you edit your question. You should generate and use key material on the YubiKey itself when possible because the idea is for the secret to not be extracted. However, that isn't always possible. For example, challenge-response requires you to pass a secret key to the YubiKey when configuring the slot. $\endgroup$ Commented Apr 7 at 18:37
  • 1
    $\begingroup$ In general, /dev/random can use more entropy sources, so it's more likely to be a strong key, but because that key is being handled by a general-purpose computer there's a lot more risk of compromise; it's a tradeoff between "key generated by a potentially-weaker RNG in a way that makes risk of it being stolen trivially small" and "key generated by an almost-certainly-stronger RNG in a way that makes risk of it being stolen depend on your own personal operational security". If there's malware or an attacker on your host while you do the key generation, you'd be better off with the yubikey. $\endgroup$ Commented Apr 7 at 21:53
  • 1
    $\begingroup$ Whereas if you're generating random content on the yubikey and relaying those random bytes to the host (as opposed to keeping key content strictly on the yubikey itself), you're getting the worst of both worlds; don't do that. $\endgroup$ Commented Apr 7 at 21:58

2 Answers 2

9
$\begingroup$

You should typically use the OS CSPRNG, which would be /dev/urandom or /dev/random. The reason is that the OS CSPRNG is typically secure, well-audited, and widely used, and on most modern desktop, laptop, and server systems, there is plenty of entropy to be had to reseed the generator periodically (usually including an on-chip TRNG). It is also typically very fast. Once we have 256 bits of entropy in a CSPRNG, we believe that's more than sufficient to generate all the data we need on a system, so a properly seeded /dev/urandom or /dev/random should be sufficient.

Another reason this should be sufficient is that the OS CSPRNG is what every other piece of software you use on your system uses. Thus, if it were insecure, all of your TLS sessions would be insecure, all of your temporary file names would be predictable, and all of the memory addresses on your system would also be predictable (leading to easy attacks on things like ASLR). We believe all the algorithms used in, say, Linux's CSPRNG are cryptographically secure and suitable for purpose, so there's no reason to think that there's any attack better than brute force.

Note that on modern Linux (5.18 and above), both /dev/urandom and /dev/random are completely identical when the CSPRNG has been properly seeded.

The YubiKey option is dependent on the hardware and firmware; it doesn't work on all YubiKeys. I also expect that it's going to be a little difficult to generate 16384 bytes quickly using a TRNG unless it also uses a DRBG (like Intel's on-chip TRNG). Since most modern machines already include the output of a TRNG (often RDRAND) in the CSPRNG anyway, there isn't much benefit to using a YubiKey here, and it's much less portable than using the OS CSPRNG, so I'd stick with the OS source.

$\endgroup$
2
  • $\begingroup$ And as far as I understand, there is no an easy way to really "measure/estimate" quality of random data?.. This answer looks quite convincing: crypto.stackexchange.com/questions/71426/randomness-testing $\endgroup$
    – DimanNe
    Commented Apr 7 at 14:29
  • 1
    $\begingroup$ We can estimate the entropy in a system with some level of capability. For example, if we have four possible equally likely values, then that's two bits of entropy. But if the output provides enough entropy and isn't invertible, then there's no difference in quality of the output. A bit of entropy is the same regardless of where it comes from. $\endgroup$
    – bk2204
    Commented Apr 7 at 15:01
5
$\begingroup$

Let's say I need to generate a key, I have these three options as to where to get random data:

  • Yubikey (gpg-connect-agent 'SCD RANDOM 16384' /bye)
  • /dev/random
  • Combine bytes from the 2 sources

There is a better option: You can write data from your Yubikey to /dev/random, and then read from /dev/urandom (or use getentropy).

On the system you are designing where you know there is a Yubikey and you know gpg-connect-agent will work to talk to it and so on, you can get data from the Yubikey and write it to /dev/random to incorporate it into the system's entropy pool and affect subsequent system RNG output before running applications that need entropy. Every major Unixish operating system supports this—for example, Linux, FreeBSD, NetBSD, OpenBSD, illumos. That will help your key generation application and all other applications you're using on the same system.

Then, after you have done that in your system, your application software should always just use /dev/urandom (or getentropy, on more recent systems) so that they generate keys based on all the entropy sources gathered by the system, including your Yubikey output, keystroke timings, environmental sensors, other hardware RNGs like RDRAND or TPM, and so on. Applications should never read from the legacy /dev/random interface for key generation; the idea that reading from /dev/random is better is a myth, and you should just use /dev/urandom, and even the Linux man page now calls /dev/random a legacy interface and advises against it. (You can write your Yubikey's output to /dev/urandom too, instead of to /dev/random, if you like.)


There is also another interface from Linux, getrandom, which is unnecessarily complicated and confusing with a variety of flags to choose between incoherent and inconsistently implemented behavior. But as long as you engineer your system to feed samples from an unpredictable process—e.g., your Yubikey—into /dev/random before applications generate keys, there is no security difference between the various different ways to use it. So you should just use getentropy anyway.

$\endgroup$

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