[Bug 192431] New: Crypt(3) (-lcrypt) does not work as documented
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Wed Aug 6 12:36:02 UTC 2014
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=192431
Bug ID: 192431
Summary: Crypt(3) (-lcrypt) does not work as documented
Product: Base System
Version: 9.3-RELEASE
Hardware: Any
OS: Any
Status: Needs Triage
Severity: Affects Many People
Priority: ---
Component: bin
Assignee: freebsd-bugs at FreeBSD.org
Reporter: papowell at astart.com
This has been reported as 189958 broken /usr/bin/crypt but this has a much more
serisous impact than is incidated that bug report and the accompanying
comments.
For that reason, I am submitting a new bug report.
On FreeBSD 9.3 Release, the crypt(3) function does not behave as
documented and also not as on FreeBSD 8.4. The documented and
expected default is tu generate the legacy DES encryption but this
has been changed. The crypt() function is used directly by Perl
and PHP and affects these as well.
The crypt(3) C library routine is used by Perl/PHP. This change
has broken a large number of other things. While there is no
argument about the 'strength' of the hash/encryption, the documentation
states that it will behave in a specific manner, and as far as I
can tell with a quick scan of the FreeBSD archives, there has been
no discussion of the impact of making this change.
I am surprised that one of the core functions behavior (crypt) was
modified and this was not put into the FreeBSD 9.3 release notes.
I would strongly suggest that you publicize this and send out
instructions on how to a) make the 'des' encryption the default b)
recompile everything that uses crypt and is statically linked c)
warn Perl and PHP users about this impact so they can update their
Perl and PHP. (Note, I might be wrong about PHP, but I checked
Perl and it uses the -lcrypt library).
Details:
NAME
crypt -- Trapdoor encryption
LIBRARY
Crypt Library (libcrypt, -lcrypt)
SYNOPSIS
#include <unistd.h> char * crypt(const char *key, const char
*salt); const char * crypt_get_format(void); int
crypt_set_format(const char *string);
DESCRIPTION
The crypt() function performs password hashing with additional
code added to deter key search attempts. Different algorithms
can be used to in the hash. Currently these include the NBS
Data Encryption Standard (DES), MD5 hash, NT-Hash (compatible
with Microsoft's NT scheme) and Blowfish. The algorithm used
will depend upon the format of the Salt (following the Modular
Crypt Format (MCF)), if DES and/or Blowfish is installed or
not, and whether crypt_set_format() has been called to change
the default.
The first argument to crypt is the data to hash (usually a
password), in a NUL-terminated string. The second is the salt,
in one of three forms: Extended If it begins with an underscore
(``_'')
then the DES
Extended Format is used in interpreting
both the key and the salt, as outlined
below.
Modular If it begins with the string ``$digit$''
then the Mod-
ular Crypt Format is used, as outlined
below.
Traditional If neither of the above is true, it assumes
the Tradi-
tional Format, using the entire string as
the salt (or the first portion).
...
Traditional crypt:
The algorithm used will depend upon whether crypt_set_format()
has been called and whether a global default format has been
specified. Unless a global default has been specified or
crypt_set_format() has set the for- mat to something else, the
built-in default format is used. This is cur- rently DES if
it is available, or MD5 if not.
The crypt_get_format() function returns a constant string that
represents the name of the algorithm currently used. Valid
values are `des', `blf', `md5', `sha256', `sha512' and `nth'.
The crypt_set_format() function sets the default encoding
format accord- ing to the supplied string.
Test Program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( int argc, char **argv, char **envp )
{
const char *password = "testpassword";
const char *salt = "_testpassword";
const char *format = crypt_get_format();
const char *output = crypt(password,password);
fprintf( stdout, "Password '%s', format '%s', output '%s'\n", password,
format, output );
output = crypt(password,salt);
fprintf( stdout, "Password '%s', salt '%s', output '%s'\n", password, salt,
output );
int status = crypt_set_format("des");
format = crypt_get_format();
output = crypt(password,password);
fprintf( stdout, "status %d, Password '%s', format '%s', output '%s'\n",
status, password, format, output );
output = crypt(password,salt);
fprintf( stdout, "Password '%s', salt '%s', output '%s'\n", password, salt,
output );
exit( 0 );
}FreeBSD 9.3:
Pssword 'testpassword', format 'sha512', output
'$6$testpassword$QvM4M3dhSAaiMa6EthlRMq3g8efvl1GySUxAyuXAIN.
DmgGZuDLqKqi.wZ/PzWadf7YYxAKVlXmjq9ajS1R7y0'
Password 'testpassword', salt '_testpassword', output '_testpass6q8PHhqkDCA'
status 1, Password 'testpassword', format 'des', output 'tek4edTZE898g'
Password 'testpassword', salt '_testpassword', output '_testpass6q8PHhqkDCA'
assword 'testpassword', salt '_testpassword', output '_testpass6q8PHhqkDCA'
FreeBSD 8.4:
Password 'testpassword', format 'des', output 'tek4edTZE898g'
Password 'testpassword', salt '_testpassword', output '_testpass6q8PHhqkDCA'
status 1, Password 'testpassword', format 'des', output 'tek4edTZE898g'
Password 'testpassword', salt '_testpassword', output '_testpass6q8PHhqkDCA'
>From the FreeBSD 8.4 source:
/usr/src/lib/libcrypt/crypt.c:
static const struct {
const char *const name;
char *(*const func)(const char *, const char *);
const char *const magic;
} crypt_types[] = {
#ifdef HAS_DES
{
"des",
crypt_des,
NULL {
"md5",
crypt_md5,
"$1$"
},
>From the FreeBSD 9.3 source. Note that the default format
is set to sha512, not des:
/*
* List of supported crypt(3) formats. The first element in the list
will
* be the default.
*/
static const struct crypt_format {
const char *const name;
char *(*const func)(const char *, const char *);
const char *const magic;
} crypt_formats[] = {
/* default format */
{ "sha512", crypt_sha512, "$6$" },
/* other supported formats */
{ "md5", crypt_md5, "$1$" },
#ifdef HAS_BLOWFISH
{ "blf", crypt_blowfish, "$2" },
#endif
{ "nth", crypt_nthash, "$3$" },
{ "sha256", crypt_sha256, "$5$" },
#ifdef HAS_DES
{ "des", crypt_des, "_" },
#endif
},
#endif
/* sentinel */
{ NULL, NULL, NULL }
};
Suggestion:
static const struct crypt_format {
const char *const name;
char *(*const func)(const char *, const char *);
const char *const magic;
} crypt_formats[] = {
/* default format */
#ifdef HAS_DES
{ "des", crypt_des, "_" },
#endif
{ "sha512", crypt_sha512, "$6$" },
/* other supported formats */
{ "md5", crypt_md5, "$1$" },
#ifdef HAS_BLOWFISH
{ "blf", crypt_blowfish, "$2" },
#endif
{ "nth", crypt_nthash, "$3$" },
{ "sha256", crypt_sha256, "$5$" },
/* sentinel */
{ NULL, NULL, NULL }
};
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list