> > jaltman> Do you really want to search through 14MB of data each time
> > jaltman> this routine is called?
> >
> > Well, that actually depends on what the real issue is. I mean, this
> > is likely to happen only once in the life of a program. I understand
> > that if it's a client program it might start quite often.
First, this is a client program and anything more than a few second
delay is unacceptable.
Second, I am properly seeding the PRNG and so I don't expect
RAND_status() to have to do any work. If for some reason there is not
proper seeing I expect RAND_status() to fail so that I can generate
more random data (perhaps by calling RAND_poll() but perhaps not).
> > However,
> > security is an issue, and in a PRNG it can be crucial. And if we're
> > talking about mostly uninitialised memory, it becomes even more
> > important to take a really big chunk, or all you'll get for entropy is
> > a line of zeroes with perhaps a few other bits quite dispersed. Well,
> > perhaps not necessarely zeroes, but the risk of getting a fairly
> > well-known or easily guessable pattern can be great at that time.
> >
> > So, there's a choice. The trade-off seems to be between speed and
> > security in this case. I'm not sure what would be the exact right
> > choice here, perhaps someone else does?
I'm not sure you understand what RAND_poll() does in this case. When
walking the heap, RAND_poll() does not feed the contents of the
allocated heap to RAND_add(), instead it feeds the contents of the
Heap Allocation descriptor:
RAND_add(&hentry, hentry.dwSize, 0);
where hentry is a struct
typedef struct tagHEAPENTRY32 {
SIZE_T dwSize;
HANDLE hHandle;
ULONG_PTR dwAddress;
SIZE_T dwBlockSize;
DWORD dwFlags;
DWORD dwLockCount;
DWORD dwResvd;
DWORD th32ProcessID;
ULONG_PTR th32HeapID;
} HEAPENTRY32;
None of this information is 0. And too be honest, it isn't all that
unpredictable. The size is fixed; the address increments by 4096 in
each call; the handle is fixed; the flags are either 0, 1, 2 most
often 0; dwResvd is always 0; and the dwLockCount is almost always 0.
In my code when I first call RAND_poll() (before RAND_status()) there
are 7 HEAPLIST32 structures and 1061 HEAPENTRY32 structures.
When RAND_poll() is called from within RAND_status() there are still
only 7 HEAPLIST32 structures (representing pools of allocated memory)
but now there are over 10,000 HEAPENTRY32 structures. The process of
allocating/deallocating all of these structures results in over
475,000 page faults.
Security is obviously important but not to the point of making the
software unuseable. Especially when the data that is being fed to
RAND_add() is not all that random. The only data that is really
random here is the first HEAPENTRY32 structure in each HEAPLIST32
list. Reading that subset of the HEAP data would take almost no time
at all.
> I understand that the problem seems to be caused mostly by the behaviour
> of RAND_status(), as it implicitly calls RAND_poll(), when used for the
> first time. The same will happen also when first calling RAND_bytes().
> While on UNIX this is cheap (it does cost an access to /dev/urandom, if
> available), it is very expensive on Windows.
What you are saying is that RAND_status() is going to call RAND_poll()
regardless of whether or not the PRNG has been seeded. In other
words, you are saying that you do not trust (and I don't really blame
you) the application author to know how to see the PRNG.
> If I didn't misunderstand the source, there is no way to work around
> this problem as of 0.9.6. As the "initialized" flag will only be set
> in ssleay_rand_bytes() and ssleay_rand_status() after RAND_poll()
> has been called, even _after_ feeding the PRNG explicitly with
> RAND_add(). So even correct seeding does not help, the delay will
> always be there. My recommondation would be at least that
> RAND_poll() is only called when there has not yet been enough
> entropy added via RAND_add().
I agree 100% with this. RAND_poll() should only be called if proper
seeding has not been done. Perhaps you can add a function that allows
the knowledgeable application designer to set the "initialized" flag
when the work has been done. That way you can still perform proper
seeding when the programmer simply called RAND_add() with a fixed
string in order to work around the error.
> There would be another way in simply not using implicit seeding at
> all and have RAND_status() and RAND_bytes() do what it should in
> this case: fail. But this of course would further increase the
> amount of confused people on the mailing list asking for the PRNG
> not seeded problem :-(
This is how I always thought that RAND_status() was supposed to work.
I think it is more important for people to understand why they need to
perform proper seeding (and provide some recommended routines that
will do it) than it is to hide things behind the developers back. If
the programmer is using OpenSSL it is because s/he wants to design
secure software. If they are ignorant of what is necessary to acheive
their goal they should be forced to learn. Auto seeding for them is
only going to result in them remaining ignorant and leaving a huge
security hole somewhere else in their code.
Many mailing lists post their FAQ to the list once a month. It might
be useful to do the same on the various OpenSSL mailing lists
describing what the list is for; reminding people not to cross post;
and explaining where answers to some of the most common questions can
be found on the web site.
In the meantime, I suggest that the if (kernel) if (snap ...) section
of RAND_poll() be rewritten to only read the first HEAPENTRY32 struct
of each HEAPLIST32. And that a mechanism be provided for application
developers to perform proper seeding prior to calling RAND_status().
Also, I would suggest that RAND_screen() be changed to call
ssleay_rand_bytes() instead of RAND_poll() since neither readscreen()
nor RAND_poll() are capable of setting the 'initialized' flag which is
a static in md_rand.c
- Jeff
Jeffrey Altman * Sr.Software Designer
The Kermit Project * Columbia University
612 West 115th St * New York, NY * 10025 * USA
http://www.kermit-project.org/ * [EMAIL PROTECTED]
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]