4

I need to generate many many initialization vectors and session keys in C++ code. I am wondering if arc4random is up to the task. Last I heard, there are many weaknesses in the RC4 cipher. Should I stick to reading from /dev/urandom instead?

I am only targeting Unix-like OS, not Windows.

Siyuan Ren
  • 342
  • 3
  • 8
  • is it possible (by your crypto library) to use a proper CSPRNG? something like Yarrow / Fortuna / AES-CTR-DRBG / HMAC-DRBG / X9.62C-PRNG ? – SEJPM Apr 09 '15 at 10:10
  • @SOJPM: I am using Apple's CommonCrypto API, which according to my cursory survey include no random number generator. – Siyuan Ren Apr 09 '15 at 10:56
  • the documentation I found claims /dev/random to be safe for crypto purposes. However you can also build your own PRNG by using the output of /dev/random as IV and key for AES-CTR (if available) – SEJPM Apr 09 '15 at 11:19

3 Answers3

7

Both arc4random and /dev/urandom have histories of problems. Some systems have reimplemented arc4random without RC4, but some systems kept RC4. I prefer arc4random over /dev/urandom, but if your goal is to avoid RC4, and you have a system where arc4random uses RC4 and /dev/urandom avoids RC4, then you would prefer /dev/urandom.

These systems have arc4random without RC4:

These use RC4: As of 2017, both DragonFly BSD and FreeBSD kept arc4random with RC4.

These problems can happen with arc4random: Fortunately, none of these problems happen if your system has fixed arc4random.

  • arc4random might use RC4.
  • arc4random might use an improved RC4 that discards the first few hundred bytes after keying the stream, but it might not discard enough bytes.
  • arc4random might fail to detect a fork. After the fork, both processes would get identical random numbers.
  • arc4random might fail to get entropy from the kernel, then seed itself using only gettimeofday and getpid, then generate predictable and insecure numbers. In DragonFly BSD and FreeBSD, the sysctl to get entropy should never fail, so arc4random should never reach the code to use only gettimeofday and getpid.

These problems can happen with /dev/urandom: Unfortunately, some of these problems don't have a fix.

  • /dev/urandom can use RC4. It did in OpenBSD before 5.5. In most other systems, /dev/urandom never used RC4.
  • /dev/urandom might not exist. This might happen inside a chroot. Some setups don't allow device nodes like /dev/urandom inside the chroot.
  • The program might fail to open /dev/urandom because it has reached the limit on file descriptors. This might not be a problem if the program doesn't open lots of files, or if it opens /dev/urandom early.
  • Multi-core machines might slow down, if multiple cores are reading /dev/urandom, but the kernel uses only core to generate the random numbers. This might not be a problem if you have few cores or don't need too many random bytes.

Because of the last 3 problems (chroot, fd limit, multiple cores), I prefer arc4random over /dev/urandom.

There is a third option: Instead of arc4random or /dev/urandom, you might use a crypto library with a secure random number generator.

GnuTLS uses ChaCha or AES for random numbers. NSS uses SHA-256 for random. OpenSSL seems to be switching from SHA-1 to AES for random. All three libraries (GnuTLS, NSS, OpenSSL) seem to avoid RC4 for random numbers.

LibreSSL might call arc4random and use RC4 in systems like DragonFly BSD. Therefore, you can't trust LibreSSL to avoid RC4.

Some people have spread doubt about random numbers from userspace. These people oppose userspace generators (like arc4random, GnuTLS, NSS, OpenSSL, and OpenSSL again) and prefer /dev/urandom for random numbers. This might have influenced Ruby to prefer /dev/urandom over OpenSSL. I prefer the userspace libraries because of my above list of problems with /dev/urandom.

George Koehler
  • 186
  • 1
  • 2
3

You should stick with /dev/urandom. Thomas Hühn has a good overview at http://www.2uo.de/myths-about-urandom/

If you are really concerned you can look at using a user space CSPRNG. Stick with well understood CSPRNGs (e.g. Blum Blum Shub, although it has some performance issues) and respected implementations.

You might want to read http://www.cypherpunks.to/~peter/06_random.pdf and http://cs.ucsb.edu/~koc/cren/project/pp/gawande-mundle.pdf.

Of course, you should also review the source code of any CSPRNG if this is really important for your application.

COL Wotohice
  • 503
  • 2
  • 10
2

RC4 has its flaws and arc4random specifically had some issues about 7 years ago (CVE-2008-5162) yet it is expected to be secured

Also, note that urandom is not the best idea or as Wikipedia says:

A counterpart to /dev/random is /dev/urandom ("unlimited"[5]/non-blocking random source[4]) which reuses the internal pool to produce more pseudo-random bits. This means that the call will not block, but the output may contain less entropy than the corresponding read from /dev/random. While it is still intended as a pseudorandom number generator suitable for most cryptographic purposes, it is not recommended for the generation of long-term cryptographic keys.

As entropy is the one thing you really crave for in PRNGs, this compromise may end in a compromised app.

GalB1t
  • 513
  • 1
  • 5
  • 9
  • 1
    If you do a bit of digging you'll discover that /dev/random and /dev/urandom use identical methods to create random numbers. The difference being that /dev/random estimates the "entropy" and blocks if there is insufficient "entropy". – COL Wotohice Apr 09 '15 at 20:02
  • And that is why it's better for crypto usage, if we are counting on its "entropy assesment" mechanism. – GalB1t Apr 10 '15 at 06:45
  • Meanwhile found this nice page, that almost convinced me that I'm wrong: http://www.2uo.de/myths-about-urandom/ – GalB1t Apr 10 '15 at 07:04
  • 1
    @GalB1t that was the page I was about to sending ;) If the Application is not startet at startup urandom is more then enough. Problem with random is that it will blocks and the missing entropy is only a issue when the device is fresh started – Serverfrog Nov 06 '17 at 09:28
  • 1
    Also, missing entropy can mostly fixed with _havege_ – Serverfrog Nov 06 '17 at 09:31