public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 3/4] Revise crypt.texi.
  2018-05-21 17:39 [PATCH 0/4 v3] libcrypt phaseout Zack Weinberg
  2018-05-21 17:39 ` [PATCH 4/4] New configure option --disable-crypt Zack Weinberg
@ 2018-05-21 17:39 ` Zack Weinberg
  2018-05-25  2:52   ` Rical Jasan
  2018-06-25 12:26   ` Florian Weimer
  2018-05-21 17:39 ` [PATCH 1/4] Disallow use of DES encryption functions in new programs Zack Weinberg
  2018-05-21 17:39 ` [PATCH 2/4] Reorganize crypt.texi Zack Weinberg
  3 siblings, 2 replies; 24+ messages in thread
From: Zack Weinberg @ 2018-05-21 17:39 UTC (permalink / raw)
  To: libc-alpha; +Cc: carlos, fweimer, rj, kukuk

This is a major rewrite of the description of 'crypt', 'getentropy',
and 'getrandom'.

A few highlights of the content changes:

 - Throughout the manual, public headers, and user-visible messages,
   I replaced the term "password" with "passphrase", the term
   "password database" with "user database", and the term
   "encrypt(ion)" with "(one-way) hashing" whenever it was applied to
   passphrases.  I didn't bother making this change in internal code
   or tests.  The use of the term "password" in ruserpass.c survives,
   because that refers to a keyword in netrc files, but it is adjusted
   to make this clearer.

   There is a note in crypt.texi explaining that they were
   traditionally called passwords but single words are not good enough
   anymore, and a note in users.texi explaining that actual passphrase
   hashes are found in a "shadow" database nowadays.

 - There is a new short introduction to the "Cryptographic Functions"
   section, explaining how we do not intend to be a general-purpose
   cryptography library, and cautioning that there _are_, or have
   been, legal restrictions on the use of cryptography in many
   countries, without getting into any kind of detail that we can't
   promise to keep up to date.

 - I added more detail about what a "one-way function" is, and why
   they are used to obscure passphrases for storage.  I removed the
   paragraph saying that systems not connected to a network need no
   user authentication, because that's a pretty rare situation
   nowadays.  (It still says "sometimes it is necessary" to
   authenticate the user, though.)

 - I added documentation for all of the hash functions that glibc
   actually supports, but not for the additional hash functions
   supported by libxcrypt.  If we're going to keep this manual section
   around after the transition is more advanced, it would probably
   make sense to add them then.

 - There is much more detailed discussion of how to generate a salt,
   and the failure behavior for crypt is documented.  (Returning an
   invalid hash on failure is what libxcrypt does; Solar Designer's
   notes say that this was done "for compatibility with old programs
   that assume crypt can never fail".)

 - As far as I can tell, the header 'crypt.h' is entirely a GNU
   invention, and never existed on any other Unix lineage.  The
   function 'crypt', however, was in Issue 1 of the SVID and is now
   in the XSI component of POSIX.  I tried to make all of the
   @standards annotations consistent with this, but I'm not sure I got
   them perfectly right.

 - The genpass.c example has been improved to use getentropy instead
   of the current time to generate the salt, and to use a SHA-256 hash
   instead of MD5. It uses more random bytes than is strictly
   necessary because I didn't want to complicate the code with proper
   base64 encoding.

 - The testpass.c example has three hardwired hashes now, to
   demonstrate that different one-way functions produce different
   hashes for the same input.  It also demonstrates how DES hashing
   only pays attention to the first eight characters of the input.

 - There is new text explaining in more detail how a CSPRNG differs
   from a regular random number generator, and how
   getentropy/getrandom are not exactly a CSPRNG.  I tried not to make
   specific falsifiable claims here.  I also tried to make the
   blocking/cancellation/error behavior of both getentropy and
   getrandom clearer.

        * crypt/crypt.h, posix/unistd.h: Update comments and
        prototypes for crypt and crypt_r.

	* manual/crypt.texi (Cryptographic Functions): New initial
	exposition.
	(crypt): Section renamed to 'Passphrase Storage'.  Full rewrite.
      	(Unpredictable Bytes): Improve initial exposition.  Clarify error
	behavior of getentropy and getrandom.
	* manual/examples/genpass.c: Generate a salt using getentropy
	instead of the current time. Use hash $5$ (SHA-2-256).
	* manual/examples/testpass.c: Demonstrate validation against
	hashes generated with three different one-way functions.

        * manual/intro.texi: crypt.texi does not need an overview
	anymore.

        * manual/nss.texi, manual/memory.texi, manual/socket.texi
        * manual/terminal.texi: Consistently refer to "passphrases"
        * instead of "passwords", and to the "user database" instead
        * of the "password database".
        * manual/users.texi: Similarly.  Add notes about how actual
        passphrase hashes are now stored in the shadow database.
        Remove 20-year-old junk todo note.
---
 crypt/crypt.h               |  21 +-
 inet/ruserpass.c            |   2 +-
 manual/contrib.texi         |   2 +-
 manual/crypt.texi           | 391 +++++++++++++++++++++++-------------
 manual/examples/genpass.c   |  44 ++--
 manual/examples/mygetpass.c |   4 +-
 manual/examples/testpass.c  |  52 +++--
 manual/intro.texi           |   1 -
 manual/memory.texi          |   2 +-
 manual/nss.texi             |  12 +-
 manual/socket.texi          |   4 +-
 manual/terminal.texi        |  14 +-
 manual/users.texi           |  22 +-
 nscd/pwdcache.c             |   4 +-
 posix/unistd.h              |  10 +-
 pwd/pwd.h                   |  29 +--
 shadow/shadow.h             |  16 +-
 17 files changed, 401 insertions(+), 229 deletions(-)

diff --git a/crypt/crypt.h b/crypt/crypt.h
index 3cb18de14d..ebe8607452 100644
--- a/crypt/crypt.h
+++ b/crypt/crypt.h
@@ -28,13 +28,18 @@
 
 __BEGIN_DECLS
 
-/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
-extern char *crypt (const char *__key, const char *__salt)
+/* One-way hash PHRASE, returning a string suitable for storage in the
+   user database.  SALT selects the one-way function to use, and
+   ensures that no two users' hashes are the same, even if they use
+   the same passphrase.  The return value points to static storage
+   which will be overwritten by the next call to crypt.  */
+extern char *crypt (const char *__phrase, const char *__salt)
      __THROW __nonnull ((1, 2));
 
 #ifdef __USE_GNU
-/* Reentrant version of 'crypt'.  The additional argument
-   points to a structure where the results are placed in.  */
+
+/* This structure provides scratch and output buffers for 'crypt_r'.
+   Its contents should not be accessed directly.  */
 struct crypt_data
   {
     char keysched[16 * 8];
@@ -49,7 +54,13 @@ struct crypt_data
     int  direction, initialized;
   };
 
-extern char *crypt_r (const char *__key, const char *__salt,
+/* Thread-safe version of 'crypt'.
+   DATA must point to a 'struct crypt_data' allocated by the caller.
+   Before the first call to 'crypt_r' with a new 'struct crypt_data',
+   that object must be initialized to all zeroes.  The pointer
+   returned, if not NULL, will point within DATA.  (It will still be
+   overwritten by the next call to 'crypt_r' with the same DATA.)  */
+extern char *crypt_r (const char *__phrase, const char *__salt,
 		      struct crypt_data * __restrict __data)
      __THROW __nonnull ((1, 2, 3));
 #endif
diff --git a/inet/ruserpass.c b/inet/ruserpass.c
index 5b2747bc50..4fa6520c1a 100644
--- a/inet/ruserpass.c
+++ b/inet/ruserpass.c
@@ -177,7 +177,7 @@ next:
 			    fstat64(fileno(cfile), &stb) >= 0 &&
 			    (stb.st_mode & 077) != 0) {
 	warnx(_("Error: .netrc file is readable by others."));
-	warnx(_("Remove password or make file unreadable by others."));
+	warnx(_("Remove 'password' line or make file unreadable by others."));
 				goto bad;
 			}
 			if (token() && *apass == 0) {
diff --git a/manual/contrib.texi b/manual/contrib.texi
index dd28e9293b..6191f46f31 100644
--- a/manual/contrib.texi
+++ b/manual/contrib.texi
@@ -129,7 +129,7 @@ Martin Galvan for contributing gdb pretty printer support to glibc and adding
 an initial set of pretty printers for structures in the POSIX Threads library.
 
 @item
-Michael Glad for the DES encryption function @code{crypt} and related
+Michael Glad for the passphrase-hashing function @code{crypt} and related
 functions.
 
 @item
diff --git a/manual/crypt.texi b/manual/crypt.texi
index 0f04ee9899..500649b4fc 100644
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -1,121 +1,200 @@
 @node Cryptographic Functions, Debugging Support, System Configuration, Top
 @chapter Cryptographic Functions
-@c %MENU% Password storage and strongly unpredictable bytes
+@c %MENU% Passphrase storage and strongly unpredictable bytes.
+
+@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
+@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
-* crypt::                       A one-way function for passwords.
-* Unpredictable Bytes::         Randomness for cryptography purposes.
+* Passphrase Storage::          One-way hashing for passphrases.
+* Unpredictable Bytes::         Randomness for cryptographic purposes.
 @end menu
 
-@node crypt
-@section Encrypting Passwords
+@node Passphrase Storage
+@section Passphrase Storage
+@cindex passphrase hashing
+@cindex one-way hashing
+@cindex hashing, passphrase
 
-On many systems, it is unnecessary to have any kind of user
-authentication; for instance, a workstation which is not connected to a
-network probably does not need any user authentication, because to use
-the machine an intruder must have physical access.
-
-Sometimes, however, it is necessary to be sure that a user is authorized
+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{password}; then, the
-system can ask someone claiming to be a user what the user's password
-is, and if the person gives the correct password then the system can
-grant the appropriate privileges.
-
-If all the passwords are just stored in a file somewhere, then this file
-has to be very carefully protected.  To avoid this, passwords are run
-through a @dfn{one-way function}, a function which makes it difficult to
-work out what its input was by looking at its output, before storing in
-the file.
-
-@Theglibc{} provides a one-way function that is compatible with
-the behavior of the @code{crypt} function introduced in FreeBSD 2.0.
-It supports two one-way algorithms: one based on the MD5
-message-digest algorithm that is compatible with modern BSD systems,
-and the other based on the Data Encryption Standard (DES) that is
-compatible with Unix systems.
-
-@deftypefun {char *} crypt (const char *@var{key}, const char *@var{salt})
-@standards{BSD, crypt.h}
-@standards{SVID, crypt.h}
+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.  The FIPS mode checker and the
-@c NSS implementations of may leak file descriptors if canceled.  The
+@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 @code{crypt} function takes a password, @var{key}, as a string, and
-a @var{salt} character array which is described below, and returns a
-printable ASCII string which starts with another salt.  It is believed
-that, given the output of the function, the best way to find a @var{key}
-that will produce that output is to guess values of @var{key} until the
-original value of @var{key} is found.
-
-The @var{salt} parameter does two things.  Firstly, it selects which
-algorithm is used, the MD5-based one or the DES-based one.  Secondly, it
-makes life harder for someone trying to guess passwords against a file
-containing many passwords; without a @var{salt}, an intruder can make a
-guess, run @code{crypt} on it once, and compare the result with all the
-passwords.  With a @var{salt}, the intruder must run @code{crypt} once
-for each different salt.
-
-For the MD5-based algorithm, the @var{salt} should consist of the string
-@code{$1$}, followed by up to 8 characters, terminated by either
-another @code{$} or the end of the string.  The result of @code{crypt}
-will be the @var{salt}, followed by a @code{$} if the salt didn't end
-with one, followed by 22 characters from the alphabet
-@code{./0-9A-Za-z}, up to 34 characters total.  Every character in the
-@var{key} is significant.
-
-For the DES-based algorithm, the @var{salt} should consist of two
-characters from the alphabet @code{./0-9A-Za-z}, and the result of
-@code{crypt} will be those two characters followed by 11 more from the
-same alphabet, 13 in total.  Only the first 8 characters in the
-@var{key} are significant.
-
-The MD5-based algorithm has no limit on the useful length of the
-password used, and is slightly more secure.  It is therefore preferred
-over the DES-based algorithm.
-
-When the user enters their password for the first time, the @var{salt}
-should be set to a new string which is reasonably random.  To verify a
-password against the result of a previous call to @code{crypt}, pass
-the result of the previous call as the @var{salt}.
+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{key}, const char *@var{salt}, {struct crypt_data *} @var{data})
+@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 @code{crypt_r} function does the same thing as @code{crypt}, but
-takes an extra parameter which includes space for its result (among
-other things), so it can be reentrant.  @code{data@w{->}initialized} must be
-cleared to zero before the first time @code{crypt_r} is called.
-
-The @code{crypt_r} function is a GNU extension.
+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 @code{crypt} and @code{crypt_r} functions are prototyped in the
-header @file{crypt.h}.
-
-The following short program is an example of how to use @code{crypt} the
-first time a password is entered.  Note that the @var{salt} generation
-is just barely acceptable; in particular, it is not unique between
-machines, and in many applications it would not be acceptable to let an
-attacker know what time the user's password was last set.
+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 shows how to verify a password.  It prompts the user
-for a password and prints ``Access granted.'' if the user types
-@code{GNU libc manual}.
+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
@@ -123,93 +202,120 @@ for a password and prints ``Access granted.'' if the user types
 
 @node Unpredictable Bytes
 @section Generating Unpredictable Bytes
-
-Some cryptographic applications (such as session key generation) need
-unpredictable bytes.
-
-In general, application code should use a deterministic random bit
-generator, which could call the @code{getentropy} function described
-below internally to obtain randomness to seed the generator.  The
-@code{getrandom} function is intended for low-level applications which
-need additional control over the blocking behavior.
+@cindex randomness source
+@cindex random numbers, cryptographic
+@cindex pseudo-random numbers, cryptographic
+@cindex cryptographic random number generator
+@cindex deterministic random bit generator
+@cindex CRNG
+@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.
+
+The pseudo-random number generators described in @ref{Pseudo-Random
+Numbers} are not unpredictable enough for these applications.  They
+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).
+
+Currently, @theglibc{} does not provide a cryptographic random number
+generator.  What it does provide is 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 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
+problem, but applications that need more than a few kilobytes of
+cryptographically strong random data should call these functions once
+and use their output to seed a CRNG.
+
+Most applications should use @code{getentropy}.  The @code{getrandom}
+function is intended for low-level applications which need additional
+control over blocking behavior.
 
 @deftypefun int getentropy (void *@var{buffer}, size_t @var{length})
 @standards{GNU, sys/random.h}
 @safety{@mtsafe{}@assafe{}@acsafe{}}
 
-This function writes @var{length} bytes of random data to the array
-starting at @var{buffer}, which must be at most 256 bytes long.  The
-function returns zero on success.  On failure, it returns @code{-1} and
-@code{errno} is updated accordingly.
-
-The @code{getentropy} function is declared in the header file
-@file{sys/random.h}.  It is derived from OpenBSD.
-
-The @code{getentropy} function is not a cancellation point.  A call to
-@code{getentropy} can block if the system has just booted and the kernel
-entropy pool has not yet been initialized.  In this case, the function
-will keep blocking even if a signal arrives, and return only after the
-entropy pool has been initialized.
-
-The @code{getentropy} function can fail with several errors, some of
-which are listed below.
+This function writes exactly @var{length} bytes of random data to the
+array starting at @var{buffer}.  @var{length} can be no more than 256.
+On success, it returns zero.  On failure, it returns @math{-1}, and
+@code{errno} is set to indicate the problem.  Some of the possible
+errors are listed below.
 
 @table @code
 @item ENOSYS
-The kernel does not implement the required system call.
+The operating system does not implement a randomness source, or does
+not support this way of accessing it.  (For instance, the system call
+used by this function was added to the Linux kernel in version 3.17.)
 
 @item EFAULT
 The combination of @var{buffer} and @var{length} arguments specifies
 an invalid memory range.
 
 @item EIO
-More than 256 bytes of randomness have been requested, or the buffer
-could not be overwritten with random data for an unspecified reason.
-
+@var{length} is larger than 256, or the kernel entropy pool has
+suffered a catastrophic failure.
 @end table
 
+A call to @code{getentropy} can only block when the system has just
+booted and the randomness source has not yet been initialized.
+However, if it does block, it cannot be interrupted by signals or
+thread cancellation.  Programs intended to run in very early stages of
+the boot process may need to use @code{getrandom} in non-blocking mode
+instead, and be prepared to cope with random data not being available
+at all.
+
+The @code{getentropy} function is declared in the header file
+@file{sys/random.h}.  It is derived from OpenBSD.
 @end deftypefun
 
 @deftypefun ssize_t getrandom (void *@var{buffer}, size_t @var{length}, unsigned int @var{flags})
 @standards{GNU, sys/random.h}
 @safety{@mtsafe{}@assafe{}@acsafe{}}
 
-This function writes @var{length} bytes of random data to the array
-starting at @var{buffer}.  On success, this function returns the number
-of bytes which have been written to the buffer (which can be less than
-@var{length}).  On error, @code{-1} is returned, and @code{errno} is
-updated accordingly.
-
-The @code{getrandom} function is declared in the header file
-@file{sys/random.h}.  It is a GNU extension.
-
-The following flags are defined for the @var{flags} argument:
+This function writes up to @var{length} bytes of random data to the
+array starting at @var{buffer}.  The @var{flags} argument should be
+either zero, or the bitwise OR of some of the following flags:
 
 @table @code
 @item GRND_RANDOM
-Use the @file{/dev/random} (blocking) pool instead of the
-@file{/dev/urandom} (non-blocking) pool to obtain randomness.  If the
-@code{GRND_RANDOM} flag is specified, the @code{getrandom} function can
-block even after the randomness source has been initialized.
+Use the @file{/dev/random} (blocking) source instead of the
+@file{/dev/urandom} (non-blocking) source to obtain randomness.
+
+If this flag is specified, the call may block, potentially for quite
+some time.  If it is not specified, the call can only block when the
+system has just booted and the randomness source has not yet been
+initialized.
 
 @item GRND_NONBLOCK
 Instead of blocking, return to the caller immediately if no data is
 available.
 @end table
 
-The @code{getrandom} function is a cancellation point.
+Unlike @code{getentropy}, the @code{getrandom} function is a
+cancellation point, and if it blocks, it can be interrupted by
+signals.
 
-Obtaining randomness from the @file{/dev/urandom} pool (i.e., a call
-without the @code{GRND_RANDOM} flag) can block if the system has just
-booted and the pool has not yet been initialized.
-
-The @code{getrandom} function can fail with several errors, some of
-which are listed below.  In addition, the function may not fill the
-buffer completely and return a value less than @var{length}.
+On success, @code{getrandom} returns the number of bytes which have
+been written to the buffer, which may be less than @var{length}.  On
+error, it returns @math{-1}, and @code{errno} is set to indicate the
+problem.  Some of the possible errors are:
 
 @table @code
 @item ENOSYS
-The kernel does not implement the @code{getrandom} system call.
+The operating system does not implement a randomness source, or does
+not support this way of accessing it.  (For instance, the system call
+used by this function was added to the Linux kernel in version 3.17.)
 
 @item EAGAIN
 No random data was available and @code{GRND_NONBLOCK} was specified in
@@ -228,4 +334,7 @@ the kernel randomness pool is initialized, this can happen even if
 The @var{flags} argument contains an invalid combination of flags.
 @end table
 
+The @code{getrandom} function is declared in the header file
+@file{sys/random.h}.  It is a GNU extension.
+
 @end deftypefun
diff --git a/manual/examples/genpass.c b/manual/examples/genpass.c
index 5edb2e9b8a..23d20789fc 100644
--- a/manual/examples/genpass.c
+++ b/manual/examples/genpass.c
@@ -16,34 +16,44 @@
 */
 
 #include <stdio.h>
-#include <time.h>
 #include <unistd.h>
 #include <crypt.h>
 
 int
 main(void)
 {
-  unsigned long seed[2];
-  char salt[] = "$1$........";
-  const char *const seedchars =
+  unsigned char ubytes[16];
+  char salt[20];
+  const char *const saltchars =
     "./0123456789ABCDEFGHIJKLMNOPQRST"
     "UVWXYZabcdefghijklmnopqrstuvwxyz";
-  char *password;
+  char *hash;
   int i;
 
-  /* Generate a (not very) random seed.
-     You should do it better than this...  */
-  seed[0] = time(NULL);
-  seed[1] = getpid() ^ (seed[0] >> 14 & 0x30000);
-
-  /* Turn it into printable characters from `seedchars'.  */
-  for (i = 0; i < 8; i++)
-    salt[3+i] = seedchars[(seed[i/5] >> (i%5)*6) & 0x3f];
-
-  /* Read in the user's password and encrypt it.  */
-  password = crypt(getpass("Password:"), salt);
+  /* 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(password);
+  puts (hash);
   return 0;
 }
diff --git a/manual/examples/mygetpass.c b/manual/examples/mygetpass.c
index dfc0c59a7f..13569b327a 100644
--- a/manual/examples/mygetpass.c
+++ b/manual/examples/mygetpass.c
@@ -1,4 +1,4 @@
-/* Reading Passwords
+/* Reading Passphrases Manually
    Copyright (C) 1991-2018 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
@@ -32,7 +32,7 @@ my_getpass (char **lineptr, size_t *n, FILE *stream)
   if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
     return -1;
 
-  /* Read the password.  */
+  /* Read the passphrase  */
   nread = getline (lineptr, n, stream);
 
   /* Restore terminal.  */
diff --git a/manual/examples/testpass.c b/manual/examples/testpass.c
index 19f1ae7de0..f8883fea17 100644
--- a/manual/examples/testpass.c
+++ b/manual/examples/testpass.c
@@ -1,4 +1,4 @@
-/* Verify a password.
+/* Verify a passphrase.
    Copyright (C) 1991-2018 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
@@ -20,24 +20,48 @@
 #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)
 {
-  /* Hashed form of "GNU libc manual".  */
-  const char *const pass = "$1$/iSaq7rB$EoUw5jJPPvAPECNaaWzMK/";
+  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}.  */
 
