This project has moved and is read-only. For the latest updates, please go here.

BUG: long Unicode passwords are broken!

Topics: Technical Issues
Apr 28, 2016 at 10:40 PM
Edited Apr 28, 2016 at 10:47 PM
When trying to make a new volume with a long Unicode password (45+ characters), Veracrypt treats the password as invalid, or not matching.

Try this please:
1) Press the button to create a new encrypted file container.
2) On the "Volume Password" screen, try pasting this password in:
ô7hÝá“3#3bža%Ñ‘¼¬<Þ%$T,‰Žžnv´!ÇZ^ÒƒÈþgH1ûßîjX
3) Notice that the "Next" button is grayed out on the bottom. This password doesn't work!
4) Now paste this password instead. It should work fine:
Dsw[#hZ.r8ikIbV1Yh]sk2iX&1{LF0k.<T]CyD.nXIb3f
This only happens when there are Unicode characters in a long password (45+ characters). Shorter passwords, even with Unicode characters, usually work fine.
The error is not consistent however. I think there is a bug in the "password verification" code.
Apr 29, 2016 at 12:01 AM
This is not a bug but a simple case of a password whose bytes encoding exceeds the 64-bytes limit imposed on the input of the key derivation function.

VeraCrypt added support for Unicode password as a way to strengthen password easily but at the end the password must be converted to bytes and the maximum size of input in bytes is 64.

By using for example the following web site, you can check the effective length of the password after conversion to bytes: https://mothereff.in/utf-8
  • First password is 45 Unicode characters: encoded using 70 bytes which exceeds the 64 bytes limit => "Next" button grayed.
  • Second password is 45 ASCII characters => encoded using 45 bytes which is below the 64 bytes limit => "Next" button activated.
In the future, it is planned to increase the 64-bytes maximum limit but there are some compatibility and performance issues that must be taken into account before making such change.
Apr 29, 2016 at 12:33 AM
Thanks for the quick response!

But why not just run the password input through SHA-512, then pass the 64-byte digest into the key derivation function? :)
Apr 29, 2016 at 7:36 PM
Actually hashing is already implemented in derive_key_XXX functions in Pkcs5.c (below an extract of derive_key_sha512)
One idea that has been proposed already is to activate the hash at the top of the logic using the same hash as the PRF and do it only for passwords exceeding the 64 bytes limit in order to retain compatibility with existing containers. The implementation has never made it to the official sources and more time is needed to study it.
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
{
    hmac_sha512_ctx hmac;
    sha512_ctx* ctx;
    char* buf = hmac.k; /* there is enough space to hold SHA512_BLOCKSIZE (128) bytes
                               * because k is followed by u in hmac_sha512_ctx
                                */
    int b, l, r;
    char key[SHA512_DIGESTSIZE];

   /* If the password is longer than the hash algorithm block size,
       let pwd = sha512(pwd), as per HMAC specifications. */
    if (pwd_len > SHA512_BLOCKSIZE)
    {
        sha512_ctx tctx;

        sha512_begin (&tctx);
        sha512_hash ((unsigned char *) pwd, pwd_len, &tctx);
        sha512_end ((unsigned char *) key, &tctx);

        pwd = key;
        pwd_len = SHA512_DIGESTSIZE;

        burn (&tctx, sizeof(tctx));        // Prevent leaks
    }