diff mbox series

[3/4] Remove documentation of passphrase-hashing functions.

Message ID 7f80cd68-69fc-4ce1-87c2-91fe38662915@app.fastmail.com
State New
Headers show
Series Remove libcrypt | expand

Commit Message

Zack Weinberg Sept. 21, 2023, 8:51 p.m. UTC
crypt.texi itself continues to exist, since it also documents
getentropy and getrandom.  I lightly edited the lead paragraphs
of the "Unpredictable Bytes" section while I was in there.

---
 manual/contrib.texi        |   2 +-
 manual/crypt.texi          | 234 ++++---------------------------------
 manual/examples/genpass.c  |  59 ----------
 manual/examples/testpass.c |  67 -----------
 manual/users.texi          |   4 +-
 5 files changed, 25 insertions(+), 341 deletions(-)
 delete mode 100644 manual/examples/genpass.c
 delete mode 100644 manual/examples/testpass.c
diff mbox series

Patch

diff --git a/manual/contrib.texi b/manual/contrib.texi
index 20d9f74780..52ebd6944a 100644
--- a/manual/contrib.texi
+++ b/manual/contrib.texi
@@ -199,7 +199,7 @@  Romain Geissler for various fixes.
 
 @item
 Michael Glad for the passphrase-hashing function @code{crypt} and related
-functions.
+functions (no longer part of glibc, but we still appreciate his work).
 
 @item
 Wolfram Gloger for contributing the memory allocation functions
diff --git a/manual/crypt.texi b/manual/crypt.texi
index af23dd7847..4882ee34e5 100644
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -1,205 +1,18 @@ 
 @node Cryptographic Functions, Debugging Support, System Configuration, Top
 @chapter Cryptographic Functions
-@c %MENU% Passphrase storage and strongly unpredictable bytes.
+@c %MENU% A few functions to support cryptographic applications
 