-  char *result;
-  int ok;
+  if (strcmp (crypt (phrase, hash_sha), hash_sha))
+    {
+      puts ("SHA: not ok");
+      status = 1;
+    }
+  else
+    puts ("SHA: ok");
 
-/*@group*/
-  /* Read in the user's password and encrypt it,
-     passing the expected password in as the salt.  */
-  result = crypt(getpass("Password:"), pass);
-/*@end group*/
+  if (strcmp (crypt (phrase, hash_md5), hash_md5))
+    {
+      puts ("MD5: not ok");
+      status = 1;
+    }
+  else
+    puts ("MD5: ok");
 
-  /* Test the result.  */
-  ok = strcmp (result, pass) == 0;
+  if (strcmp (crypt (phrase, hash_des), hash_des))
+    {
+      puts ("DES: not ok");
+      status = 1;
+    }
+  else
+    puts ("DES: ok");
 
-  puts(ok ? "Access granted." : "Access denied.");
-  return ok ? 0 : 1;
+  return status;
 }
diff --git a/manual/intro.texi b/manual/intro.texi
index cc9c99f543..779fec8f3d 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -1321,7 +1321,6 @@ this manual.
 @c Message Translation (8)
 @c Resource Usage And Limitations (22)
 @c Inter-Process Communication (27)
-@c DES Encryption and Password Handling (33)
 @c Debugging support (34)
 @c POSIX Threads (35)
 @c Internal Probes (36)
diff --git a/manual/memory.texi b/manual/memory.texi
index b95f6aa1b9..3fa56569c4 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -3452,7 +3452,7 @@ system performance.  In this case, locking pages can help.
 @item
 Privacy.  If you keep secrets in virtual memory and that virtual memory
 gets paged out, that increases the chance that the secrets will get out.
-If a password gets written out to disk swap space, for example, it might
+If a passphrase gets written out to disk swap space, for example, it might
 still be there long after virtual and real memory have been wiped clean.
 
 @end itemize
diff --git a/manual/nss.texi b/manual/nss.texi
index d534c260d3..18361b6f42 100644
--- a/manual/nss.texi
+++ b/manual/nss.texi
@@ -84,15 +84,15 @@ Network names and numbers, @pxref{Networks Database}.
 @item protocols
 Network protocols, @pxref{Protocols Database}.
 @item passwd
-User passwords, @pxref{User Database}.
+User identities, @pxref{User Database}.
 @item rpc
-Remote procedure call names and numbers,
+Remote procedure call names and numbers.
 @comment @pxref{RPC Database}.
 @item services
 Network services, @pxref{Services Database}.
 @item shadow
-Shadow user passwords,
-@comment @pxref{Shadow Password Database}.
+User passphrase hashes and related information.
+@comment @pxref{Shadow Passphrase Database}.
 @end table
 
 @noindent
@@ -526,7 +526,7 @@ with the main application.)
 The @code{get@var{XXX}by@var{YYY}} functions are the most important
 functions in the NSS modules.  But there are others which implement
 the other ways to access system databases (say for the
-password database, there are @code{setpwent}, @code{getpwent}, and
+user database, there are @code{setpwent}, @code{getpwent}, and
 @code{endpwent}).  These will be described in more detail later.
 Here we give a general way to determine the
 signature of the module function:
@@ -650,7 +650,7 @@ general rules must be followed by all functions.
 In fact there are four kinds of different functions which may appear in
 the interface.  All derive from the traditional ones for system databases.
 @var{db} in the following table is normally an abbreviation for the
-database (e.g., it is @code{pw} for the password database).
+database (e.g., it is @code{pw} for the user database).
 
 @table @code
 @item enum nss_status _nss_@var{database}_set@var{db}ent (void)
diff --git a/manual/socket.texi b/manual/socket.texi
index 79eb4208be..a6c44b77c3 100644
--- a/manual/socket.texi
+++ b/manual/socket.texi
@@ -257,7 +257,7 @@ system assigns an address automatically if you have not specified one.
 
 Occasionally a client needs to specify an address because the server
 discriminates based on address; for example, the rsh and rlogin
-protocols look at the client's socket address and only bypass password
+protocols look at the client's socket address and only bypass passphrase
 checking if it is less than @code{IPPORT_RESERVED} (@pxref{Ports}).
 
 The details of socket addresses vary depending on what namespace you are
@@ -3277,7 +3277,7 @@ or request that comes in.  If @var{style} uses connections, then
 @var{user} is the user name that the server should run as.  @code{inetd} runs
 as root, so it can set the user ID of its children arbitrarily.  It's
 best to avoid using @samp{root} for @var{user} if you can; but some
-servers, such as Telnet and FTP, read a username and password
+servers, such as Telnet and FTP, read a username and passphrase
 themselves.  These servers need to be root initially so they can log
 in as commanded by the data coming over the network.
 
diff --git a/manual/terminal.texi b/manual/terminal.texi
index 0b275fc002..d830baacd7 100644
--- a/manual/terminal.texi
+++ b/manual/terminal.texi
@@ -24,7 +24,7 @@ descriptor is and how to open a file descriptor for a terminal device.
 * Line Control::                Sending break sequences, clearing
                                  terminal buffers @dots{}
 * Noncanon Example::            How to read single characters without echo.
-* getpass::                     Prompting the user for a password.
+* getpass::                     Prompting the user for a passphrase.
 * Pseudo-Terminals::            How to open a pseudo-terminal.
 @end menu
 
@@ -1873,9 +1873,9 @@ handlers for job control signals that reset terminal modes.  The above
 example does so.
 
 @node getpass
-@section Reading Passwords
+@section Reading Passphrases
 
-When reading in a password, it is desirable to avoid displaying it on
+When reading in a passphrase, it is desirable to avoid displaying it on
 the screen, to help keep it secret.  The following function handles this
 in a convenient way.
 
@@ -1884,7 +1884,7 @@ in a convenient way.
 @safety{@prelim{}@mtunsafe{@mtasuterm{}}@asunsafe{@ascuheap{} @asulock{} @asucorrupt{}}@acunsafe{@acuterm{} @aculock{} @acucorrupt{}}}
 @c This function will attempt to create a stream for terminal I/O, but
 @c will fallback to stdio/stderr.  It attempts to change the terminal
-@c mode in a thread-unsafe way, write out the prompt, read the password,
+@c mode in a thread-unsafe way, write out the prompt, read the passphrase,
 @c then restore the terminal mode.  It has a cleanup to close the stream
 @c in case of (synchronous) cancellation, but not to restore the
 @c terminal mode.
@@ -1892,14 +1892,14 @@ in a convenient way.
 @code{getpass} outputs @var{prompt}, then reads a string in from the
 terminal without echoing it.  It tries to connect to the real terminal,
 @file{/dev/tty}, if possible, to encourage users not to put plaintext
-passwords in files; otherwise, it uses @code{stdin} and @code{stderr}.
+passphrases in files; otherwise, it uses @code{stdin} and @code{stderr}.
 @code{getpass} also disables the INTR, QUIT, and SUSP characters on the
 terminal using the @code{ISIG} terminal attribute (@pxref{Local Modes}).
 The terminal is flushed before and after @code{getpass}, so that
-characters of a mistyped password are not accidentally visible.
+characters of a mistyped passphrase are not accidentally visible.
 
 In other C libraries, @code{getpass} may only return the first
-@code{PASS_MAX} bytes of a password.  @Theglibc{} has no limit, so
+@code{PASS_MAX} bytes of a passphrase.  @Theglibc{} has no limit, so
 @code{PASS_MAX} is undefined.
 
 The prototype for this function is in @file{unistd.h}.  @code{PASS_MAX}
diff --git a/manual/users.texi b/manual/users.texi
index 8690b65633..242f0aea0e 100644
--- a/manual/users.texi
+++ b/manual/users.texi
@@ -1722,7 +1722,6 @@ members.  Older systems do not even have the @code{ut_host} member.
 @node User Database
 @section User Database
 @cindex user database
-@cindex password database
 @pindex /etc/passwd
 
 This section describes how to search and scan the database of registered
@@ -1730,6 +1729,16 @@ users.  The database itself is kept in the file @file{/etc/passwd} on
 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
+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
+no longer considered safe to make passphrase hashes available to all
+users, so they have been moved to a ``shadow'' database that can only
+be accessed with special privileges.
+
 @menu
 * User Data Structure::         What each user record contains.
 * Lookup User::                 How to look for a particular user.
@@ -1753,8 +1762,10 @@ entries in the system user data base.  It has at least the following members:
 @item char *pw_name
 The user's login name.
 
-@item char *pw_passwd.
-The encrypted password string.
+@item char *pw_passwd
+Historically, this field would hold the one-way hash of the user's
+passphrase.  Nowadays, it will almost always be the single character
+@samp{x}, indicating that the hash is in the shadow database.
 
 @item uid_t pw_uid
 The user ID number.
@@ -2105,7 +2116,7 @@ rewritten on subsequent calls to @code{fgetpwent}.  You must copy the
 contents of the structure if you wish to save the information.
 
 The stream must correspond to a file in the same format as the standard
-password database file.
+user database file.
 @end deftypefun
 
 @deftypefun int fgetpwent_r (FILE *@var{stream}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
@@ -2126,7 +2137,7 @@ first @var{buflen} bytes of the additional buffer pointed to by
 strings which are pointed to by the elements of the result structure.
 
 The stream must correspond to a file in the same format as the standard
-password database file.
+user database file.
 
 If the function returns zero @var{result} points to the structure with
 the wanted data (normally this is in @var{result_buf}).  If errors
@@ -2234,7 +2245,6 @@ avoid using it, because it makes sense only on the assumption that the
 on a system which merges the traditional Unix data base with other
 extended information about users, adding an entry using this function
 would inevitably leave out much of the important information.
-@c Then how are programmers to modify the password file? -zw
 
 The group and user ID fields are left empty if the group or user name
 starts with a - or +.
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 997d7c08fc..96ba46345a 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -405,9 +405,9 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
   if (__glibc_unlikely (debug_level > 0))
     {
       if (he == NULL)
-	dbg_log (_("Haven't found \"%s\" in password cache!"), keystr);
+	dbg_log (_("Haven't found \"%s\" in user database cache!"), keystr);
       else
-	dbg_log (_("Reloading \"%s\" in password cache!"), keystr);
+	dbg_log (_("Reloading \"%s\" in user database cache!"), keystr);
     }
 
   while (lookup (req->type, key, &resultbuf, buffer, buflen, &pwd) != 0
diff --git a/posix/unistd.h b/posix/unistd.h
index 5c3da702b6..9b30f553d7 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -107,7 +107,7 @@ __BEGIN_DECLS
 /* The X/Open Unix extensions are available.  */
 #define _XOPEN_UNIX	1
 
-/* Encryption is present.  */
+/* One-way hashing of passphrases is available.  */
 #define	_XOPEN_CRYPT	1
 
 /* The enhanced internationalization capabilities according to XPG4.2
@@ -1119,8 +1119,12 @@ extern int fdatasync (int __fildes);
 #endif /* Use POSIX199309 */
 
 #ifdef	__USE_XOPEN
-/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
-extern char *crypt (const char *__key, const char *__salt)
+/* One-way hash PHRASE, returning a string suitable for storage in the
+   user database.  SALT selects the one-way function to use, and
+   ensures that no two users' hashes are the same, even if they use
+   the same passphrase.  The return value points to static storage
+   which will be overwritten by the next call to crypt.  */
+extern char *crypt (const char *__phrase, const char *__salt)
      __THROW __nonnull ((1, 2));
 
 /* Swab pairs bytes in the first N bytes of the area pointed to by
diff --git a/pwd/pwd.h b/pwd/pwd.h
index 25c6b97551..e6d20cd78b 100644
--- a/pwd/pwd.h
+++ b/pwd/pwd.h
@@ -45,11 +45,12 @@ typedef __uid_t uid_t;
 # endif
 #endif
 
-/* The passwd structure.  */
+/* A record in the user database.  */
 struct passwd
 {
   char *pw_name;		/* Username.  */
-  char *pw_passwd;		/* Password.  */
+  char *pw_passwd;		/* Hashed passphrase, if shadow database
+                                   not in use (see shadow.h).  */
   __uid_t pw_uid;		/* User ID.  */
   __gid_t pw_gid;		/* Group ID.  */
   char *pw_gecos;		/* Real name.  */
@@ -64,19 +65,19 @@ struct passwd
 
 
 #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
-/* Rewind the password-file stream.
+/* Rewind the user database stream.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern void setpwent (void);
 
-/* Close the password-file stream.
+/* Close the user database stream.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern void endpwent (void);
 
-/* Read an entry from the password-file stream, opening it if necessary.
+/* Read an entry from the user database stream, opening it if necessary.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
@@ -84,7 +85,7 @@ extern struct passwd *getpwent (void);
 #endif
 
 #ifdef	__USE_MISC
-/* Read an entry from STREAM.
+/* Read a user database entry from STREAM.
 
    This function is not part of POSIX and therefore no official
    cancellation point.  But due to similarity with an POSIX interface
@@ -92,7 +93,7 @@ extern struct passwd *getpwent (void);
    therefore not marked with __THROW.  */
 extern struct passwd *fgetpwent (FILE *__stream) __nonnull ((1));
 
-/* Write the given entry onto the given stream.
+/* Write a given user database entry onto the given stream.
 
    This function is not part of POSIX and therefore no official
    cancellation point.  But due to similarity with an POSIX interface
@@ -102,13 +103,13 @@ extern int putpwent (const struct passwd *__restrict __p,
 		     FILE *__restrict __f);
 #endif
 
-/* Search for an entry with a matching user ID.
+/* Retrieve the user database entry for the given user ID.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern struct passwd *getpwuid (__uid_t __uid);
 
-/* Search for an entry with a matching username.
+/* Retrieve the user database entry for the given username.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
@@ -155,8 +156,8 @@ extern int getpwnam_r (const char *__restrict __name,
 
 
 # ifdef	__USE_MISC
-/* Read an entry from STREAM.  This function is not standardized and
-   probably never will.
+/* Read a user database entry from STREAM.  This function is not
+   standardized and probably never will.
 
    This function is not part of POSIX and therefore no official
    cancellation point.  But due to similarity with an POSIX interface
@@ -172,9 +173,9 @@ extern int fgetpwent_r (FILE *__restrict __stream,
 #endif	/* POSIX or reentrant */
 
 #ifdef __USE_GNU
-/* Re-construct the password-file line for the given uid
-   in the given buffer.  This knows the format that the caller
-   will expect, but this need not be the format of the password file.
+/* Write a traditional /etc/passwd line, based on the user database
+   entry for the given UID, to BUFFER; space for BUFFER must be
+   allocated by the caller.
 
    This function is not part of POSIX and therefore no official
    cancellation point.  But due to similarity with an POSIX interface
diff --git a/shadow/shadow.h b/shadow/shadow.h
index 6f3a570e4b..351882e448 100644
--- a/shadow/shadow.h
+++ b/shadow/shadow.h
@@ -15,7 +15,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-/* Declaration of types and functions for shadow password suite.  */
+/* Declaration of types and functions for "shadow" storage of hashed
+   passphrases.  The shadow database is like the user database, but is
+   only accessible with special privileges, so that malicious users
+   cannot retrieve everyone else's hashed passphrase to brute-force at
+   their convenience.  */
 
 #ifndef _SHADOW_H
 #define _SHADOW_H	1
@@ -35,11 +39,11 @@
 
 __BEGIN_DECLS
 
-/* Structure of the password file.  */
+/* A record in the shadow database.  */
 struct spwd
   {
     char *sp_namp;		/* Login name.  */
-    char *sp_pwdp;		/* Encrypted password.  */
+    char *sp_pwdp;		/* Hashed passphrase.  */
     long int sp_lstchg;		/* Date of last change.  */
     long int sp_min;		/* Minimum number of days between changes.  */
     long int sp_max;		/* Maximum number of days between changes.  */
@@ -101,7 +105,7 @@ extern struct spwd *sgetspent (const char *__string);
    therefore not marked with __THROW.  */
 extern struct spwd *fgetspent (FILE *__stream);
 
-/* Write line containing shadow password entry to stream.
+/* Write line containing shadow entry to stream.
 
    This function is not part of POSIX and therefore no official
    cancellation point.  But due to similarity with an POSIX interface
@@ -137,10 +141,10 @@ extern int fgetspent_r (FILE *__stream, struct spwd *__result_buf,
 /* The simple locking functionality provided here is not suitable for
    multi-threaded applications.  */
 
-/* Protect password file against multi writers.  */
+/* Request exclusive access to /etc/passwd and /etc/shadow.  */
 extern int lckpwdf (void) __THROW;
 
-/* Unlock password file.  */
+/* Release exclusive access to /etc/passwd and /etc/shadow.  */
 extern int ulckpwdf (void) __THROW;
 
 __END_DECLS
-- 
2.17.0

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 0/4 v3] libcrypt phaseout
@ 2018-05-21 17:39 Zack Weinberg
  2018-05-21 17:39 ` [PATCH 4/4] New configure option --disable-crypt Zack Weinberg
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Zack Weinberg @ 2018-05-21 17:39 UTC (permalink / raw)
  To: libc-alpha; +Cc: carlos, fweimer, rj, kukuk

Here comes another revision of the patchset to begin phasing out
libcrypt (and also improve the documentation for 'crypt'.)  Major
changes from the previous revision are:

 - Rather than just marking them deprecated, I have gone ahead and
   disallowed use of the DES encryption functions in new programs.
   The only reason I hadn't done that already was because 'setkey' and
   'encrypt' are still in POSIX; but the insecurity of DES is more
   important than that, and libxcrypt already took the plunge.
   Conveniently, this means all of the documentation of those
   functions can be dropped and I don't have to figure out how to
   explain the bizarro things that some of them do.

 - I changed my mind about consolidating the random number generation
   discussion.  "Unpredictable Bytes" now remains in crypt.texi and
   "Pseudo-Random Numbers" remains in math.texi.

 - I went back to using hardwired hashes in the testpass.c example,
   because that way the program actually works as a demo; also it
   allows me to show how the DES-based hash ignores all but the first
   eight characters of the input passphrase.

 - Terminology has been made consistent throughout the manual and the
   public headers: "passphrase", "user database", and "(one-way)
   hashing", not "password", "password database", or "encryption".

 - Lots more documentation improvements.

Zack Weinberg (4):
  Disallow use of DES encryption functions in new programs.
  Reorganize crypt.texi.
  Revise crypt.texi.
  New configure option --disable-crypt.

 INSTALL                     |  11 +
 Makeconfig                  |   9 +-
 NEWS                        |  25 ++
 config.make.in              |   1 +
 configure                   |  18 +
 configure.ac                |  11 +
 conform/Makefile            |  11 +-
 conform/data/stdlib.h-data  |   3 -
 conform/data/unistd.h-data  |   3 -
 crypt/Makefile              |   4 -
 crypt/Versions              |   3 +
 crypt/cert.c                |  29 ++
 crypt/crypt-entry.c         |  15 +-
 crypt/crypt.h               |  37 +-
 crypt/crypt_util.c          |   9 +
 elf/Makefile                |  27 +-
 elf/tst-linkall-static.c    |   4 +-
 inet/ruserpass.c            |   2 +-
 manual/contrib.texi         |   2 +-
 manual/crypt.texi           | 695 +++++++++++++-----------------------
 manual/examples/genpass.c   |  44 ++-
 manual/examples/mygetpass.c |   4 +-
 manual/examples/testpass.c  |  52 ++-
 manual/install.texi         |  12 +
 manual/intro.texi           |   1 -
 manual/memory.texi          |   2 +-
 manual/nss.texi             |  12 +-
 manual/socket.texi          |   4 +-
 manual/string.texi          |  82 ++---
 manual/terminal.texi        |  45 +++
 manual/users.texi           |  22 +-
 nscd/pwdcache.c             |   4 +-
 posix/unistd.h              |  19 +-
 pwd/pwd.h                   |  29 +-
 shadow/shadow.h             |  16 +-
 stdlib/stdlib.h             |   6 -
 sunrpc/Makefile             |   2 +-
 sunrpc/des_crypt.c          |   7 +-
 sunrpc/des_soft.c           |   2 +-
 39 files changed, 651 insertions(+), 633 deletions(-)

-- 
2.17.0

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 4/4] New configure option --disable-crypt.
  2018-05-21 17:39 [PATCH 0/4 v3] libcrypt phaseout Zack Weinberg
@ 2018-05-21 17:39 ` Zack Weinberg
  2018-05-21 19:52   ` Joseph Myers
  2018-05-21 17:39 ` [PATCH 3/4] Revise crypt.texi Zack Weinberg
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: Zack Weinberg @ 2018-05-21 17:39 UTC (permalink / raw)
  To: libc-alpha; +Cc: carlos, fweimer, rj, kukuk

Some Linux distributions are experimenting with a new, separately
maintained and hopefully more agile implementation of the crypt(3)
API.  To facilitate this, add a configure option which disables
glibc's embedded libcrypt.  When this option is given, libcrypt.*
and crypt.h will not be built nor installed.

unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.

The bulk of the patch is just various places that need to take note of
libcrypt possibly not getting built.

        * configure.ac: New command-line option --disable-crypt.
        Force --disable-nss-crypt when --disable-crypt is given, with a
        warning if it was explicitly enabled.
        * configure: Regenerate.
        * config.make.in: New boolean substitution variable $(build-crypt).
        * Makeconfig: Only include 'crypt' in all-subdirs and rpath-dirs
        when $(build-crypt).
        * manual/install.texi: Document --disable-crypt.
        * INSTALL: Regenerate.

        * crypt/Makefile: Remove code conditional on $(crypt-in-libc),
        which is never set.
        * conform/Makefile: Only include libcrypt.a in
        linknamespace-libs-xsi and linknamespace-libs-XPG4
        when $(build-crypt).
        * elf/Makefile (CFLAGS-tst-linkall-static.c): Only define
        USE_CRYPT to 1 when $(build-crypt).
        (tst-linkall-static): Only link libcrypt.a when $(build-crypt).
        (localplt-built-dso): Only add libcrypt.so when $(build-crypt).
        * elf/tst-linkall-static.c: Only include crypt.h when USE_CRYPT.
---
 INSTALL                  | 11 +++++++++++
 Makeconfig               |  9 +++++++--
 NEWS                     | 13 +++++++++++++
 config.make.in           |  1 +
 configure                | 18 ++++++++++++++++++
 configure.ac             | 11 +++++++++++
 conform/Makefile         | 11 +++++++----
 crypt/Makefile           |  4 ----
 elf/Makefile             | 27 +++++++++++++++++++--------
 elf/tst-linkall-static.c |  4 +++-
 manual/install.texi      | 12 ++++++++++++
 11 files changed, 102 insertions(+), 19 deletions(-)

diff --git a/INSTALL b/INSTALL
index 052b1b6f89..37ec68fb3d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -197,6 +197,17 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
      libnss_nisplus are not built at all.  Use this option to enable
      libnsl with all depending NSS modules and header files.
 
+'--disable-crypt'
+     Do not install the passphrase-hashing library 'libcrypt' or the
+     header file 'crypt.h'.  'unistd.h' will still declare the function
+     'crypt', as required by POSIX.  Using this option does not change
+     the set of programs that may need to be linked with '-lcrypt'; it
+     only means that the GNU C Library will not provide that library.
+
+     This option is for hackers and distributions experimenting with
+     independently-maintained implementations of libcrypt.  It may
+     become the default in a future release.
+
 '--disable-experimental-malloc'
      By default, a per-thread cache is enabled in 'malloc'.  While this
      cache can be disabled on a per-application basis using tunables
diff --git a/Makeconfig b/Makeconfig
index 1afe86475c..608ffe648c 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -566,7 +566,7 @@ link-libc-printers-tests = $(link-libc-rpath) \
 			   $(link-libc-tests-after-rpath-link)
 
 # This is how to find at build-time things that will be installed there.
-rpath-dirs = math elf dlfcn nss nis rt resolv crypt mathvec support
+rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support
 rpath-link = \
 $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
 else  # build-static
@@ -1205,9 +1205,14 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal	    \
 	      stdlib stdio-common libio malloc string wcsmbs time dirent    \
 	      grp pwd posix io termios resource misc socket sysvipc gmon    \
 	      gnulib iconv iconvdata wctype manual shadow gshadow po argp   \
-	      crypt localedata timezone rt conform debug mathvec support    \
+	      localedata timezone rt conform debug mathvec support	    \
 	      dlfcn elf
 
+ifeq ($(build-crypt),yes)
+all-subdirs += crypt
+rpath-dirs += crypt
+endif
+
 ifndef avoid-generated
 # sysd-sorted itself will contain rules making the sysd-sorted target
 # depend on Depend files.  But if you just added a Depend file to an
diff --git a/NEWS b/NEWS
index 0bd21948f6..e80d3d800c 100644
--- a/NEWS
+++ b/NEWS
@@ -86,6 +86,19 @@ Deprecated and removed features, and other changes affecting compatibility:
   binaries.  It was just another name for the standard function 'crypt',
   and it has not appeared in any header file in many years.
 
+* We have tentative plans to hand off maintenance of the passphrase-hashing
+  library, libcrypt, to a separate development project that will, we hope,
+  keep up better with new passphrase-hashing algorithms.  We will continue
+  to declare 'crypt' in <unistd.h>, as required by POSIX, and programs that
+  use 'crypt' or 'crypt_r' should not need to change at all; however, system
+  integrators will need to install <crypt.h> and libcrypt from the separate
+  project.
+
+  In this release, if the configure option --disable-crypt is used, glibc
+  will not install <crypt.h> or libcrypt, making room for the separate
+  project's versions of these files.  The plan is to make this the default
+  behavior in a future release.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/config.make.in b/config.make.in
index 9e5e24b2c6..d9891b2cd8 100644
--- a/config.make.in
+++ b/config.make.in
@@ -96,6 +96,7 @@ cross-compiling = @cross_compiling@
 force-install = @force_install@
 link-obsolete-rpc = @link_obsolete_rpc@
 build-obsolete-nsl = @build_obsolete_nsl@
+build-crypt = @build_crypt@
 build-nscd = @build_nscd@
 use-nscd = @use_nscd@
 build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
diff --git a/configure b/configure
index 7a8bd3f817..ef18302215 100755
--- a/configure
+++ b/configure
@@ -676,6 +676,7 @@ build_obsolete_nsl
 link_obsolete_rpc
 libc_cv_static_nss_crypt
 libc_cv_nss_crypt
+build_crypt
 experimental_malloc
 enable_werror
 all_warnings
@@ -779,6 +780,7 @@ enable_all_warnings
 enable_werror
 enable_multi_arch
 enable_experimental_malloc
+enable_crypt
 enable_nss_crypt
 enable_obsolete_rpc
 enable_obsolete_nsl
@@ -1448,6 +1450,8 @@ Optional Features:
                           architectures
   --disable-experimental-malloc
                           disable experimental malloc features
+  --disable-crypt         do not build nor install the passphrase hashing
+                          library, libcrypt
   --enable-nss-crypt      enable libcrypt to use nss
   --enable-obsolete-rpc   build and install the obsolete RPC code for
                           link-time usage
@@ -3505,6 +3509,15 @@ fi
 
 
 
+# Check whether --enable-crypt was given.
+if test "${enable_crypt+set}" = set; then :
+  enableval=$enable_crypt; build_crypt=$enableval
+else
+  build_crypt=yes
+fi
+
+
+
 # Check whether --enable-nss-crypt was given.
 if test "${enable_nss_crypt+set}" = set; then :
   enableval=$enable_nss_crypt; nss_crypt=$enableval
@@ -3512,6 +3525,11 @@ else
   nss_crypt=no
 fi
 
+if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&5
+$as_echo "$as_me: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&2;}
+  nss_crypt=no
+fi
 if test x$nss_crypt = xyes; then
   nss_includes=-I$(nss-config --includedir 2>/dev/null)
   if test $? -ne 0; then
diff --git a/configure.ac b/configure.ac
index ca1282a6b3..dc517017f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -302,11 +302,22 @@ AC_ARG_ENABLE([experimental-malloc],
 	      [experimental_malloc=yes])
 AC_SUBST(experimental_malloc)
 
+AC_ARG_ENABLE([crypt],
+              AC_HELP_STRING([--disable-crypt],
+                             [do not build nor install the passphrase hashing library, libcrypt]),
+              [build_crypt=$enableval],
+              [build_crypt=yes])
+AC_SUBST(build_crypt)
+
 AC_ARG_ENABLE([nss-crypt],
 	      AC_HELP_STRING([--enable-nss-crypt],
 			     [enable libcrypt to use nss]),
 	      [nss_crypt=$enableval],
 	      [nss_crypt=no])
+if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
+  AC_MSG_WARN([--enable-nss-crypt has no effect when libcrypt is disabled])
+  nss_crypt=no
+fi
 if test x$nss_crypt = xyes; then
   nss_includes=-I$(nss-config --includedir 2>/dev/null)
   if test $? -ne 0; then
diff --git a/conform/Makefile b/conform/Makefile
index 864fdeca21..74fbda0786 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -193,13 +193,11 @@ linknamespace-libs-thr = $(linknamespace-libs-isoc) \
 			 $(common-objpfx)rt/librt.a $(static-thread-library)
 linknamespace-libs-posix = $(linknamespace-libs-thr) \
 			   $(common-objpfx)dlfcn/libdl.a
-linknamespace-libs-xsi = $(linknamespace-libs-posix) \
-			 $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-xsi = $(linknamespace-libs-posix)
 linknamespace-libs-ISO = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)
-linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \
-			  $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 = $(linknamespace-libs-isoc)
 linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)
 linknamespace-libs-POSIX = $(linknamespace-libs-thr)
 linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi)
