Discussion:
Problem with CipherStream and BufferedAeadBlockCipher DoFinal
Ivo Rothschild
2012-12-11 08:26:55 UTC
Permalink
Hi Everyone,

First off, let me say I'm new to using BouncyCastle. I'm using the C#
version 1.7 and Mono 3.5.

I think I've found a problem using BufferedAeadBlockCipher with
CipherStream for decrypting. I am using a GcmBlockCipher. When I encrypt
something of 16 bytes (or a multiple of), the decryption never does the
final mac check (the GCMBlockCipher DoFinal() never gets called.) Other
lengths of input work properly.

In CipherStream, when the end of the read stream is reached, it calls
inCipher.DoFinal(block, 0, numRead). If the data is aligned to the block
size, numRead will be 0.

The problem seems to be in the BufferedAeadBlockCipher DoFinal method(s)
where it checks length > 0. If inLen == 0, length = 0.

public override byte[] DoFinal(
byte[] input,
int inOff,
int inLen)
{
...
int length = GetOutputSize(inLen);
...
if (length > 0)
// Do the call that triggers the mac check

I have worked around this by checking for 0 in my own code after the
decryption:

if (inCipher.GetOutputSize(0) >= 0)
{
inCipher.DoFinal(new byte[0],0);
}

I think that the BufferedAeadBlockCipher should be handling it properly
likes it does for non-block-aligned data lengths.

It's possible I'm not using one of the classes properly. Attached is a
complete test.

Regards,
Ivo
Peter Dettman
2012-12-12 03:17:54 UTC
Permalink
Hi Ivo,
Thanks for reporting this (and for including a simple test case). This
is now fixed in CVS.
There have been a few other bug fixes and performance improvements to
GCM (and other AEAD modes) since the last release so I would encourage
you to try building the latest from source if you haven't already.

Pete.
Post by Ivo Rothschild
Hi Everyone,
First off, let me say I'm new to using BouncyCastle. I'm using the C#
version 1.7 and Mono 3.5.
I think I've found a problem using BufferedAeadBlockCipher with
CipherStream for decrypting. I am using a GcmBlockCipher. When I
encrypt something of 16 bytes (or a multiple of), the decryption never
does the final mac check (the GCMBlockCipher DoFinal() never gets
called.) Other lengths of input work properly.
In CipherStream, when the end of the read stream is reached, it calls
inCipher.DoFinal(block, 0, numRead). If the data is aligned to the
block size, numRead will be 0.
Loading...