-function performs password hashing with additional code added to
-deter key search attempts.
-Different algorithms can be used to
-in the hash.
-.\"
-.\" NOTICE:
-.\" If you add more algorithms, make sure to update this list
-.\" and the default used for the Traditional format, below.
-.\"
-Currently these include the
-.Tn NBS
-.Tn Data Encryption Standard (DES) ,
-.Tn MD5
-hash,
-.Tn NT-Hash
-.Pq compatible with Microsoft's NT scheme
-and
-.Tn Blowfish .
-The algorithm used will depend upon the format of the Salt
-.Po
-following
-the Modular Crypt Format
-.Pq MCF
-.Pc ,
-if
-.Tn DES
-and/or
-.Tn Blowfish
-is installed or not, and whether
+The
+.Nm libcrypt
+library covers functions related to password hashing.
+.Pp
+Password hashing is different than a standard one way hash function. Password hashing tries to make it difficult to recover a low-entropy key
+.Pq e.g. a typed password
+from the resultant output hash. Offline recovery by exhaustive key search
+.Pq brute-force and dictionary attacks
+is stymied by the password hashing being one-way, and often computationally expensive. Different algorithms can be selected to produce the password hash, with varying ability to effectively deter key search attempts.
+.Pp
+The hashing algorithm to be used for an invocation of crypt is chosen by supplying a salt parameter of a particular format. The algorithms currently supported are:
+.Sx bcrypt ,
+.Sx sha512-crypt ,
+.Sx sha256-crypt ,
+.Sx md5-crypt ,
+.Sx DES Extended Format ,
+.Sx Traditional DES Format ,
+and
+.Sx NT-Hash .
+.Pp
+Current computational capabilities make all but the bcrypt and sha-crypt families known to be susceptible to exhaustive key searches. The tuneable work factor of the bcrypt and sha-crypt families has allowed them to be set to be more computationally intensive over time. The use of the other families is not recommended at this time, but are maintained for legacy compatibility.
+.Pp
+The first argument to
+.Fn crypt
+is the
+.Fa key
+to hash
+.Pq usually a password ,
+as a NUL-terminated string. The second is the
+.Fa salt .
+A salt is a random value that assists in complicating offline recovery. The length and format of the salt, and how it will be used is algorithm dependent. For best results, specify at least sixteen characters of salt.
+.Pp
+If the salt begins with the string
+.Qq $digit ,
+then the
+.Sx Modular Crypt Format
+is used. If it begins with an underscore
+.Qq _ ,
+then the
+.Sx DES Extended Format
+is used. If the salt is 2 or 13 characters and includes only 0-9, a-z, A-Z a dot . or a slash /, then
+.Sx Traditional DES Format
+is used. If none of these conditions are true, crypt will use the default hash function set by crypt_set_format,
+.Pq or Traditional DES Format if no default has been set, for systems with DES support .
+.Pp
+The
+.Fn crypt_makesalt
+function populates an
+.Fa output
+buffer with a newly generated salt for the specified valid
+.Fa format .
+The size of the pre-allocated buffer is passed via
+.Fa out_len .
+If the output buffer is too small, the required size is set in
+.Fa out_len .
+.Pp
+The
+.Fn crypt_get_format
+function returns a constant string that represents the name of the algorithm set as the default. Its use is deprecated.
+.Pp
+The
.Fn crypt_set_format
-has been called to change the default.
-.Pp
-The first argument to
-.Nm
-is the data to hash
-.Pq usually a password ,
-in a
-.Dv NUL Ns -terminated
-string.
-The second is the salt, in one of three forms:
-.Pp
-.Bl -tag -width Traditional -compact -offset indent
-.It Extended
-If it begins with an underscore
-.Pq Dq _
-then the
-.Tn DES
-Extended Format
-is used in interpreting both the key and the salt, as outlined below.
-.It Modular
-If it begins with the string
-.Dq $digit$
-then the Modular Crypt Format is used, as outlined below.
-.It Traditional
-If neither of the above is true, it assumes the Traditional Format,
-using the entire string as the salt
-.Pq or the first portion .
+function sets the default encoding
+.Fa format
+according to the supplied string. Its use is deprecated.
+.Pp
+The salts, formats, and algorithms are outlined below.
+
+.Sh Modular Crypt Format
+.Pp
+Modular Crypt Format is the current standard way to describe which algorithm and parameters to use for a particular crypt invocation. Salts that are prefixed with $digit are using the modular crypt format. The prefix selects the algorithm to use. Valid prefixes are:
-For each additional group, the XOR of the encryption of the current
-.Tn DES
-key with itself and the group bits becomes the next
-.Tn DES
-key.
-.Pp
-The salt is a 9-character array consisting of an underscore followed
-by 4 bytes of iteration count and 4 bytes of salt.
-These are encoded as printable characters, 6 bits per character,
-least significant character first.
-The values 0 to 63 are encoded as
-.Dq ./0-9A-Za-z .
-This allows 24 bits for both
-.Fa count
-and
-.Fa salt .
+Everything following the prefix in the salt parameter is algorithm dependant, but includes things like work factor, and an actual salt
+.Pq random value for that particular invocation .
+
+.Ss md5-crypt
+.Bl -column ".Sy Output Hash Example:" ".Sy 8 characters from the set [a-zA-Z0-9./]"
+.It Li Format Strings: Ta $1$, md5
+.It Li Salt Format: Ta 8 characters from the set [a-zA-Z0-9./]
+.It Li Full Salt Example: Ta $1$deadbeef$
+.It Li Output Hash Example: Ta $1$deadbeef$0Huu6KHrKLVWfqa4WljDE0
+.El
.Pp
-The
-.Fa salt
-introduces disorder in the
-.Tn DES
-algorithm in one of 16777216 or 4096 possible ways
-.Po
-i.e., with 24 or 12 bits: if bit
-.Em i
-of the
-.Ar salt
-is set, then bits
-.Em i
-and
-.Em i+24
-are swapped in the
-.Tn DES
-E-box output
-.Pc .
+md5-crypt was the default crypt format in FreeBSD for many years, developed by Poul-Henning Kamp.
.Pp
-The
-.Tn DES
-key is used to encrypt a 64-bit constant using
-.Ar count
-iterations of
-.Tn DES .
-The value returned is a
-.Dv NUL Ns -terminated
-string, 20 or 13 bytes
-.Pq plus NUL
-in length, consisting of the
-.Ar salt
-followed by the encoded 64-bit encryption.
-.Ss Modular crypt:
-If the salt begins with the string
-.Fa $digit$
-then the Modular Crypt Format is used.
-The
-.Fa digit
-represents which algorithm is used in encryption.
-Following the token is
-the actual salt to use in the encryption.
-The maximum length of the salt used depends upon the module.
-The salt must be terminated with the end of the string character
-.Pq NUL
-or a dollar sign.
-Any characters after the dollar sign are ignored.
-.Pp
-Currently supported algorithms are:
-.Pp
-.Bl -enum -compact -offset indent
-.It
-MD5
-.It
-Blowfish
-.It
-NT-Hash
-.It
-(unused)
-.It
-SHA-256
-.It
-SHA-512
+It has seen widespread use in many commercial products, and for a long time was good enough. It has a fixed work factor, which means that as computers became faster, the ability to attack it has increased proportionally.
+.It Li Format Strings: Ta $2$[rounds]$, $2a$[rounds]$, $2b$[rounds]$, blf
+.It Li Salt Format: Ta 16 bytes then base-64 encoded from the set [a-zA-Z0-9./]
+.It Li Full Salt Example: Ta $2a$05$CCCCCCCCCCCCCCCCCCCCC.
+.It Li Output Hash Example: Ta $2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK
.El
.Pp
-Other crypt formats may be easily added.
-An example salt would be:
-.Bl -tag -width 6n -offset indent
-.It Cm "$4$thesalt$rest"
+bcrypt is the first algorithm to support a tuneable work factor. It was initially introduced in OpenBSD, by Niels Provos, based on the Usenix paper "A Future-Adaptable Password Scheme" by Niels Provos and David Mazi\(`eres.
+.Pp
+There are three variations supported, each with minor bug fixes. 2b is the recommended variation.
+.Pp
+The work factor is specified by the rounds parameter in the format string. These rounds are logarithmic. That is,
+.Qq $2b$08$
+will take approximately twice as long as
+.Qq $2b$07$
+for the same salt and key. 04 is the lowest supported work factor, and 31 is the highest.
+.It Li Format Strings: Ta $5$, $5$rounds=[rounds]$, sha256
+.It Li Salt Format: Ta 16 characters from the set [a-zA-Z0-9./]
+.It Li Full Salt Examples: Ta $5$saltstring$, $5$rounds=10000$saltstringsaltst$
+.It Li Output Hash Examples: Ta $5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5, $5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2.opqey6IcA
.El
-.Ss Traditional crypt:
-The algorithm used will depend upon whether
-.Fn crypt_set_format
-has been called and whether a global default format has been specified.
-Unless a global default has been specified or
-.Fn crypt_set_format
-has set the format to something else, the built-in default format is
-used.
-This is currently
-.\"
-.\" NOTICE: Also make sure to update this
-.\"
-DES
-if it is available, or MD5 if not.
.Pp
-How the salt is used will depend upon the algorithm for the hash.
-For
-best results, specify at least eight characters of salt.
+sha256 supports a tunable work factor. It was developed by Ulrich Drepper of Red Hat, and is detailed in
+.Qq Unix crypt using SHA-256 and SHA-512 .
.Pp
-The
-.Fn crypt_get_format
-function returns a constant string that represents the name of the
-algorithm currently used.
-Valid values are
-.\"
-.\" NOTICE: Also make sure to update this, too, as well
-.\"
-.Ql des ,
-.Ql blf ,
-.Ql md5 ,
-.Ql sha256 ,
-.Ql sha512
-and
-.Ql nth .
+From that document:
.Pp
-The
+.Qo
+Security departments in companies are trying to phase out all uses of MD5. They demand a method which is officially sanctioned. For US-based users this means tested by the NIST.
+.Pp
+This rules out the use of another already implemented method with limited spread: the use of the Blowfish encryption method. The choice comes down to tested encryption
+.Pq 3DES, AES
+or hash sums
+.Pq the SHA family .
+.Qc
+.Pp
+The prepositions in the above statement are misleading. Blowfish as a primitive, like 3DES or AES, has stood up to years of scrutinty by the cryptographic communinty. bcrypt, the password hashing function, is ubiquitous. It also currently provides greater resilience against pipe-lined or GPU-based attacks for the approximate same CPU workload as the sha-crypt family, based on its limited memory requirements. This is not expected to remain true with future improvements to GPUs. An additional subtle difference between bcrypt and the sha families is that bcrypt's salt is 2^128 bits, while the sha family is 2^96 bits.
+.Pp
+If you require a algorithm that includes NIST sanctioned primitives, choose one of the sha-crypt methods.
+.Pp
+The work factor is specified by the rounds parameter in the format string. These rounds are linear. That is,
+.Qq $5$rounds=20000$
+will take approximately twice as long as
+.Qq $5$rounds=10000$
+for the same salt and key. 1000 is the minimum number of rounds, 999999999 is the maximum.
+.It Li Format Strings: Ta $6$, $6$rounds=[rounds]$, sha512
+.It Li Salt Format: Ta 16 characters from the set [a-zA-Z0-9./]
+.It Li Full Salt Examples: Ta $6$saltstring$, $6$rounds=10000$saltstringsaltst$
+.It Li Output Hash Examples: Ta $6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJuesI68u4OTLiBFdcbYEdFCoEOfaS35inz1, $6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sbHbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v.
+.El
+sha512 is nearly equivalent to sha256, except that it uses SHA512 as a primitive. See Unix crypt using SHA-256 and SHA-512 for more details.
+
+The details provided in sha256 apply here as well.
+
+When the format string
+.Qq sha512 ,
+or
+.Qq $6$
+is specified, it is equivalent to specifying
+.Qq $6$rounds=5000$ .
+
+.Sh DES Extended Format:
+.Pp
+The key is divided into groups of 8 characters
+.Pq the last group is NUL-padded
+and the low-order 7 bits of each character
+.Pq 56 bits per group
+are used to form the DES key as follows: the first group of 56 bits becomes the initial DES key. For each additional group, the XOR of the encryption of the current DES key with itself and the group bits becomes the next DES key.
+.Pp
+The salt is a 9-character array consisting of an underscore followed by 4 bytes of iteration count and 4 bytes of salt. These are encoded as printable characters, 6 bits per character, least significant character first. The values 0 to 63 are encoded as
+.Qq ./0-9A-Za-z .
+This allows 24 bits for both count and salt.
+.Pp
+The salt introduces disorder in the DES algorithm in one of 16777216 or 4096 possible ways
+.Pq i.e., with 24 or 12 bits: if bit i of the salt is set, then bits i and i+24 are swapped in the DES E-box output .
+.Pp
+The DES key is used to encrypt a 64-bit constant using count iterations of DES. The value returned is a NUL-terminated string, 20 or 13 bytes
+.Pq plus NUL
+in length, consisting of the salt followed by the encoded 64-bit encryption.
+
+.Sh Traditional DES Format:
+.Pp
+The algorithm used will depend upon whether
.Fn crypt_set_format
function sets the default encoding format according to the supplied
.Fa string .
@@ -257,7 +281,8 @@
.Fa data ,
making it thread-safe.
.Sh RETURN VALUES
-The
+.Pp
+The
.Fn crypt
and
.Fn crypt_r
@@ -268,23 +293,131 @@
will always return a pointer to a string.
.Pp
The
+.Fn crypt_makesalt
+function will return a 0 on success, or non-zero on failure. It may fail in one of two
+ways. If
+.Fa out_len
+has changed, the
+.Fa output
+buffer was not large enough to store the salt. The required size will be stored
+in
+.Fa out_len .
+If
+.Fa out_len
+has not changed, then the
+.Fa format
+passed was invalid.
+.Pp
+The
.Fn crypt_set_format
-function will return 1 if the supplied encoding format was valid.
-Otherwise, a value of 0 is returned.
+function will return 1 if the supplied encoding format was valid. Otherwise, a value of 0 is returned.
+
+
+.Sh EXAMPLES
+.Bd -literal
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+
+#include <pwd.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+
+int
+main()
+{
+ char *global_static_buffer;
+ char final[_PASSWORD_LEN + 1];
+ char test[_PASSWORD_LEN + 1];
+ char salt[256];
+ size_t salt_sz = sizeof(salt);
+
+ int exit_code = 0;
+
+ /* threaded implementations should use a mutex around crypt */
+ pthread_mutex_t mtx;
+ if (pthread_mutex_init(&mtx, NULL) ) {
+ exit_code = 1;
+ goto exit1;
+ }
+
+ if (crypt_makesalt(salt, "$2b$08$", &salt_sz) ) {
+ if ( salt_sz != sizeof(salt) ) {
+ printf("Destination buffer too small for algorithm salt\\n");
+ exit_code = 2;
+ goto exit;
+ }
+
+ printf("Invalid format specified\\n");
+ exit_code = 3;
+ goto exit;
+ }
+ printf("crypt_makesalt result: %s\\n", salt);
+
+ /*
+ * Generate a crypt for storage
+ */
+
+ /* crypt buffer is global static */
+ pthread_mutex_lock(&mtx);
+ global_static_buffer = crypt("you'll never guess me!", salt);