On 19 Jan 2017, at 21:04, William A Rowe Jr <wr...@rowe-clan.net> wrote: > On Thu, Jan 19, 2017 at 1:50 PM, Dirk-Willem van Gulik <di...@webweaving.org> > wrote: >> >>> On 19 Jan 2017, at 19:50, Graham Leggett <minf...@sharp.fm> wrote: >>> On 19 Jan 2017, at 18:29, Dirk-Willem van Gulik <di...@webweaving.org> >>> wrote: >>> >>>> 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 secure. >> >> 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 when >> 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_MD4, APR_CRYPTO_MD5, .... 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 #ifdef APU_HAVE_CRYPTO 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 its 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 ? Dw.