libgcrypt integration into OSS-Fuzz differential cryptography fuzzer

Guido Vranken guidovranken at gmail.com
Thu May 9 02:35:19 CEST 2019


Here's an example of different outputs with chunked input:

#include <stdbool.h>
#include <stdint.h>
#include <gcrypt.h>

#define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }

int main(void)
{
    uint8_t out[1024];
    const uint8_t cleartext[16] = {0};
    const uint8_t iv[16] = {0};
    const uint8_t key[32] = {0};
    size_t idx = 0;

    gcry_cipher_hd_t h;
    bool hOpen = false;
    CF_CHECK_EQ(gcry_cipher_open(&h, GCRY_CIPHER_CHACHA20,
GCRY_CIPHER_MODE_STREAM, 0), GPG_ERR_NO_ERROR);
    hOpen = true;
    CF_CHECK_EQ(gcry_cipher_setkey(h, key, sizeof(key)), GPG_ERR_NO_ERROR);
    CF_CHECK_EQ(gcry_cipher_setiv(h, iv, sizeof(iv)), GPG_ERR_NO_ERROR);

#if defined(CHUNKED)
    const int lengths[] = {1, 15};
#else
    const int lengths[] = {16};
#endif

    for (size_t i = 0; i < sizeof(lengths) / sizeof(lengths[0]); i++) {
        CF_CHECK_EQ(gcry_cipher_encrypt(h, out, sizeof(out) - idx,
cleartext + idx, lengths[i]), GPG_ERR_NO_ERROR);
        idx += lengths[i];
    }

    for (size_t i = 0; i < idx; i++) {
        printf("%02X ", out[i]);
    }
    printf("\n");

end:
    if ( hOpen == true ) {
        gcry_cipher_close(h);
    }
}

Compile with and without -DCHUNKED. Am I doing something wrong?

'make check' did not report any errors but I'll look into it further.

Guido

On Wed, May 8, 2019 at 10:53 PM Jussi Kivilinna <jussi.kivilinna at iki.fi>
wrote:

> On 8.5.2019 22.58, Guido Vranken wrote:
> > While we're on the subject, can you comment on which ciphers/cipher
> modes allow for "chunked updating"? Eg. if you have a cleartext of 16
> bytes, when is it allowed to call gcry_cipher_encrypt with the first 10
> bytes, then another 3 bytes, then the final 3 bytes (for example)? I've
> been noticing a host of wrong outputs if I allow "chunked updating" with
> libgcrypt.
>
> Following modes should work with "chunked updating":
>     GCRY_CIPHER_MODE_STREAM
>     GCRY_CIPHER_MODE_OFB
>     GCRY_CIPHER_MODE_CTR
>     GCRY_CIPHER_MODE_CFB
>     GCRY_CIPHER_MODE_CCM
>     GCRY_CIPHER_MODE_GCM
>     GCRY_CIPHER_MODE_EAX
>     GCRY_CIPHER_MODE_POLY1305
>
> ECB and CBC require input length in multiples of cipher blocksize.
>
> For XTS input length can be from 16 to 16*2^20 bytes.
>
> OCB requires first N-1 input buffer lengths to be multiples of cipher
> blocksize. Before last input buffer 'gcry_cipher_final()' needs to be
> called and last Nth input buffer does not have restriction on input size.
>
> > The documentation states "Depending on the selected algorithms and
> encryption mode, the length of the buffers must be a multiple of the block
> size." but this doesn't make it clear when it is allowed exactly. And
> should the function not just fail if chunked input is attempted when full
> blocks are expected?
>
> Modes that do not accept chunked input return error.
>
> >
> > Also, I consistently get the error message "selftest for CFB failed -
> see syslog for details" both from git master and 1.8.4. Is this expected?
>
> That is not expected. Which compiler and what kind of configuration are
> you using? Do you get these errors when running libgcrypt build tests,
> "make check"?
>
> -Jussi
>
> >
> > Thanks
> >
> > Guido
> >
> > On Wed, May 8, 2019 at 9:48 PM Jussi Kivilinna <jussi.kivilinna at iki.fi
> <mailto:jussi.kivilinna at iki.fi>> wrote:
> >
> >     Hello,
> >
> >     On 8.5.2019 16.31, Guido Vranken wrote:
> >     > Hi,
> >     >
> >     > I've been building a differential cryptography fuzzer that has
> been finding some nice bugs in major cryptographic libraries:
> https://github.com/guidovranken/cryptofuzz#hall-of-fame
> >     > It's very effective as it can find the Whirlpool bug (before
> 1.60.0) and the recent Stribog bug instantly.
> >     >
> >     > It finds errors in message digests like RipeMD160 in the current
> master branch that are not present in 1.8.4. I still have to research the
> cause.. I can post demonstration code later.
> >
> >     Thanks! It looks like culprit commit is
> 46d7dbbc293fdc1e04656798b3e6f58873fee110 which breaks md4, md5 and rmd160.
> Quickly looking at code, this happens when input size is '64*nblks +
> 56..63'. Bug is at md4.c/md5.c/rmd160.c new code path "/* need one extra
> block */" and when writing bit count to buffer. Buffer offsets there should
> be "hd->bctx.buf + 56 + 64" and "hd->bctx.buf + 60 + 64". Other message
> digests modified in that commit appear to get this right.
> >
> >     Bigger issue here is that there is quite big cap in testing coverage
> for digest finalization functions.. fuzzing against different libraries
> would definitely help.
> >
> >     >
> >     > It's running 24/7 on Google's OSS-Fuzz. Are the libgcrypt
> maintainers interested in participating in the OSS-Fuzz project? This
> entails that results for message digests, HMACs, CMACs and symmetric
> ciphers are compared to other libraries, and if there is a mismatch,
> everyone gets an e-mail. At that point we have to find out which library is
> emitting the wrong result, and the bug has to be fixed.
> >     >
> >
> >     I'd be interested getting emails of such mismatches.
> >
> >     What do others think? Werner? Niibe?
> >
> >
> >     -Jussi
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gnupg.org/pipermail/gcrypt-devel/attachments/20190509/abf19d3a/attachment-0001.html>


More information about the Gcrypt-devel mailing list