On Friday 08 January 2016 06:57:54 Amos Jeffries wrote:
> On 8/01/2016 4:30 a.m., Tim Ruehsen wrote:
> > On Thursday 07 January 2016 15:05:38 Niels Möller wrote:
> >> Tim Ruehsen writes:
> >>> But what's wrong with providing a larger buffer than needed ?
> >> 
> >> I don't think about it as the size of the provided buffer, but as the
> >> requested size of the digest (intended for the usecase of truncated
> >> digests). And it's not defined how to produce a 20-byte md5 digest. If
> >> 
> >>   md5_digest(&md5, 20, digest);
> >> 
> >> were allowed, what should it do? Write 16 bytes, and leave the remaining
> >> 4 bytes untouched?
> > 
> > You put the answer into my mouth... yes, that seems intuitive to me.
> 
> Then what will the application do with 4 random bytes of output?
> It clearly is not aware of the 16-byte digest size limit. So what basis
> do we have to be certain it will output or use only those 16 bytes, and
> not doing something such as sending the buffer to snprintf with length
> parameter of 20 there as well. Or worse, passing just the (unterminated)
> buffer start pointer to sprintf.

??? 

> It is a very bad policy for any code, let alone security code, to just
> blindly trust that the external software will operate correctly.

Sorry, that is IMO bullshit. You say a low-level function is responsible for 
what the (high-level caller | application) is doing. *head shake*
It is absolutely in the callers responsibility to use the output of any 
function correctly - and his basis is the documentation.

> The choice is also not so black and white. There are a bunch of other
> "intuitive" actions that could be performed:

You are right, 'intuition' is not the point. The point is what is documented 
and what not.

Here on Debian I have no man pages for any nettle functions - so I looked into 
the header files to find the function prototypes and used them 'intuitive'. 
Which worked immediately until I started to use a larger digest buffer than 
'allowed'. I am using the same buffer for other algorithms/hash functions as 
well, so using 'sizeof' was straight forward. Nettle functions unexpectedly 
crashed of my application instead of a sane return value(all those function 
are void, *_digest() could return error or the number of bytes written).

I meanwhile found the nettle docs on the web 
(http://www.lysator.liu.se/~nisse/nettle/nettle.html#MD5):

###########
Function: void md5_digest (struct md5_ctx *ctx, size_t length, uint8_t 
*digest)

Performs final processing and extracts the message digest, writing it to 
digest. length may be smaller than MD5_DIGEST_SIZE, in which case only the 
first length octets of the digest are written. 
###########

Not a simple word saying 'If length is larger than MD5_DIGEST_SIZE' the 
function does not return - it calls abort()'.

I would like to see that documented for every *_digest() function !


> >>> Some admins have their jobs due to 'stop-by-assertion' software - at
> >>> least
> >>> that is good thing about assertions ;)
> >> 
> >> I suspect that 'continue-with-silent-data-corruption' software would
> >> give them even more work...
> > 
> > Definitely. That's why I try to avoid either of them.
> > 
> > An assertion doesn't give the higher layers a chance to intervene.
> 
> The higher layers are clearly broken in their designed use of the nettle
> API. This is not a dynamic limit being checked, but an explicit and
> fixed global value of MD5_DIGEST_SIZE.

See the excerpt from the docs above. What you say is not correct, you can 
provide a smaller digest buffer than MD5_DIGEST_SIZE. If you were right, the 
'length' param wouldn't make sense.
In my eyes it makes sense as saying: 'digest' is 'length' bytes large - please 
do not overwrite (= put at most 'length' bytes into 'digest'). The typical C 
buffer over flow prevention. But any such functions generally are fine with 
larger buffers - they put their payload into the buffer and leave the rest 
alone (except otherwise documented). Returning the actual number of bytes put 
into 'digest' would be of large help as well.


Just an impression for you what I am doing and why fixed digest sizes doesn't 
matter resp. are uninteresting here:

For my high-level hash function I use GnuTLS (wrapper around nettle|other), 
Nettle or Gcrypt (configurable). 

unsigned char digest[128]; // *should* be large enough, if not we get an error
char *algo = <user input>
if ((len=hash(algo,text,textlen,digest,digestsize)) < 0) {
  // error like 'unknown algo', 'digest size too small', ... 
} else {
  // got <len> bytes in digest, e.g. print as hex values
}

At this level MD5_DIGEST_SIZE etc. is unknown and not interesting.

(For nettle i found the nettle_hash structure variables and it's digest_size 
variable. Everything is working fine.)

Regards, Tim

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to