+.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
+.Pp
+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
+From that document:
+.Pp
+.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
+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
+The algorithm used will depend upon whether
.Fn crypt_set_format
function sets the default encoding format according to the supplied
.Fa string .
@@ -263,32 +316,107 @@
.Fn crypt_r
functions return a pointer to the encrypted value on success, and NULL on
failure.
-Note: this is not a standard behaviour, AT&T
+Note: this is not a standard behavior, AT&T
.Fn crypt
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.
+.Sh EXAMPLES
+.Bd -literal
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(void)
+{
+ struct crypt_data buf1, buf2;
+ char *hash, *check;
+ char salt[256];
+ size_t salt_sz = sizeof(salt);
+
+ /* Generate a salt for a crypt format specification. */
+ if (crypt_makesalt(salt, "$2b$08$", &salt_sz)) {
+ if (salt_sz != sizeof(salt)) {
+ printf("Buffer too small for format salt.\\n");
+ return (1);
+ }
+
+ printf("Invalid format specified.\\n");
+ return (2);
+ }
+
+ printf("crypt_makesalt result: %s\\n", salt);
+
+ /*
+ * Generate a crypt for storage, using salt as the algorithm selection
+ * and parameters.
+ */
+ hash = crypt_r("Initial example password.", salt, &buf1);
+ if (hash == NULL) {
+ printf("crypt_r (hash) failed.\\n");
+ return (3);
+ }
+
+ printf("crypt_r (hash) result: %s\\n", hash);
+
+ /* Generate a crypt of a known value using the salt of a stored hash. */
+ check = crypt_r("Password provided at a later time.", hash, &buf2);
+ if (check == NULL) {
+ printf("crypt_r (check) failed.\\n");
+ return (4);
+ }
+
+ printf("crypt_r (check) result: %s\\n", check);
+
+ /*
+ * Do not leak anything about the original hash when comparing. Timing-
+ * safe comparison is prudent.
+ */
+ if (timingsafe_bcmp(hash, check, strlen(hash)) != 0) {
+ printf("The two passwords do not match.\\n");
+ return (5);
+ }
+
+ printf("The two passwords match.\\n");
+
+ return (0);
+}
+.Ed
.Sh SEE ALSO
.Xr login 1 ,
.Xr passwd 1 ,
.Xr getpass 3 ,
+.Xr login_getcapstr 3 ,
.Xr passwd 5
.Sh HISTORY
A rotor-based
.Fn crypt
-function appeared in
-.At v6 .
+function appeared in Version 6 AT&T UNIX.
The current style
.Fn crypt
-first appeared in
-.At v7 .
+first appeared in Version 7 AT&T UNIX.
.Pp
-The
-.Tn DES
-section of the code (FreeSec 1.0) was developed outside the United
+The DES section of the code (FreeSec 1.0) was developed outside the United
States of America as an unencumbered replacement for the U.S.-only
.Nx
libcrypt encryption library.
@@ -298,30 +426,42 @@
function was added in
.Fx 12.0 .
.Sh AUTHORS
-.An -nosplit
Originally written by
-.An David Burren Aq Mt davidb@werj.com.au ,
-later additions and changes by
+.An -nosplit
+.An David Burren Aq Mt davidb@werj.com.au
+, later additions and changes by
.An Poul-Henning Kamp ,
.An Mark R V Murray ,
.An Michael Bretterklieber ,
.An Kris Kennaway ,
.An Brian Feldman ,
-.An Paul Herman
-and
-.An Niels Provos .
+.An Paul Herman ,
+.An Niels Provos , and
+.An Derek Marcotte .
.Sh BUGS
The
.Fn crypt
-function returns a pointer to static data, and subsequent calls to
+function returns a pointer to static data, and subsequent
+calls to
.Fn crypt
will modify the same data.
Likewise,
.Fn crypt_set_format
modifies static data.
+.Sh SECURITY CONSIDERATIONS
+The following algorithms are considered insecure, and are not recommended
+for new implementations:
+.Sx md5-crypt ,
+.Sx DES Extended Format ,
+.Sx Traditional DES Format ,
+and
+.Sx NT-Hash .
.Pp
-The NT-hash scheme does not use a salt,
-and is not hard
-for a competent attacker
-to break.
-Its use is not recommended.
+.Sx bcrypt
+is preferred over
+.Sx sha512-crypt ,
+or
+.Sx sha256-crypt ,
+because of
+its resiliance to pipelined, and GPU based attacks - unless having a