about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--NEWS17
-rw-r--r--conform/data/stdlib.h-data3
-rw-r--r--conform/data/unistd.h-data6
-rw-r--r--crypt/cert.c26
-rw-r--r--crypt/crypt-entry.c15
-rw-r--r--crypt/crypt.h18
-rw-r--r--crypt/crypt_util.c9
-rw-r--r--manual/conf.texi2
-rw-r--r--manual/crypt.texi201
-rw-r--r--manual/string.texi82
-rw-r--r--posix/unistd.h16
-rw-r--r--stdlib/stdlib.h6
-rw-r--r--sunrpc/Makefile2
-rw-r--r--sunrpc/des_crypt.c7
-rw-r--r--sunrpc/des_soft.c2
16 files changed, 142 insertions, 303 deletions
diff --git a/ChangeLog b/ChangeLog
index 55d4f3a3c5..d3c4c423e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2018-06-29  Zack Weinberg  <zackw@panix.com>
+	    Florian Weimer <fweimer@redhat.com>
+
+	* posix/unistd.h: Do not declare encrypt.
+	(_XOPEN_CRYPT): Remove macro definition.
+	(crypt): Declare only for _USE_MISC.
+	* 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/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.
+	* manual/conf.texi (Constants for Sysconf): Mention that
+	_XOPEN_CRYPT is no longer impelemented.
+
+	* conform/data/unistd.h-data: Remove crypt function declaration.
+
 2018-06-29  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #23351]
diff --git a/NEWS b/NEWS
index d1de6830a1..ebe63a2f40 100644
--- a/NEWS
+++ b/NEWS
@@ -116,6 +116,23 @@ Deprecated and removed features, and other changes affecting compatibility:
   fcntl and LFS support is handled transparently.  Also for Linux, the OFD
   locks act as a cancellation entrypoint.
 
+* 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.
+
+* Reflecting the removal of the encrypt and setkey functions above, the
+  macro _XOPEN_CRYPT is no longer defined.  As a consequence, the crypt
+  function is no longer declared unless _DEFAULT_SOURCE or _GNU_SOURCE is
+  enabled.
+
+* 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..aa070528e8 100644
--- a/conform/data/unistd.h-data
+++ b/conform/data/unistd.h-data
@@ -437,9 +437,6 @@ function int chroot (const char*)
 function int chown (const char*, uid_t, gid_t)
 function int close (int)
 function size_t confstr (int, char*, size_t)
-#if !defined POSIX && !defined POSIX2008
-function {char*} crypt (const char*, const char*)
-#endif
 #if defined XPG4 || defined XPG42 || defined UNIX98
 function {char*} ctermid (char*)
 function {char*} cuserid (char*)
@@ -449,9 +446,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/cert.c b/crypt/cert.c
index 80029e9078..e070ca398d 100644
--- a/crypt/cert.c
+++ b/crypt/cert.c
@@ -10,6 +10,22 @@
 #include <stdlib.h>
 #include "crypt.h"
 
+/* This file tests the deprecated setkey/encrypt interface.  */
+#include <shlib-compat.h>
+#if TEST_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 +120,13 @@ 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/conf.texi b/manual/conf.texi
index f1dce4aa44..dbd1d30287 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -778,6 +778,8 @@ Inquire about the parameter corresponding to @code{_XOPEN_LEGACY}.
 @item _SC_XOPEN_CRYPT
 @standards{X/Open, unistd.h}
 Inquire about the parameter corresponding to @code{_XOPEN_CRYPT}.
+@Theglibc no longer implements the @code{_XOPEN_CRYPT} extensions,
+so @samp{sysconf (_SC_XOPEN_CRYPT)} always returns @code{-1}.
 
 @item _SC_XOPEN_ENH_I18N
 @standards{X/Open, unistd.h}
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..afb08f5186 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -107,9 +107,6 @@ __BEGIN_DECLS
 /* The X/Open Unix extensions are available.  */
 #define _XOPEN_UNIX	1
 
-/* Encryption is present.  */
-#define	_XOPEN_CRYPT	1
-
 /* The enhanced internationalization capabilities according to XPG4.2
    are present.  */
 #define	_XOPEN_ENH_I18N	1
@@ -1118,20 +1115,13 @@ 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
+#ifdef __USE_MISC
 /* 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));
+#endif
 
-/* 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_XOPEN
 /* 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 0e2f8d7c9e..85b0b3356a 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)