<div dir="ltr"><div dir="ltr"><div>Here's an example of different outputs with chunked input:</div><div><br></div><div>#include <stdbool.h><br>#include <stdint.h><br>#include <gcrypt.h><br><br>#define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }<br><br>int main(void)<br>{<br> uint8_t out[1024];<br> const uint8_t cleartext[16] = {0};<br> const uint8_t iv[16] = {0};<br> const uint8_t key[32] = {0};<br> size_t idx = 0;<br><br> gcry_cipher_hd_t h;<br> bool hOpen = false;<br> CF_CHECK_EQ(gcry_cipher_open(&h, GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_STREAM, 0), GPG_ERR_NO_ERROR);<br> hOpen = true;<br> CF_CHECK_EQ(gcry_cipher_setkey(h, key, sizeof(key)), GPG_ERR_NO_ERROR);<br> CF_CHECK_EQ(gcry_cipher_setiv(h, iv, sizeof(iv)), GPG_ERR_NO_ERROR);<br><br>#if defined(CHUNKED)<br> const int lengths[] = {1, 15};<br>#else<br> const int lengths[] = {16};<br>#endif<br><br> for (size_t i = 0; i < sizeof(lengths) / sizeof(lengths[0]); i++) {<br> CF_CHECK_EQ(gcry_cipher_encrypt(h, out, sizeof(out) - idx, cleartext + idx, lengths[i]), GPG_ERR_NO_ERROR);<br> idx += lengths[i];<br> }<br><br> for (size_t i = 0; i < idx; i++) {<br> printf("%02X ", out[i]);<br> }<br> printf("\n");<br><br>end:<br> if ( hOpen == true ) {<br> gcry_cipher_close(h);<br> }<br>}<br></div><div><br></div><div>Compile with and without -DCHUNKED. Am I doing something wrong?<br></div><div><br></div><div>'make check' did not report any errors but I'll look into it further.</div><div><br></div><div>Guido<br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, May 8, 2019 at 10:53 PM Jussi Kivilinna <<a href="mailto:jussi.kivilinna@iki.fi">jussi.kivilinna@iki.fi</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 8.5.2019 22.58, Guido Vranken wrote:<br>
> 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.<br>
<br>
Following modes should work with "chunked updating":<br>
GCRY_CIPHER_MODE_STREAM<br>
GCRY_CIPHER_MODE_OFB<br>
GCRY_CIPHER_MODE_CTR<br>
GCRY_CIPHER_MODE_CFB<br>
GCRY_CIPHER_MODE_CCM<br>
GCRY_CIPHER_MODE_GCM<br>
GCRY_CIPHER_MODE_EAX<br>
GCRY_CIPHER_MODE_POLY1305<br>
<br>
ECB and CBC require input length in multiples of cipher blocksize.<br>
<br>
For XTS input length can be from 16 to 16*2^20 bytes. <br>
<br>
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.<br>
<br>
> 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?<br>
<br>
Modes that do not accept chunked input return error.<br>
<br>
> <br>
> 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?<br>
<br>
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"?<br>
<br>
-Jussi<br>
<br>
> <br>
> Thanks<br>
> <br>
> Guido<br>
> <br>
> On Wed, May 8, 2019 at 9:48 PM Jussi Kivilinna <<a href="mailto:jussi.kivilinna@iki.fi" target="_blank">jussi.kivilinna@iki.fi</a> <mailto:<a href="mailto:jussi.kivilinna@iki.fi" target="_blank">jussi.kivilinna@iki.fi</a>>> wrote:<br>
> <br>
> Hello,<br>
> <br>
> On 8.5.2019 16.31, Guido Vranken wrote:<br>
> > Hi,<br>
> ><br>
> > I've been building a differential cryptography fuzzer that has been finding some nice bugs in major cryptographic libraries: <a href="https://github.com/guidovranken/cryptofuzz#hall-of-fame" rel="noreferrer" target="_blank">https://github.com/guidovranken/cryptofuzz#hall-of-fame</a><br>
> > It's very effective as it can find the Whirlpool bug (before 1.60.0) and the recent Stribog bug instantly.<br>
> ><br>
> > 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.<br>
> <br>
> 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.<br>
> <br>
> Bigger issue here is that there is quite big cap in testing coverage for digest finalization functions.. fuzzing against different libraries would definitely help.<br>
> <br>
> ><br>
> > 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.<br>
> ><br>
> <br>
> I'd be interested getting emails of such mismatches.<br>
> <br>
> What do others think? Werner? Niibe?<br>
> <br>
> <br>
> -Jussi<br>
> <br>
<br>
</blockquote></div>