Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: prng quality



Dear Sirs,

On the darwin-users list I began asking about examination of Darwin's /dev/random, and eventually reported that (especially for large reads) Darwin's /dev/random seemed at first glance to have great apparent unpredictibility and incompressibility. However, chi-square analysis of output from Darwin's /dev/random invited closer examination. I poked in the code and was surprised to be reminded that actual entropy collection in Darwin is undertaken not within the kernel but by a userland daemon (the Security Server). (I had assumed this was possible due to kernel pre-emption and had not initially investigated it.)

I also noticed that Darwin's /dev/random is actually exactly the same as its /dev/urandom:

	devfs_make_node(makedev (ret, 0), DEVFS_CHAR,
		UID_ROOT, GID_WHEEL, 0666, "random", 0);

	/*
	 * also make urandom
	 * (which is exactly the same thing in our context)
	 */
	devfs_make_node(makedev (ret, 1), DEVFS_CHAR,
		UID_ROOT, GID_WHEEL, 0666, "urandom", 0);

The man page on urandom makes it clear that Apple's /dev/random is identical to its /dev/random, so Apple is aware of this and apparently does not comprehend the problem it invites, instead calling those concerned about this problem "paranoid" and trying to suggest programs which depend on /dev/random should take steps to acquire better entropy if /dev/urandom is not good enough. The reason this is a problem can be illustrated with reference to the origin of Apple's /dev/random, and is less related to paranoia than to math.

Darwin possess an outstanding /dev/urandom, which provides incompressibly irregular output of arbitrary length without great demand on the kernel. The decision to use this code also in Darwin's /dev/random was grounded in -- and my source is the now-closed bug tracker through which Apple used to provide a window on its internal Darwin development -- (a) a bug filed that "Darwin has no /dev/random" (at a time in which there was no /dev/urandom either), (b) Wilfredo's assurance of Apple engineers that a /dev/random was not a Unix joke but a genuine OS feature depended upon by porters of serious crypto projects, and that absence of a quality /dev/random was a legitimate problem, and (c) a supervisor closed the bug on the strength of the argument that a prng based on Yarrow code was "better" than the /dev/random in FreeBSD and that this Yarrow-based prng would be used for Darwin's /dev/random.

So, what exactly is wrong with using /dev/urandom instead or /dev/random for an entropy source in crypto tools?

People creating and using cryptographic keys of any substantial length will certainly request entropy which greatly exceeds the size of the key from which Darwin generates its output, even if Darwin doubles or quadruples the key length from that in the Yarrow-160 code on which Darwin's prng is based. This is especially true on machines creating HTTPS connections or otherwise generating keys, which will require many key creations between re-seeds of the Yarrow-based prng. Thus, 1024-bit and 2048-bit PGP/GPG keys may reflect actual entropy of, say, 160 bits (based on the Yarrow-160 code; I have not compared Apple's code to the originally published Yarrow code to determine if Apple's is slightly larger or not, but it looks like Security Server's re-seed is based on a read of eight values of). Successive keys made before re-seeding will also have a capped limit of their actual entropy content, but the situation is worse: they will be using the exact same entropy used for every other key in the between-reseeding period. The very Yarrow paper, by the authors of the Yarrow-160 code on which Darwin's /dev/random code is based, expressly warns against use of the Yarrow prng for the purposes to which a /dev/random device is put:

"Like any other cryptographic primitive, a Yarrow generator has a limited strength which we express in the size of the key. Yarrow-160 relies on the strength of three-key triple-DES and SHA-1, and has an effective key length of about 160 bits. Systems that have switched to new cryptographic mechanisms (such as the new AES cipher...) in the interest of getting higher security should use a different version of Yarrow to rely on those new mechanisms. IF A LONGER KEY IS NECESSARY, THEN A FUTURE "LARGER" VERSION OF YARROW SHOULD BE USED; IT MAKES NO SENSE TO USE A 160-BIT PRNG TO GENERATE A 256-BIT KEY FOR A BLOCK CIPHER, IF 256 BITS OF SECURITY ARE ACTUALLY REQUIRED" <http://schneier.com/paper-yarrow.ps.gz> (emphasis added); see also <http://www.counterpane.com/yarrow.html>

Thus, Yarrow by its nature is a supplier of /dev/urandom and should in no circumstance be advertised as /dev/random, which the ordinary cryptographic user will mistake for a source of actual entropy with a number of bits of entropy virtually identical to the number of bits read (even if several KB are read). (One fix is to provide, with respect to /dev/random reads, an enforced re-seeding every N bits, where N is not greater than the entropy in the Yarrow prng key) Indeed, making a PGP/GPG key with Darwin's /dev/random as an entropy source guarantees that the key will fall victim to the very first pitfall identified in the Yarrow paper: overestimation of the entropy actually present in the "random" input used to generate keys.

The distinction between /dev/random and /dev/urandom is not lost on programmers, as the (languishing) systrace code created for MacOS X (complete with Cocoa GUI!) demonstrated with its example allowing iTunes to query /dev/urandom (iTunes' shuffle feature works with this systrace policy, proving iTunes actually reads /dev/urandom and not /dev/random). Thus, dice-rolling programs (and first-person shooters, Asteroids, etc.) query /dev/urandom at leisure without straining the kernel or threatening the system's entropy pool, but when actual bit-for-bit strong entropy is required of a certain length, an actual /dev/random should be available to supply the expected entropy (and not merely 160 bits of entropy served, and served as leftovers, and then reheated again after being frozen, to appear to unsuspecting guests as 2048 bits of entropy).

Solutions appear to be (a) modifying /dev/random to demand re-seed once for every N bits of output demanded before giving out more than N bits, where N is the amount of entropy in the Yarrow generator's key [downside: on a busy SSL site or other frequent key-creating system, this will demand the userland Security Server be busy, or cause delays until the Security Server wakes and writes entropy into /dev/random; can the kernel really wait for the userland process? Am I mistaken that Darwin is the only place entropy is written to /dev/random from outside the kernel?], or (b) taking BSD-licensed code known to produce actual entropy from /dev/random and using that for free. Am I missing any alternate theories?

Has anyone got an analysis they believe vindicates the recycling of entropy for crypto input?

Best regards,
	Chris

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwinos-users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/darwinos-users/email@hidden

This email sent to email@hidden
References: 
 >prng quality (From: "Christopher D. Lewis" <email@hidden>)
 >Re: prng quality (From: Justin Walker <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.