libgcrypt integration into OSS-Fuzz differential cryptography fuzzer
Guido Vranken
guidovranken at gmail.com
Thu May 9 03:08:07 CEST 2019
Never mind, I've noticed my bug, please ignore :).
On Thu, May 9, 2019 at 2:35 AM Guido Vranken <guidovranken at gmail.com> wrote:
> 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/5acc473d/attachment.html>
More information about the Gcrypt-devel
mailing list