(Bug) Buffer overrun in gcry_cipher_gettag

Peter Wu peter at lekensteyn.nl
Tue Mar 22 23:27:26 CET 2016


On Tue, Mar 22, 2016 at 02:16:06PM +0100, Werner Koch wrote:
> On Tue, 22 Mar 2016 11:08, peter at lekensteyn.nl said:
> 
> > implementations of the gcry_cipher_gettag routine do not properly
> > validate their tag length.
> 
> Please explain.
> 
> >     _gcry_cipher_ocb_get_tag (gcry_cipher_hd_t c,
> >                               unsigned char *outtag, size_t outtagsize)
> >     {
> >       if (c->u_mode.ocb.taglen > outtagsize)
> >         return GPG_ERR_BUFFER_TOO_SHORT;
> >     ...
> >
> >       memcpy (outtag, c->u_mode.ocb.tag, c->u_mode.ocb.taglen);
> 
> The coment above that function states:
> 
> /* Copy the already computed tag to OUTTAG.  OUTTAGSIZE is the
>    allocated size of OUTTAG; the function returns an error if that is
>    too short to hold the tag.  */
> 
> This I can't see why there would be a buffer overrun:  OUTTAG has been
> allocated by the caller with a size of OUTTAGSIZE.  We check that the
> tag we want to copy to OUTBUF is less or equal than the buffer allocated
> for OUTTAG.  And then we do the memcpy.  Where do you see the problem or
> what did I miss?

Ah, my bad. OCB happens to be unaffected, I included it because the code
is smaller than the GCM case. I originally triggered it with AES-GCM.
Please find minimal reproducers in the attached crash.c file.

On the current stable (1.6.5) it crashes. On master, the GCM
implementation also crashes when setiv/gettag(/authenticate?) is called
before setkey is called.

Last time I forgot to ask, is there a way to query the valid size for
the tag length? (This can then be used to allocate a buffer for the tag
without having to know what cipher or mode is in use.)
-- 
Kind regards,
Peter Wu
https://lekensteyn.nl



More information about the Gcrypt-devel mailing list