-@Theglibc{} includes only a few special-purpose cryptographic
-functions: one-way hash functions for passphrase storage, and access
-to a cryptographic randomness source, if one is provided by the
-operating system.  Programs that need general-purpose cryptography
-should use a dedicated cryptography library, such as
+@Theglibc{} includes only one type of special-purpose cryptographic
+functions; these allow use of a source of cryptographically strong
+pseudorandom numbers, if such a source is provided by the operating
+system.  Programs that need general-purpose cryptography should use
+a dedicated cryptography library, such as
 @uref{https://www.gnu.org/software/libgcrypt/,,libgcrypt}.
 
-Many countries place legal restrictions on the import, export,
-possession, or use of cryptographic software.  We deplore these
-restrictions, but we must still warn you that @theglibc{} may be
-subject to them, even if you do not use the functions in this chapter
-yourself.  The restrictions vary from place to place and are changed
-often, so we cannot give any more specific advice than this warning.
-
 @menu
-* Passphrase Storage::          One-way hashing for passphrases.
 * Unpredictable Bytes::         Randomness for cryptographic purposes.
 @end menu
 
-@node Passphrase Storage
-@section Passphrase Storage
-@cindex passphrase hashing
-@cindex one-way hashing
-@cindex hashing, passphrase
-
-Sometimes it is necessary to be sure that a user is authorized
-to use some service a machine provides---for instance, to log in as a
-particular user id (@pxref{Users and Groups}).  One traditional way of
-doing this is for each user to choose a secret @dfn{passphrase}; then, the
-system can ask someone claiming to be a user what the user's passphrase
-is, and if the person gives the correct passphrase then the system can
-grant the appropriate privileges.  (Traditionally, these were called
-``passwords,'' but nowadays a single word is too easy to guess.)
-
-Programs that handle passphrases must take special care not to reveal
-them to anyone, no matter what.  It is not enough to keep them in a
-file that is only accessible with special privileges.  The file might
-be ``leaked'' via a bug or misconfiguration, and system administrators
-shouldn't learn everyone's passphrase even if they have to edit that
-file for some reason.  To avoid this, passphrases should also be
-converted into @dfn{one-way hashes}, using a @dfn{one-way function},
-before they are stored.
-
-A one-way function is easy to compute, but there is no known way to
-compute its inverse.  This means the system can easily check
-passphrases, by hashing them and comparing the result with the stored
-hash.  But an attacker who discovers someone's passphrase hash can
-only discover the passphrase it corresponds to by guessing and
-checking.  The one-way functions are designed to make this process
-impractically slow, for all but the most obvious guesses.  (Do not use
-a word from the dictionary as your passphrase.)
-
-@Theglibc{} provides an interface to four one-way functions, based on
-the SHA-2-512, SHA-2-256, MD5, and DES cryptographic primitives.  New
-passphrases should be hashed with either of the SHA-based functions.
-The others are too weak for newly set passphrases, but we continue to
-support them for verifying old passphrases.  The DES-based hash is
-especially weak, because it ignores all but the first eight characters
-of its input.
-
-@deftypefun {char *} crypt (const char *@var{phrase}, const char *@var{salt})
-@standards{X/Open, unistd.h}
-@standards{GNU, crypt.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
-@c Besides the obvious problem of returning a pointer into static
-@c storage, the DES initializer takes an internal lock with the usual
-@c set of problems for AS- and AC-Safety.
-@c The NSS implementations may leak file descriptors if cancelled.
-@c The MD5, SHA256 and SHA512 implementations will malloc on long keys,
-@c and NSS relies on dlopening, which brings about another can of worms.
-
-The function @code{crypt} converts a passphrase string, @var{phrase},
-into a one-way hash suitable for storage in the user database.  The
-string that it returns will consist entirely of printable ASCII
-characters.  It will not contain whitespace, nor any of the characters
-@samp{:}, @samp{;}, @samp{*}, @samp{!}, or @samp{\}.
-
-The @var{salt} parameter controls which one-way function is used, and
-it also ensures that the output of the one-way function is different
-for every user, even if they have the same passphrase.  This makes it
-harder to guess passphrases from a large user database.  Without salt,
-the attacker could make a guess, run @code{crypt} on it once, and
-compare the result with all the hashes.  Salt forces the attacker to
-make separate calls to @code{crypt} for each user.
-
-To verify a passphrase, pass the previously hashed passphrase as the
-@var{salt}.  To hash a new passphrase for storage, set @var{salt} to a
-string consisting of a prefix plus a sequence of randomly chosen
-characters, according to this table:
-
-@multitable @columnfractions .2 .1 .3
-@headitem One-way function @tab Prefix @tab Random sequence
-@item SHA-2-512
-@tab @samp{$6$}
-@tab 16 characters
-@item SHA-2-256
-@tab @samp{$5$}
-@tab 16 characters
-@item MD5
-@tab @samp{$1$}
-@tab 8 characters
-@item DES
-@tab @samp{}
-@tab 2 characters
-@end multitable
-
-In all cases, the random characters should be chosen from the alphabet
-@code{./0-9A-Za-z}.
-
-With all of the hash functions @emph{except} DES, @var{phrase} can be
-arbitrarily long, and all eight bits of each byte are significant.
-With DES, only the first eight characters of @var{phrase} affect the
-output, and the eighth bit of each byte is also ignored.
-
-@code{crypt} can fail.  Some implementations return @code{NULL} on
-failure, and others return an @emph{invalid} hashed passphrase, which
-will begin with a @samp{*} and will not be the same as @var{salt}.  In
-either case, @code{errno} will be set to indicate the problem.  Some
-of the possible error codes are:
-
-@table @code
-@item EINVAL
-@var{salt} is invalid; neither a previously hashed passphrase, nor a
-well-formed new salt for any of the supported hash functions.
-
-@item EPERM
-The system configuration forbids use of the hash function selected by
-@var{salt}.
-
-@item ENOMEM
-Failed to allocate internal scratch storage.
-
-@item ENOSYS
-@itemx EOPNOTSUPP
-Hashing passphrases is not supported at all, or the hash function
-selected by @var{salt} is not supported.  @Theglibc{} does not use
-these error codes, but they may be encountered on other operating
-systems.
-@end table
-
-@code{crypt} uses static storage for both internal scratchwork and the
-string it returns.  It is not safe to call @code{crypt} from multiple
-threads simultaneously, and the string it returns will be overwritten
-by any subsequent call to @code{crypt}.
-
-@code{crypt} is specified in the X/Open Portability Guide and is
-present on nearly all historical Unix systems.  However, the XPG does
-not specify any one-way functions.
-
-@code{crypt} is declared in @file{unistd.h}.  @Theglibc{} also
-declares this function in @file{crypt.h}.
-@end deftypefun
-
-@deftypefun {char *} crypt_r (const char *@var{phrase}, const char *@var{salt}, struct crypt_data *@var{data})
-@standards{GNU, crypt.h}
-@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
-@tindex struct crypt_data
-@c Compared with crypt, this function fixes the @mtasurace:crypt
-@c problem, but nothing else.
-
-The function @code{crypt_r} is a thread-safe version of @code{crypt}.
-Instead of static storage, it uses the memory pointed to by its
-@var{data} argument for both scratchwork and the string it returns.
-It can safely be used from multiple threads, as long as different
-@var{data} objects are used in each thread.  The string it returns
-will still be overwritten by another call with the same @var{data}.
-
-@var{data} must point to a @code{struct crypt_data} object allocated
-by the caller.  All of the fields of @code{struct crypt_data} are
-private, but before one of these objects is used for the first time,
-it must be initialized to all zeroes, using @code{memset} or similar.
-After that, it can be reused for many calls to @code{crypt_r} without
-erasing it again.  @code{struct crypt_data} is very large, so it is
-best to allocate it with @code{malloc} rather than as a local
-variable.  @xref{Memory Allocation}.
-
-@code{crypt_r} is a GNU extension.  It is declared in @file{crypt.h},
-as is @code{struct crypt_data}.
-@end deftypefun
-
-The following program shows how to use @code{crypt} the first time a
-passphrase is entered.  It uses @code{getentropy} to make the salt as
-unpredictable as possible; @pxref{Unpredictable Bytes}.
-
-@smallexample
-@include genpass.c.texi
-@end smallexample
-
-The next program demonstrates how to verify a passphrase.  It checks a
-hash hardcoded into the program, because looking up real users' hashed
-passphrases may require special privileges (@pxref{User Database}).
-It also shows that different one-way functions produce different
-hashes for the same passphrase.
-
-@smallexample
-@include testpass.c.texi
-@end smallexample
-
 @node Unpredictable Bytes
 @section Generating Unpredictable Bytes
 @cindex randomness source
@@ -211,27 +24,24 @@  hashes for the same passphrase.
 @cindex CSPRNG
 @cindex DRBG
 
-Cryptographic applications often need some random data that will be as
-difficult as possible for a hostile eavesdropper to guess.  For
-instance, encryption keys should be chosen at random, and the ``salt''
-strings used by @code{crypt} (@pxref{Passphrase Storage}) should also
-be chosen at random.
-
-Some pseudo-random number generators do not provide unpredictable-enough
-output for cryptographic applications; @pxref{Pseudo-Random Numbers}.
-Such applications need to use a @dfn{cryptographic random number
-generator} (CRNG), also sometimes called a @dfn{cryptographically strong
-pseudo-random number generator} (CSPRNG) or @dfn{deterministic random
-bit generator} (DRBG).
+Cryptographic applications often need random data that will be as
+difficult as possible for a hostile eavesdropper to guess.
+The pseudo-random number generators provided by @theglibc{}
+(@pxref{Pseudo-Random Numbers}) are not suitable for this purpose.
+They produce output that is @emph{statistically} random, but fails to
+be @emph{unpredictable}.  Cryptographic applications require a
+@dfn{cryptographic random number generator} (CRNG), also known as a
+@dfn{cryptographically strong pseudo-random number generator} (CSPRNG)
+or a @dfn{deterministic random bit generator} (DRBG).
 
 Currently, @theglibc{} does not provide a cryptographic random number
-generator, but it does provide functions that read random data from a
-@dfn{randomness source} supplied by the operating system.  The
-randomness source is a CRNG at heart, but it also continually
-``re-seeds'' itself from physical sources of randomness, such as
-electronic noise and clock jitter.  This means applications do not need
-to do anything to ensure that the random numbers it produces are
-different on each run.
+generator, but it does provide functions that read cryptographically
+strong random data from a @dfn{randomness source} supplied by the
+operating system.  This randomness source is a CRNG at heart, but it
+also continually ``re-seeds'' itself from physical sources of
+randomness, such as electronic noise and clock jitter.  This means
+applications do not need to do anything to ensure that the random
+numbers it produces are different on each run.
 
 The catch, however, is that these functions will only produce
 relatively short random strings in any one call.  Often this is not a
diff --git a/manual/examples/genpass.c b/manual/examples/genpass.c
deleted file mode 100644
index e40efc782b..0000000000
--- a/manual/examples/genpass.c
+++ /dev/null
@@ -1,59 +0,0 @@ 
-/* Encrypting Passwords
-   Copyright (C) 1991-2023 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <https://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <crypt.h>
-
-int
-main(void)
-{
-  unsigned char ubytes[16];
-  char salt[20];
-  const char *const saltchars =
-    "./0123456789ABCDEFGHIJKLMNOPQRST"
-    "UVWXYZabcdefghijklmnopqrstuvwxyz";
-  char *hash;
-  int i;
-
-  /* Retrieve 16 unpredictable bytes from the operating system.  */
-  if (getentropy (ubytes, sizeof ubytes))
-    {
-      perror ("getentropy");
-      return 1;
-    }
-
-  /* Use them to fill in the salt string.  */
-  salt[0] = '$';
-  salt[1] = '5'; /* SHA-256 */
-  salt[2] = '$';
-  for (i = 0; i < 16; i++)
-    salt[3+i] = saltchars[ubytes[i] & 0x3f];
-  salt[3+i] = '\0';
-
-  /* Read in the user's passphrase and hash it.  */
-  hash = crypt (getpass ("Enter new passphrase: "), salt);
-  if (!hash || hash[0] == '*')
-    {
-      perror ("crypt");
-      return 1;
-    }
-
-  /* Print the results.  */
-  puts (hash);
-  return 0;
-}
diff --git a/manual/examples/testpass.c b/manual/examples/testpass.c
deleted file mode 100644
index 555fe115c4..0000000000
--- a/manual/examples/testpass.c
+++ /dev/null
@@ -1,67 +0,0 @@ 
-/* Verify a passphrase.
-   Copyright (C) 1991-2023 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <https://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <crypt.h>
-
-/* @samp{GNU's Not Unix} hashed using SHA-256, MD5, and DES.  */
-static const char hash_sha[] =
-  "$5$DQ2z5NHf1jNJnChB$kV3ZTR0aUaosujPhLzR84Llo3BsspNSe4/tsp7VoEn6";
-static const char hash_md5[] = "$1$A3TxDv41$rtXVTUXl2LkeSV0UU5xxs1";
-static const char hash_des[] = "FgkTuF98w5DaI";
-
-int
-main(void)
-{
-  char *phrase;
-  int status = 0;
-
-  /* Prompt for a passphrase.  */
-  phrase = getpass ("Enter passphrase: ");
-
-  /* Compare against the stored hashes.  Any input that begins with
-     @samp{GNU's No} will match the DES hash, but the other two will
-     only match @samp{GNU's Not Unix}.  */
-
-  if (strcmp (crypt (phrase, hash_sha), hash_sha))
-    {
-      puts ("SHA: not ok");
-      status = 1;
-    }
-  else
-    puts ("SHA: ok");
-
-  if (strcmp (crypt (phrase, hash_md5), hash_md5))
-    {
-      puts ("MD5: not ok");
-      status = 1;
-    }
-  else
-    puts ("MD5: ok");
-
-  if (strcmp (crypt (phrase, hash_des), hash_des))
-    {
-      puts ("DES: not ok");
-      status = 1;
-    }
-  else
-    puts ("DES: ok");
-
-  return status;
-}
diff --git a/manual/users.texi b/manual/users.texi
index 72da3fb714..4c83f12c42 100644
--- a/manual/users.texi
+++ b/manual/users.texi
@@ -1731,8 +1731,8 @@  most systems, but on some systems a special network server gives access
 to it.
 
 Historically, this database included one-way hashes of user
-passphrases (@pxref{Passphrase Storage}) as well as public information
-about each user (such as their user ID and full name).  Many of the
+passphrases, as well as public information about each user
+(such as their user ID and full name).  Many of the names of
 functions and data structures associated with this database, and the
 filename @file{/etc/passwd} itself, reflect this history.  However,
 the information in this database is available to all users, and it is