jedisct1 / libsodium

A modern, portable, easy to use crypto library.

Home Page:https://libsodium.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

crypto_generichash_blake2b_salt_personal takes 16 byte input but docs say the input must be 8 bytes

0x4f53 opened this issue · comments

Our team was working on a key derivation function based on libsodium's crypto_generichash_blake2b_salt_personal(). We noticed the docs mentioning that the ctx is supposed to be 8 characters, and thus 8 bytes (1 char = 1 byte in C). However, the actual function in the library takes a 16 byte input.

What's also weird is that if we supply an 8 byte ctx while it's expecting 16 bytes, we don't get an error of any kind telling us that the context is of incorrect size. This can have major consequences for those following the docs.


We decided to use crypto_generichash_blake2b_salt_personal() since the default crypto_kdf_derive_from_key() function only supports a 32 byte master_key and we wanted to derive keys from a 64 byte master_key input.

We stumbled upon this after 5 days of scratching our heads over why we were getting a different hash each time for the exact same parameters. We are using LazySodium-Android, which is a Java wrapper for libsodium. We tried several things, including empty ByteArrays, passing unsigned integers, and more. We observed that the hash was different each time, but sometimes, it would be correct and then change again randomly.

When we changed the context from an 8 character string to a 16 character string, the issue was completely gone. Had we caught an exception telling us that the context is of incorrect length, we could've avoided a lot of trouble.

The link you are mentioning is for the crypto_kdf_derive_from_key() function. And the documentation seems correct. The context size is crypto_kdf_CONTEXTBYTES, which is 8.

crypto_generichash_blake2b_salt_personal() is a low-level function, with different parameter limits.

Like all functions, the parameters come with constants representing the limits and expected sizes. Here, for the personal parameter, this is crypto_generichash_blake2b_PERSONALBYTES.

That being said, if that Java wrapper accepts inputs of incorrect sizes, this is an issue you should report to that project.

That shouldn't be possible in a language like Java.