Re: pgcrypto seeding problem when ssl=on

From: Marko Kreen <markokr(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Noah Misch <noah(at)leadboat(dot)com>, Postgres Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: pgcrypto seeding problem when ssl=on
Date: 2012-12-27 15:21:22
Message-ID: CACMqXCJYYrjWWZZL-4AN7kuDW5UjORvKDK1mFj6X839ukcOTMQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Sun, Dec 23, 2012 at 9:45 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Marko Kreen <markokr(at)gmail(dot)com> writes:
>> On Sat, Dec 22, 2012 at 9:20 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> >> I'm not thrilled with the suggestion to do RAND_cleanup() after forking
> >> though, as that seems like it'll guarantee that each session starts out
> >> with only a minimal amount of entropy.
>
> > No, that's actually the right fix - that forces OpenSSL to do new reseed
> > with system randomness, thus making backend (including SSL_accept)
> > maximally disconnected from static pool in postmaster.
>
> I don't think that "maximal disconnectedness" is the deciding factor
> here, or even a very important factor. If we do RAND_cleanup() then
> each new session will be forced to suck entropy from /dev/urandom
> (immediately, if an SSL connection is attempted). This opens the door
> to quasi-denial-of-service attacks that bleed all the entropy out of the
> system, forcing long delays for new PRNG-using processes, Postgres or
> otherwise. And long delays are the *best case* scenario --- worst case,
> if the system lacks decent /dev/random support, is that new processes
> are starting up with highly correlated PRNG states.

You cannot realistically drain /dev/urandom - it's just a CSPRNG, periodically
seeded from /dev/random. And it cannot cause long-delays. Sessions keys
are actually it's main use-case.

And anyway - if best way to attack Postgres SSL session is to drain and
cryptoanalyze /dev/urandom via SSL attempts, then we are in pretty good
shape. When depening only on properly-used OpenSSL PRNG, we are still
good, but bit worse situation - it's gets minimal amount of entropy
after initial seeding, thus successful cryptoanalyze is more probable
than on /dev/urandom. And when depending on incorrectly used OpenSSL PRNG
(current situation) then the situation is bad - we seem to be depending
on security of single hash.

> If such an approach were a good thing, the OpenSSL guys would have
> implemented it internally --- it'd be easy enough to do, just by forcing
> RAND_cleanup anytime getpid() reads differently than it did when the
> pool was set up.

I thought about it and I realized they cannot do it - the libcrypto has
no idea of application lifetime, so doing such cleanup without application
knowledge is wrong.

Eg. imagine a daemon that loads config, sets up SSL, goes background into
empty chroot.

So the current idea of hashing getpid() on each call is best they can
do to help badly written applications - like Postgres.

> gettimeofday() might not be the very best way of changing the inherited
> PRNG state from child to child, but I think it's a more attractive
> solution than RAND_cleanup.

1. It optimizes CPU for unrealistic attack scenario.

2. It spends more CPU in single-threaded postmaster when SSL is not used -
as postmaster does not know whether incoming connection is SSL or not
it needs to do the PRNG feeding anyway. This might be noticeable
in realistic short-connections scenario, where SSL is used only
for admin or replication connections.

> > This also makes behaviour equal to current ssl=off and exec-backend
> > mode, which already do initial seeding in backend.
>
> No, it's not "equal", because when ssl=off seeding attempts won't happen
> immediately after fork and thus an attacker doesn't have such an easy
> way of draining entropy. If we do what you're suggesting, the attacker
> doesn't even need a valid database login to drain entropy --- he can
> just fire-and-forget NEGOTIATE_SSL startup packets.

You can't just fire-and-forget them - you need to do TCP handshake
plus Postgres SSL handshake; this means each request takes noticeable
amount of setup time from attacker side and on server side the sucker's
IP is visible in logs.

And /dev/urandom seeding is prettly inexpensive compared to SSL pubkey
crypto. It does not look like a scenario we need to design against.

> (The exec-backend
> case will have such issues anyway, but who thought Windows was a secure
> OS?)

ATM the Windows is pretty good shape compared to our Unix situation...

> > If you decide against RAND_cleanup in backend and instead
> > do workarounds in backend or postmaster, then please
> > also to periodic RAND_cleanup in postmaster. This should
> > make harder to exploit weaknesses in reused slowly moving state.
>
> We could consider that, but it's not apparent to me that it has any
> real value.

Properly-designed and properly-used CSPRNG feeding and extraction
should tolerate minor breaks in low-level hashes/ciphers. If we are
not using it as intended, then we lose that guarantee and need to
limit the damage on our side.

--
marko

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Claudio Freire 2012-12-27 15:31:08 Re: A stab at implementing better password hashing, with mixed results
Previous Message Peter Bex 2012-12-27 14:46:38 A stab at implementing better password hashing, with mixed results