apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dirk-Willem van Gulik <di...@webweaving.org>
Subject Re: SHA256 and friends.
Date Fri, 20 Jan 2017 08:22:31 GMT
On 19 Jan 2017, at 21:04, William A Rowe Jr <wrowe@rowe-clan.net> wrote:
> On Thu, Jan 19, 2017 at 1:50 PM, Dirk-Willem van Gulik <dirkx@webweaving.org> wrote:
>>> On 19 Jan 2017, at 19:50, Graham Leggett <minfrin@sharp.fm> wrote:
>>> On 19 Jan 2017, at 18:29, Dirk-Willem van Gulik <dirkx@webweaving.org>
>>>> Am wondering now it if makes sense to create a new directory with:
>>>>  hash/*
>>>> section (or something in crypto) where I cull things/move out of the current
apr_random, sha256_glue and apr_md4/5 and apr_sha1 - and
>>>> then all give them below treatment.
>>>> It would make wiring them up to OS specific things or to nss/openssl/CommonCrypto
also a bit easier.
>>>> And then perhaps come up with a few extra apr_hash things that do a subset
of what we currently do in the various apr_sha/md’s.
>>>> Or is that not worth it - as mid to long term md4/md5 and sha1 will evaporate.
>>> I've always been keen to create an apr_crypto_hash_*() set of functions that
do hashing, but guaranteed to be implemented by crypto libraries (OpenSSL et al) and therefore
>> So I guess we could move them in one place - platform neutral (right now sha256 is
unix only).
>> And then rely on our own md4/5/sha1/256 when APU_HAVE_CRYPTO is not defined; and
>> it is - allow a driver to be specified - but if none is yet specified or loaded -
we use the same
>> order as in configure (CommonCrypto, openssl, nss) -- but refuse to fall back to
our 'own'.
>> And rework the innards of our existing hash functions to that apr_hash_ ctx form;
so they
>> can stay as 'legacy' bridges.
>> Would that work ?
> Yes. This allows us to have either crypto-authored implementations, or
> even FIPS validated implementations, if we will simply be dispatching.

So turns out where are not using this that much - so retroactively fixing things should be
easy - and we may be able to deprecate quickly.

As to the selection of the hash - I can see three strategies

A)	current approach (we do this I think only for sha256):

		 apr_crypto_hash_t * ctx = apr_crypto_sha256_new(pool);

 	followed by a hash neutral/generic

   		apr_hash(sha256_ctx, &buf, &len,  plain, plainlen, pool);

	and then create the the corresponding

		apr_crypto_md4_new(apr_pool_t *);
		apr_crypto_md5_new(apr_pool_t *);
		apr_crypto_sha1_new(apr_pool_t *);
		apr_crypto_sha256_new(apr_pool_t *);
	and create new ones (eg. SHA512 etc, etc) as we go along.

B)	more of the ENUM approach as used elsewhere in APR:

		enum {
			APR_CRYPTO_SANE_DEFAULT = APR_CRYPTO_SHA256, // whatever the report of Ecrypt/NIST recommended
in the year of the release.

		apr_crypto_hash_t * ctx = apr_crypto_hash_new(pool, APR_CRYPTO_MD4);	

	with the goal of deprectating the apr_crypto_sha256_new soon. Which has
	the downside that this ultimately means numbers rather than symbols
	and limiting what you can spot at link time.

C)	something more akin to what I use now (as the code I am trying
	to get under long term maintenance control fudges things a bit
	to deal with hardware base crypto (network HSMs and cheap
	USB chipcards/SIMS):

		#define APR_CRYPTO_MD4 "MD4"
		apr_crypto_hash_t * ctx = apr_crypto_hash_new(pool, APR_CRYPTO_MD4);	

	where the strings are picked so that they work with the existing
	char* based pickers of openssl and nss (EVP_get_digestbyname et.al.).

Option A and B have the advantage that with an


one can cleanly add in things like SHA512 -- and option A really locks this down (i.e. in
A you cannot (dynamically) link and thus run a binary unsafe). With option B that becomes
a compile time thing and option C - while ultimately flexible - would be more prone to fiddling
and surprises.

What is the general thought on this ? I am tempted to go for 'A' -- as it gives strong guarantees
- hard to make things go wrong. And if at some point a paying customer or employer of some
one needs things like FIPS #ifdefs - these can be 'strong'.

However I do note that most crypto libraries seem to go for a const char*; and that their
names are pretty much interoperable. (Though internally most use something like A, e.g. openssl

	const EVP_MD *EVP_sha512(void) { return (&sha512_md); }

I would have thought this to be an easy choice - but for the fact that I was somewhat disheartened
by the general state of our hashes - and how far out of date we are. And recognize that A
and B are more impediments for people who want to do the  right thing; than ''C' -- where
as long as you link to a capable crypto library you automatically get anything new.

Does anyone have any strong opinions ? 


View raw message