# Salt length in SHA-512 version of Unix crypt command

SHA-512 crypt specs reports that SHA-512 crypt uses 128bit salt.

The FreeBSD/Linux password generation code builds the salt using 16 bytes random data (128bits) and then it translates the random data using something like the B64 encoding (which is a base64 variation).

because of the cardinality of the subset, each character represents 6 bits of information. Having a salt of size 16 characters generated by this method gives 16x6 = 96 bits of pseudo random data.

In conclusion it looks like the salt of this implementation uses only 96 bits.

I don't agree with this because here the B64 is just used to have printable characters. The random values are used to pick up a valid character. Base64 encoded string grows in length, here we have the same length. The random string is then used as it is by the SHA-512 implementation (where it pass a 128 bit value).

Can somebody confirm the advisor statement and explain more?

Analysis of the C code is off-topic. It outputs a string of SALTSIZE=32 characters each obtained by indexing a string of 64 base-characters encoded in ASCII as a single byte. The indexes are obtained according to the low-order $$4\times6$$ bits of what seems to a pseudo-random 32-bit value produced by arc4random().

Thus the output is a 32-byte bytestring (not counting the string terminator character/byte) with each byte drawn from a set of 64, thus $$32\times8=256\,$$bits, with $$32\,\log_2(64)=192\,$$bits of entropy (at most, assuming full-entropy source).

I conclude neither "16x6 = 96 bits of pseudo random data" nor "128 bit value" apply to what the linked code produces. But wait, the linked specification tells

For the SHA-based methods the SALT string can be a simple string of which up to 16 characters are used.

which suggests that something (at least, the code that does cryptography with the salt) should truncate that 32-character salt to 16. In which case there remains a 16-byte bytestring with each byte drawn from a set of 64, thus $$16\times8=128\,$$bits, with $$16\,\log_2(64)=96\,$$bits of entropy (at most, assuming full-entropy source).

That matches what the advisor states, although the end could be restated more clearly with "gives 16x6 = 96 bits worth of pseudo random data".

The statement "Base64 encoded string grows in length" applies to Base64 encoding, not to what the code does.

My (debatable) position: after truncation to 16 characters, the salt is 128-bit with $$2^{96}$$ possible values, thus to be considered (at best) as effective as a 96-bit uniformly random salt with full entropy from the standpoint of preventing pre-computations. Which is way enough.