Deprecate libcrypt and don't build it by default.

Message ID 20170829184247.6875-1-zackw@panix.com
State Superseded
Headers

Commit Message

Zack Weinberg Aug. 29, 2017, 6:42 p.m. UTC
  Back in June, Björn Esser proposed to add OpenBSD-compatible bcrypt
support to our implementation of crypt(3), and I replied that it might
actually make more sense to _remove_ libcrypt from glibc, freeing up
libcrypt.so.1 and crypt.h to be provided by a separate project that
could move faster.  (For instance, libxcrypt:
https://github.com/besser82/libxcrypt)

This patch disables build and installation of libcrypt by default.  It
can be re-enabled with --enable-obsolete-crypt to configure.  Unlike
libnsl, we do *not* install a runtime shared library; that's left to
the replacement.  (Unlike the SunRPC situation, I think we can
probably drop this code altogether in a release or two.)

The function prototypes for crypt and encrypt are removed from
unistd.h, and the function prototype for setkey is removed from
stdlib.h; they do *not* come back with --enable-obsolete-crypt.  This
means glibc no longer provides the POSIX CRYPT option, and the macro
_XOPEN_CRYPT is also removed from unistd.h to indicate that.
(_SC_XOPEN_CRYPT is still defined, but sysconf(_SC_XOPEN_CRYPT) will
return -1 at runtime.)  These functions are also unconditionally
removed from conform/data/{stdlib,unistd}.h-data.

	* posix/unistd.h (_XOPEN_CRYPT, crypt, encrypt): Don't declare.
	* stdlib/stdlib.h (setkey): Don't declare.

	* configure.ac (--enable-obsolete-crypt): New configure option.
	* configure: Regenerate.
	* config.make.in (build-obsolete-crypt): New makefile variable.
	* crypt/Banner: Delete file.
	* crypt/Makefile: Don't build anything unless
	$(build-obsolete-crypt) is 'yes'.
	* sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile: Only add things
	to libcrypt-sysdep_routines when $(build-obsolete-crypt) is 'yes'.
	* sysdeps/sparc/sparc64/multiarch/Makefile: Likewise.
	* sysdeps/unix/sysv/linux/arm/Makefile: Likewise.

	* conform/Makefile: Only include libcrypt.a in linknamespace tests
	when $(build-obsolete-crypt) is 'yes'.
	* conform/data/stdlib.h-data (setkey): Don't expect.
	* conform/data/unistd.h-data (crypt, encrypt): Don't expect.
	* elf/Makefile: Only perform various tests of libcrypt.so/libcrypt.a
	when $(build-obsolete-crypt) is 'yes'.
	* elf/tst-linkall-static.c: Don't include crypt.h when USE_CRYPT
	is false.
---
 NEWS                                             | 18 ++++++++++++++++++
 config.make.in                                   |  1 +
 configure                                        | 13 +++++++++++++
 configure.ac                                     |  8 ++++++++
 conform/Makefile                                 | 14 ++++++++++----
 conform/data/stdlib.h-data                       |  3 ---
 conform/data/unistd.h-data                       |  6 ------
 crypt/Banner                                     |  1 -
 crypt/Makefile                                   |  5 +++++
 elf/Makefile                                     | 14 +++++++++++---
 elf/tst-linkall-static.c                         |  2 ++
 posix/unistd.h                                   | 16 ----------------
 stdlib/stdlib.h                                  |  6 ------
 sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile |  2 ++
 sysdeps/sparc/sparc64/multiarch/Makefile         |  2 ++
 sysdeps/unix/sysv/linux/arm/Makefile             |  2 ++
 16 files changed, 74 insertions(+), 39 deletions(-)
 delete mode 100644 crypt/Banner
  

Comments

Joseph Myers Aug. 29, 2017, 8:16 p.m. UTC | #1
On Tue, 29 Aug 2017, Zack Weinberg wrote:

> Back in June, Björn Esser proposed to add OpenBSD-compatible bcrypt
> support to our implementation of crypt(3), and I replied that it might
> actually make more sense to _remove_ libcrypt from glibc, freeing up
> libcrypt.so.1 and crypt.h to be provided by a separate project that
> could move faster.  (For instance, libxcrypt:
> https://github.com/besser82/libxcrypt)

I don't believe libxcrypt's claim to be a binary-compatible replacement 
for libcrypt.so.1.  It looks to me like it uses symbol version GLIBC_2.0 
unconditionally for the glibc symbols, when the actual base version 
depends on the architecture / ABI for which glibc is built; GLIBC_2.0 is 
only for a few architectures such as i386 with very longstanding ports.  
(It could of course be taught to find the base version at configure time, 
e.g. by checking the output of objdump -T on libc for a symbol such as abs 
we can be confident won't get new symbol versions, though for that you 
first need to locate the shared libc the compiler is linking against, 
which is not completely trivial - "$CC $CFLAGS $CPPFLAGS 
-print-file-name=libc.so" will give you the linker script, not the shared 
library, and paths therein may be relative to a sysroot so you'd need to 
process the linker script and combine with -print-sysroot output; "$CC 
$CFLAGS $CPPFLAGS -print-file-name=libc.so.6" is incorrect on alpha where 
it's libc.so.6.1.)
  
Zack Weinberg Aug. 29, 2017, 8:49 p.m. UTC | #2
On Tue, Aug 29, 2017 at 4:16 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Tue, 29 Aug 2017, Zack Weinberg wrote:
>> Back in June, Björn Esser proposed to add OpenBSD-compatible bcrypt
>> support to our implementation of crypt(3), and I replied that it might
>> actually make more sense to _remove_ libcrypt from glibc, freeing up
>> libcrypt.so.1 and crypt.h to be provided by a separate project that
>> could move faster.  (For instance, libxcrypt:
>> https://github.com/besser82/libxcrypt)
>
> I don't believe libxcrypt's claim to be a binary-compatible replacement
> for libcrypt.so.1.  It looks to me like it uses symbol version GLIBC_2.0
> unconditionally for the glibc symbols, when the actual base version
> depends on the architecture / ABI for which glibc is built; GLIBC_2.0 is
> only for a few architectures such as i386 with very longstanding ports.

Well, that's just a plain old bug.  Obviously a bug that needs to be
fixed before we can call libxcrypt a binary-compatible drop-in
replacement, but not a _difficult_ bug - they can crib from the
libcrypt.abilist files.  I'm willing to try to work up a patch if
Björn agrees.

(The soname needs to be libcrypt.so.1.1 on alpha, too.)

zw
  
Joseph Myers Aug. 29, 2017, 8:58 p.m. UTC | #3
On Tue, 29 Aug 2017, Zack Weinberg wrote:

> On Tue, Aug 29, 2017 at 4:16 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> > On Tue, 29 Aug 2017, Zack Weinberg wrote:
> >> Back in June, Björn Esser proposed to add OpenBSD-compatible bcrypt
> >> support to our implementation of crypt(3), and I replied that it might
> >> actually make more sense to _remove_ libcrypt from glibc, freeing up
> >> libcrypt.so.1 and crypt.h to be provided by a separate project that
> >> could move faster.  (For instance, libxcrypt:
> >> https://github.com/besser82/libxcrypt)
> >
> > I don't believe libxcrypt's claim to be a binary-compatible replacement
> > for libcrypt.so.1.  It looks to me like it uses symbol version GLIBC_2.0
> > unconditionally for the glibc symbols, when the actual base version
> > depends on the architecture / ABI for which glibc is built; GLIBC_2.0 is
> > only for a few architectures such as i386 with very longstanding ports.
> 
> Well, that's just a plain old bug.  Obviously a bug that needs to be
> fixed before we can call libxcrypt a binary-compatible drop-in
> replacement, but not a _difficult_ bug - they can crib from the
> libcrypt.abilist files.  I'm willing to try to work up a patch if
> Björn agrees.

I'm not convinced that duplicating all the information about which ABIs 
use which symbol versions, and how to distinguish different ABIs on each 
architecture that has ABIs with different base versions, is a good idea.

(powerpc64le uses libcrypt-le.abilist; if you just used libcrypt.abilist 
files, you'd miss that one.)
  
Zack Weinberg Aug. 29, 2017, 9:20 p.m. UTC | #4
On Tue, Aug 29, 2017 at 4:58 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Tue, 29 Aug 2017, Zack Weinberg wrote:
>> On Tue, Aug 29, 2017 at 4:16 PM, Joseph Myers <joseph@codesourcery.com> wrote:
>> >
>> > I don't believe libxcrypt's claim to be a binary-compatible replacement
>> > for libcrypt.so.1.  It looks to me like it uses symbol version GLIBC_2.0
>> > unconditionally for the glibc symbols,
>>
>> Well, that's just a plain old bug.  Obviously a bug that needs to be
>> fixed before we can call libxcrypt a binary-compatible drop-in
>> replacement, but not a _difficult_ bug - they can crib from the
>> libcrypt.abilist files.  I'm willing to try to work up a patch if
>> Björn agrees.
>
> I'm not convinced that duplicating all the information about which ABIs
> use which symbol versions, and how to distinguish different ABIs on each
> architecture that has ABIs with different base versions, is a good idea.

The plan would be to remove libcrypt from glibc one or two releases
after this deprecation, so it's not so much _duplicating_ the
information as _moving_ it.

zw
  
Carlos O'Donell Aug. 31, 2017, 5:29 p.m. UTC | #5
On 08/29/2017 04:20 PM, Zack Weinberg wrote:
> On Tue, Aug 29, 2017 at 4:58 PM, Joseph Myers <joseph@codesourcery.com> wrote:
>> On Tue, 29 Aug 2017, Zack Weinberg wrote:
>>> On Tue, Aug 29, 2017 at 4:16 PM, Joseph Myers <joseph@codesourcery.com> wrote:
>>>>
>>>> I don't believe libxcrypt's claim to be a binary-compatible replacement
>>>> for libcrypt.so.1.  It looks to me like it uses symbol version GLIBC_2.0
>>>> unconditionally for the glibc symbols,
>>>
>>> Well, that's just a plain old bug.  Obviously a bug that needs to be
>>> fixed before we can call libxcrypt a binary-compatible drop-in
>>> replacement, but not a _difficult_ bug - they can crib from the
>>> libcrypt.abilist files.  I'm willing to try to work up a patch if
>>> Björn agrees.
>>
>> I'm not convinced that duplicating all the information about which ABIs
>> use which symbol versions, and how to distinguish different ABIs on each
>> architecture that has ABIs with different base versions, is a good idea.
> 
> The plan would be to remove libcrypt from glibc one or two releases
> after this deprecation, so it's not so much _duplicating_ the
> information as _moving_ it.

I disagree that removal can happen on those timescales, but I agree that
it would be a good idea to split libcrypt out of glibc to allow for a
different development model

For example libcrypt + Network Security Services (NSS) (--enable-nss-crypt)
is used by many users who need US government compliance with FIPS 140-1. It's
not clear to me that libxcrypt provides that kind of compliance. This means
that until then we'd need to keep the compat code in glibc. This doesn't mean
we can just sit around waiting for things to happen, I think Red Hat can and
should take an active role in helping libxcrypt.

Like the Sun RPC to TIRPC transition, it is a long, long, way to Tipperary.
  
Dmitry V. Levin Sept. 8, 2017, 1:23 p.m. UTC | #6
On Thu, Aug 31, 2017 at 12:29:48PM -0500, Carlos O'Donell wrote:
> On 08/29/2017 04:20 PM, Zack Weinberg wrote:
> > On Tue, Aug 29, 2017 at 4:58 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> >> On Tue, 29 Aug 2017, Zack Weinberg wrote:
> >>> On Tue, Aug 29, 2017 at 4:16 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> >>>>
> >>>> I don't believe libxcrypt's claim to be a binary-compatible replacement
> >>>> for libcrypt.so.1.  It looks to me like it uses symbol version GLIBC_2.0
> >>>> unconditionally for the glibc symbols,
> >>>
> >>> Well, that's just a plain old bug.  Obviously a bug that needs to be
> >>> fixed before we can call libxcrypt a binary-compatible drop-in
> >>> replacement, but not a _difficult_ bug - they can crib from the
> >>> libcrypt.abilist files.  I'm willing to try to work up a patch if
> >>> Björn agrees.
> >>
> >> I'm not convinced that duplicating all the information about which ABIs
> >> use which symbol versions, and how to distinguish different ABIs on each
> >> architecture that has ABIs with different base versions, is a good idea.
> > 
> > The plan would be to remove libcrypt from glibc one or two releases
> > after this deprecation, so it's not so much _duplicating_ the
> > information as _moving_ it.
> 
> I disagree that removal can happen on those timescales, but I agree that
> it would be a good idea to split libcrypt out of glibc to allow for a
> different development model

If the consensus is to remove libcrypt from glibc sooner or later rather
than extend libcrypt with API from crypt_blowfish project, then libxcrypt
is not going to be the only alternative.

In ALT, I merged crypt_blowfish into glibc's libcrypt more than 16 years
ago, and the way it's done is incompatible with the approach taken later
by libxcrypt:
function names in XCRYPT_2.0 interface differ from function names in new
interfaces we added, and the plugin approach implemented in libxcrypt that
uses dlopen+dlsym to pull in encryption methods is absolutely no-no for
the system libcrypt.

As extending libcrypt within glibc doesn't seem to be a viable option, the
current status quo works well for us because the burden of rebasing a huge
patch on top of the stale libcrypt is minimal.

On the contrary, libcrypt removal would force ALT to fork a standalone
libcrypt, that is, to invest our time and efforts into a project without
any clear benefits to anyone.
  

Patch

diff --git a/NEWS b/NEWS
index 8fe0879bc44..9a35ca4a050 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,24 @@  Major new features:
 
 Deprecated and removed features, and other changes affecting compatibility:
 
+* The password-hashing library is deprecated, and will not be built or
+  installed by default.  This only affects programs that link with -lcrypt,
+  include the header <crypt.h>, use the functions 'crypt', 'encrypt', or
+  'setkey' (which were formerly declared in <unistd.h> and/or <stdlib.h>),
+  or inspect the feature-test macro _XOPEN_CRYPT.
+
+  A drop-in replacement for libcrypt and crypt.h is available from
+  https://github.com/besser82/libxcrypt.  It also supports newer and more
+  secure password hashes.
+
+  The configure option --enable-obsolete-crypt will cause libcrypt and
+  crypt.h to be built and installed, but will not restore the declarations
+  of 'crypt', 'encrypt', and 'setkey' in other headers, nor will it cause
+  the feature-test macro _XOPEN_CRYPT to be defined.
+
+  Note that the configure option --enable-nss-crypt only affects libcrypt,
+  and therefore will only have an effect when --enable-obsolete-crypt is used.
+
 * On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer
   defined by <sys/ptrace.h>.
 
diff --git a/config.make.in b/config.make.in
index ea7a42cc191..ad8de5e3ed0 100644
--- a/config.make.in
+++ b/config.make.in
@@ -81,6 +81,7 @@  mach-interface-list = @mach_interface_list@
 
 experimental-malloc = @experimental_malloc@
 
+build-obsolete-crypt = @build_obsolete_crypt@
 nss-crypt = @libc_cv_nss_crypt@
 static-nss-crypt = @libc_cv_static_nss_crypt@
 
diff --git a/configure b/configure
index 5cb52101077..5e2af72678b 100755
--- a/configure
+++ b/configure
@@ -672,6 +672,7 @@  add_ons
 have_tunables
 build_pt_chown
 build_nscd
+build_obsolete_crypt
 build_obsolete_nsl
 link_obsolete_rpc
 libc_cv_static_nss_crypt
@@ -786,6 +787,7 @@  enable_experimental_malloc
 enable_nss_crypt
 enable_obsolete_rpc
 enable_obsolete_nsl
+enable_obsolete_crypt
 enable_systemtap
 enable_build_nscd
 enable_nscd
@@ -1461,6 +1463,7 @@  Optional Features:
                           link-time usage
   --enable-obsolete-nsl   build and install the obsolete libnsl library and
                           depending NSS modules
+  --enable-obsolete-crypt build and install the obsolete libcrypt library
   --enable-systemtap      enable systemtap static probe points [default=no]
   --disable-build-nscd    disable building and installing the nscd daemon
   --disable-nscd          library functions will not contact the nscd daemon
@@ -3660,6 +3663,16 @@  if test "$build_obsolete_nsl" = yes; then
 
 fi
 
+# Check whether --enable-obsolete-crypt was given.
+if test "${enable_obsolete_crypt+set}" = set; then :
+  enableval=$enable_obsolete_crypt; build_obsolete_crypt=$enableval
+else
+  build_obsolete_crypt=no
+fi
+
+
+
+
 # Check whether --enable-systemtap was given.
 if test "${enable_systemtap+set}" = set; then :
   enableval=$enable_systemtap; systemtap=$enableval
diff --git a/configure.ac b/configure.ac
index 2c6308883c5..6ac1a826e26 100644
--- a/configure.ac
+++ b/configure.ac
@@ -392,6 +392,14 @@  if test "$build_obsolete_nsl" = yes; then
   AC_DEFINE(LINK_OBSOLETE_NSL)
 fi
 
+AC_ARG_ENABLE([obsolete-crypt],
+              AC_HELP_STRING([--enable-obsolete-crypt],
+                             [build and install the obsolete libcrypt library]),
+              [build_obsolete_crypt=$enableval],
+              [build_obsolete_crypt=no])
+AC_SUBST(build_obsolete_crypt)
+
+
 AC_ARG_ENABLE([systemtap],
               [AS_HELP_STRING([--enable-systemtap],
 	       [enable systemtap static probe points @<:@default=no@:>@])],
diff --git a/conform/Makefile b/conform/Makefile
index 9ec41c7244a..8f2a329a188 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -208,22 +208,28 @@  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)
 linknamespace-libs-XOPEN2K = $(linknamespace-libs-xsi)
 linknamespace-libs-POSIX2008 = $(linknamespace-libs-posix)
 linknamespace-libs-XOPEN2K8 = $(linknamespace-libs-xsi)
+
+ifeq ($(build-obsolete-crypt),yes)
+linknamespace-libs-xsi += $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 += $(common-objpfx)crypt/libcrypt.a
+endif
+
 linknamespace-libs = $(foreach std,$(conformtest-standards),\
 				   $(linknamespace-libs-$(std)))
 
+
+
 $(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \
 					$(linknamespace-libs)
 	LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \
diff --git a/conform/data/stdlib.h-data b/conform/data/stdlib.h-data
index d8fcccc2fba..6913828196f 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 ddf4f251326..aa070528e83 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/Banner b/crypt/Banner
deleted file mode 100644
index 9cb25bdf0c4..00000000000
--- a/crypt/Banner
+++ /dev/null
@@ -1 +0,0 @@ 
-crypt add-on version 2.1 by Michael Glad and others
diff --git a/crypt/Makefile b/crypt/Makefile
index 0280fba8a71..a7485de290b 100644
--- a/crypt/Makefile
+++ b/crypt/Makefile
@@ -22,6 +22,8 @@  subdir	:= crypt
 
 include ../Makeconfig
 
+ifeq ($(build-obsolete-crypt),yes)
+
 headers := crypt.h
 
 extra-libs := libcrypt
@@ -50,9 +52,11 @@  tests += md5test sha256test sha512test
 # machine over a minute.
 xtests = md5test-giant
 endif
+endif
 
 include ../Rules
 
+ifeq ($(build-obsolete-crypt),yes)
 ifneq ($(nss-crypt),yes)
 md5-routines := md5 $(filter md5%,$(libcrypt-sysdep_routines))
 sha256-routines := sha256 $(filter sha256%,$(libcrypt-sysdep_routines))
@@ -69,3 +73,4 @@  $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so
 else
 $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a
 endif
+endif
diff --git a/elf/Makefile b/elf/Makefile
index 7cf959aabdf..82ee6e8d39c 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -378,8 +378,9 @@  $(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.
+ifeq ($(build-obsolete-crypt),yes)
+# If the libcrypt library is being built, tst-linkall-static should
+# try to use crypt routines to test static libcrypt use.
 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.
@@ -387,6 +388,9 @@  CFLAGS-tst-linkall-static.c = -DUSE_CRYPT=1
 ifeq (yesno,$(nss-crypt)$(static-nss-crypt))
 CFLAGS-tst-linkall-static.c = -DUSE_CRYPT=0
 endif
+else
+CFLAGS-tst-linkall-static.c = -DUSE_CRYPT=0
+endif
 
 include ../Rules
 
@@ -1106,8 +1110,10 @@  localplt-built-dso := $(addprefix $(common-objpfx),\
 				  rt/librt.so \
 				  dlfcn/libdl.so \
 				  resolv/libresolv.so \
-				  crypt/libcrypt.so \
 		       )
+ifeq ($(build-obsolete-crypt),yes)
+localplt-built-dso += $(addprefix $(common-objpfx), crypt/libcrypt.so)
+endif
 ifeq ($(build-mathvec),yes)
 localplt-built-dso += $(addprefix $(common-objpfx), mathvec/libmvec.so)
 endif
@@ -1388,6 +1394,7 @@  $(objpfx)tst-linkall-static: \
   $(common-objpfx)resolv/libanl.a \
   $(static-thread-library)
 
+ifeq ($(build-obsolete-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
@@ -1403,6 +1410,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 8f40657244a..cf58f21e0c3 100644
--- a/elf/tst-linkall-static.c
+++ b/elf/tst-linkall-static.c
@@ -18,7 +18,9 @@ 
 
 #include <math.h>
 #include <pthread.h>
+#if USE_CRYPT
 #include <crypt.h>
+#endif
 #include <resolv.h>
 #include <dlfcn.h>
 #include <utmp.h>
diff --git a/posix/unistd.h b/posix/unistd.h
index 32b0f4898fd..299b9a34857 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
@@ -1113,20 +1110,7 @@  extern int lockf64 (int __fd, int __cmd, __off64_t __len) __wur;
 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 7a720cfd11e..87e1138c272 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -843,12 +843,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/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile b/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
index 4ad7aff9147..5e9b3e5f03f 100644
--- a/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
+++ b/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
@@ -1,6 +1,8 @@ 
 ifeq ($(subdir),crypt)
+ifeq ($(build-obsolete-crypt),yes)
 libcrypt-sysdep_routines += md5-crop sha256-crop sha512-crop
 endif
+endif
 
 ifeq ($(subdir),locale)
 localedef-aux += md5-crop
diff --git a/sysdeps/sparc/sparc64/multiarch/Makefile b/sysdeps/sparc/sparc64/multiarch/Makefile
index 55b757f9add..60d528b88c9 100644
--- a/sysdeps/sparc/sparc64/multiarch/Makefile
+++ b/sysdeps/sparc/sparc64/multiarch/Makefile
@@ -1,6 +1,8 @@ 
 ifeq ($(subdir),crypt)
+ifeq ($(build-obsolete-crypt),yes)
 libcrypt-sysdep_routines += md5-crop sha256-crop sha512-crop
 endif
+endif
 
 ifeq ($(subdir),locale)
 localedef-aux += md5-crop
diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index 4adc35de04a..6cab4f3a31a 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -19,8 +19,10 @@  endif
 # Add a syscall function to each library that needs one.
 
 ifeq ($(subdir),crypt)
+ifeq ($(build-obsolete-crypt),yes)
 libcrypt-sysdep_routines += libc-do-syscall
 endif
+endif
 
 ifeq ($(subdir),rt)
 librt-sysdep_routines += libc-do-syscall