Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 2 Jan 2012 03:55:30 +0400
From: Solar Designer <>
To:, Nolan Lum <>,
	Colin Percival <>,,
	Todd Miller <>
Subject: OpenSSL and *BSD *_Final context struct zeroization (was: weird crypt-sha* in DragonFly BSD)

On Tue, Nov 15, 2011 at 11:52:34PM +0400, Solar Designer wrote:
> On Tue, Nov 15, 2011 at 06:35:02AM +0400, Solar Designer wrote:
> > There's also minor weirdness in the code - such as two local pointer
> > variables being declared static seemingly for no reason, and only
> > "final" but not "ctx" being zeroized in the end.  But even this lack of
> > proper cleanup is very minor compared to the lack of stretching.
> It turns out that these other minor issues were inherited from phk's
> md5crypt.c from FreeBSD.
> Currently in FreeBSD, crypt-md5.c: crypt_md5() has extra static
> declarations (not only the output buffer, but also three pointers), and
> it forgets to zeroize ctx and ctx1 (even though it does zeroize final).
> md5crypt.c: __md5crypt() in NetBSD no longer has the extra statics, but
> it does forget to zeroize ctx and ctx1.
> md5crypt.c: md5crypt() in OpenBSD has the weird static pointers and
> forgets to zeroize ctx and ctx1.

I was wrong about the not zeroized ctx* - it turns out that *BSD's
MD5Final and the like, unlike OpenSSL's, fully zeroize the context
struct.  I've tested this with MD5Final corresponding to <md5.h> on
OpenBSD 4.6 (whatever I happened to have installed).  I did not test on
other *BSD's and other of their *Final functions, but I hope they're
similar.  Sorry for the noise.  (The weirdness with static pointers on
some systems still applies, though.  But it has no security relevance.)

However, this made me discover something else: OpenSSL's *_Final() (at
least MD5_Final() on my build of OpenSSL 1.0.0d as well as on OpenBSD 4.6)
partially zeroizes the context structure.  This makes little sense to
me: why zeroize _partially_?  Then the caller is expected to zeroize
fully (if it cares) anyway.

Specifically, the computed hash and the length of input in bits remain
in the context struct after MD5_Final() (and likely after other
*_Final()s as well).  My only guess as to the rationale may be that the
API is defined such that *_Final() may be called multiple times, so it
does what it can as it relates to zeroization under this limitation.
Is this the case?  ...No, not confirmed: calling OpenSSL's MD5_Final() a
second time in a row yields a different hash value.

So the partial zeroization in OpenSSL looks like an implementation bug
to me, then.


Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.