Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Sep 2012 09:43:09 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
Cc:        freebsd-security@FreeBSD.org, RW <rwmaillists@googlemail.com>
Subject:   Re: Collecting entropy from device_attach() times.
Message-ID:  <20120928084927.R5001@besplex.bde.org>
In-Reply-To: <86fw63w20o.fsf@ds4.des.no>
References:  <20120918211422.GA1400@garage.freebsd.pl> <20120919192836.3a60cdfd@gumby.homeunix.com> <863923pzgi.fsf@ds4.des.no> <CAG5KPzwhq4UzPxbx74vX5KKtqC4tWkTsKAHjGDsdD8MqJVVkRg@mail.gmail.com> <20120927125956.0594fa73@gumby.homeunix.com> <86pq57o7ps.fsf@ds4.des.no> <20120928062245.K4426@besplex.bde.org> <86fw63w20o.fsf@ds4.des.no>

next in thread | previous in thread | raw e-mail | index | archive | help
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--0-1241331444-1348789389=:5001
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

On Fri, 28 Sep 2012, [utf-8] Dag-Erling Sm=C3=B8rgrav wrote:

> Bruce Evans <brde@optusnet.com.au> writes:
>> "Dag-Erling Sm=C3=B8rgrav" <des@des.no> writes:
>>> RW <rwmaillists@googlemail.com> writes:
>>>> binuptime(&bt);
>>>> return (bt.frac ^ bt.sec);
>>> Why the heck does it xor the integer and fractional parts together?
>> Because most of the entropy is in the fractional part,
>
> This is not about entropy, it's about implementing get_cyclecount() on a
> platform that doesn't have a TSC.  It's supposed to be monotonic, and
> this implementation clearly isn't.  Even when bt.sec is small enough

Its monotonicity and documentation of same is a bug.

> that it doesn't affect significant digits of bt.frac (which should be
> most of the time, unless the resolution of the underlying timecounter
> exceeds ~2^32 Hz), get_cyclecount() will go backward every time a new
> second ticks over.

Its implementation demonstrates that it was never actually monotonic.
Even rdtsc() isn't necessarily monotonic.

Its comment in at least the i386 version still says that it "Return[s]
contents of an in-cpu fast counter as a sort of "bogo-time" for random-
harvesting purposes".  This has rotted in various ways:
- on i386 without tsc_present, it never used an in-cpu fast counter
   (since there is none)
- on i386, without tsc_present, it now uses the generic cpu_ticks()
   and gets whatever that gives, which happens to be a more monotonic
   less bogus time that before, and which doesn't have the xor hack.
- on i386, with tsc_present, it now uses the generic cpu_ticks()
   and gets whatever that gives, which happens to be the same in-cpu
   fast counter as before.
It shouldn't be commenting about what cpu_ticks() [doesn't] do.
- its man page says that it uses a "register available in most modern
   CPUs to return a value that is monotonically increasing inside each
   CPU", and explicitly documents that each CPU gives a separate monotonic
   sequence.  A strict reading of this says that it doesn't exist on
   non-modern CPUs or on some modern CPUS.  Bugs in this include:
   - over-specification of implementation details.  Lots of bugs in the
     details:
     - at least in i386, the value isn't necessarily increasing even with
       in each CPU, since rdtsc() isn't serialized and maybe something
       resets the register.  The implementation just uses rdtsc() without
       worrying about these points.
     - on more modern CPUs, the values are synced, so the sequences aren't
       separate.
   - guaranteeing monotonicity.
- it is now abused for non-random-harvesting purposes, and some of these
   require it to be monotonic.  These places mostly just want a timestamp
   for debugging and should be using microtime().  See one of my old mails
   for full details of this and more details of the bogusness of
   get_cyclecount().

I should have objected more strongly when it was implemented.  Just using
binuptime() was adequate iff the timecounter hardware is the same as
the cycle counter (TSC on x86).  A TSC usable for timecounter hardware is
normal now.  I don't like cpu_tick() either, but it solves the efficiency
problem with the timecounter hardware not being the cycle counter.  It
solves them for use mainly in thread runtime accounting, but is usable
for get_cyclecount() too, and is in fact used for get_cyclecount() on i386
(get_cyclecount() just wraps it and no one except bde cares about the
inefficiency of this).  cpu_tick() is undocumented, so there are no bugs
in its man page to fix.

Bruce
--0-1241331444-1348789389=:5001--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120928084927.R5001>