@@ -209,6 +207,11 @@ linknamespace-libs-XOPEN2K8 = $(linknamespace-libs-xsi)
 linknamespace-libs = $(foreach std,$(conformtest-standards),\
 				   $(linknamespace-libs-$(std)))
 
+ifeq ($(build-crypt),yes)
+linknamespace-libs-xsi += $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 += $(common-objpfx)crypt/libcrypt.a
+endif
+
 $(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \
 					$(linknamespace-libs)
 	LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \
diff --git a/crypt/Makefile b/crypt/Makefile
index 303800df73..3811b6e298 100644
--- a/crypt/Makefile
+++ b/crypt/Makefile
@@ -32,10 +32,6 @@ libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
 
 tests := cert md5c-test sha256c-test sha512c-test badsalttest
 
-ifeq ($(crypt-in-libc),yes)
-routines += $(libcrypt-routines)
-endif
-
 ifeq ($(nss-crypt),yes)
 nss-cpp-flags := -DUSE_NSS \
   -I$(shell nss-config --includedir) -I$(shell nspr-config --includedir)
diff --git a/elf/Makefile b/elf/Makefile
index 2dcd2b88e0..5b94f8d038 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -387,14 +387,21 @@ $(objpfx)tst-_dl_addr_inside_object: $(objpfx)dl-addr-obj.os
 CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag)
 endif
 
