Re: kerneli blowfish/twofish compromised?

rohloff@informatik.tu-muenchen.de
Sun, 22 Nov 1998 20:42:15 +0000


On Sat, Nov 21, 1998 at 06:26:06PM +0100, Alexander Kjeldaas wrote:
> [cc'd to the author who can answer to these allegations better than
> me]
Thanks, otherwise I would have missed it, because I don't read
linux-kernel any longer. (Too much traffic...)

> > Module loop_fish2.c function blockEncrypt_CBC at line #437 zeros
> > the IV (reverting to far less secure ECB mode, hmmm):
> > if ( ( len & 0x1FF) == 0)
> > {
> > iv0=0;
> > iv1=0;
> > iv2=0;
> > iv3=0;
> > }
> >
No, this is definitely not "less secure" than ECB.

As you see (some lines below) IV is xored with the 128-Bit plaintext. This
means that the first 128 Bit are just encrypted in normal ECB Mode. If you
chose the first IV to be a random _constant_ different from zero,
it's no improvement, because the 128 bits are xored with the K-subkeys 0-3
anyway (the so called input-whitening). Any start constant is as good as the
others in CBC mode.

The reason why this is reapeated every 512 Bytes
(which is done by the "& 0x1FF") is that you can only chain one sector with
CBC mode, which is exactly 512 bytes, if you want to be on the safe side.
(I can explain this in detail, if someone is interested. The maximum
would be the block size of the device.)

> This makes sense. In CBC-mode, two messages are identical up to the
> first difference in the plaintext. Each block on the device is
> treated as a separate message. Finding repeating patterns is
> expected, and therefore the implementation isn't *necessarily* broken.
> Say you had 200k of zeros that would be 400 messages (512 bytes each)
> and 400 repeating patterns.
>
> One solution to avoid this is to initialize CBC-mode with the
> block-number as an initialization block. You *know* this - you were
> trying to fix exactly this weakness so I'm really confused about what
> you're trying to show.

Exactly. I also wrote a README file which accompanied the
two ciphers which explains this. From the README

"Both algorithms use CBC mode to encrypt a single sector (512
Bytes). So identical sectors produce identical crypted sectors,
which is not ideal. A solution would be to use the number of the
sector in the cryption algorithm, but this would require some
interface changes to loop.c and since I'm not the maintainer I
didn't want to do that."

The problem is that the sector number of the first sector,
isn't passed to the transfer functions. It's no problem to change that,
but this IS an interface change.

> > This accounts for the repeating patterns in ciphertext. Now my
> > confidence in the International Crypto Patch is shaken and I wonder
> > if blowfish also has problems. More checking... blowfish from the
> > patch appears to leak plaintext directly into ciphertext...
> >
> > Module loop_blow.c function blowfish_cbc_encrypt at line #361:
> > if (size & 0x000001FF)
> > {
> > memcpy(dst, src, size);
> > return;
> > }
> >
> > Module loop_blow.c function blowfish_cbc_decrypt at line #420 recovers
> > the leaked plaintext.
...

> I agree that this looks bad!
>
> However, I'm pretty sure the above code will never be executed since I
> don't think it is possible to get the kernel to read or write less
> than 512 bytes from a block device - the whole cbc-mode depends on
> this (I don't think the kernel will read/write less than a page - can
> someone confirm this?). The code is trying to cope with the kernel
> not requesting a multiple of 512 bytes. Failing instead of leaking
> plaintext would probably be a better idea, but I wouldn't call the
> code compromised if the kernel never reads less than 512 bytes.

Exactly.
If you have a look at "loop.c" you can find the following line
in do_lo_request(void):

len = current_request->current_nr_sectors << 9;

Data is always written and read in sectors, which means in 512 byte
chunks. I think that it is possible to request single sectors, if
you set the block size to 512 Bytes when the files system is
created.

You are correct again to state that the CBC mode depends on this. If
it would be possible to read single bytes, then encryption would be
impossible without an interface change.
Even more CBC mode depends on the fact that the data is always read
and written on 512 byte boundaries.

The code with the "memcpy(...)" comes from a time, when I wasn't
really sure about it (as I'm now). When I was testing the algorithms,
I was afraid to lose data completely so I figured it was better
to copy it than to discard it (which is wrong from a security point
of view).

What misses is a kernel warning if such an error happens. (If such
an error happens something has to be REALLY REALLY wrong, which
is why I forgot about it.)

so long
Ingo

PS: By The Way, who is the maintainer of the loop-device at the
moment ? (Is there anyone ?)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/