[patch] libcrypt & friends - modular crypt format support in /etc/login.conf

Jilles Tjoelker jilles at stack.nl
Sat Feb 14 23:17:16 UTC 2015


On Tue, Feb 10, 2015 at 07:26:07AM -0500, Derek (freebsd lists) wrote:
> I've been working on this for a while, and I've produced a patch 
> that does a few things with the base system:

> 1. allows modular crypt to be specified as passwd_format in 
> /etc/login.conf
>    - this allows setting the algorithm *and rounds*, i.e. $2b$10$ 
> for users of varying classes.
>    - this will allow any future algorithms and parameters 
> supported by crypt(3) to be supported by the tools around login.conf

OK.

> 2. introduces a new api, crypt_makesalt which will generate an 
> appropriate salt for any algorithm selected

I like the idea.

> 3. updates userland to use this API, and removes totally the 
> {crypt_set_format, login_setcryptfmt, login_getcryptfmt} APIs

Removing API functions completely requires a SHLIB_MAJOR bump. I think
this can be avoided by replacing the functions with a stub instead, so
they would behave as if the default always applied and not allow changes
to it.

> 4. switches crypt algorithms to use thread-local storage, so the 
> good old global crypt buffer is thread-local

This uses quite a bit of memory for each thread created, even if it does
not call crypt() at all. Fortunately, libcrypt is not commonly used.

Given that crypt() has never been thread-safe, consider implementing
crypt_r() as in glibc and leaving crypt() thread-unsafe.

Thread-local storage via pthread_key_create() (one key for libcrypt) is
still "magic" but reduces the memory waste for threads that do not call
crypt().

> 5. includes a bunch of new test vectors for libcrypt ATF tests

OK.

Some remarks about the code:

lib/libcrypt/crypt.c crypt_makesalt()
> b64_from_24bit((uint8_t) rand_buf[2], (uint8_t) rand_buf[1], (uint8_t)
> rand_buf[0], diff, (int *) &(diff), &out);

All these casts can be avoided by making the affected variables the
proper type in the first place. The cast of &diff causes a
strict-aliasing violation and is definitely wrong on 64-bit big-endian
systems.

rand_buf is a salt, not a secret, so clearing it afterwards is
unnecessary.

Consider memcpy() and adding '\0' afterward instead of strncpy(). It
seems unnecessary to clear the buffer completely.

-- 
Jilles Tjoelker


More information about the freebsd-security mailing list