Whirlpool in gcrypt <= 1.5.3 broken (if writes in chunks)?
Hi,
since this commit (present in 1.6.0)
"md: Fix Whirlpool flaw."
http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff;h=0a28b2d2c9181a536fc894e24626714832619923
seems that Whirlpool hash produces different output if data are written in parts.
(If entered as one buffer, it seems to be compatible though.)
Unfortunately, cryptsetup in its anti-forensic filter uses something like this:
gcry_md_write(iv, iv_size)
gcry_md_write(buf, buf_size)
gcry_md_read ...
Change above seems to breaks all LUKS devices which used Whirlpool as hash before and upgraded to gcrypt 1.6.0 (cryptsetup cannot open them anymore).
See for example https://bbs.archlinux.org/viewtopic.php?id=175737
Is my assumption that all whirlpool implementations before libgcrypt 1.6.0 are broken if used this way?
(Using different crypto backend seems to support this assumption...)
Thanks,
Milan
Quoted 2 lines · On Fri, 17 Jan 2014 19:25, [email protected] said:
Is my assumption that all whirlpool implementations before libgcrypt 1.6.0 are broken if used this way?
Right. Now why are you using a non-standard algorithm and then also hit the 62 byte problem :-(
Anyway, I see that we need to do something about it. Changing the correct implementation is not a good idea but I would be possible to add a bug emulation flag. We do something similar in GnuPG to workaround a pgp-2 incompatibility.
I can see two ways to implement it: If you only hash small amounts of data, retrying with the hash operation with the bug emulation flag set would be the easiest way. The other option would be to implement a variant of Whirlpool with this bug not fixed. Then you could add this as a second hash algorithm to the same context and hash only one. That is practical for streamed data but it does not save time because it always hashes twice (could be optimized but we would end up with quite some complexity).
I would really prefer to add a bug emulation flag so that you could go and re-encrypt the data on the fly (using the fixed Whirlpool or SHA-x for better performance).
Shalom-Salam,
Werner
Signature · 1 line
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Quoted 7 lines · Werner Koch
Quoted 2 lines · On Fri, 17 Jan 2014 19:25, [email protected] said:
Is my assumption that all whirlpool implementations before libgcrypt 1.6.0 are broken if used this way?
Right. Now why are you using a non-standard algorithm and then also hit the 62 byte problem :-(
Whirlpool was never default but people like to fiddle with things :) No idea how many devices use this but with more systems using libgcrypt 1.6.0, more problems will appear...
Quoted 5 lines
Anyway, I see that we need to do something about it. Changing the correct implementation is not a good idea but I would be possible to add a bug emulation flag. We do something similar in GnuPG to workaround a pgp-2 incompatibility.
Quoted 8 lines
I can see two ways to implement it: If you only hash small amounts of data, retrying with the hash operation with the bug emulation flag set would be the easiest way. The other option would be to implement a variant of Whirlpool with this bug not fixed. Then you could add this as a second hash algorithm to the same context and hash only one. That is practical for streamed data but it does not save time because it always hashes twice (could be optimized but we would end up with quite some complexity).
The problem is in AF filter
http://code.google.com/p/cryptsetup/source/browse/lib/luks1/af.c
which uses hash to diffuse key to several encrypted sectors, hash is called a lot of times there.
But I really do not care about speed here - the goal is create to some easy way how to fix existing LUKS headers to work with new gcrypt.
Quoted 3 lines
I would really prefer to add a bug emulation flag so that you could go and re-encrypt the data on the fly (using the fixed Whirlpool or SHA-x for better performance).
Yes, I prefer this as well. I had already code to reencrypt device, here we need only to reencrypt header and keyslots.
I just need to have access to both whirlpool variants.
So if there is a "bug emulation flag" it could help to implement it.
Thanks,
Milan
Quoted 1 line · On Fri, 17 Jan 2014 21:58, [email protected] said:
So if there is a "bug emulation flag" it could help to implement it.
Done in master. The code is not very sophisticated: I added the flag and then re-added most of the old code. If this works out for you I will backport it to 1.6 and release a 1.6.1 soon.
The suggested way of using the flag is:
if (whirlpool_bug_assumed)
{
#if GCRYPT_VERSION_NUMBER >= 0x010601
err = gcry_md_open (&hd, GCRY_MD_WHIRLPOOL, GCRY_MD_FLAG_BUGEMU1)
if (gpg_err_code (err) == GPG_ERR_INV_ARG)
error ("Need at least Libggcrypt 1.6.1 for the fix");
else
{
do_hash (hd);
gcry_md_close (hd);
}
#endif
}Salam-Shalom,
Werner
Signature · 1 line
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Quoted 7 lines · Werner Koch
Quoted 1 line · On Fri, 17 Jan 2014 21:58, [email protected] said:
So if there is a "bug emulation flag" it could help to implement it.
Done in master. The code is not very sophisticated: I added the flag and then re-added most of the old code. If this works out for you I will backport it to 1.6 and release a 1.6.1 soon.
It works, thanks! Please could you also add pbkdf2 speed fix to 1.6.1?
Because cryptsetup supports several backends (where this flawed whirlpool was never present), I won't do any automatic repairs but instead I added internal "whirlpool_gcryptbug" hash name to gcrypt cryptsetup backend (which uses this flag with gcrypt > 1.6.0)
This will allow people to use it if really needed.
Thanks,
Milan
Quoted 1 line · On Sun, 19 Jan 2014 20:49, [email protected] said:
It works, thanks! Please could you also add pbkdf2 speed fix to 1.6.1?
Sure.
Shalom-Salam,
Werner
Signature · 1 line
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.