-# By default tst-linkall-static should try to use crypt routines to test
-# static libcrypt use.
+# We can only test static libcrypt use if libcrypt has been built,
+# and either NSS crypto is not in use, or static NSS libraries are
+# available.
+ifeq ($(build-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
+else
+ifeq ($(nss-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
+else
+ifeq ($(static-nss-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
+else
 CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
-# However, if we are using NSS crypto and we don't have a static
-# library, then we exclude the use of crypt functions in the test.
-# We similarly exclude libcrypt.a from the static link (see below).
-ifeq (yesno,$(nss-crypt)$(static-nss-crypt))
-CFLAGS-tst-linkall-static.c += -UUSE_CRYPT -DUSE_CRYPT=0
+endif
+endif
 endif
 
 include ../Rules
@@ -1115,7 +1122,6 @@ localplt-built-dso := $(addprefix $(common-objpfx),\
 				  rt/librt.so \
 				  dlfcn/libdl.so \
 				  resolv/libresolv.so \
-				  crypt/libcrypt.so \
 		       )
 ifeq ($(build-mathvec),yes)
 localplt-built-dso += $(addprefix $(common-objpfx), mathvec/libmvec.so)
@@ -1123,6 +1129,9 @@ endif
 ifeq ($(have-thread-library),yes)
 localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library))
 endif
+ifeq ($(build-crypt),yes)
+localplt-built-dso += $(addprefix $(common-objpfx), crypt/libcrypt.so)
+endif
 
 vpath localplt.data $(+sysdep_dirs)
 
@@ -1397,6 +1406,7 @@ $(objpfx)tst-linkall-static: \
   $(common-objpfx)resolv/libanl.a \
   $(static-thread-library)
 
+ifeq ($(build-crypt),yes)
 # If we are using NSS crypto and we have the ability to link statically
 # then we include libcrypt.a, otherwise we leave out libcrypt.a and
 # link as much as we can into the tst-linkall-static test.  This assumes
@@ -1412,6 +1422,7 @@ ifeq (no,$(nss-crypt))
 $(objpfx)tst-linkall-static: \
   $(common-objpfx)crypt/libcrypt.a
 endif
+endif
 
 # The application depends on the DSO, and the DSO loads the plugin.
 # The plugin also depends on the DSO. This creates the circular
diff --git a/elf/tst-linkall-static.c b/elf/tst-linkall-static.c
index e8df38f74e..d0f2592e67 100644
--- a/elf/tst-linkall-static.c
+++ b/elf/tst-linkall-static.c
@@ -18,7 +18,9 @@
 
 #include <math.h>
 #include <pthread.h>
-#include <crypt.h>
+#if USE_CRYPT
+# include <crypt.h>
+#endif
 #include <resolv.h>
 #include <dlfcn.h>
 #include <utmp.h>
diff --git a/manual/install.texi b/manual/install.texi
index 4bbbfcffa5..6e18f85b8b 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -230,6 +230,18 @@ libnss_nisplus are not built at all.
 Use this option to enable libnsl with all depending NSS modules and
 header files.
 
+@item --disable-crypt
+Do not install the passphrase-hashing library @file{libcrypt} or the
+header file @file{crypt.h}.  @file{unistd.h} will still declare the
+function @code{crypt}, as required by POSIX@.  Using this option does
+not change the set of programs that may need to be linked with
+@option{-lcrypt}; it only means that @theglibc{} will not provide that
+library.
+
+This option is for hackers and distributions experimenting with
+independently-maintained implementations of libcrypt.  It may become
+the default in a future release.
+
 @item --disable-experimental-malloc
 By default, a per-thread cache is enabled in @code{malloc}.  While
 this cache can be disabled on a per-application basis using tunables
-- 
2.17.0

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 1/4] Disallow use of DES encryption functions in new programs.
  2018-05-21 17:39 [PATCH 0/4 v3] libcrypt phaseout Zack Weinberg
  2018-05-21 17:39 ` [PATCH 4/4] New configure option --disable-crypt Zack Weinberg
  2018-05-21 17:39 ` [PATCH 3/4] Revise crypt.texi Zack Weinberg
@ 2018-05-21 17:39 ` Zack Weinberg
  2018-05-22  6:58   ` Florian Weimer
  2018-05-23  3:37   ` Rical Jasan
  2018-05-21 17:39 ` [PATCH 2/4] Reorganize crypt.texi Zack Weinberg
  3 siblings, 2 replies; 24+ messages in thread
From: Zack Weinberg @ 2018-05-21 17:39 UTC (permalink / raw)
  To: libc-alpha; +Cc: carlos, fweimer, rj, kukuk

The functions encrypt, setkey, encrypt_r, setkey_r, cbc_crypt,
ecb_crypt, and des_setparity should not be used in new programs,
because they use the DES block cipher, which is unacceptably weak by
modern standards.  Demote all of them to compatibility symbols, and
remove their prototypes from installed headers.  cbc_crypt, ecb_crypt,
and des_setparity were already compat symbols when glibc was
configured with --disable-obsolete-rpc.

This is running a little ahead of POSIX, where encrypt and setkey are
still part of the current standard, but I doubt anyone will mind.
See <http://austingroupbugs.net/view.php?id=1192> for the progress of
their removal from POSIX.

The entire "DES Encryption" section is dropped from the manual, as is
the mention of AUTH_DES and FIPS 140-2 in the introduction to
crypt.texi.  The documentation of 'memfrob' cross-referenced the DES
Encryption section, which is replaced by a hyperlink to libgcrypt, and
while I was in there I spruced up the actual documentation of
'memfrob' and 'strfry' a little.  It's still fairly jokey, because
those functions _are_ jokes, but they do also have real use cases, so
people trying to use them for real should have all the information
they need.

DES-based authentication for Sun RPC is also insecure and should be
deprecated or even removed, but maybe that can be left as TI-RPC's
problem.

        * posix/unistd.h: Do not declare encrypt.
        * stdlib/stdlib.h: Do not declare setkey.
	* crypt/crypt.h: Do not declare encrypt, setkey, encrypt_r, setkey_r.
        * sunrpc/Makefile: Do not install des_crypt.h nor rpc_des.h.

        * crypt/Versions: Add an empty stanza for GLIBC_2.28.
        * crypt/crypt-entry.c: Make fcrypt a compat symbol.
        * crypt/crypt_util.c: Make encrypt, encrypt_r, setkey, setkey_r
        into compat symbols.  Don't define initial_perm if it's not
        going to be used.
        * crypt/cert.c: Link explicitly with the expected versions for
        setkey and encrypt.  If they are not available at all, mark
        the test as unsupported.

        * sunrpc/des_crypt.c: Unconditionally block linkage with
        cbc_crypt and ecb_crypt for new binaries.
        * sunrpc/des_soft.c: Unconditionally block linkage with
        des_setparity for new binaries.

        * manual/crypt.texi: Remove the entire "DES Encryption"
        section.  Also remove the paragraph talking about FIPS 140-2
        from the introduction.
        * manual/string.texi (strfry, memfrob): Revise.  Recommend use
        of libgcrypt for "real" encryption, not DES.

        * conform/data/stdlib.h-data: Do not expect setkey.
        * conform/data/unistd.h-data: Do not expect encrypt.
---
 NEWS                       |  12 +++
 conform/data/stdlib.h-data |   3 -
 conform/data/unistd.h-data |   3 -
 crypt/Versions             |   3 +
 crypt/cert.c               |  29 ++++++
 crypt/crypt-entry.c        |  15 +--
 crypt/crypt.h              |  18 +---
 crypt/crypt_util.c         |   9 ++
 manual/crypt.texi          | 201 -------------------------------------
 manual/string.texi         |  82 +++++++--------
 posix/unistd.h             |   9 --
 stdlib/stdlib.h            |   6 --
 sunrpc/Makefile            |   2 +-
 sunrpc/des_crypt.c         |   7 +-
 sunrpc/des_soft.c          |   2 +-
 15 files changed, 105 insertions(+), 296 deletions(-)

diff --git a/NEWS b/NEWS
index bade9e4765..0bd21948f6 100644
--- a/NEWS
+++ b/NEWS
@@ -74,6 +74,18 @@ Deprecated and removed features, and other changes affecting compatibility:
   and could not usefully be used with the GNU C Library on systems with
   version 3.1 or later of the Linux kernel.
 
+* The obsolete functions 'encrypt', 'encrypt_r', 'setkey', 'setkey_r',
+  'cbc_crypt', 'ecb_crypt', and 'des_setparity' are no longer available to
+  newly linked binaries, and the headers <rpc/des_crypt.h> and
+  <rpc/rpc_des.h> are no longer installed.  These functions encrypted and
+  decrypted data with the DES block cipher, which is no longer considered
+  secure.  Software that still uses these functions should switch to a
+  modern cryptography library, such as libgcrypt.
+
+* The obsolete function 'fcrypt' is no longer available to newly linked
+  binaries.  It was just another name for the standard function 'crypt',
+  and it has not appeared in any header file in many years.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/conform/data/stdlib.h-data b/conform/data/stdlib.h-data
index d8fcccc2fb..6913828196 100644
--- a/conform/data/stdlib.h-data
+++ b/conform/data/stdlib.h-data
@@ -149,9 +149,6 @@ function {unsigned short int*} seed48 (unsigned short int[3])
 #if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX && !defined XPG4 && !defined XPG42 && !defined UNIX98
 function int setenv (const char*, const char*, int)
 #endif
-#if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX && !defined POSIX2008
-function void setkey (const char*)
-#endif
 #if !defined ISO && !defined ISO99 && !defined ISO11 && !defined XPG4 && !defined POSIX && !defined POSIX2008
 function {char*} setstate (char*)
 #endif
diff --git a/conform/data/unistd.h-data b/conform/data/unistd.h-data
index ddf4f25132..68a7cd973e 100644
--- a/conform/data/unistd.h-data
+++ b/conform/data/unistd.h-data
@@ -449,9 +449,6 @@ allow cuserid
 #endif
 function int dup (int)
 function int dup2 (int, int)
-#if !defined POSIX && !defined POSIX2008
-function void encrypt (char[64], int)
-#endif
 function int execl (const char*, const char*, ...)
 function int execle (const char*, const char*, ...)
 function int execlp (const char*, const char*, ...)
diff --git a/crypt/Versions b/crypt/Versions
index 389e7d544a..d3e9d30174 100644
--- a/crypt/Versions
+++ b/crypt/Versions
@@ -2,4 +2,7 @@ libcrypt {
   GLIBC_2.0 {
     crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
   }
+  GLIBC_2.28 {
+    # used in SHLIB_COMPAT directives
+  }
 }
diff --git a/crypt/cert.c b/crypt/cert.c
index 80029e9078..3bab49b1ea 100644
--- a/crypt/cert.c
+++ b/crypt/cert.c
@@ -10,6 +10,26 @@
 #include <stdlib.h>
 #include "crypt.h"
 
+/* This file tests the deprecated setkey/encrypt interface.  */
+#undef MODULE_NAME
+#define MODULE_NAME libcrypt
+#define SHARED
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
+
+#define libcrypt_version_reference(symbol, version) \
+  _libcrypt_version_reference (symbol, VERSION_libcrypt_##version)
+#define _libcrypt_version_reference(symbol, version) \
+  __libcrypt_version_reference (symbol, version)
+#define __libcrypt_version_reference(symbol, version) \
+  __asm__ (".symver " #symbol ", " #symbol "@" #version)
+
+extern void setkey (const char *);
+extern void encrypt (const char *, int);
+libcrypt_version_reference (setkey, GLIBC_2_0);
+libcrypt_version_reference (encrypt, GLIBC_2_0);
+
 int totfails = 0;
 
 int main (int argc, char *argv[]);
@@ -104,3 +124,12 @@ put8 (char *cp)
 	  printf("%02x", t);
 	}
 }
+
+#else /* encrypt and setkey are not available.  */
+
+int main(void)
+{
+  return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/crypt/crypt-entry.c b/crypt/crypt-entry.c
index 58691fb384..4e95f74878 100644
--- a/crypt/crypt-entry.c
+++ b/crypt/crypt-entry.c
@@ -35,6 +35,7 @@
 #endif
 
 #include "crypt-private.h"
+#include <shlib-compat.h>
 
 /* Prototypes for local functions.  */
 #ifndef __GNU_LIBRARY__
@@ -176,17 +177,7 @@ crypt (const char *key, const char *salt)
   return __crypt_r (key, salt, &_ufc_foobar);
 }
 
-
-/*
- * To make fcrypt users happy.
- * They don't need to call init_des.
- */
-#ifdef _LIBC
+#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
 weak_alias (crypt, fcrypt)
-#else
-char *
-__fcrypt (const char *key, const char *salt)
-{
-  return crypt (key, salt);
-}
+compat_symbol (libcrypt, fcrypt, fcrypt, GLIBC_2_0);
 #endif
diff --git a/crypt/crypt.h b/crypt/crypt.h
index 5da098b715..3cb18de14d 100644
--- a/crypt/crypt.h
+++ b/crypt/crypt.h
@@ -32,16 +32,8 @@ __BEGIN_DECLS
 extern char *crypt (const char *__key, const char *__salt)
      __THROW __nonnull ((1, 2));
 
-/* Setup DES tables according KEY.  */
-extern void setkey (const char *__key) __THROW __nonnull ((1));
-
-/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
-   block in place.  */
-extern void encrypt (char *__glibc_block, int __edflag)
-     __THROW __nonnull ((1));
-
 #ifdef __USE_GNU
-/* Reentrant versions of the functions above.  The additional argument
+/* Reentrant version of 'crypt'.  The additional argument
    points to a structure where the results are placed in.  */
 struct crypt_data
   {
@@ -60,14 +52,6 @@ struct crypt_data
 extern char *crypt_r (const char *__key, const char *__salt,
 		      struct crypt_data * __restrict __data)
      __THROW __nonnull ((1, 2, 3));
-
-extern void setkey_r (const char *__key,
-		      struct crypt_data * __restrict __data)
-     __THROW __nonnull ((1, 2));
-
-extern void encrypt_r (char *__glibc_block, int __edflag,
-		       struct crypt_data * __restrict __data)
-     __THROW __nonnull ((1, 3));
 #endif
 
 __END_DECLS
diff --git a/crypt/crypt_util.c b/crypt/crypt_util.c
index 4958918770..fbfc783751 100644
--- a/crypt/crypt_util.c
+++ b/crypt/crypt_util.c
@@ -34,6 +34,7 @@
 #endif
 
 #include "crypt-private.h"
+#include <shlib-compat.h>
 
 /* Prototypes for local functions.  */
 #ifndef __GNU_LIBRARY__
@@ -150,6 +151,7 @@ static const int sbox[8][4][16]= {
 	}
 };
 
+#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
 /*
  * This is the initial
  * permutation matrix
@@ -160,6 +162,7 @@ static const int initial_perm[64] = {
   57, 49, 41, 33, 25, 17,  9,  1, 59, 51, 43, 35, 27, 19, 11, 3,
   61, 53, 45, 37, 29, 21, 13,  5, 63, 55, 47, 39, 31, 23, 15, 7
 };
+#endif
 
 /*
  * This is the final
@@ -785,6 +788,7 @@ _ufc_output_conversion_r (ufc_long v1, ufc_long v2, const char *salt,
   __data->crypt_3_buf[13] = 0;
 }
 
+#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
 
 /*
  * UNIX encrypt function. Takes a bitvector
@@ -885,12 +889,14 @@ __encrypt_r (char *__block, int __edflag,
   }
 }
 weak_alias (__encrypt_r, encrypt_r)
+compat_symbol (libcrypt, encrypt_r, encrypt_r, GLIBC_2_0);
 
 void
 encrypt (char *__block, int __edflag)
 {
   __encrypt_r(__block, __edflag, &_ufc_foobar);
 }
+compat_symbol (libcrypt, encrypt, encrypt, GLIBC_2_0);
 
 
 /*
@@ -915,12 +921,15 @@ __setkey_r (const char *__key, struct crypt_data * __restrict __data)
   _ufc_mk_keytab_r((char *) ktab, __data);
 }
 weak_alias (__setkey_r, setkey_r)
+compat_symbol (libcrypt, setkey_r, setkey_r, GLIBC_2_0);
 
 void
 setkey (const char *__key)
 {
   __setkey_r(__key, &_ufc_foobar);
 }
+compat_symbol (libcrypt, setkey, setkey, GLIBC_2_0);
+#endif /* SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28) */
 
 void
 __b64_from_24bit (char **cp, int *buflen,
diff --git a/manual/crypt.texi b/manual/crypt.texi
index 99d2d8e092..6bbe2bfdc5 100644
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -30,21 +30,10 @@ message-digest algorithm that is compatible with modern BSD systems,
 and the other based on the Data Encryption Standard (DES) that is
 compatible with Unix systems.
 
-@vindex AUTH_DES
-@cindex FIPS 140-2
-It also provides support for Secure RPC, and some library functions that
-can be used to perform normal DES encryption.  The @code{AUTH_DES}
-authentication flavor in Secure RPC, as provided by @theglibc{},
-uses DES and does not comply with FIPS 140-2 nor does any other use of DES
-within @theglibc{}.  It is recommended that Secure RPC should not be used
-for systems that need to comply with FIPS 140-2 since all flavors of
-encrypted authentication use normal DES.
-
 @menu
 * Legal Problems::              This software can get you locked up, or worse.
 * getpass::                     Prompting the user for a password.
 * crypt::                       A one-way function for passwords.
-* DES Encryption::              Routines for DES encryption.
 * Unpredictable Bytes::         Randomness for cryptography purposes.
 @end menu
 
@@ -223,196 +212,6 @@ The @code{crypt_r} function is a GNU extension.
 The @code{crypt} and @code{crypt_r} functions are prototyped in the
 header @file{crypt.h}.
 
-@node DES Encryption
-@section DES Encryption
-
-@cindex FIPS 46-3
-The Data Encryption Standard is described in the US Government Federal
-Information Processing Standards (FIPS) 46-3 published by the National
-Institute of Standards and Technology.  The DES has been very thoroughly
-analyzed since it was developed in the late 1970s, and no new
-significant flaws have been found.
-
-However, the DES uses only a 56-bit key (plus 8 parity bits), and a
-machine has been built in 1998 which can search through all possible
-keys in about 6 days, which cost about US$200000; faster searches would
-be possible with more money.  This makes simple DES insecure for most
-purposes, and NIST no longer permits new US government systems
-to use simple DES.
-
-For serious encryption functionality, it is recommended that one of the
-many free encryption libraries be used instead of these routines.
-
-The DES is a reversible operation which takes a 64-bit block and a
-64-bit key, and produces another 64-bit block.  Usually the bits are
-numbered so that the most-significant bit, the first bit, of each block
-is numbered 1.
-
-Under that numbering, every 8th bit of the key (the 8th, 16th, and so
-on) is not used by the encryption algorithm itself.  But the key must
-have odd parity; that is, out of bits 1 through 8, and 9 through 16, and
-so on, there must be an odd number of `1' bits, and this completely
-specifies the unused bits.
-
-@deftypefun void setkey (const char *@var{key})
-@standards{BSD, crypt.h}
-@standards{SVID, crypt.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
-@c The static buffer stores the key, making it fundamentally
-@c thread-unsafe.  The locking issues are only in the initialization
-@c path; cancelling the initialization will leave the lock held, it
-@c would otherwise repeat the initialization on the next call.
-
-The @code{setkey} function sets an internal data structure to be an
-expanded form of @var{key}.  @var{key} is specified as an array of 64
-bits each stored in a @code{char}, the first bit is @code{key[0]} and
-the 64th bit is @code{key[63]}.  The @var{key} should have the correct
-parity.
-@end deftypefun
-
-@deftypefun void encrypt (char *@var{block}, int @var{edflag})
-@standards{BSD, crypt.h}
-@standards{SVID, crypt.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
-@c Same issues as setkey.
-
-The @code{encrypt} function encrypts @var{block} if
-@var{edflag} is 0, otherwise it decrypts @var{block}, using a key
-previously set by @code{setkey}.  The result is
-placed in @var{block}.
-
-Like @code{setkey}, @var{block} is specified as an array of 64 bits each
-stored in a @code{char}, but there are no parity bits in @var{block}.
-@end deftypefun
-
-@deftypefun void setkey_r (const char *@var{key}, {struct crypt_data *} @var{data})
-@deftypefunx void encrypt_r (char *@var{block}, int @var{edflag}, {struct crypt_data *} @var{data})
-@standards{GNU, crypt.h}
-@c setkey_r: @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
-@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
-
-These are reentrant versions of @code{setkey} and @code{encrypt}.  The
-only difference is the extra parameter, which stores the expanded
-version of @var{key}.  Before calling @code{setkey_r} the first time,
-@code{data->initialized} must be cleared to zero.
-@end deftypefun
-
-The @code{setkey_r} and @code{encrypt_r} functions are GNU extensions.
-@code{setkey}, @code{encrypt}, @code{setkey_r}, and @code{encrypt_r} are
-defined in @file{crypt.h}.
-
-@deftypefun int ecb_crypt (char *@var{key}, char *@var{blocks}, unsigned int @var{len}, unsigned int @var{mode})
-@standards{SUNRPC, rpc/des_crypt.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-The function @code{ecb_crypt} encrypts or decrypts one or more blocks
-using DES.  Each block is encrypted independently.
-
-The @var{blocks} and the @var{key} are stored packed in 8-bit bytes, so
-that the first bit of the key is the most-significant bit of
-@code{key[0]} and the 63rd bit of the key is stored as the
-least-significant bit of @code{key[7]}.  The @var{key} should have the
-correct parity.
-
-@var{len} is the number of bytes in @var{blocks}.  It should be a
-multiple of 8 (so that there are a whole number of blocks to encrypt).
-@var{len} is limited to a maximum of @code{DES_MAXDATA} bytes.
-
-The result of the encryption replaces the input in @var{blocks}.
-
-The @var{mode} parameter is the bitwise OR of two of the following:
-
-@vtable @code
-@item DES_ENCRYPT
-@standards{SUNRPC, rpc/des_crypt.h}
-This constant, used in the @var{mode} parameter, specifies that
-@var{blocks} is to be encrypted.
-
-@item DES_DECRYPT
-@standards{SUNRPC, rpc/des_crypt.h}
-This constant, used in the @var{mode} parameter, specifies that
-@var{blocks} is to be decrypted.
-
-@item DES_HW
-@standards{SUNRPC, rpc/des_crypt.h}
-This constant, used in the @var{mode} parameter, asks to use a hardware
-device.  If no hardware device is available, encryption happens anyway,
-but in software.
-
-@item DES_SW
-@standards{SUNRPC, rpc/des_crypt.h}
-This constant, used in the @var{mode} parameter, specifies that no
-hardware device is to be used.
-@end vtable
-
-The result of the function will be one of these values:
-
-@vtable @code
-@item DESERR_NONE
-@standards{SUNRPC, rpc/des_crypt.h}
-The encryption succeeded.
-
-@item DESERR_NOHWDEVICE
-@standards{SUNRPC, rpc/des_crypt.h}
-The encryption succeeded, but there was no hardware device available.
-
-@item DESERR_HWERROR
-@standards{SUNRPC, rpc/des_crypt.h}
-The encryption failed because of a hardware problem.
-
-@item DESERR_BADPARAM
-@standards{SUNRPC, rpc/des_crypt.h}
-The encryption failed because of a bad parameter, for instance @var{len}
-is not a multiple of 8 or @var{len} is larger than @code{DES_MAXDATA}.
-@end vtable
-@end deftypefun
-
-@deftypefun int DES_FAILED (int @var{err})
-@standards{SUNRPC, rpc/des_crypt.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-This macro returns 1 if @var{err} is a `success' result code from
-@code{ecb_crypt} or @code{cbc_crypt}, and 0 otherwise.
-@end deftypefun
-
-@deftypefun int cbc_crypt (char *@var{key}, char *@var{blocks}, unsigned int @var{len}, unsigned int @var{mode}, char *@var{ivec})
-@standards{SUNRPC, rpc/des_crypt.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-The function @code{cbc_crypt} encrypts or decrypts one or more blocks
-using DES in Cipher Block Chaining mode.
-
-For encryption in CBC mode, each block is exclusive-ored with @var{ivec}
-before being encrypted, then @var{ivec} is replaced with the result of
-the encryption, then the next block is processed.  Decryption is the
-reverse of this process.
-
-This has the advantage that blocks which are the same before being
-encrypted are very unlikely to be the same after being encrypted, making
-it much harder to detect patterns in the data.
-
-Usually, @var{ivec} is set to 8 random bytes before encryption starts.
-Then the 8 random bytes are transmitted along with the encrypted data
-(without themselves being encrypted), and passed back in as @var{ivec}
-for decryption.  Another possibility is to set @var{ivec} to 8 zeroes
-initially, and have the first block encrypted consist of 8 random
-bytes.
-
-Otherwise, all the parameters are similar to those for @code{ecb_crypt}.
-@end deftypefun
-
-@deftypefun void des_setparity (char *@var{key})
-@standards{SUNRPC, rpc/des_crypt.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-The function @code{des_setparity} changes the 64-bit @var{key}, stored
-packed in 8-bit bytes, to have odd parity by altering the low bits of
-each byte.
-@end deftypefun
-
-The @code{ecb_crypt}, @code{cbc_crypt}, and @code{des_setparity}
-functions and their accompanying macros are all defined in the header
-@file{rpc/des_crypt.h}.
-
 @node Unpredictable Bytes
 @section Generating Unpredictable Bytes
 
diff --git a/manual/string.texi b/manual/string.texi
index b07cfb4550..a1c58e58fa 100644
--- a/manual/string.texi
+++ b/manual/string.texi
@@ -36,8 +36,8 @@ too.
 				 for delimiters.
 * Erasing Sensitive Data::      Clearing memory which contains sensitive
                                  data, after it's no longer needed.
-* strfry::                      Function for flash-cooking a string.
-* Trivial Encryption::          Obscuring data.
+* Shuffling Bytes::             Or how to flash-cook a string.
+* Obfuscating Data::            Reversibly obscuring data from casual view.
 * Encode Binary Data::          Encoding and Decoding of Binary Data.
 * Argz and Envz Vectors::       Null-separated string vectors.
 @end menu
@@ -2426,73 +2426,73 @@ functionality under a different name, such as @code{explicit_memset},
 systems it may be in @file{strings.h} instead.
 @end deftypefun
 
-@node strfry
-@section strfry
+
+@node Shuffling Bytes
+@section Shuffling Bytes
 
 The function below addresses the perennial programming quandary: ``How do
 I take good data in string form and painlessly turn it into garbage?''
-This is actually a fairly simple task for C programmers who do not use
-@theglibc{} string functions, but for programs based on @theglibc{},
-the @code{strfry} function is the preferred method for
-destroying string data.
+This is not a difficult thing to code for oneself, but the authors of
+@theglibc{} wish to make it as convenient as possible.
 
-The prototype for this function is in @file{string.h}.
+To @emph{erase} data, use @code{explicit_bzero} (@pxref{Erasing
+Sensitive Data}); to obfuscate it reversibly, use @code{memfrob}
+(@pxref{Obfuscating Data}).
 
 @deftypefun {char *} strfry (char *@var{string})
 @standards{GNU, string.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 @c Calls initstate_r, time, getpid, strlen, and random_r.
 
-@code{strfry} creates a pseudorandom anagram of a string, replacing the
-input with the anagram in place.  For each position in the string,
-@code{strfry} swaps it with a position in the string selected at random
-(from a uniform distribution).  The two positions may be the same.
+@code{strfry} performs an in-place shuffle on @var{string}.  Each
+character is swapped to a position selected at random, within the
+portion of the string starting with the character's original position.
+(This is the Fisher-Yates algorithm for unbiased shuffling.)
+
+Calling @code{strfry} will not disturb any of the random number
+generators that have global state (@pxref{Pseudo-Random Numbers}).
 
 The return value of @code{strfry} is always @var{string}.
 
 @strong{Portability Note:}  This function is unique to @theglibc{}.
-
+It is declared in @file{string.h}.
 @end deftypefun
 
 
-@node Trivial Encryption
-@section Trivial Encryption
-@cindex encryption
-
-
-The @code{memfrob} function converts an array of data to something
-unrecognizable and back again.  It is not encryption in its usual sense
-since it is easy for someone to convert the encrypted data back to clear
-text.  The transformation is analogous to Usenet's ``Rot13'' encryption
-method for obscuring offensive jokes from sensitive eyes and such.
-Unlike Rot13, @code{memfrob} works on arbitrary binary data, not just
-text.
+@node Obfuscating Data
+@section Obfuscating Data
 @cindex Rot13
 
-For true encryption, @xref{Cryptographic Functions}.
+The @code{memfrob} function reversibly obfuscates an array of binary
+data.  This is not true encryption; the obfuscated data still bears a
+clear relationship to the original, and no secret key is required to
+undo the obfuscation.  It is analogous to the ``Rot13'' cipher used on
+Usenet for obscuring offensive jokes, spoilers for works of fiction,
+and so on, but it can be applied to arbitrary binary data.
 
-This function is declared in @file{string.h}.
-@pindex string.h
+Programs that need true encryption---a transformation that completely
+obscures the original and cannot be reversed without knowledge of a
+secret key---should use a dedicated cryptography library, such as
+@uref{https://www.gnu.org/software/libgcrypt/,,libgcrypt}.
+
+Programs that need to @emph{destroy} data should use
+@code{explicit_bzero} (@pxref{Erasing Sensitive Data}), or possibly
+@code{strfry} (@pxref{Shuffling Bytes}).
 
 @deftypefun {void *} memfrob (void *@var{mem}, size_t @var{length})
 @standards{GNU, string.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
-@code{memfrob} transforms (frobnicates) each byte of the data structure
-at @var{mem}, which is @var{length} bytes long, by bitwise exclusive
-oring it with binary 00101010.  It does the transformation in place and
-its return value is always @var{mem}.
+The function @code{memfrob} obfuscates @var{length} bytes of data
+beginning at @var{mem}, in place.  Each byte is bitwise xor-ed with
+the binary pattern 00101010 (hexadecimal 0x2A).  The return value is
+always @var{mem}.
 
-Note that @code{memfrob} a second time on the same data structure
-returns it to its original state.
-
-This is a good function for hiding information from someone who doesn't
-want to see it or doesn't want to see it very much.  To really prevent
-people from retrieving the information, use stronger encryption such as
-that described in @xref{Cryptographic Functions}.
+@code{memfrob} a second time on the same data returns it to
+its original state.
 
 @strong{Portability Note:}  This function is unique to @theglibc{}.
-
+It is declared in @file{string.h}.
 @end deftypefun
 
 @node Encode Binary Data
diff --git a/posix/unistd.h b/posix/unistd.h
index 4d149f9945..5c3da702b6 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -1118,20 +1118,11 @@ ssize_t copy_file_range (int __infd, __off64_t *__pinoff,
 extern int fdatasync (int __fildes);
 #endif /* Use POSIX199309 */
 
-
-/* XPG4.2 specifies that prototypes for the encryption functions must
-   be defined here.  */
 #ifdef	__USE_XOPEN
 /* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
 extern char *crypt (const char *__key, const char *__salt)
      __THROW __nonnull ((1, 2));
 
-/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
-   block in place.  */
-extern void encrypt (char *__glibc_block, int __edflag)
-     __THROW __nonnull ((1));
-
-
 /* Swab pairs bytes in the first N bytes of the area pointed to by
    FROM and copy the result to TO.  The value of TO must not be in the
    range [FROM - N + 1, FROM - 1].  If N is odd the first byte in FROM
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 6b1ead31e0..8e23e93557 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -958,12 +958,6 @@ extern int getsubopt (char **__restrict __optionp,
 #endif
 
 
-#ifdef __USE_XOPEN
-/* Setup DES tables according KEY.  */
-extern void setkey (const char *__key) __THROW __nonnull ((1));
-#endif
-
-
 /* X/Open pseudo terminal handling.  */
 
 #ifdef __USE_XOPEN2KXSI
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index 8f2a3c8213..ab2e0daaea 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -51,7 +51,7 @@ rpcsvc = bootparam_prot.x nlm_prot.x rstat.x \
 headers-sunrpc = $(addprefix rpc/,auth.h auth_unix.h clnt.h pmap_clnt.h \
 				  pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h \
 				  svc.h svc_auth.h types.h xdr.h auth_des.h \
-				  des_crypt.h key_prot.h rpc_des.h) \
+				  key_prot.h) \
 		       $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h
 headers = rpc/netdb.h
 install-others = $(inst_sysconfdir)/rpc
diff --git a/sunrpc/des_crypt.c b/sunrpc/des_crypt.c
index a4d8b2936b..9b4bd2d5dd 100644
--- a/sunrpc/des_crypt.c
+++ b/sunrpc/des_crypt.c
@@ -86,6 +86,9 @@ common_crypt (char *key, char *buf, register unsigned len,
   return desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE;
 }
 
+/* Note: these cannot be excluded from the build yet, because they are
+   still used internally.  */
+
 /*
  * CBC mode encryption
  */
@@ -102,7 +105,7 @@ cbc_crypt (char *key, char *buf, unsigned int len, unsigned int mode,
   COPY8 (dp.des_ivec, ivec);
   return err;
 }
-libc_hidden_nolink_sunrpc (cbc_crypt, GLIBC_2_1)
+hidden_nolink (cbc_crypt, libc, GLIBC_2_1)
 
 /*
  * ECB mode encryption
@@ -115,4 +118,4 @@ ecb_crypt (char *key, char *buf, unsigned int len, unsigned int mode)
   dp.des_mode = ECB;
   return common_crypt (key, buf, len, mode, &dp);
 }
-libc_hidden_nolink_sunrpc (ecb_crypt, GLIBC_2_1)
+hidden_nolink (ecb_crypt, libc, GLIBC_2_1)
diff --git a/sunrpc/des_soft.c b/sunrpc/des_soft.c
index f884f8f21b..a87de96cc7 100644
--- a/sunrpc/des_soft.c
+++ b/sunrpc/des_soft.c
@@ -71,4 +71,4 @@ des_setparity (char *p)
       p++;
     }
 }
-libc_hidden_nolink_sunrpc (des_setparity, GLIBC_2_1)
+hidden_nolink (des_setparity, libc, GLIBC_2_1)
-- 
2.17.0

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 2/4] Reorganize crypt.texi.
  2018-05-21 17:39 [PATCH 0/4 v3] libcrypt phaseout Zack Weinberg
                   ` (2 preceding siblings ...)
  2018-05-21 17:39 ` [PATCH 1/4] Disallow use of DES encryption functions in new programs Zack Weinberg
@ 2018-05-21 17:39 ` Zack Weinberg
  2018-05-23  5:23   ` Rical Jasan
  3 siblings, 1 reply; 24+ messages in thread
From: Zack Weinberg @ 2018-05-21 17:39 UTC (permalink / raw)
  To: libc-alpha; +Cc: carlos, fweimer, rj, kukuk

In preparation for a major revision of the documentation for
crypt(_r), getentropy, and getrandom, reorganize crypt.texi.  This
patch does not change any text; it only deletes and moves text.

The description of 'getpass' moves to terminal.texi, since all it does
is read a password from the controlling terminal with echo disabled.
The "Legal Problems" section of crypt.texi is dropped, and the
introductory text is shifted down to the "Encrypting Passwords"
section; the next patch will add some new introductory text.

Also, it is no longer true that crypt.texi's top @node needs to have
no pointers.  That was a vestige of crypt/ being an add-on.  (makeinfo
itself doesn't need @node pointers anymore, but the scripts that
assemble the libc manual's topmost node rely on each chapter-level
node having them.)

	* manual/crypt.texi: Use a normal top-level @node declaration.
        Move most of the introductory text to the 'crypt' section.
        Move the example programs below the @deftypefun for 'crypt_r'.
        Move the 'getpass' section...
        * manual/terminal.texi: ...here.
---
 manual/crypt.texi    | 147 +++++++++----------------------------------
 manual/terminal.texi |  45 +++++++++++++
 2 files changed, 73 insertions(+), 119 deletions(-)

diff --git a/manual/crypt.texi b/manual/crypt.texi
index 6bbe2bfdc5..0f04ee9899 100644
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -1,8 +1,14 @@
-@c This node must have no pointers.
-@node Cryptographic Functions
-@c @node Cryptographic Functions, Debugging Support, System Configuration, Top
-@chapter DES Encryption and Password Handling
-@c %MENU% DES encryption and password handling
+@node Cryptographic Functions, Debugging Support, System Configuration, Top
+@chapter Cryptographic Functions
+@c %MENU% Password storage and strongly unpredictable bytes
+
+@menu
+* crypt::                       A one-way function for passwords.
+* Unpredictable Bytes::         Randomness for cryptography purposes.
+@end menu
+
+@node crypt
+@section Encrypting Passwords
 
 On many systems, it is unnecessary to have any kind of user
 authentication; for instance, a workstation which is not connected to a
@@ -30,103 +36,6 @@ message-digest algorithm that is compatible with modern BSD systems,
 and the other based on the Data Encryption Standard (DES) that is
 compatible with Unix systems.
 
-@menu
-* Legal Problems::              This software can get you locked up, or worse.
-* getpass::                     Prompting the user for a password.
-* crypt::                       A one-way function for passwords.
-* Unpredictable Bytes::         Randomness for cryptography purposes.
-@end menu
-
-@node Legal Problems
-@section Legal Problems
-
-Because of the continuously changing state of the law, it's not possible
-to provide a definitive survey of the laws affecting cryptography.
-Instead, this section warns you of some of the known trouble spots; this
-may help you when you try to find out what the laws of your country are.
-
-Some countries require that you have a license to use, possess, or import
-cryptography.  These countries are believed to include Byelorussia,
-Burma, India, Indonesia, Israel, Kazakhstan, Pakistan, Russia, and Saudi
-Arabia.
-
-Some countries restrict the transmission of encrypted messages by radio;
-some telecommunications carriers restrict the transmission of encrypted
-messages over their network.
-
-Many countries have some form of export control for encryption software.
-The Wassenaar Arrangement is a multilateral agreement between 33
-countries (Argentina, Australia, Austria, Belgium, Bulgaria, Canada, the
-Czech Republic, Denmark, Finland, France, Germany, Greece, Hungary,
-Ireland, Italy, Japan, Luxembourg, the Netherlands, New Zealand, Norway,
-Poland, Portugal, the Republic of Korea, Romania, the Russian
-Federation, the Slovak Republic, Spain, Sweden, Switzerland, Turkey,
-Ukraine, the United Kingdom and the United States) which restricts some
-kinds of encryption exports.  Different countries apply the arrangement
-in different ways; some do not allow the exception for certain kinds of
-``public domain'' software (which would include this library), some
-only restrict the export of software in tangible form, and others impose
-significant additional restrictions.
-
-The United States has additional rules.  This software would generally
-be exportable under 15 CFR 740.13(e), which permits exports of
-``encryption source code'' which is ``publicly available'' and which is
-``not subject to an express agreement for the payment of a licensing fee or
-royalty for commercial production or sale of any product developed with
-the source code'' to most countries.
-
-The rules in this area are continuously changing.  If you know of any
-information in this manual that is out-of-date, please report it to
-the bug database.  @xref{Reporting Bugs}.
-
-@node getpass
-@section Reading Passwords
-
-When reading in a password, it is desirable to avoid displaying it on
-the screen, to help keep it secret.  The following function handles this
-in a convenient way.
-
-@deftypefun {char *} getpass (const char *@var{prompt})
-@standards{BSD, unistd.h}
-@safety{@prelim{}@mtunsafe{@mtasuterm{}}@asunsafe{@ascuheap{} @asulock{} @asucorrupt{}}@acunsafe{@acuterm{} @aculock{} @acucorrupt{}}}
-@c This function will attempt to create a stream for terminal I/O, but
-@c will fallback to stdio/stderr.  It attempts to change the terminal
-@c mode in a thread-unsafe way, write out the prompt, read the password,
-@c then restore the terminal mode.  It has a cleanup to close the stream
-@c in case of (synchronous) cancellation, but not to restore the
-@c terminal mode.
-
-@code{getpass} outputs @var{prompt}, then reads a string in from the
-terminal without echoing it.  It tries to connect to the real terminal,
-@file{/dev/tty}, if possible, to encourage users not to put plaintext
-passwords in files; otherwise, it uses @code{stdin} and @code{stderr}.
-@code{getpass} also disables the INTR, QUIT, and SUSP characters on the
-terminal using the @code{ISIG} terminal attribute (@pxref{Local Modes}).
-The terminal is flushed before and after @code{getpass}, so that
-characters of a mistyped password are not accidentally visible.
-
-In other C libraries, @code{getpass} may only return the first
-@code{PASS_MAX} bytes of a password.  @Theglibc{} has no limit, so
-@code{PASS_MAX} is undefined.
-
-The prototype for this function is in @file{unistd.h}.  @code{PASS_MAX}
-would be defined in @file{limits.h}.
-@end deftypefun
-
-This precise set of operations may not suit all possible situations.  In
-this case, it is recommended that users write their own @code{getpass}
-substitute.  For instance, a very simple substitute is as follows:
-
-@smallexample
-@include mygetpass.c.texi
-@end smallexample
-
-The substitute takes the same parameters as @code{getline}
-(@pxref{Line Input}); the user must print any prompt desired.
-
-@node crypt
-@section Encrypting Passwords
-
 @deftypefun {char *} crypt (const char *@var{key}, const char *@var{salt})
 @standards{BSD, crypt.h}
 @standards{SVID, crypt.h}
@@ -177,6 +86,23 @@ password against the result of a previous call to @code{crypt}, pass
 the result of the previous call as the @var{salt}.
 @end deftypefun
 
+@deftypefun {char *} crypt_r (const char *@var{key}, const char *@var{salt}, {struct crypt_data *} @var{data})
+@standards{GNU, crypt.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
+@c Compared with crypt, this function fixes the @mtasurace:crypt
+@c problem, but nothing else.
+
+The @code{crypt_r} function does the same thing as @code{crypt}, but
+takes an extra parameter which includes space for its result (among
+other things), so it can be reentrant.  @code{data@w{->}initialized} must be
+cleared to zero before the first time @code{crypt_r} is called.
+
+The @code{crypt_r} function is a GNU extension.
+@end deftypefun
+
+The @code{crypt} and @code{crypt_r} functions are prototyped in the
+header @file{crypt.h}.
+
 The following short program is an example of how to use @code{crypt} the
 first time a password is entered.  Note that the @var{salt} generation
 is just barely acceptable; in particular, it is not unique between
@@ -195,23 +121,6 @@ for a password and prints ``Access granted.'' if the user types
 @include testpass.c.texi
 @end smallexample
 
-@deftypefun {char *} crypt_r (const char *@var{key}, const char *@var{salt}, {struct crypt_data *} @var{data})
-@standards{GNU, crypt.h}
-@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
-@c Compared with crypt, this function fixes the @mtasurace:crypt
-@c problem, but nothing else.
-
-The @code{crypt_r} function does the same thing as @code{crypt}, but
-takes an extra parameter which includes space for its result (among
-other things), so it can be reentrant.  @code{data@w{->}initialized} must be
-cleared to zero before the first time @code{crypt_r} is called.
-
-The @code{crypt_r} function is a GNU extension.
-@end deftypefun
-
-The @code{crypt} and @code{crypt_r} functions are prototyped in the
-header @file{crypt.h}.
-
 @node Unpredictable Bytes
 @section Generating Unpredictable Bytes
 
diff --git a/manual/terminal.texi b/manual/terminal.texi
index 4aace48b14..0b275fc002 100644
--- a/manual/terminal.texi
+++ b/manual/terminal.texi
@@ -24,6 +24,7 @@ descriptor is and how to open a file descriptor for a terminal device.
 * Line Control::                Sending break sequences, clearing
                                  terminal buffers @dots{}
 * Noncanon Example::            How to read single characters without echo.
+* getpass::                     Prompting the user for a password.
 * Pseudo-Terminals::            How to open a pseudo-terminal.
 @end menu
 
@@ -1871,6 +1872,50 @@ existing shells do not actually do this, so you may wish to establish
 handlers for job control signals that reset terminal modes.  The above
 example does so.
 
+@node getpass
+@section Reading Passwords
+
+When reading in a password, it is desirable to avoid displaying it on
+the screen, to help keep it secret.  The following function handles this
+in a convenient way.
+
+@deftypefun {char *} getpass (const char *@var{prompt})
+@standards{BSD, unistd.h}
+@safety{@prelim{}@mtunsafe{@mtasuterm{}}@asunsafe{@ascuheap{} @asulock{} @asucorrupt{}}@acunsafe{@acuterm{} @aculock{} @acucorrupt{}}}
+@c This function will attempt to create a stream for terminal I/O, but
+@c will fallback to stdio/stderr.  It attempts to change the terminal
+@c mode in a thread-unsafe way, write out the prompt, read the password,
+@c then restore the terminal mode.  It has a cleanup to close the stream
+@c in case of (synchronous) cancellation, but not to restore the
+@c terminal mode.
+
+@code{getpass} outputs @var{prompt}, then reads a string in from the
+terminal without echoing it.  It tries to connect to the real terminal,
+@file{/dev/tty}, if possible, to encourage users not to put plaintext
+passwords in files; otherwise, it uses @code{stdin} and @code{stderr}.
+@code{getpass} also disables the INTR, QUIT, and SUSP characters on the
+terminal using the @code{ISIG} terminal attribute (@pxref{Local Modes}).
+The terminal is flushed before and after @code{getpass}, so that
+characters of a mistyped password are not accidentally visible.
+
+In other C libraries, @code{getpass} may only return the first
+@code{PASS_MAX} bytes of a password.  @Theglibc{} has no limit, so
+@code{PASS_MAX} is undefined.
+
+The prototype for this function is in @file{unistd.h}.  @code{PASS_MAX}
+would be defined in @file{limits.h}.
+@end deftypefun
+
+This precise set of operations may not suit all possible situations.  In
+this case, it is recommended that users write their own @code{getpass}
+substitute.  For instance, a very simple substitute is as follows:
+
+@smallexample
+@include mygetpass.c.texi
+@end smallexample
+
+The substitute takes the same parameters as @code{getline}
+(@pxref{Line Input}); the user must print any prompt desired.
 
 @node Pseudo-Terminals
 @section Pseudo-Terminals
-- 
2.17.0

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-05-21 17:39 ` [PATCH 4/4] New configure option --disable-crypt Zack Weinberg
@ 2018-05-21 19:52   ` Joseph Myers
  2018-05-21 22:07     ` Zack Weinberg
  0 siblings, 1 reply; 24+ messages in thread
From: Joseph Myers @ 2018-05-21 19:52 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: libc-alpha, carlos, fweimer, rj, kukuk

On Mon, 21 May 2018, Zack Weinberg wrote:

> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.

I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt 
and setkey.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-05-21 19:52   ` Joseph Myers
@ 2018-05-21 22:07     ` Zack Weinberg
  2018-05-21 22:34       ` Joseph Myers
  0 siblings, 1 reply; 24+ messages in thread
From: Zack Weinberg @ 2018-05-21 22:07 UTC (permalink / raw)
  To: Joseph Myers
  Cc: GNU C Library, Carlos O'Donell, Florian Weimer, Rical Jasan,
	Thorsten Kukuk

On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Mon, 21 May 2018, Zack Weinberg wrote:
>
>> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
>
> I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
> and setkey.

No, this is an intentional deviation from the present state of POSIX,
anticipating the removal of those functions from the standard.

zw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-05-21 22:07     ` Zack Weinberg
@ 2018-05-21 22:34       ` Joseph Myers
  2018-05-22  1:08         ` Zack Weinberg
  2018-06-20 20:40         ` Florian Weimer
  0 siblings, 2 replies; 24+ messages in thread
From: Joseph Myers @ 2018-05-21 22:34 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: GNU C Library, Carlos O'Donell, Florian Weimer, Rical Jasan,
	Thorsten Kukuk

On Mon, 21 May 2018, Zack Weinberg wrote:

> On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> > On Mon, 21 May 2018, Zack Weinberg wrote:
> >
> >> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
> >
> > I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
> > and setkey.
> 
> No, this is an intentional deviation from the present state of POSIX,
> anticipating the removal of those functions from the standard.

That would only seem relevant to the _XOPEN_CRYPT value in future POSIX 
modes, not current ones.

The conform/ data is in any case meant to correspond to the standard 
versions in question (plus defect corrections from TCs etc., not plus 
feature changes from other revisions to the standard).  Intentionally 
unsupported features are listed in that data with appropriate XFAILs (see 
e.g. those for varargs.h in conform/Makefile).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-05-21 22:34       ` Joseph Myers
@ 2018-05-22  1:08         ` Zack Weinberg
  2018-06-20 20:40         ` Florian Weimer
  1 sibling, 0 replies; 24+ messages in thread
From: Zack Weinberg @ 2018-05-22  1:08 UTC (permalink / raw)
  To: Joseph Myers
  Cc: GNU C Library, Carlos O'Donell, Florian Weimer, Rical Jasan,
	Thorsten Kukuk

On Mon, May 21, 2018 at 6:34 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Mon, 21 May 2018, Zack Weinberg wrote:
>
>> On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
>> > On Mon, 21 May 2018, Zack Weinberg wrote:
>> >
>> >> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
>> >
>> > I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
>> > and setkey.
>>
>> No, this is an intentional deviation from the present state of POSIX,
>> anticipating the removal of those functions from the standard.
>
> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
> modes, not current ones.

Making _XOPEN_CRYPT be -1 or undefined in current conformance modes
would be a disservice to any program that is actually using it, since
it is overwhelmingly likely that they are using it to detect crypt,
not encrypt or setkey.

> The conform/ data is in any case meant to correspond to the standard
> versions in question (plus defect corrections from TCs etc., not plus
> feature changes from other revisions to the standard).  Intentionally
> unsupported features are listed in that data with appropriate XFAILs (see
> e.g. those for varargs.h in conform/Makefile).

This I can change.

zw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] Disallow use of DES encryption functions in new programs.
  2018-05-21 17:39 ` [PATCH 1/4] Disallow use of DES encryption functions in new programs Zack Weinberg
@ 2018-05-22  6:58   ` Florian Weimer
  2018-05-23  3:37   ` Rical Jasan
  1 sibling, 0 replies; 24+ messages in thread
From: Florian Weimer @ 2018-05-22  6:58 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha; +Cc: carlos, rj, kukuk

On 05/21/2018 07:38 PM, Zack Weinberg wrote:
> diff --git a/crypt/Versions b/crypt/Versions
> index 389e7d544a..d3e9d30174 100644
> --- a/crypt/Versions
> +++ b/crypt/Versions
> @@ -2,4 +2,7 @@ libcrypt {
>     GLIBC_2.0 {
>       crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
>     }
> +  GLIBC_2.28 {
> +    # used in SHLIB_COMPAT directives
> +  }
>   }

This part isn't needed because we already have GLIBC_2.28 symbols in math/.

Regarding the use of hidden_nolink, I would have expected adjustments to 
the wrapper headers in include/, but I'm not familiar with these constructs.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] Disallow use of DES encryption functions in new programs.
  2018-05-21 17:39 ` [PATCH 1/4] Disallow use of DES encryption functions in new programs Zack Weinberg
  2018-05-22  6:58   ` Florian Weimer
@ 2018-05-23  3:37   ` Rical Jasan
  2018-05-23 16:50     ` Joseph Myers
  1 sibling, 1 reply; 24+ messages in thread
From: Rical Jasan @ 2018-05-23  3:37 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: libc-alpha, carlos, fweimer, kukuk

> diff --git a/manual/crypt.texi b/manual/crypt.texi
...

OK (purely removal).

> diff --git a/manual/string.texi b/manual/string.texi
> index b07cfb4550..a1c58e58fa 100644
> --- a/manual/string.texi
> +++ b/manual/string.texi
> @@ -36,8 +36,8 @@ too.
>  				 for delimiters.
>  * Erasing Sensitive Data::      Clearing memory which contains sensitive
>                                   data, after it's no longer needed.
> -* strfry::                      Function for flash-cooking a string.
> -* Trivial Encryption::          Obscuring data.
> +* Shuffling Bytes::             Or how to flash-cook a string.
> +* Obfuscating Data::            Reversibly obscuring data from casual view.

OK.

>  * Encode Binary Data::          Encoding and Decoding of Binary Data.
>  * Argz and Envz Vectors::       Null-separated string vectors.
>  @end menu
> @@ -2426,73 +2426,73 @@ functionality under a different name, such as @code{explicit_memset},
>  systems it may be in @file{strings.h} instead.
>  @end deftypefun
>  
> -@node strfry
> -@section strfry
> +
> +@node Shuffling Bytes
> +@section Shuffling Bytes
>  
>  The function below addresses the perennial programming quandary: ``How do
>  I take good data in string form and painlessly turn it into garbage?''
> -This is actually a fairly simple task for C programmers who do not use
> -@theglibc{} string functions, but for programs based on @theglibc{},
> -the @code{strfry} function is the preferred method for
> -destroying string data.
> +This is not a difficult thing to code for oneself, but the authors of
> +@theglibc{} wish to make it as convenient as possible.

I don't think this introduction needed to be changed, but the new text
is tongue-in-cheek enough that I'm OK with it.

> -The prototype for this function is in @file{string.h}.
> +To @emph{erase} data, use @code{explicit_bzero} (@pxref{Erasing
> +Sensitive Data}); to obfuscate it reversibly, use @code{memfrob}
> +(@pxref{Obfuscating Data}).

Good addition.

>  @deftypefun {char *} strfry (char *@var{string})
>  @standards{GNU, string.h}
>  @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
>  @c Calls initstate_r, time, getpid, strlen, and random_r.
>  
> -@code{strfry} creates a pseudorandom anagram of a string, replacing the
> -input with the anagram in place.  For each position in the string,
> -@code{strfry} swaps it with a position in the string selected at random
> -(from a uniform distribution).  The two positions may be the same.
> +@code{strfry} performs an in-place shuffle on @var{string}.  Each
> +character is swapped to a position selected at random, within the
> +portion of the string starting with the character's original position.
> +(This is the Fisher-Yates algorithm for unbiased shuffling.)

I like the "pseudorandom anagram" analogy, personally, as it's
rearranging a string.  What about combining the two?  I'm not sure we
even need to go into this much detail about how it happens, though I do
think it's good to mention that it happens "in-place" (which both
versions do).  What about:

@code{strfry} creates a pseudorandom anagram of @var{string}, replacing
it in-place using the Fisher-Yates algorithm for unbiased shuffling.

> +Calling @code{strfry} will not disturb any of the random number
> +generators that have global state (@pxref{Pseudo-Random Numbers}).

Another good addition.

>  The return value of @code{strfry} is always @var{string}.
>  
>  @strong{Portability Note:}  This function is unique to @theglibc{}.
> -
> +It is declared in @file{string.h}.

OK.

>  @end deftypefun
>  
>  
> -@node Trivial Encryption
> -@section Trivial Encryption
> -@cindex encryption
> -
> -
> -The @code{memfrob} function converts an array of data to something
> -unrecognizable and back again.  It is not encryption in its usual sense
> -since it is easy for someone to convert the encrypted data back to clear
> -text.  The transformation is analogous to Usenet's ``Rot13'' encryption
> -method for obscuring offensive jokes from sensitive eyes and such.
> -Unlike Rot13, @code{memfrob} works on arbitrary binary data, not just
> -text.
> +@node Obfuscating Data
> +@section Obfuscating Data
>  @cindex Rot13
>  
> -For true encryption, @xref{Cryptographic Functions}.
> +The @code{memfrob} function reversibly obfuscates an array of binary
> +data.  This is not true encryption; the obfuscated data still bears a
> +clear relationship to the original, and no secret key is required to
> +undo the obfuscation.  It is analogous to the ``Rot13'' cipher used on
> +Usenet for obscuring offensive jokes, spoilers for works of fiction,
> +and so on, but it can be applied to arbitrary binary data.
>  
> -This function is declared in @file{string.h}.
> -@pindex string.h
> +Programs that need true encryption---a transformation that completely
> +obscures the original and cannot be reversed without knowledge of a
> +secret key---should use a dedicated cryptography library, such as
> +@uref{https://www.gnu.org/software/libgcrypt/,,libgcrypt}.
> +
> +Programs that need to @emph{destroy} data should use
> +@code{explicit_bzero} (@pxref{Erasing Sensitive Data}), or possibly
> +@code{strfry} (@pxref{Shuffling Bytes}).
>  
>  @deftypefun {void *} memfrob (void *@var{mem}, size_t @var{length})
>  @standards{GNU, string.h}
>  @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
>  
> -@code{memfrob} transforms (frobnicates) each byte of the data structure
> -at @var{mem}, which is @var{length} bytes long, by bitwise exclusive
> -oring it with binary 00101010.  It does the transformation in place and
> -its return value is always @var{mem}.
> +The function @code{memfrob} obfuscates @var{length} bytes of data
> +beginning at @var{mem}, in place.  Each byte is bitwise xor-ed with
> +the binary pattern 00101010 (hexadecimal 0x2A).  The return value is
> +always @var{mem}.
>  
> -Note that @code{memfrob} a second time on the same data structure
> -returns it to its original state.
> -
> -This is a good function for hiding information from someone who doesn't
> -want to see it or doesn't want to see it very much.  To really prevent
> -people from retrieving the information, use stronger encryption such as
> -that described in @xref{Cryptographic Functions}.
> +@code{memfrob} a second time on the same data returns it to
> +its original state.
>  
>  @strong{Portability Note:}  This function is unique to @theglibc{}.
> -
> +It is declared in @file{string.h}.
>  @end deftypefun

OK.  Not much really changed in the content, but there was a good bit
that was due for removal.

Good cleanup overall, and good eye catching the additional
"cryptography"-related content.

Thanks,
Rical

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/4] Reorganize crypt.texi.
  2018-05-21 17:39 ` [PATCH 2/4] Reorganize crypt.texi Zack Weinberg
@ 2018-05-23  5:23   ` Rical Jasan
  0 siblings, 0 replies; 24+ messages in thread
From: Rical Jasan @ 2018-05-23  5:23 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: libc-alpha, carlos, fweimer, kukuk

On 05/21/2018 10:38 AM, Zack Weinberg wrote:
> In preparation for a major revision of the documentation for
> crypt(_r), getentropy, and getrandom, reorganize crypt.texi.  This
> patch does not change any text; it only deletes and moves text.

LGTM.

Rical

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/4] Disallow use of DES encryption functions in new programs.
  2018-05-23  3:37   ` Rical Jasan
@ 2018-05-23 16:50     ` Joseph Myers
  0 siblings, 0 replies; 24+ messages in thread
From: Joseph Myers @ 2018-05-23 16:50 UTC (permalink / raw)
  To: Rical Jasan; +Cc: Zack Weinberg, libc-alpha, carlos, fweimer, kukuk

On Tue, 22 May 2018, Rical Jasan wrote:

> > -@code{strfry} creates a pseudorandom anagram of a string, replacing the
> > -input with the anagram in place.  For each position in the string,
> > -@code{strfry} swaps it with a position in the string selected at random
> > -(from a uniform distribution).  The two positions may be the same.
> > +@code{strfry} performs an in-place shuffle on @var{string}.  Each
> > +character is swapped to a position selected at random, within the
> > +portion of the string starting with the character's original position.
> > +(This is the Fisher-Yates algorithm for unbiased shuffling.)
> 
> I like the "pseudorandom anagram" analogy, personally, as it's
> rearranging a string.  What about combining the two?  I'm not sure we
> even need to go into this much detail about how it happens, though I do
> think it's good to mention that it happens "in-place" (which both
> versions do).  What about:
> 
> @code{strfry} creates a pseudorandom anagram of @var{string}, replacing
> it in-place using the Fisher-Yates algorithm for unbiased shuffling.

Note that there's the pre-existing condition that, contrary to the 
documentation, the distribution is not actually uniform (especially for 
very long strings), because it uses a random nonnegative 32-bit integer 
modulo the remaining length of the string (see bug 4403).  (As a 
pre-existing condition, this is not a problem with any variant of this 
patch.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/4] Revise crypt.texi.
  2018-05-21 17:39 ` [PATCH 3/4] Revise crypt.texi Zack Weinberg
@ 2018-05-25  2:52   ` Rical Jasan
  2018-06-25 12:21     ` Florian Weimer
  2018-06-25 12:26   ` Florian Weimer
  1 sibling, 1 reply; 24+ messages in thread
From: Rical Jasan @ 2018-05-25  2:52 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: libc-alpha, carlos, fweimer, kukuk

On 05/21/2018 10:38 AM, Zack Weinberg wrote:
...
> diff --git a/crypt/crypt.h b/crypt/crypt.h
...
> diff --git a/inet/ruserpass.c b/inet/ruserpass.c
...
> diff --git a/manual/contrib.texi b/manual/contrib.texi
...
> diff --git a/manual/crypt.texi b/manual/crypt.texi
...

I have no comments or complaints on anything up to this point.

> @@ -123,93 +202,120 @@ for a password and prints ``Access granted.'' if the user types
>  
>  @node Unpredictable Bytes
>  @section Generating Unpredictable Bytes
> -
> -Some cryptographic applications (such as session key generation) need
> -unpredictable bytes.
> -
> -In general, application code should use a deterministic random bit
> -generator, which could call the @code{getentropy} function described
> -below internally to obtain randomness to seed the generator.  The
> -@code{getrandom} function is intended for low-level applications which
> -need additional control over the blocking behavior.
> +@cindex randomness source
> +@cindex random numbers, cryptographic
> +@cindex pseudo-random numbers, cryptographic
> +@cindex cryptographic random number generator
> +@cindex deterministic random bit generator
> +@cindex CRNG
> +@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.
> +
> +The pseudo-random number generators described in @ref{Pseudo-Random
> +Numbers} are not unpredictable enough for these applications.  They

@ref will still render with the "see" verb in some formats, so it's
generally a bad choice.  Maybe:

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).
> +
> +Currently, @theglibc{} does not provide a cryptographic random number
> +generator.  What it does provide is functions that read random data

"are functions"

> +from a @dfn{randomness source} supplied by the operating system.  The
> +randomness source is a CRNG at heart, but it also also continually

Double "also".

> +``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
> +problem, but applications that need more than a few kilobytes of
> +cryptographically strong random data should call these functions once
> +and use their output to seed a CRNG.
> +
> +Most applications should use @code{getentropy}.  The @code{getrandom}
> +function is intended for low-level applications which need additional
> +control over blocking behavior.
>  
>  @deftypefun int getentropy (void *@var{buffer}, size_t @var{length})
>  @standards{GNU, sys/random.h}
>  @safety{@mtsafe{}@assafe{}@acsafe{}}
>  
> -This function writes @var{length} bytes of random data to the array
> -starting at @var{buffer}, which must be at most 256 bytes long.  The
> -function returns zero on success.  On failure, it returns @code{-1} and
> -@code{errno} is updated accordingly.
> -
> -The @code{getentropy} function is declared in the header file
> -@file{sys/random.h}.  It is derived from OpenBSD.
> -
> -The @code{getentropy} function is not a cancellation point.  A call to
> -@code{getentropy} can block if the system has just booted and the kernel
> -entropy pool has not yet been initialized.  In this case, the function
> -will keep blocking even if a signal arrives, and return only after the
> -entropy pool has been initialized.
> -
> -The @code{getentropy} function can fail with several errors, some of
> -which are listed below.
> +This function writes exactly @var{length} bytes of random data to the
> +array starting at @var{buffer}.  @var{length} can be no more than 256.
> +On success, it returns zero.  On failure, it returns @math{-1}, and
> +@code{errno} is set to indicate the problem.  Some of the possible
> +errors are listed below.
>  
>  @table @code
>  @item ENOSYS
> -The kernel does not implement the required system call.
> +The operating system does not implement a randomness source, or does
> +not support this way of accessing it.  (For instance, the system call
> +used by this function was added to the Linux kernel in version 3.17.)

I'm not sure if I'm missing a (possibly not so) subtle point here, but I
feel like this is more words to say the same thing.  What other ways of
accessing an operating system's (as opposed to the kernel's) source of
randomness would glibc take advantage of?  It kind of sounds like we're
not doing due diligence in that light.  I could just be reading this
wrong, though.

>  @item EFAULT
>  The combination of @var{buffer} and @var{length} arguments specifies
>  an invalid memory range.
>  
>  @item EIO
> -More than 256 bytes of randomness have been requested, or the buffer
> -could not be overwritten with random data for an unspecified reason.
> -
> +@var{length} is larger than 256, or the kernel entropy pool has
> +suffered a catastrophic failure.

Someone else may need to comment on this.  The original version leaves
it pretty wide open as to why one would get EIO.  Is it really only just
because LENGTH was greater than 256 or there was a problem in a specific
subsystem of the kernel?  If so, then OK.

I do appreciate that this would be the first use of "catastrophic
failure" in an errno description.  :)

>  @end table
>  
> +A call to @code{getentropy} can only block when the system has just
> +booted and the randomness source has not yet been initialized.
> +However, if it does block, it cannot be interrupted by signals or
> +thread cancellation.  Programs intended to run in very early stages of
> +the boot process may need to use @code{getrandom} in non-blocking mode
> +instead, and be prepared to cope with random data not being available
> +at all.

Good.

> +The @code{getentropy} function is declared in the header file
> +@file{sys/random.h}.  It is derived from OpenBSD.

Should the @standards be adjusted?  If this isn't purely a GNU
extension, I think credit should be given where credit's due.  Does BSD
declare it in sys/random.h?

>  @end deftypefun
>  
>  @deftypefun ssize_t getrandom (void *@var{buffer}, size_t @var{length}, unsigned int @var{flags})
>  @standards{GNU, sys/random.h}
>  @safety{@mtsafe{}@assafe{}@acsafe{}}
>  
> -This function writes @var{length} bytes of random data to the array
> -starting at @var{buffer}.  On success, this function returns the number
> -of bytes which have been written to the buffer (which can be less than
> -@var{length}).  On error, @code{-1} is returned, and @code{errno} is
> -updated accordingly.
> -
> -The @code{getrandom} function is declared in the header file
> -@file{sys/random.h}.  It is a GNU extension.
> -
> -The following flags are defined for the @var{flags} argument:
> +This function writes up to @var{length} bytes of random data to the
> +array starting at @var{buffer}.  The @var{flags} argument should be
> +either zero, or the bitwise OR of some of the following flags:
>  
>  @table @code
>  @item GRND_RANDOM
> -Use the @file{/dev/random} (blocking) pool instead of the
> -@file{/dev/urandom} (non-blocking) pool to obtain randomness.  If the
> -@code{GRND_RANDOM} flag is specified, the @code{getrandom} function can
> -block even after the randomness source has been initialized.
> +Use the @file{/dev/random} (blocking) source instead of the
> +@file{/dev/urandom} (non-blocking) source to obtain randomness.

Referring to the (entropy) "pool" seems more natural in this context;
did you change it to "source" strictly for consistency?  OK either way,
but it's noticeable.

> +If this flag is specified, the call may block, potentially for quite
> +some time.  If it is not specified, the call can only block when the
> +system has just booted and the randomness source has not yet been
> +initialized.

I think the prior information that using this flag can cause the call to
block "even after the randomness source has been initialized" is
valuable.  It's more to the point, IMO, as it directly addresses the use
of this flag.  (Though without a GRND_URANDOM flag, it is fair to
address the non-use of this flag here, which I see you pulled from below.)

>  @item GRND_NONBLOCK
>  Instead of blocking, return to the caller immediately if no data is
>  available.
>  @end table
>  
> -The @code{getrandom} function is a cancellation point.
> +Unlike @code{getentropy}, the @code{getrandom} function is a
> +cancellation point, and if it blocks, it can be interrupted by
> +signals.

Good.

> -Obtaining randomness from the @file{/dev/urandom} pool (i.e., a call
> -without the @code{GRND_RANDOM} flag) can block if the system has just
> -booted and the pool has not yet been initialized.

(Moved to GRND_RANDOM discussion.)  OK.  Otherwise, I would have
considered moving it earlier in the description, but it would be
difficult to avoid disrupting the flow leading to the flags discussion.

> -The @code{getrandom} function can fail with several errors, some of
> -which are listed below.  In addition, the function may not fill the
> -buffer completely and return a value less than @var{length}.
> +On success, @code{getrandom} returns the number of bytes which have
> +been written to the buffer, which may be less than @var{length}.  On
> +error, it returns @math{-1}, and @code{errno} is set to indicate the
> +problem.  Some of the possible errors are:

I like the way you used "up to LENGTH" earlier, and moved the
conversation about return values here without being redundant.

>  @table @code
>  @item ENOSYS
> -The kernel does not implement the @code{getrandom} system call.
> +The operating system does not implement a randomness source, or does
> +not support this way of accessing it.  (For instance, the system call
> +used by this function was added to the Linux kernel in version 3.17.)

(See comments on ENOSYS for getentropy.)

>  @item EAGAIN
>  No random data was available and @code{GRND_NONBLOCK} was specified in
> @@ -228,4 +334,7 @@ the kernel randomness pool is initialized, this can happen even if
>  The @var{flags} argument contains an invalid combination of flags.
>  @end table
>  
> +The @code{getrandom} function is declared in the header file
> +@file{sys/random.h}.  It is a GNU extension.
> +
>  @end deftypefun

Good, moving this to the bottom of the description, which is where this
information is typically located.

Does the extra blank line make a noticeable improvement in the rendered
output?  (Some places in the manual have @comments saying to preserve
them for that reason.)

> diff --git a/manual/examples/genpass.c b/manual/examples/genpass.c

...

I don't have time to review the examples right now, and there's even
more after that, so I'll try to finish this over the weekend.  It's a
pretty heavy rewrite.  So far, there have been a few things I don't
think needed to be so heavily rewritten, but it's quality.  :)  So far,
so good.

Rical

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-05-21 22:34       ` Joseph Myers
  2018-05-22  1:08         ` Zack Weinberg
@ 2018-06-20 20:40         ` Florian Weimer
  2018-06-20 22:48           ` Zack Weinberg
  1 sibling, 1 reply; 24+ messages in thread
From: Florian Weimer @ 2018-06-20 20:40 UTC (permalink / raw)
  To: Joseph Myers, Zack Weinberg
  Cc: GNU C Library, Carlos O'Donell, Rical Jasan, Thorsten Kukuk

On 05/22/2018 12:34 AM, Joseph Myers wrote:
> On Mon, 21 May 2018, Zack Weinberg wrote:
> 
>> On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
>>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>>
>>>> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
>>>
>>> I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
>>> and setkey.
>>
>> No, this is an intentional deviation from the present state of POSIX,
>> anticipating the removal of those functions from the standard.
> 
> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
> modes, not current ones.

So we should stop defining _XOPEN_CRYPT, but continue to declare crypt 
in <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.

I would like to see this committed this cycle, and will try to get this 
committed on Zack's behalf.

> The conform/ data is in any case meant to correspond to the standard
> versions in question (plus defect corrections from TCs etc., not plus
> feature changes from other revisions to the standard).  Intentionally
> unsupported features are listed in that data with appropriate XFAILs (see
> e.g. those for varargs.h in conform/Makefile).

I find these XFAILs fairly annoying, by the way.  Especially for things 
we simply cannot fix because we do not supply the header (<ndbm.h> comes 
to my mind).

Thanks,
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-06-20 20:40         ` Florian Weimer
@ 2018-06-20 22:48           ` Zack Weinberg
  2018-06-21  9:31             ` Florian Weimer
  0 siblings, 1 reply; 24+ messages in thread
From: Zack Weinberg @ 2018-06-20 22:48 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Joseph Myers, GNU C Library, Carlos O'Donell, Rical Jasan,
	Thorsten Kukuk

On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com> wrote:
> On 05/22/2018 12:34 AM, Joseph Myers wrote:
>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>> No, this is an intentional deviation from the present state of POSIX,
>>> anticipating the removal of those functions from the standard.
>>
>> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
>> modes, not current ones.
>
> So we should stop defining _XOPEN_CRYPT, but continue to declare crypt in
> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.

Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
in any mode.  Yes, this is an intentional deviation from POSIX, but I
think it is far less likely to break existing programs than the
alternative.

zw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-06-20 22:48           ` Zack Weinberg
@ 2018-06-21  9:31             ` Florian Weimer
  2018-06-21  9:32               ` Florian Weimer
  2018-06-28 18:52               ` Zack Weinberg
  0 siblings, 2 replies; 24+ messages in thread
From: Florian Weimer @ 2018-06-21  9:31 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: Joseph Myers, GNU C Library, Carlos O'Donell, Rical Jasan,
	Thorsten Kukuk

On 06/21/2018 12:47 AM, Zack Weinberg wrote:
> On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 05/22/2018 12:34 AM, Joseph Myers wrote:
>>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>>> No, this is an intentional deviation from the present state of POSIX,
>>>> anticipating the removal of those functions from the standard.
>>>
>>> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
>>> modes, not current ones.
>>
>> So we should stop defining _XOPEN_CRYPT, but continue to declare crypt in
>> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.
> 
> Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
> in any mode.  Yes, this is an intentional deviation from POSIX, but I
> think it is far less likely to break existing programs than the
> alternative.

How can we resolve this conflict?

We have mostly cleaned up Fedora 28 to build with !_XOPEN_CRYPT already. 
  There weren't many changes AFAICS, and they fall broadly into two 
categories:

(1) Not including <crypt.h> for the crypt function, only <unistd.h>.
(2) Using DES functions.

(1) was far more common than (2).

We'll keep the declaration of crypt in <unistd.h> for _DEFAULT_SOURCE, 
so (1) will not be a problem.  (2) will not be addressed independently 
of the definition of _XOPEN_CRYPT.

This is why I'm fine with Joseph's approach.  It may even make it 
marginally easier to check whether you need your own DES implementation.

I would like to see a decision soon because I'm wondering if I have to 
back out the libxcrypt switch.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-06-21  9:31             ` Florian Weimer
@ 2018-06-21  9:32               ` Florian Weimer
  2018-06-28 18:52               ` Zack Weinberg
  1 sibling, 0 replies; 24+ messages in thread
From: Florian Weimer @ 2018-06-21  9:32 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: Joseph Myers, GNU C Library, Carlos O'Donell, Rical Jasan,
	Thorsten Kukuk

On 06/21/2018 11:31 AM, Florian Weimer wrote:
> On 06/21/2018 12:47 AM, Zack Weinberg wrote:
>> On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com> 
>> wrote:
>>> On 05/22/2018 12:34 AM, Joseph Myers wrote:
>>>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>>>> No, this is an intentional deviation from the present state of POSIX,
>>>>> anticipating the removal of those functions from the standard.
>>>>
>>>> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
>>>> modes, not current ones.
>>>
>>> So we should stop defining _XOPEN_CRYPT, but continue to declare 
>>> crypt in
>>> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.
>>
>> Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
>> in any mode.  Yes, this is an intentional deviation from POSIX, but I
>> think it is far less likely to break existing programs than the
>> alternative.
> 
> How can we resolve this conflict?
> 
> We have mostly cleaned up Fedora 28 to build with !_XOPEN_CRYPT already. 
>   There weren't many changes AFAICS, and they fall broadly into two 
> categories:
> 
> (1) Not including <crypt.h> for the crypt function, only <unistd.h>.
> (2) Using DES functions.
> 
> (1) was far more common than (2).
> 
> We'll keep the declaration of crypt in <unistd.h> for _DEFAULT_SOURCE, 
> so (1) will not be a problem.  (2) will not be addressed independently 
> of the definition of _XOPEN_CRYPT.
> 
> This is why I'm fine with Joseph's approach.  It may even make it 
> marginally easier to check whether you need your own DES implementation.
> 
> I would like to see a decision soon because I'm wondering if I have to 
> back out the libxcrypt switch.

In Fedora, of course.  Sorry for being unclear.

Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/4] Revise crypt.texi.
  2018-05-25  2:52   ` Rical Jasan
@ 2018-06-25 12:21     ` Florian Weimer
  0 siblings, 0 replies; 24+ messages in thread
From: Florian Weimer @ 2018-06-25 12:21 UTC (permalink / raw)
  To: Rical Jasan, Zack Weinberg; +Cc: libc-alpha, carlos, kukuk

On 05/25/2018 04:52 AM, Rical Jasan wrote:
> On 05/21/2018 10:38 AM, Zack Weinberg wrote:
> ...
>> diff --git a/crypt/crypt.h b/crypt/crypt.h
> ...
>> diff --git a/inet/ruserpass.c b/inet/ruserpass.c
> ...
>> diff --git a/manual/contrib.texi b/manual/contrib.texi
> ...
>> diff --git a/manual/crypt.texi b/manual/crypt.texi
> ...
> 
> I have no comments or complaints on anything up to this point.
> 
>> @@ -123,93 +202,120 @@ for a password and prints ``Access granted.'' if the user types
>>   
>>   @node Unpredictable Bytes
>>   @section Generating Unpredictable Bytes
>> -
>> -Some cryptographic applications (such as session key generation) need
>> -unpredictable bytes.
>> -
>> -In general, application code should use a deterministic random bit
>> -generator, which could call the @code{getentropy} function described
>> -below internally to obtain randomness to seed the generator.  The
>> -@code{getrandom} function is intended for low-level applications which
>> -need additional control over the blocking behavior.
>> +@cindex randomness source
>> +@cindex random numbers, cryptographic
>> +@cindex pseudo-random numbers, cryptographic
>> +@cindex cryptographic random number generator
>> +@cindex deterministic random bit generator
>> +@cindex CRNG
>> +@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.
>> +
>> +The pseudo-random number generators described in @ref{Pseudo-Random
>> +Numbers} are not unpredictable enough for these applications.  They
> 
> @ref will still render with the "see" verb in some formats, so it's
> generally a bad choice.  Maybe:
> 
> Some pseudo-random number generators do not provide unpredictable-enough
> output for cryptographic applications; @pxref{Pseudo-Random Numbers}.
> Such applications...

Thanks, applied.

>> +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).
>> +
>> +Currently, @theglibc{} does not provide a cryptographic random number
>> +generator.  What it does provide is functions that read random data
> 
> "are functions"

I'm going to use this:

“
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
”

>> +from a @dfn{randomness source} supplied by the operating system.  The
>> +randomness source is a CRNG at heart, but it also also continually
> 
> Double "also".

Fixed.

>>   @table @code
>>   @item ENOSYS
>> -The kernel does not implement the required system call.
>> +The operating system does not implement a randomness source, or does
>> +not support this way of accessing it.  (For instance, the system call
>> +used by this function was added to the Linux kernel in version 3.17.)
> 
> I'm not sure if I'm missing a (possibly not so) subtle point here, but I
> feel like this is more words to say the same thing.  What other ways of
> accessing an operating system's (as opposed to the kernel's) source of
> randomness would glibc take advantage of?  It kind of sounds like we're
> not doing due diligence in that light.  I could just be reading this
> wrong, though.

I think it's about covering the Hurd, which does not have kernel support 
for getrandom.  But I don't feel strongly about this.

> 
>>   @item EFAULT
>>   The combination of @var{buffer} and @var{length} arguments specifies
>>   an invalid memory range.
>>   
>>   @item EIO
>> -More than 256 bytes of randomness have been requested, or the buffer
>> -could not be overwritten with random data for an unspecified reason.
>> -
>> +@var{length} is larger than 256, or the kernel entropy pool has
>> +suffered a catastrophic failure.
> 
> Someone else may need to comment on this.  The original version leaves
> it pretty wide open as to why one would get EIO.  Is it really only just
> because LENGTH was greater than 256 or there was a problem in a specific
> subsystem of the kernel?  If so, then OK.
> 
> I do appreciate that this would be the first use of "catastrophic
> failure" in an errno description.  :)

I think both versions are okay.  I expect that Zack looked at the kernel 
sources here.

>> +The @code{getentropy} function is declared in the header file
>> +@file{sys/random.h}.  It is derived from OpenBSD.
> 
> Should the @standards be adjusted?  If this isn't purely a GNU
> extension, I think credit should be given where credit's due.

Well, we already give credit to OpenBSD here.

> Does BSD declare it in sys/random.h?

No, that header was pioneered by Solaris.

>>   @table @code
>>   @item GRND_RANDOM
>> -Use the @file{/dev/random} (blocking) pool instead of the
>> -@file{/dev/urandom} (non-blocking) pool to obtain randomness.  If the
>> -@code{GRND_RANDOM} flag is specified, the @code{getrandom} function can
>> -block even after the randomness source has been initialized.
>> +Use the @file{/dev/random} (blocking) source instead of the
>> +@file{/dev/urandom} (non-blocking) source to obtain randomness.
> 
> Referring to the (entropy) "pool" seems more natural in this context;
> did you change it to "source" strictly for consistency?  OK either way,
> but it's noticeable.

I think “source” is more useful to the casual reader who doesn't know 
about implementation strategies for CSPRNGs.

>> +If this flag is specified, the call may block, potentially for quite
>> +some time.  If it is not specified, the call can only block when the
>> +system has just booted and the randomness source has not yet been
>> +initialized.
> 
> I think the prior information that using this flag can cause the call to
> block "even after the randomness source has been initialized" is
> valuable.

Agreed, this is critical information.  I'm going with this:

“
If this flag is specified, the call may block, potentially for quite
some time, even after the randomness source has been initialized.  If it
is not specified, the call can only block when the system has just
booted and the randomness source has not yet been initialized.
”

>> +The @code{getrandom} function is declared in the header file
>> +@file{sys/random.h}.  It is a GNU extension.
>> +
>>   @end deftypefun
> 
> Good, moving this to the bottom of the description, which is where this
> information is typically located.
> 
> Does the extra blank line make a noticeable improvement in the rendered
> output?  (Some places in the manual have @comments saying to preserve
> them for that reason.)

I think current makeinfo is way less sensitive about input whitespace 
then it used to be.  The blank line does not survive into HTML and Info 
output (but the latter is difficult to tell because there's no text 
after it in the node).

Thanks,
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/4] Revise crypt.texi.
  2018-05-21 17:39 ` [PATCH 3/4] Revise crypt.texi Zack Weinberg
  2018-05-25  2:52   ` Rical Jasan
@ 2018-06-25 12:26   ` Florian Weimer
  1 sibling, 0 replies; 24+ messages in thread
From: Florian Weimer @ 2018-06-25 12:26 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha; +Cc: carlos, rj, kukuk

On 05/21/2018 07:38 PM, Zack Weinberg wrote:
> --- a/manual/users.texi
> +++ b/manual/users.texi
> @@ -1722,7 +1722,6 @@ members.  Older systems do not even have the @code{ut_host} member.
>   @node User Database
>   @section User Database
>   @cindex user database
> -@cindex password database
>   @pindex /etc/passwd

I'm going to preserve the reference to “password database” because there 
is a paragraph that explains this historic usage.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-06-21  9:31             ` Florian Weimer
  2018-06-21  9:32               ` Florian Weimer
@ 2018-06-28 18:52               ` Zack Weinberg
  1 sibling, 0 replies; 24+ messages in thread
From: Zack Weinberg @ 2018-06-28 18:52 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Joseph Myers, GNU C Library, Carlos O'Donell, Rical Jasan,
	Thorsten Kukuk

On Thu, Jun 21, 2018 at 5:31 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 06/21/2018 12:47 AM, Zack Weinberg wrote:
>> On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com>
>>>
>>> So we should stop defining _XOPEN_CRYPT, but continue to declare crypt in
>>> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.
>>
>>
>> Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
>> in any mode.  Yes, this is an intentional deviation from POSIX, but I
>> think it is far less likely to break existing programs than the
>> alternative.
>
> How can we resolve this conflict?
>
> We have mostly cleaned up Fedora 28 to build with !_XOPEN_CRYPT already.
> There weren't many changes AFAICS, and they fall broadly into two
> categories:
>
> (1) Not including <crypt.h> for the crypt function, only <unistd.h>.
> (2) Using DES functions.
>
> (1) was far more common than (2).
>
> We'll keep the declaration of crypt in <unistd.h> for _DEFAULT_SOURCE, so
> (1) will not be a problem.  (2) will not be addressed independently of the
> definition of _XOPEN_CRYPT.

Based on this I withdraw my objection.  I was primarily worried about
programs that might substitute their own, possibly DES-only, crypt()
implementation if _XOPEN_CRYPT wasn't defined.

zw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-05-08 15:00   ` Florian Weimer
@ 2018-05-08 15:22     ` Zack Weinberg
  0 siblings, 0 replies; 24+ messages in thread
From: Zack Weinberg @ 2018-05-08 15:22 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library

On Tue, May 8, 2018 at 11:00 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> +     header file 'crypt.h'.  'unistd.h' will still declare the function
>> +     'crypt', as required by POSIX. Using this option does not change
>> +     the set of programs that may need to be linked with '-lcrypt'; it
>> +     only means that the GNU C Library will not provide that library.
>
> Two spaces after dot; see below.
...
>> +Do not install the password-hashing library @file{libcrypt} or the
>> +header file @file{crypt.h}.  @file{unistd.h} will still declare the
>> +function @code{crypt}, as required by POSIX.  Using this option does
>> +not change the set of programs that may need to be linked with
>> +@option{-lcrypt}; it only means that @theglibc{} will not provide that
>> +library.
> You need to use “POSIX@.” instead of “POSIX.” here.

Will fix.  Thanks for the extra-careful proofreading.

zw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 4/4] New configure option --disable-crypt.
  2018-05-06 17:52 ` [PATCH 4/4] New configure option --disable-crypt Zack Weinberg
@ 2018-05-08 15:00   ` Florian Weimer
  2018-05-08 15:22     ` Zack Weinberg
  0 siblings, 1 reply; 24+ messages in thread
From: Florian Weimer @ 2018-05-08 15:00 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha; +Cc: carlos, rj

On 05/06/2018 07:51 PM, Zack Weinberg wrote:
> diff --git a/INSTALL b/INSTALL
> index 052b1b6f89..6de609c9d6 100644
> --- a/INSTALL
> +++ b/INSTALL
> @@ -197,6 +197,17 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
>        libnss_nisplus are not built at all.  Use this option to enable
>        libnsl with all depending NSS modules and header files.
>   
> +'--disable-crypt'
> +     Do not install the password-hashing library 'libcrypt' or the
> +     header file 'crypt.h'.  'unistd.h' will still declare the function
> +     'crypt', as required by POSIX. Using this option does not change
> +     the set of programs that may need to be linked with '-lcrypt'; it
> +     only means that the GNU C Library will not provide that library.

Two spaces after dot; see below.

> +     This option is for hackers and distributions experimenting with
> +     independently-maintained implementations of libcrypt.  It may
> +     become the default in a future release.

Okay.

> diff --git a/Makeconfig b/Makeconfig
> index 1afe86475c..608ffe648c 100644
> --- a/Makeconfig
> +++ b/Makeconfig
> @@ -566,7 +566,7 @@ link-libc-printers-tests = $(link-libc-rpath) \
>   			   $(link-libc-tests-after-rpath-link)
>   
>   # This is how to find at build-time things that will be installed there.
> -rpath-dirs = math elf dlfcn nss nis rt resolv crypt mathvec support
> +rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support
>   rpath-link = \
>   $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
>   else  # build-static
> @@ -1205,9 +1205,14 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal	    \
>   	      stdlib stdio-common libio malloc string wcsmbs time dirent    \
>   	      grp pwd posix io termios resource misc socket sysvipc gmon    \
>   	      gnulib iconv iconvdata wctype manual shadow gshadow po argp   \
> -	      crypt localedata timezone rt conform debug mathvec support    \
> +	      localedata timezone rt conform debug mathvec support	    \
>   	      dlfcn elf
>   
> +ifeq ($(build-crypt),yes)
> +all-subdirs += crypt
> +rpath-dirs += crypt
> +endif

Okay.

>   ifndef avoid-generated
>   # sysd-sorted itself will contain rules making the sysd-sorted target
>   # depend on Depend files.  But if you just added a Depend file to an
> diff --git a/NEWS b/NEWS
> index 2fe2da8b59..cfc58f71bb 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -71,6 +71,18 @@ Deprecated and removed features, and other changes affecting compatibility:
>     encrypt and setkey are not thread-safe.  Software that still uses these
>     functions should switch to a modern cryptography library, such as GnuTLS.
>   
> +* We have tentative plans to deprecate glibc's implementation of the
> +  password-hashing functions 'crypt' and 'crypt_r'.  We will continue
> +  to declare crypt in <unistd.h>, as required by POSIX, and programs
> +  that use crypt or crypt_r should not need to change at all.  However,
> +  the header file <crypt.h> and library libcrypt.{a,so} will come from
> +  a separate development project that will, we hope, keep up better with
> +  new password-hashing algorithms.
> +
> +  In this release, if the configure option --disable-crypt is used,
> +  glibc will not install <crypt.h> or libcrypt.  The plan is to make
> +  this the default behavior in a future release.

Okay.

> diff --git a/config.make.in b/config.make.in
> index 9e5e24b2c6..d9891b2cd8 100644
> --- a/config.make.in
> +++ b/config.make.in
> @@ -96,6 +96,7 @@ cross-compiling = @cross_compiling@
>   force-install = @force_install@
>   link-obsolete-rpc = @link_obsolete_rpc@
>   build-obsolete-nsl = @build_obsolete_nsl@
> +build-crypt = @build_crypt@
>   build-nscd = @build_nscd@
>   use-nscd = @use_nscd@
>   build-hardcoded-path-in-tests= @hardcoded_path_in_tests@

Okay.

> diff --git a/configure b/configure
> index 7a8bd3f817..7317c1aee4 100755
> --- a/configure
> +++ b/configure

Okay (generated file).

> diff --git a/configure.ac b/configure.ac
> index ca1282a6b3..05e03f2f72 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -302,11 +302,22 @@ AC_ARG_ENABLE([experimental-malloc],
>   	      [experimental_malloc=yes])
>   AC_SUBST(experimental_malloc)
>   
> +AC_ARG_ENABLE([crypt],
> +              AC_HELP_STRING([--disable-crypt],
> +                             [do not build nor install the password hashing library, libcrypt]),
> +              [build_crypt=$enableval],
> +              [build_crypt=yes])
> +AC_SUBST(build_crypt)

Okay.

>   AC_ARG_ENABLE([nss-crypt],
>   	      AC_HELP_STRING([--enable-nss-crypt],
>   			     [enable libcrypt to use nss]),
>   	      [nss_crypt=$enableval],
>   	      [nss_crypt=no])
> +if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
> +  AC_MSG_WARN([--enable-nss-crypt has no effect when libcrypt is disabled])
> +  nss_crypt=no
> +fi

Okay.

>   if test x$nss_crypt = xyes; then
>     nss_includes=-I$(nss-config --includedir 2>/dev/null)
>     if test $? -ne 0; then
> diff --git a/conform/Makefile b/conform/Makefile
> index 864fdeca21..74fbda0786 100644
> --- a/conform/Makefile
> +++ b/conform/Makefile
> @@ -193,13 +193,11 @@ linknamespace-libs-thr = $(linknamespace-libs-isoc) \
>   			 $(common-objpfx)rt/librt.a $(static-thread-library)
>   linknamespace-libs-posix = $(linknamespace-libs-thr) \
>   			   $(common-objpfx)dlfcn/libdl.a
> -linknamespace-libs-xsi = $(linknamespace-libs-posix) \
> -			 $(common-objpfx)crypt/libcrypt.a
> +linknamespace-libs-xsi = $(linknamespace-libs-posix)
>   linknamespace-libs-ISO = $(linknamespace-libs-isoc)
>   linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)
>   linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)
> -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \
> -			  $(common-objpfx)crypt/libcrypt.a
> +linknamespace-libs-XPG4 = $(linknamespace-libs-isoc)
>   linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)
>   linknamespace-libs-POSIX = $(linknamespace-libs-thr)
>   linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi)
> @@ -209,6 +207,11 @@ linknamespace-libs-XOPEN2K8 = $(linknamespace-libs-xsi)
>   linknamespace-libs = $(foreach std,$(conformtest-standards),\
>   				   $(linknamespace-libs-$(std)))
>   
> +ifeq ($(build-crypt),yes)
> +linknamespace-libs-xsi += $(common-objpfx)crypt/libcrypt.a
> +linknamespace-libs-XPG4 += $(common-objpfx)crypt/libcrypt.a
> +endif
> +

Okay.

>   $(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \
>   					$(linknamespace-libs)
>   	LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \
> diff --git a/crypt/Makefile b/crypt/Makefile
> index e122bcebf0..1e2f21bf52 100644
> --- a/crypt/Makefile
> +++ b/crypt/Makefile
> @@ -35,10 +35,6 @@ tests := cert md5c-test sha256c-test sha512c-test badsalttest
>   # cert.c tests the deprecated setkey/encrypt interface
>   CFLAGS-cert.c = -Wno-deprecated-declarations
>   
> -ifeq ($(crypt-in-libc),yes)
> -routines += $(libcrypt-routines)
> -endif
> -

Okay.

>   ifeq ($(nss-crypt),yes)
>   nss-cpp-flags := -DUSE_NSS \
>     -I$(shell nss-config --includedir) -I$(shell nspr-config --includedir)
> diff --git a/crypt/crypt.h b/crypt/crypt.h
> index 22cf13ff89..4f928901f3 100644
> --- a/crypt/crypt.h
> +++ b/crypt/crypt.h
> @@ -28,7 +28,10 @@
>   
>   __BEGIN_DECLS
>   
> -/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
> +/* Hash a password, KEY, for storage in /etc/shadow.  SALT selects the
> +   hashing algorithm to be used, and ensures that no two users' passwords
> +   are hashed to the same string.  The return value points to static
> +   storage which will be overwritten by the next call to crypt.  */
>   extern char *crypt (const char *__key, const char *__salt)
>        __THROW __nonnull ((1, 2));

Okay.

> diff --git a/elf/Makefile b/elf/Makefile
> index e658928305..ef9155dbd7 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -385,14 +385,21 @@ $(objpfx)tst-_dl_addr_inside_object: $(objpfx)dl-addr-obj.os
>   CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag)
>   endif
>   
> -# By default tst-linkall-static should try to use crypt routines to test
> -# static libcrypt use.
> +# We can only test static libcrypt use if libcrypt has been built,
> +# and either NSS crypto is not in use, or static NSS libraries are
> +# available.
> +ifeq ($(build-crypt),no)
> +CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
> +else
> +ifeq ($(nss-crypt),no)
> +CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
> +else
> +ifeq ($(static-nss-crypt),no)
> +CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
> +else
>   CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
> -# However, if we are using NSS crypto and we don't have a static
> -# library, then we exclude the use of crypt functions in the test.
> -# We similarly exclude libcrypt.a from the static link (see below).
> -ifeq (yesno,$(nss-crypt)$(static-nss-crypt))
> -CFLAGS-tst-linkall-static.c += -UUSE_CRYPT -DUSE_CRYPT=0
> +endif
> +endif
>   endif

Okay.

> @@ -1113,7 +1120,6 @@ localplt-built-dso := $(addprefix $(common-objpfx),\
>   				  rt/librt.so \
>   				  dlfcn/libdl.so \
>   				  resolv/libresolv.so \
> -				  crypt/libcrypt.so \
>   		       )
>   ifeq ($(build-mathvec),yes)
>   localplt-built-dso += $(addprefix $(common-objpfx), mathvec/libmvec.so)
> @@ -1121,6 +1127,9 @@ endif
>   ifeq ($(have-thread-library),yes)
>   localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library))
>   endif
> +ifeq ($(build-crypt),yes)
> +localplt-built-dso += $(addprefix $(common-objpfx), crypt/libcrypt.so)
> +endif

Okay.

> @@ -1395,6 +1404,7 @@ $(objpfx)tst-linkall-static: \
>     $(common-objpfx)resolv/libanl.a \
>     $(static-thread-library)
>   
> +ifeq ($(build-crypt),yes)
>   # If we are using NSS crypto and we have the ability to link statically
>   # then we include libcrypt.a, otherwise we leave out libcrypt.a and
>   # link as much as we can into the tst-linkall-static test.  This assumes
> @@ -1410,6 +1420,7 @@ ifeq (no,$(nss-crypt))
>   $(objpfx)tst-linkall-static: \
>     $(common-objpfx)crypt/libcrypt.a
>   endif
> +endif

Okay.

>   # The application depends on the DSO, and the DSO loads the plugin.
>   # The plugin also depends on the DSO. This creates the circular
> diff --git a/elf/tst-linkall-static.c b/elf/tst-linkall-static.c
> index e8df38f74e..d0f2592e67 100644
> --- a/elf/tst-linkall-static.c
> +++ b/elf/tst-linkall-static.c
> @@ -18,7 +18,9 @@
>   
>   #include <math.h>
>   #include <pthread.h>
> -#include <crypt.h>
> +#if USE_CRYPT
> +# include <crypt.h>
> +#endif
>   #include <resolv.h>
>   #include <dlfcn.h>
>   #include <utmp.h>

Okay.

> diff --git a/manual/install.texi b/manual/install.texi
> index 4bbbfcffa5..ce2d049f1a 100644
> --- a/manual/install.texi
> +++ b/manual/install.texi
> @@ -230,6 +230,18 @@ libnss_nisplus are not built at all.
>   Use this option to enable libnsl with all depending NSS modules and
>   header files.
>   
> +@item --disable-crypt
> +Do not install the password-hashing library @file{libcrypt} or the
> +header file @file{crypt.h}.  @file{unistd.h} will still declare the
> +function @code{crypt}, as required by POSIX.  Using this option does
> +not change the set of programs that may need to be linked with
> +@option{-lcrypt}; it only means that @theglibc{} will not provide that
> +library.

You need to use “POSIX@.” instead of “POSIX.” here.

> +This option is for hackers and distributions experimenting with
> +independently-maintained implementations of libcrypt.  It may become
> +the default in a future release.

Okay.

>   @item --disable-experimental-malloc
>   By default, a per-thread cache is enabled in @code{malloc}.  While
>   this cache can be disabled on a per-application basis using tunables
> diff --git a/posix/unistd.h b/posix/unistd.h
> index 5d4e07f6c8..fdf2d4b208 100644
> --- a/posix/unistd.h
> +++ b/posix/unistd.h
> @@ -1119,10 +1119,11 @@ extern int fdatasync (int __fildes);
>   #endif /* Use POSIX199309 */
>   
>   
> -/* XPG4.2 specifies that prototypes for the encryption functions must
> -   be defined here.  */
>   #ifdef	__USE_XOPEN
> -/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
> +/* Hash a password, KEY, for storage in /etc/shadow.  SALT selects the
> +   hashing algorithm to be used, and ensures that no two users' passwords
> +   are hashed to the same string.  The return value points to static
> +   storage which will be overwritten by the next call to crypt.  */
>   extern char *crypt (const char *__key, const char *__salt)
>        __THROW __nonnull ((1, 2));

Okay.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 4/4] New configure option --disable-crypt.
  2018-05-06 17:52 [PATCH 0/4 v3] Revise crypto documentation, deprecate DES, add --disable-crypt Zack Weinberg
@ 2018-05-06 17:52 ` Zack Weinberg
  2018-05-08 15:00   ` Florian Weimer
  0 siblings, 1 reply; 24+ messages in thread
From: Zack Weinberg @ 2018-05-06 17:52 UTC (permalink / raw)
  To: libc-alpha; +Cc: carlos, fweimer, rj

Some Linux distributions are experimenting with a new, separately
maintained and hopefully more agile implementation of the crypt(3)
APIs.  To facilitate this, add a configure option which disables
glibc's embedded libcrypt.  When this option is given, libcrypt.*
and crypt.h will not be built nor installed.

unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.

The bulk of the patch is just various places that need to take note of
libcrypt possibly not getting built.

        * configure.ac: New command-line option --disable-crypt.
        Force --disable-nss-crypt when --disable-crypt is given, with a
        warning if it was explicitly enabled.
        * configure: Regenerate.
        * config.make.in: New boolean substitution variable $(build-crypt).
        * Makeconfig: Only include 'crypt' in all-subdirs and rpath-dirs
        when $(build-crypt).
        * manual/install.texi: Document --disable-crypt.
        * INSTALL: Regenerate.

        * crypt/Makefile: Remove code conditional on $(crypt-in-libc),
        which is never set.
        * conform/Makefile: Only include libcrypt.a in
        linknamespace-libs-xsi and linknamespace-libs-XPG4
        when $(build-crypt).
        * elf/Makefile (CFLAGS-tst-linkall-static.c): Only define
        USE_CRYPT to 1 when $(build-crypt).
        (tst-linkall-static): Only link libcrypt.a when $(build-crypt).
        (localplt-built-dso): Only add libcrypt.so when $(build-crypt).
        * elf/tst-linkall-static.c: Only include crypt.h when USE_CRYPT.

        * crypt/crypt.h: Update comments above crypt.
        * posix/unistd.h: Update comments above crypt.
---
 INSTALL                  | 11 +++++++++++
 Makeconfig               |  9 +++++++--
 NEWS                     | 12 ++++++++++++
 config.make.in           |  1 +
 configure                | 18 ++++++++++++++++++
 configure.ac             | 11 +++++++++++
 conform/Makefile         | 11 +++++++----
 crypt/Makefile           |  4 ----
 crypt/crypt.h            |  5 ++++-
 elf/Makefile             | 27 +++++++++++++++++++--------
 elf/tst-linkall-static.c |  4 +++-
 manual/install.texi      | 12 ++++++++++++
 posix/unistd.h           |  7 ++++---
 13 files changed, 109 insertions(+), 23 deletions(-)

diff --git a/INSTALL b/INSTALL
index 052b1b6f89..6de609c9d6 100644
--- a/INSTALL
+++ b/INSTALL
@@ -197,6 +197,17 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
      libnss_nisplus are not built at all.  Use this option to enable
      libnsl with all depending NSS modules and header files.
 
+'--disable-crypt'
+     Do not install the password-hashing library 'libcrypt' or the
+     header file 'crypt.h'.  'unistd.h' will still declare the function
+     'crypt', as required by POSIX. Using this option does not change
+     the set of programs that may need to be linked with '-lcrypt'; it
+     only means that the GNU C Library will not provide that library.
+
+     This option is for hackers and distributions experimenting with
+     independently-maintained implementations of libcrypt.  It may
+     become the default in a future release.
+
 '--disable-experimental-malloc'
      By default, a per-thread cache is enabled in 'malloc'.  While this
      cache can be disabled on a per-application basis using tunables
diff --git a/Makeconfig b/Makeconfig
index 1afe86475c..608ffe648c 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -566,7 +566,7 @@ link-libc-printers-tests = $(link-libc-rpath) \
 			   $(link-libc-tests-after-rpath-link)
 
 # This is how to find at build-time things that will be installed there.
-rpath-dirs = math elf dlfcn nss nis rt resolv crypt mathvec support
+rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support
 rpath-link = \
 $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
 else  # build-static
@@ -1205,9 +1205,14 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal	    \
 	      stdlib stdio-common libio malloc string wcsmbs time dirent    \
 	      grp pwd posix io termios resource misc socket sysvipc gmon    \
 	      gnulib iconv iconvdata wctype manual shadow gshadow po argp   \
-	      crypt localedata timezone rt conform debug mathvec support    \
+	      localedata timezone rt conform debug mathvec support	    \
 	      dlfcn elf
 
+ifeq ($(build-crypt),yes)
+all-subdirs += crypt
+rpath-dirs += crypt
+endif
+
 ifndef avoid-generated
 # sysd-sorted itself will contain rules making the sysd-sorted target
 # depend on Depend files.  But if you just added a Depend file to an
diff --git a/NEWS b/NEWS
index 2fe2da8b59..cfc58f71bb 100644
--- a/NEWS
+++ b/NEWS
@@ -71,6 +71,18 @@ Deprecated and removed features, and other changes affecting compatibility:
   encrypt and setkey are not thread-safe.  Software that still uses these
   functions should switch to a modern cryptography library, such as GnuTLS.
 
+* We have tentative plans to deprecate glibc's implementation of the
+  password-hashing functions 'crypt' and 'crypt_r'.  We will continue
+  to declare crypt in <unistd.h>, as required by POSIX, and programs
+  that use crypt or crypt_r should not need to change at all.  However,
+  the header file <crypt.h> and library libcrypt.{a,so} will come from
+  a separate development project that will, we hope, keep up better with
+  new password-hashing algorithms.
+
+  In this release, if the configure option --disable-crypt is used,
+  glibc will not install <crypt.h> or libcrypt.  The plan is to make
+  this the default behavior in a future release.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/config.make.in b/config.make.in
index 9e5e24b2c6..d9891b2cd8 100644
--- a/config.make.in
+++ b/config.make.in
@@ -96,6 +96,7 @@ cross-compiling = @cross_compiling@
 force-install = @force_install@
 link-obsolete-rpc = @link_obsolete_rpc@
 build-obsolete-nsl = @build_obsolete_nsl@
+build-crypt = @build_crypt@
 build-nscd = @build_nscd@
 use-nscd = @use_nscd@
 build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
diff --git a/configure b/configure
index 7a8bd3f817..7317c1aee4 100755
--- a/configure
+++ b/configure
@@ -676,6 +676,7 @@ build_obsolete_nsl
 link_obsolete_rpc
 libc_cv_static_nss_crypt
 libc_cv_nss_crypt
+build_crypt
 experimental_malloc
 enable_werror
 all_warnings
@@ -779,6 +780,7 @@ enable_all_warnings
 enable_werror
 enable_multi_arch
 enable_experimental_malloc
+enable_crypt
 enable_nss_crypt
 enable_obsolete_rpc
 enable_obsolete_nsl
@@ -1448,6 +1450,8 @@ Optional Features:
                           architectures
   --disable-experimental-malloc
                           disable experimental malloc features
+  --disable-crypt         do not build nor install the password hashing
+                          library, libcrypt
   --enable-nss-crypt      enable libcrypt to use nss
   --enable-obsolete-rpc   build and install the obsolete RPC code for
                           link-time usage
@@ -3505,6 +3509,15 @@ fi
 
 
 
+# Check whether --enable-crypt was given.
+if test "${enable_crypt+set}" = set; then :
+  enableval=$enable_crypt; build_crypt=$enableval
+else
+  build_crypt=yes
+fi
+
+
+
 # Check whether --enable-nss-crypt was given.
 if test "${enable_nss_crypt+set}" = set; then :
   enableval=$enable_nss_crypt; nss_crypt=$enableval
@@ -3512,6 +3525,11 @@ else
   nss_crypt=no
 fi
 
+if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&5
+$as_echo "$as_me: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&2;}
+  nss_crypt=no
+fi
 if test x$nss_crypt = xyes; then
   nss_includes=-I$(nss-config --includedir 2>/dev/null)
   if test $? -ne 0; then
diff --git a/configure.ac b/configure.ac
index ca1282a6b3..05e03f2f72 100644
--- a/configure.ac
+++ b/configure.ac
@@ -302,11 +302,22 @@ AC_ARG_ENABLE([experimental-malloc],
 	      [experimental_malloc=yes])
 AC_SUBST(experimental_malloc)
 
+AC_ARG_ENABLE([crypt],
+              AC_HELP_STRING([--disable-crypt],
+                             [do not build nor install the password hashing library, libcrypt]),
+              [build_crypt=$enableval],
+              [build_crypt=yes])
+AC_SUBST(build_crypt)
+
 AC_ARG_ENABLE([nss-crypt],
 	      AC_HELP_STRING([--enable-nss-crypt],
 			     [enable libcrypt to use nss]),
 	      [nss_crypt=$enableval],
 	      [nss_crypt=no])
+if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
+  AC_MSG_WARN([--enable-nss-crypt has no effect when libcrypt is disabled])
+  nss_crypt=no
+fi
 if test x$nss_crypt = xyes; then
   nss_includes=-I$(nss-config --includedir 2>/dev/null)
   if test $? -ne 0; then
diff --git a/conform/Makefile b/conform/Makefile
index 864fdeca21..74fbda0786 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -193,13 +193,11 @@ linknamespace-libs-thr = $(linknamespace-libs-isoc) \
 			 $(common-objpfx)rt/librt.a $(static-thread-library)
 linknamespace-libs-posix = $(linknamespace-libs-thr) \
 			   $(common-objpfx)dlfcn/libdl.a
-linknamespace-libs-xsi = $(linknamespace-libs-posix) \
-			 $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-xsi = $(linknamespace-libs-posix)
 linknamespace-libs-ISO = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)
-linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \
-			  $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 = $(linknamespace-libs-isoc)
 linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)
 linknamespace-libs-POSIX = $(linknamespace-libs-thr)
 linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi)
@@ -209,6 +207,11 @@ linknamespace-libs-XOPEN2K8 = $(linknamespace-libs-xsi)
 linknamespace-libs = $(foreach std,$(conformtest-standards),\
 				   $(linknamespace-libs-$(std)))
 
+ifeq ($(build-crypt),yes)
+linknamespace-libs-xsi += $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 += $(common-objpfx)crypt/libcrypt.a
+endif
+
 $(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \
 					$(linknamespace-libs)
 	LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \
diff --git a/crypt/Makefile b/crypt/Makefile
index e122bcebf0..1e2f21bf52 100644
--- a/crypt/Makefile
+++ b/crypt/Makefile
@@ -35,10 +35,6 @@ tests := cert md5c-test sha256c-test sha512c-test badsalttest
 # cert.c tests the deprecated setkey/encrypt interface
 CFLAGS-cert.c = -Wno-deprecated-declarations
 
-ifeq ($(crypt-in-libc),yes)
-routines += $(libcrypt-routines)
-endif
-
 ifeq ($(nss-crypt),yes)
 nss-cpp-flags := -DUSE_NSS \
   -I$(shell nss-config --includedir) -I$(shell nspr-config --includedir)
diff --git a/crypt/crypt.h b/crypt/crypt.h
index 22cf13ff89..4f928901f3 100644
--- a/crypt/crypt.h
+++ b/crypt/crypt.h
@@ -28,7 +28,10 @@
 
 __BEGIN_DECLS
 
-/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
+/* Hash a password, KEY, for storage in /etc/shadow.  SALT selects the
+   hashing algorithm to be used, and ensures that no two users' passwords
+   are hashed to the same string.  The return value points to static
+   storage which will be overwritten by the next call to crypt.  */
 extern char *crypt (const char *__key, const char *__salt)
      __THROW __nonnull ((1, 2));
 
diff --git a/elf/Makefile b/elf/Makefile
index e658928305..ef9155dbd7 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -385,14 +385,21 @@ $(objpfx)tst-_dl_addr_inside_object: $(objpfx)dl-addr-obj.os
 CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag)
 endif
 
-# By default tst-linkall-static should try to use crypt routines to test
-# static libcrypt use.
+# We can only test static libcrypt use if libcrypt has been built,
+# and either NSS crypto is not in use, or static NSS libraries are
+# available.
+ifeq ($(build-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
+else
+ifeq ($(nss-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
+else
+ifeq ($(static-nss-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
+else
 CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
-# However, if we are using NSS crypto and we don't have a static
-# library, then we exclude the use of crypt functions in the test.
-# We similarly exclude libcrypt.a from the static link (see below).
-ifeq (yesno,$(nss-crypt)$(static-nss-crypt))
-CFLAGS-tst-linkall-static.c += -UUSE_CRYPT -DUSE_CRYPT=0
+endif
+endif
 endif
 
 include ../Rules
@@ -1113,7 +1120,6 @@ localplt-built-dso := $(addprefix $(common-objpfx),\
 				  rt/librt.so \
 				  dlfcn/libdl.so \
 				  resolv/libresolv.so \
-				  crypt/libcrypt.so \
 		       )
 ifeq ($(build-mathvec),yes)
 localplt-built-dso += $(addprefix $(common-objpfx), mathvec/libmvec.so)
@@ -1121,6 +1127,9 @@ endif
 ifeq ($(have-thread-library),yes)
 localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library))
 endif
+ifeq ($(build-crypt),yes)
+localplt-built-dso += $(addprefix $(common-objpfx), crypt/libcrypt.so)
+endif
 
 vpath localplt.data $(+sysdep_dirs)
 
@@ -1395,6 +1404,7 @@ $(objpfx)tst-linkall-static: \
   $(common-objpfx)resolv/libanl.a \
   $(static-thread-library)
 
+ifeq ($(build-crypt),yes)
 # If we are using NSS crypto and we have the ability to link statically
 # then we include libcrypt.a, otherwise we leave out libcrypt.a and
 # link as much as we can into the tst-linkall-static test.  This assumes
@@ -1410,6 +1420,7 @@ ifeq (no,$(nss-crypt))
 $(objpfx)tst-linkall-static: \
   $(common-objpfx)crypt/libcrypt.a
 endif
+endif
 
 # The application depends on the DSO, and the DSO loads the plugin.
 # The plugin also depends on the DSO. This creates the circular
diff --git a/elf/tst-linkall-static.c b/elf/tst-linkall-static.c
index e8df38f74e..d0f2592e67 100644
--- a/elf/tst-linkall-static.c
+++ b/elf/tst-linkall-static.c
@@ -18,7 +18,9 @@
 
 #include <math.h>
 #include <pthread.h>
-#include <crypt.h>
+#if USE_CRYPT
+# include <crypt.h>
+#endif
 #include <resolv.h>
 #include <dlfcn.h>
 #include <utmp.h>
diff --git a/manual/install.texi b/manual/install.texi
index 4bbbfcffa5..ce2d049f1a 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -230,6 +230,18 @@ libnss_nisplus are not built at all.
 Use this option to enable libnsl with all depending NSS modules and
 header files.
 
+@item --disable-crypt
+Do not install the password-hashing library @file{libcrypt} or the
+header file @file{crypt.h}.  @file{unistd.h} will still declare the
+function @code{crypt}, as required by POSIX.  Using this option does
+not change the set of programs that may need to be linked with
+@option{-lcrypt}; it only means that @theglibc{} will not provide that
+library.
+
+This option is for hackers and distributions experimenting with
+independently-maintained implementations of libcrypt.  It may become
+the default in a future release.
+
 @item --disable-experimental-malloc
 By default, a per-thread cache is enabled in @code{malloc}.  While
 this cache can be disabled on a per-application basis using tunables
diff --git a/posix/unistd.h b/posix/unistd.h
index 5d4e07f6c8..fdf2d4b208 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -1119,10 +1119,11 @@ extern int fdatasync (int __fildes);
 #endif /* Use POSIX199309 */
 
 
-/* XPG4.2 specifies that prototypes for the encryption functions must
-   be defined here.  */
 #ifdef	__USE_XOPEN
-/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
+/* Hash a password, KEY, for storage in /etc/shadow.  SALT selects the
+   hashing algorithm to be used, and ensures that no two users' passwords
+   are hashed to the same string.  The return value points to static
+   storage which will be overwritten by the next call to crypt.  */
 extern char *crypt (const char *__key, const char *__salt)
      __THROW __nonnull ((1, 2));
 
-- 
2.17.0

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2018-06-28 18:52 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-21 17:39 [PATCH 0/4 v3] libcrypt phaseout Zack Weinberg
2018-05-21 17:39 ` [PATCH 4/4] New configure option --disable-crypt Zack Weinberg
2018-05-21 19:52   ` Joseph Myers
2018-05-21 22:07     ` Zack Weinberg
2018-05-21 22:34       ` Joseph Myers
2018-05-22  1:08         ` Zack Weinberg
2018-06-20 20:40         ` Florian Weimer
2018-06-20 22:48           ` Zack Weinberg
2018-06-21  9:31             ` Florian Weimer
2018-06-21  9:32               ` Florian Weimer
2018-06-28 18:52               ` Zack Weinberg
2018-05-21 17:39 ` [PATCH 3/4] Revise crypt.texi Zack Weinberg
2018-05-25  2:52   ` Rical Jasan
2018-06-25 12:21     ` Florian Weimer
2018-06-25 12:26   ` Florian Weimer
2018-05-21 17:39 ` [PATCH 1/4] Disallow use of DES encryption functions in new programs Zack Weinberg
2018-05-22  6:58   ` Florian Weimer
2018-05-23  3:37   ` Rical Jasan
2018-05-23 16:50     ` Joseph Myers
2018-05-21 17:39 ` [PATCH 2/4] Reorganize crypt.texi Zack Weinberg
2018-05-23  5:23   ` Rical Jasan
  -- strict thread matches above, loose matches on Subject: below --
2018-05-06 17:52 [PATCH 0/4 v3] Revise crypto documentation, deprecate DES, add --disable-crypt Zack Weinberg
2018-05-06 17:52 ` [PATCH 4/4] New configure option --disable-crypt Zack Weinberg
2018-05-08 15:00   ` Florian Weimer
2018-05-08 15:22     ` Zack Weinberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).