+#ifdef __DJGPP__
+int RAND_poll(void)
+{
+    for (i = 0; i < sizeof(buf); i++) {
+        srand(rawclock() + i);
+        ...

The problem is that value returned by rawclock() will most likely remain constant for every invocation of the routine in question. Or rather that probability of its changing is diminishingly low even for elder CPU, as it has enough time for limited number of trivial arithmetic operations. Essentially it's meaningless to filter the value returned by rawclock() through [s]rand[om] as it won't *add* any entropy. There is a number of other things one can do. If you run at privilege level 0 and on Pentium or better you have the option to time hlt instruction, e.g.:


rdtsc; mov %eax,%ecx; hlt; rdtsc; sub %ecx,%eax.

There is new OPENSSL_instrument_halt() implemented in HEAD, which does the above and returns 0 if it was not appropriate to instrument halt. Preliminary tests show that this seems to be the best candidate for providing *some* entropy. It should be noted however that even under MS-DOS, running at privilege level 0 doesn't seem to be wide-spread option. At least the default DPMI driver provided with DJGPP is not privileged. There are replacements provided, CWSDPR0.EXE and PMODE/DJ, but who uses them?


Alternatively (as last resort in unprivileged mode on [34]86) one can simply spin waiting for uclock change, e.g.:

for(u0=uclock(),rnd=0; u0!=uclock(); rnd++)

Naturally the idea was to 'for (... u0==uclock();...)'. I far as I can tell uclock() is essentially equivalent to previously suggested set_timeout(0). uclock() does port I/O, which is apparently slower than the counter being read, which must be the reason why it turned out that rnd remained 0 (at least on the computer I've tried). But even though uclock() returns different values at every invocation, if called in tight loop, the *difference* between returned values hardly varies, so that it can't provide entropy. At least not if called in loop. It should be possible to use it as poor-man replacement for Pentium TSC to instrument *other* events. E.g. one can intrument poll for I/O and take timestamps upon socket receive (in hope that the very moment of packet delivery carries some entropy).


I've also tried 'for (t0=rawclock(),rnd=0; t0==rawclock(); rnd++)'. Essentially it should provide sort of the amount of entropy OPENSSL_instrument_halt() provides *divided* by average number of oscillations per loop spin, right? And the trouble is that it might be quite a number, at least big enough to mask whatever entropy OPENSSL_instrument_halt() might be providing. One can try to squeeze it by inlining rawclock() and taking segment selector load out of the loop...

Opinions? A.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to