summary refs log tree commit diff
path: root/crypt
diff options
context:
space:
mode:
authorGeoff Keating <geoffk@cygnus.com>2000-03-04 00:47:31 +0000
committerGeoff Keating <geoffk@cygnus.com>2000-03-04 00:47:31 +0000
commitb11f59548803413101b72d28f42cbe997d64a144 (patch)
tree4898a19a9169c9cedd0250e0e7590dbc6058b189 /crypt
parente3d53b06cc8520c23a010909ab2f0bde93f2abfc (diff)
downloadglibc-b11f59548803413101b72d28f42cbe997d64a144.tar.gz
glibc-b11f59548803413101b72d28f42cbe997d64a144.tar.xz
glibc-b11f59548803413101b72d28f42cbe997d64a144.zip
* Makeconfig (rpath-dirs): Add crypt.
(all-subdirs): Remove md5crypt. 
* crypt/sysdeps/unix/crypt.c: Move to crypt/. 
* crypt/sysdeps/unix/crypt-entry.c: Move to crypt/. 
* sysdeps/generic/crypt-entry.c: Delete. 
* crypt/sysdeps/unix/crypt.h: Move to crypt/. 
* sysdeps/generic/crypt.h: Delete. 
* crypt/sysdeps/unix/crypt-private.h: Move to crypt/. 
* crypt/sysdeps/unix/crypt_util.c: Move to crypt/. 
* crypt/sysdeps/unix/des_impl.c: Move to sunrpc/. 
* sysdeps/generic/des_impl.c: Delete. 
* crypt/sysdeps/unix/ufc-crypt.h: Move to crypt/. 
* crypt/sysdeps: Delete. 
* crypt/crypt_util.c: Don't use `patchlevel.h'. 
* md5-crypt/Versions: Move to crypt/. 
* md5-crypt/md5-crypt.c: Move to crypt/. 
* md5-crypt/md5.c: Move to crypt/. 
* md5-crypt/md5c-test.c: Move to crypt/. 
* md5-crypt/md5test.c: Move to crypt/. 
* md5-crypt: Delete. 
* crypt/Makefile: Adjust for new structure.
2000-03-03  Geoff Keating  <geoffk@cygnus.com>

	* Makeconfig (rpath-dirs): Add crypt.
	(all-subdirs): Remove md5crypt.
	* crypt/sysdeps/unix/crypt.c: Move to crypt/.
	* crypt/sysdeps/unix/crypt-entry.c: Move to crypt/.
	* sysdeps/generic/crypt-entry.c: Delete.
	* crypt/sysdeps/unix/crypt.h: Move to crypt/.
	* sysdeps/generic/crypt.h: Delete.
	* crypt/sysdeps/unix/crypt-private.h: Move to crypt/.
	* crypt/sysdeps/unix/crypt_util.c: Move to crypt/.
	* crypt/sysdeps/unix/des_impl.c: Move to sunrpc/.
	* sysdeps/generic/des_impl.c: Delete.
	* crypt/sysdeps/unix/ufc-crypt.h: Move to crypt/.
	* crypt/sysdeps: Delete.
	* crypt/crypt_util.c: Don't use `patchlevel.h'.
	* md5-crypt/Versions: Move to crypt/.
	* md5-crypt/md5-crypt.c: Move to crypt/.
	* md5-crypt/md5.c: Move to crypt/.
	* md5-crypt/md5c-test.c: Move to crypt/.
	* md5-crypt/md5test.c: Move to crypt/.
	* md5-crypt: Delete.
	* crypt/Makefile: Adjust for new structure.
Diffstat (limited to 'crypt')
-rw-r--r--crypt/Makefile33
-rw-r--r--crypt/Versions5
-rw-r--r--crypt/crypt-entry.c (renamed from crypt/sysdeps/unix/crypt-entry.c)0
-rw-r--r--crypt/crypt-private.h (renamed from crypt/sysdeps/unix/crypt-private.h)0
-rw-r--r--crypt/crypt.c (renamed from crypt/sysdeps/unix/crypt.c)0
-rw-r--r--crypt/crypt.h (renamed from crypt/sysdeps/unix/crypt.h)0
-rw-r--r--crypt/crypt_util.c (renamed from crypt/sysdeps/unix/crypt_util.c)5
-rw-r--r--crypt/md5-crypt.c223
-rw-r--r--crypt/md5.c428
-rw-r--r--crypt/md5.h147
-rw-r--r--crypt/md5c-test.c15
-rw-r--r--crypt/md5test.c45
-rw-r--r--crypt/sysdeps/mach/hurd/Implies2
-rw-r--r--crypt/sysdeps/unix/Makefile4
-rw-r--r--crypt/sysdeps/unix/des_impl.c615
-rw-r--r--crypt/sysdeps/unix/patchlevel.h25
-rw-r--r--crypt/ufc-crypt.h (renamed from crypt/sysdeps/unix/ufc-crypt.h)0
17 files changed, 888 insertions, 659 deletions
diff --git a/crypt/Makefile b/crypt/Makefile
index 1be33be001..a9ce7da41e 100644
--- a/crypt/Makefile
+++ b/crypt/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996 Free Software Foundation, Inc.
+# Copyright (C) 1996, 2000 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -17,20 +17,35 @@
 # Boston, MA 02111-1307, USA.
 
 #
-#	Sub-makefile for DES crypt portion of the library.
+#	Sub-makefile for crypt() portion of the library.
 #
 subdir	:= crypt
 
-tests = cert
+headers := crypt.h
+
+distribute := md5.h
+
+extra-libs := libcrypt
+extra-libs-others := $(extra-libs)
+
+libcrypt-routines := crypt-entry md5-crypt md5 crypt crypt_util
+
+tests = cert md5test md5c-test
 
 include ../Makeconfig
 
-rpath-dirs += md5-crypt
+ifeq ($(crypt-in-libc),yes)
+routines += $(libcrypt-routines)
+endif
+
+$(objpfx)md5test: $(objpfx)md5.o
 
 include ../Rules
 
-ifeq ($(build-shared),yes)
-$(objpfx)cert: $(common-objpfx)md5-crypt/libcrypt.so$(libcrypt.so-version)
-else
-$(objpfx)cert: $(common-objpfx)md5-crypt/libcrypt.a
-endif
+LDLIBS-cert = crypt/libcrypt
+LDLIBS-md5c-test = crypt/libcrypt
+
+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
+# This ensures they will load libc.so for needed symbols if loaded by
+# a statically-linked program that hasn't already loaded it.
+$(objpfx)libcrypt.so: $(common-objpfx)libc.so
diff --git a/crypt/Versions b/crypt/Versions
new file mode 100644
index 0000000000..389e7d544a
--- /dev/null
+++ b/crypt/Versions
@@ -0,0 +1,5 @@
+libcrypt {
+  GLIBC_2.0 {
+    crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
+  }
+}
diff --git a/crypt/sysdeps/unix/crypt-entry.c b/crypt/crypt-entry.c
index 9d99c53a2b..9d99c53a2b 100644
--- a/crypt/sysdeps/unix/crypt-entry.c
+++ b/crypt/crypt-entry.c
diff --git a/crypt/sysdeps/unix/crypt-private.h b/crypt/crypt-private.h
index 130cccd373..130cccd373 100644
--- a/crypt/sysdeps/unix/crypt-private.h
+++ b/crypt/crypt-private.h
diff --git a/crypt/sysdeps/unix/crypt.c b/crypt/crypt.c
index 8e2a576a70..8e2a576a70 100644
--- a/crypt/sysdeps/unix/crypt.c
+++ b/crypt/crypt.c
diff --git a/crypt/sysdeps/unix/crypt.h b/crypt/crypt.h
index 7018cb16ce..7018cb16ce 100644
--- a/crypt/sysdeps/unix/crypt.h
+++ b/crypt/crypt.h
diff --git a/crypt/sysdeps/unix/crypt_util.c b/crypt/crypt_util.c
index 671571c51d..1eb2d4cc63 100644
--- a/crypt/sysdeps/unix/crypt_util.c
+++ b/crypt/crypt_util.c
@@ -1,7 +1,7 @@
 /*
  * UFC-crypt: ultra fast crypt(3) implementation
  *
- * Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
+ * Copyright (C) 1991, 92, 93, 96, 97, 98, 2000 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -34,7 +34,6 @@
 #endif
 
 #ifndef DOS
-#include "patchlevel.h"
 #include "ufc-crypt.h"
 #else
 /*
@@ -61,8 +60,6 @@ STATIC void shuffle_sb (long64 *k, ufc_long saltbits);
 #endif
 
 
-static const char patchlevel_str[] = PATCHLEVEL;
-
 /*
  * Permutation done once on the 56 bit
  *  key derived from the original 8 byte ASCII key.
diff --git a/crypt/md5-crypt.c b/crypt/md5-crypt.c
new file mode 100644
index 0000000000..126103503c
--- /dev/null
+++ b/crypt/md5-crypt.c
@@ -0,0 +1,223 @@
+/* One way encryption based on MD5 sum.
+   Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+
+#include "md5.h"
+
+
+/* Define our magic string to mark salt for MD5 "encryption"
+   replacement.  This is meant to be the same as for other MD5 based
+   encryption implementations.  */
+static const char md5_salt_prefix[] = "$1$";
+
+/* Table with characters for base64 transformation.  */
+static const char b64t[64] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+
+/* Prototypes for local functions.  */
+extern char *__md5_crypt_r __P ((const char *key, const char *salt,
+				 char *buffer, int buflen));
+extern char *__md5_crypt __P ((const char *key, const char *salt));
+
+
+/* This entry point is equivalent to the `crypt' function in Unix
+   libcs.  */
+char *
+__md5_crypt_r (key, salt, buffer, buflen)
+     const char *key;
+     const char *salt;
+     char *buffer;
+     int buflen;
+{
+  unsigned char alt_result[16];
+  struct md5_ctx ctx;
+  struct md5_ctx alt_ctx;
+  size_t salt_len;
+  size_t key_len;
+  size_t cnt;
+  char *cp;
+
+  /* Find beginning of salt string.  The prefix should normally always
+     be present.  Just in case it is not.  */
+  if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
+    /* Skip salt prefix.  */
+    salt += sizeof (md5_salt_prefix) - 1;
+
+  salt_len = MIN (strcspn (salt, "$"), 8);
+  key_len = strlen (key);
+
+  /* Prepare for the real work.  */
+  __md5_init_ctx (&ctx);
+
+  /* Add the key string.  */
+  __md5_process_bytes (key, key_len, &ctx);
+
+  /* Because the SALT argument need not always have the salt prefix we
+     add it separately.  */
+  __md5_process_bytes (md5_salt_prefix, sizeof (md5_salt_prefix) - 1, &ctx);
+
+  /* The last part is the salt string.  This must be at most 8
+     characters and it ends at the first `$' character (for
+     compatibility which existing solutions).  */
+  __md5_process_bytes (salt, salt_len, &ctx);
+
+
+  /* Compute alternate MD5 sum with input KEY, SALT, and KEY.  The
+     final result will be added to the first context.  */
+  __md5_init_ctx (&alt_ctx);
+
+  /* Add key.  */
+  __md5_process_bytes (key, key_len, &alt_ctx);
+
+  /* Add salt.  */
+  __md5_process_bytes (salt, salt_len, &alt_ctx);
+
+  /* Add key again.  */
+  __md5_process_bytes (key, key_len, &alt_ctx);
+
+  /* Now get result of this (16 bytes) and add it to the other
+     context.  */
+  __md5_finish_ctx (&alt_ctx, alt_result);
+
+  /* Add for any character in the key one byte of the alternate sum.  */
+  for (cnt = key_len; cnt > 16; cnt -= 16)
+    __md5_process_bytes (alt_result, 16, &ctx);
+  __md5_process_bytes (alt_result, cnt, &ctx);
+
+  /* For the following code we need a NUL byte.  */
+  *alt_result = '\0';
+
+  /* The original implementation now does something weird: for every 1
+     bit in the key the first 0 is added to the buffer, for every 0
+     bit the first character of the key.  This does not seem to be
+     what was intended but we have to follow this to be compatible.  */
+  for (cnt = key_len; cnt > 0; cnt >>= 1)
+    __md5_process_bytes ((cnt & 1) != 0 ? (const char *) alt_result : key, 1,
+			 &ctx);
+
+  /* Create intermediate result.  */
+  __md5_finish_ctx (&ctx, alt_result);
+
+  /* Now comes another weirdness.  In fear of password crackers here
+     comes a quite long loop which just processes the output of the
+     previous round again.  We cannot ignore this here.  */
+  for (cnt = 0; cnt < 1000; ++cnt)
+    {
+      /* New context.  */
+      __md5_init_ctx (&ctx);
+
+      /* Add key or last result.  */
+      if ((cnt & 1) != 0)
+	__md5_process_bytes (key, key_len, &ctx);
+      else
+	__md5_process_bytes (alt_result, 16, &ctx);
+
+      /* Add salt for numbers not divisible by 3.  */
+      if (cnt % 3 != 0)
+	__md5_process_bytes (salt, salt_len, &ctx);
+
+      /* Add key for numbers not divisible by 7.  */
+      if (cnt % 7 != 0)
+	__md5_process_bytes (key, key_len, &ctx);
+
+      /* Add key or last result.  */
+      if ((cnt & 1) != 0)
+	__md5_process_bytes (alt_result, 16, &ctx);
+      else
+	__md5_process_bytes (key, key_len, &ctx);
+
+      /* Create intermediate result.  */
+      __md5_finish_ctx (&ctx, alt_result);
+    }
+
+  /* Now we can construct the result string.  It consists of three
+     parts.  */
+  cp = __stpncpy (buffer, md5_salt_prefix, MAX (0, buflen));
+  buflen -= sizeof (md5_salt_prefix);
+
+  cp = __stpncpy (cp, salt, MIN ((size_t) buflen, salt_len));
+  buflen -= MIN ((size_t) buflen, salt_len);
+
+  if (buflen > 0)
+    {
+      *cp++ = '$';
+      --buflen;
+    }
+
+#define b64_from_24bit(B2, B1, B0, N)					      \
+  do {									      \
+    unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0);			      \
+    int n = (N);							      \
+    while (n-- > 0 && buflen > 0)					      \
+      {									      \
+	*cp++ = b64t[w & 0x3f];						      \
+	--buflen;							      \
+	w >>= 6;							      \
+      }									      \
+  } while (0)
+
+
+  b64_from_24bit (alt_result[0], alt_result[6], alt_result[12], 4);
+  b64_from_24bit (alt_result[1], alt_result[7], alt_result[13], 4);
+  b64_from_24bit (alt_result[2], alt_result[8], alt_result[14], 4);
+  b64_from_24bit (alt_result[3], alt_result[9], alt_result[15], 4);
+  b64_from_24bit (alt_result[4], alt_result[10], alt_result[5], 4);
+  b64_from_24bit (0, 0, alt_result[11], 2);
+  if (buflen <= 0)
+    {
+      __set_errno (ERANGE);
+      buffer = NULL;
+    }
+  else
+    *cp = '\0';		/* Terminate the string.  */
+
+  /* Clear the buffer for the intermediate result so that people
+     attaching to processes or reading core dumps cannot get any
+     information.  */
+  memset (alt_result, '\0', sizeof (alt_result));
+
+  return buffer;
+}
+
+
+char *
+__md5_crypt (const char *key, const char *salt)
+{
+  /* We don't want to have an arbitrary limit in the size of the
+     password.  We can compute the size of the result in advance and
+     so we can prepare the buffer we pass to `md5_crypt_r'.  */
+  static char *buffer = NULL;
+  static int buflen = 0;
+  int needed = 3 + strlen (salt) + 1 + 26 + 1;
+
+  if (buflen < needed)
+    {
+      buflen = needed;
+      if ((buffer = realloc (buffer, buflen)) == NULL)
+	return NULL;
+    }
+
+  return __md5_crypt_r (key, salt, buffer, buflen);
+}
diff --git a/crypt/md5.c b/crypt/md5.c
new file mode 100644
index 0000000000..478429f8e6
--- /dev/null
+++ b/crypt/md5.c
@@ -0,0 +1,428 @@
+/* md5.c - Functions to compute MD5 message digest of files or memory blocks
+   according to the definition of MD5 in RFC 1321 from April 1992.
+   Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#if STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#include "md5.h"
+
+#ifdef _LIBC
+# include <endian.h>
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define WORDS_BIGENDIAN 1
+# endif
+/* We need to keep the namespace clean so define the MD5 function
+   protected using leading __ .  */
+# define md5_init_ctx __md5_init_ctx
+# define md5_process_block __md5_process_block
+# define md5_process_bytes __md5_process_bytes
+# define md5_finish_ctx __md5_finish_ctx
+# define md5_read_ctx __md5_read_ctx
+# define md5_stream __md5_stream
+# define md5_buffer __md5_buffer
+#endif
+
+#ifdef WORDS_BIGENDIAN
+# define SWAP(n)							\
+    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+# define SWAP(n) (n)
+#endif
+
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
+
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+void
+md5_init_ctx (ctx)
+     struct md5_ctx *ctx;
+{
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->total[0] = ctx->total[1] = 0;
+  ctx->buflen = 0;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result
+   must be in little endian byte order.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+md5_read_ctx (ctx, resbuf)
+     const struct md5_ctx *ctx;
+     void *resbuf;
+{
+  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+
+  return resbuf;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+   prolog according to the standard and write the result to RESBUF.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+md5_finish_ctx (ctx, resbuf)
+     struct md5_ctx *ctx;
+     void *resbuf;
+{
+  /* Take yet unprocessed bytes into account.  */
+  md5_uint32 bytes = ctx->buflen;
+  size_t pad;
+
+  /* Now count remaining bytes.  */
+  ctx->total[0] += bytes;
+  if (ctx->total[0] < bytes)
+    ++ctx->total[1];
+
+  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+  memcpy (&ctx->buffer[bytes], fillbuf, pad);
+
+  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
+  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
+							(ctx->total[0] >> 29));
+
+  /* Process last bytes.  */
+  md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
+
+  return md5_read_ctx (ctx, resbuf);
+}
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+int
+md5_stream (stream, resblock)
+     FILE *stream;
+     void *resblock;
+{
+  /* Important: BLOCKSIZE must be a multiple of 64.  */
+#define BLOCKSIZE 4096
+  struct md5_ctx ctx;
+  char buffer[BLOCKSIZE + 72];
+  size_t sum;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Iterate over full file contents.  */
+  while (1)
+    {
+      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
+	 computation function processes the whole buffer so that with the
+	 next round of the loop another block can be read.  */
+      size_t n;
+      sum = 0;
+
+      /* Read block.  Take care for partial reads.  */
+      do
+	{
+	  n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+
+	  sum += n;
+	}
+      while (sum < BLOCKSIZE && n != 0);
+      if (n == 0 && ferror (stream))
+        return 1;
+
+      /* If end of file is reached, end the loop.  */
+      if (n == 0)
+	break;
+
+      /* Process buffer with BLOCKSIZE bytes.  Note that
+			BLOCKSIZE % 64 == 0
+       */
+      md5_process_block (buffer, BLOCKSIZE, &ctx);
+    }
+
+  /* Add the last bytes if necessary.  */
+  if (sum > 0)
+    md5_process_bytes (buffer, sum, &ctx);
+
+  /* Construct result in desired memory.  */
+  md5_finish_ctx (&ctx, resblock);
+  return 0;
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *
+md5_buffer (buffer, len, resblock)
+     const char *buffer;
+     size_t len;
+     void *resblock;
+{
+  struct md5_ctx ctx;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Process whole buffer but last len % 64 bytes.  */
+  md5_process_bytes (buffer, len, &ctx);
+
+  /* Put result in desired memory area.  */
+  return md5_finish_ctx (&ctx, resblock);
+}
+
+
+void
+md5_process_bytes (buffer, len, ctx)
+     const void *buffer;
+     size_t len;
+     struct md5_ctx *ctx;
+{
+  /* When we already have some bits in our internal buffer concatenate
+     both inputs first.  */
+  if (ctx->buflen != 0)
+    {
+      size_t left_over = ctx->buflen;
+      size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+      memcpy (&ctx->buffer[left_over], buffer, add);
+      ctx->buflen += add;
+
+      if (left_over + add > 64)
+	{
+	  md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
+	  /* The regions in the following copy operation cannot overlap.  */
+	  memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+		  (left_over + add) & 63);
+	  ctx->buflen = (left_over + add) & 63;
+	}
+
+      buffer = (const char *) buffer + add;
+      len -= add;
+    }
+
+  /* Process available complete blocks.  */
+  if (len > 64)
+    {
+      md5_process_block (buffer, len & ~63, ctx);
+      buffer = (const char *) buffer + (len & ~63);
+      len &= 63;
+    }
+
+  /* Move remaining bytes in internal buffer.  */
+  if (len > 0)
+    {
+      memcpy (ctx->buffer, buffer, len);
+      ctx->buflen = len;
+    }
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 64 == 0.  */
+
+void
+md5_process_block (buffer, len, ctx)
+     const void *buffer;
+     size_t len;
+     struct md5_ctx *ctx;
+{
+  md5_uint32 correct_words[16];
+  const md5_uint32 *words = buffer;
+  size_t nwords = len / sizeof (md5_uint32);
+  const md5_uint32 *endp = words + nwords;
+  md5_uint32 A = ctx->A;
+  md5_uint32 B = ctx->B;
+  md5_uint32 C = ctx->C;
+  md5_uint32 D = ctx->D;
+
+  /* First increment the byte count.  RFC 1321 specifies the possible
+     length of the file up to 2^64 bits.  Here we only compute the
+     number of bytes.  Do a double word increment.  */
+  ctx->total[0] += len;
+  if (ctx->total[0] < len)
+    ++ctx->total[1];
+
+  /* Process all bytes in the buffer with 64 bytes in each round of
+     the loop.  */
+  while (words < endp)
+    {
+      md5_uint32 *cwp = correct_words;
+      md5_uint32 A_save = A;
+      md5_uint32 B_save = B;
+      md5_uint32 C_save = C;
+      md5_uint32 D_save = D;
+
+      /* First round: using the given function, the context and a constant
+	 the next context is computed.  Because the algorithms processing
+	 unit is a 32-bit word and it is determined to work on words in
+	 little endian byte order we perhaps have to change the byte order
+	 before the computation.  To reduce the work for the next steps
+	 we store the swapped words in the array CORRECT_WORDS.  */
+
+#define OP(a, b, c, d, s, T)						\
+      do								\
+        {								\
+	  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;		\
+	  ++words;							\
+	  CYCLIC (a, s);						\
+	  a += b;							\
+        }								\
+      while (0)
+
+      /* It is unfortunate that C does not provide an operator for
+	 cyclic rotation.  Hope the C compiler is smart enough.  */
+#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
+
+      /* Before we start, one word to the strange constants.
+	 They are defined in RFC 1321 as
+
+	 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+       */
+
+      /* Round 1.  */
+      OP (A, B, C, D,  7, 0xd76aa478);
+      OP (D, A, B, C, 12, 0xe8c7b756);
+      OP (C, D, A, B, 17, 0x242070db);
+      OP (B, C, D, A, 22, 0xc1bdceee);
+      OP (A, B, C, D,  7, 0xf57c0faf);
+      OP (D, A, B, C, 12, 0x4787c62a);
+      OP (C, D, A, B, 17, 0xa8304613);
+      OP (B, C, D, A, 22, 0xfd469501);
+      OP (A, B, C, D,  7, 0x698098d8);
+      OP (D, A, B, C, 12, 0x8b44f7af);
+      OP (C, D, A, B, 17, 0xffff5bb1);
+      OP (B, C, D, A, 22, 0x895cd7be);
+      OP (A, B, C, D,  7, 0x6b901122);
+      OP (D, A, B, C, 12, 0xfd987193);
+      OP (C, D, A, B, 17, 0xa679438e);
+      OP (B, C, D, A, 22, 0x49b40821);
+
+      /* For the second to fourth round we have the possibly swapped words
+	 in CORRECT_WORDS.  Redefine the macro to take an additional first
+	 argument specifying the function to use.  */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)					\
+      do 								\
+	{								\
+	  a += f (b, c, d) + correct_words[k] + T;			\
+	  CYCLIC (a, s);						\
+	  a += b;							\
+	}								\
+      while (0)
+
+      /* Round 2.  */
+      OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
+      OP (FG, D, A, B, C,  6,  9, 0xc040b340);
+      OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+      OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
+      OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
+      OP (FG, D, A, B, C, 10,  9, 0x02441453);
+      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+      OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
+      OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
+      OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
+      OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
+      OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
+      OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
+      OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
+      OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
+      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+      /* Round 3.  */
+      OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
+      OP (FH, D, A, B, C,  8, 11, 0x8771f681);
+      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+      OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+      OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
+      OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
+      OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
+      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+      OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
+      OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
+      OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
+      OP (FH, B, C, D, A,  6, 23, 0x04881d05);
+      OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
+      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+      OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
+
+      /* Round 4.  */
+      OP (FI, A, B, C, D,  0,  6, 0xf4292244);
+      OP (FI, D, A, B, C,  7, 10, 0x432aff97);
+      OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+      OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
+      OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
+      OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
+      OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+      OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
+      OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
+      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+      OP (FI, C, D, A, B,  6, 15, 0xa3014314);
+      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+      OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
+      OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+      OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
+      OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
+
+      /* Add the starting values of the context.  */
+      A += A_save;
+      B += B_save;
+      C += C_save;
+      D += D_save;
+    }
+
+  /* Put checksum in context given as argument.  */
+  ctx->A = A;
+  ctx->B = B;
+  ctx->C = C;
+  ctx->D = D;
+}
diff --git a/crypt/md5.h b/crypt/md5.h
new file mode 100644
index 0000000000..fbc2bdbf93
--- /dev/null
+++ b/crypt/md5.h
@@ -0,0 +1,147 @@
+/* Declaration of functions and data types used for MD5 sum computing
+   library functions.
+   Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _MD5_H
+#define _MD5_H 1
+
+#include <stdio.h>
+
+#if defined HAVE_LIMITS_H || _LIBC
+# include <limits.h>
+#endif
+
+/* The following contortions are an attempt to use the C preprocessor
+   to determine an unsigned integral type that is 32 bits wide.  An
+   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+   doing that would require that the configure script compile and *run*
+   the resulting executable.  Locally running cross-compiled executables
+   is usually not possible.  */
+
+#ifdef _LIBC
+# include <sys/types.h>
+typedef u_int32_t md5_uint32;
+#else
+# if defined __STDC__ && __STDC__
+#  define UINT_MAX_32_BITS 4294967295U
+# else
+#  define UINT_MAX_32_BITS 0xFFFFFFFF
+# endif
+
+/* If UINT_MAX isn't defined, assume it's a 32-bit type.
+   This should be valid for all systems GNU cares about because
+   that doesn't include 16-bit systems, and only modern systems
+   (that certainly have <limits.h>) have 64+-bit integral types.  */
+
+# ifndef UINT_MAX
+#  define UINT_MAX UINT_MAX_32_BITS
+# endif
+
+# if UINT_MAX == UINT_MAX_32_BITS
+   typedef unsigned int md5_uint32;
+# else
+#  if USHRT_MAX == UINT_MAX_32_BITS
+    typedef unsigned short md5_uint32;
+#  else
+#   if ULONG_MAX == UINT_MAX_32_BITS
+     typedef unsigned long md5_uint32;
+#   else
+     /* The following line is intended to evoke an error.
+        Using #error is not portable enough.  */
+     "Cannot determine unsigned 32-bit data type."
+#   endif
+#  endif
+# endif
+#endif
+
+#undef __P
+#if defined (__STDC__) && __STDC__
+# define __P(x) x
+#else
+# define __P(x) ()
+#endif
+
+/* Structure to save state of computation between the single steps.  */
+struct md5_ctx
+{
+  md5_uint32 A;
+  md5_uint32 B;
+  md5_uint32 C;
+  md5_uint32 D;
+
+  md5_uint32 total[2];
+  md5_uint32 buflen;
+  char buffer[128];
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+extern void __md5_init_ctx __P ((struct md5_ctx *ctx));
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is necessary that LEN is a multiple of 64!!! */
+extern void __md5_process_block __P ((const void *buffer, size_t len,
+				      struct md5_ctx *ctx));
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is NOT required that LEN is a multiple of 64.  */
+extern void __md5_process_bytes __P ((const void *buffer, size_t len,
+				      struct md5_ctx *ctx));
+
+/* Process the remaining bytes in the buffer and put result from CTX
+   in first 16 bytes following RESBUF.  The result is always in little
+   endian byte order, so that a byte-wise output yields to the wanted
+   ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+extern void *__md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
+
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result is
+   always in little endian byte order, so that a byte-wise output yields
+   to the wanted ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+extern void *__md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
+
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+extern int __md5_stream __P ((FILE *stream, void *resblock));
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+extern void *__md5_buffer __P ((const char *buffer, size_t len,
+				void *resblock));
+
+#endif /* md5.h */
diff --git a/crypt/md5c-test.c b/crypt/md5c-test.c
new file mode 100644
index 0000000000..f56d0eb4ab
--- /dev/null
+++ b/crypt/md5c-test.c
@@ -0,0 +1,15 @@
+#include <crypt.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+  const char salt[] = "$1$saltstring";
+  char *cp;
+  int result = 0;
+
+  cp = crypt ("Hello world!", salt);
+  result |= strcmp ("$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1", cp);
+
+  return result;
+}
diff --git a/crypt/md5test.c b/crypt/md5test.c
new file mode 100644
index 0000000000..cfd9605099
--- /dev/null
+++ b/crypt/md5test.c
@@ -0,0 +1,45 @@
+#include <string.h>
+#include "md5.h"
+
+static const struct
+{
+  const char *input;
+  const char result[16];
+} tests[] =
+  {
+    { "",
+      "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e" },
+    { "a",
+      "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61" },
+    { "abc",
+      "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72" },
+    { "message digest",
+      "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0" },
+    { "abcdefghijklmnopqrstuvwxyz",
+      "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1\x3b" },
+    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+      "\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f" },
+    { "123456789012345678901234567890123456789012345678901234567890"
+      "12345678901234567890",
+      "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6\x7a" }
+  };
+
+
+int
+main (int argc, char *argv[])
+{
+  struct md5_ctx ctx;
+  char sum[16];
+  int result = 0;
+  int cnt;
+
+  for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
+    {
+      __md5_init_ctx (&ctx);
+      __md5_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx);
+      __md5_finish_ctx (&ctx, sum);
+      result |= memcmp (tests[cnt].result, sum, 16);
+    }
+
+  return result;
+}
diff --git a/crypt/sysdeps/mach/hurd/Implies b/crypt/sysdeps/mach/hurd/Implies
deleted file mode 100644
index 03a772586f..0000000000
--- a/crypt/sysdeps/mach/hurd/Implies
+++ /dev/null
@@ -1,2 +0,0 @@
-# The Hurd uses Unix like DES crypto function.
-unix
diff --git a/crypt/sysdeps/unix/Makefile b/crypt/sysdeps/unix/Makefile
deleted file mode 100644
index 65810482d0..0000000000
--- a/crypt/sysdeps/unix/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-ifeq ($(subdir),md5-crypt)
-libcrypt-routines += crypt crypt_util
-dont_distribute += crypt.c crypt_util.c
-endif
diff --git a/crypt/sysdeps/unix/des_impl.c b/crypt/sysdeps/unix/des_impl.c
deleted file mode 100644
index f4fee720a1..0000000000
--- a/crypt/sysdeps/unix/des_impl.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/* Copyright (C) 1992 Eric Young - see COPYING for more details */
-/* Collected from libdes and modified for SECURE RPC by Martin Kuck 1994 */
-#include <string.h>
-#include "des.h"
-
-
-static const unsigned long des_SPtrans[8][64] =
-{
-  {				/* nibble 0 */
-    0x00820200, 0x00020000, 0x80800000, 0x80820200,
-    0x00800000, 0x80020200, 0x80020000, 0x80800000,
-    0x80020200, 0x00820200, 0x00820000, 0x80000200,
-    0x80800200, 0x00800000, 0x00000000, 0x80020000,
-    0x00020000, 0x80000000, 0x00800200, 0x00020200,
-    0x80820200, 0x00820000, 0x80000200, 0x00800200,
-    0x80000000, 0x00000200, 0x00020200, 0x80820000,
-    0x00000200, 0x80800200, 0x80820000, 0x00000000,
-    0x00000000, 0x80820200, 0x00800200, 0x80020000,
-    0x00820200, 0x00020000, 0x80000200, 0x00800200,
-    0x80820000, 0x00000200, 0x00020200, 0x80800000,
-    0x80020200, 0x80000000, 0x80800000, 0x00820000,
-    0x80820200, 0x00020200, 0x00820000, 0x80800200,
-    0x00800000, 0x80000200, 0x80020000, 0x00000000,
-    0x00020000, 0x00800000, 0x80800200, 0x00820200,
-    0x80000000, 0x80820000, 0x00000200, 0x80020200},
-
-  {				/* nibble 1 */
-    0x10042004, 0x00000000, 0x00042000, 0x10040000,
-    0x10000004, 0x00002004, 0x10002000, 0x00042000,
-    0x00002000, 0x10040004, 0x00000004, 0x10002000,
-    0x00040004, 0x10042000, 0x10040000, 0x00000004,
-    0x00040000, 0x10002004, 0x10040004, 0x00002000,
-    0x00042004, 0x10000000, 0x00000000, 0x00040004,
-    0x10002004, 0x00042004, 0x10042000, 0x10000004,
-    0x10000000, 0x00040000, 0x00002004, 0x10042004,
-    0x00040004, 0x10042000, 0x10002000, 0x00042004,
-    0x10042004, 0x00040004, 0x10000004, 0x00000000,
-    0x10000000, 0x00002004, 0x00040000, 0x10040004,
-    0x00002000, 0x10000000, 0x00042004, 0x10002004,
-    0x10042000, 0x00002000, 0x00000000, 0x10000004,
-    0x00000004, 0x10042004, 0x00042000, 0x10040000,
-    0x10040004, 0x00040000, 0x00002004, 0x10002000,
-    0x10002004, 0x00000004, 0x10040000, 0x00042000},
-
-  {				/* nibble 2 */
-    0x41000000, 0x01010040, 0x00000040, 0x41000040,
-    0x40010000, 0x01000000, 0x41000040, 0x00010040,
-    0x01000040, 0x00010000, 0x01010000, 0x40000000,
-    0x41010040, 0x40000040, 0x40000000, 0x41010000,
-    0x00000000, 0x40010000, 0x01010040, 0x00000040,
-    0x40000040, 0x41010040, 0x00010000, 0x41000000,
-    0x41010000, 0x01000040, 0x40010040, 0x01010000,
-    0x00010040, 0x00000000, 0x01000000, 0x40010040,
-    0x01010040, 0x00000040, 0x40000000, 0x00010000,
-    0x40000040, 0x40010000, 0x01010000, 0x41000040,
-    0x00000000, 0x01010040, 0x00010040, 0x41010000,
-    0x40010000, 0x01000000, 0x41010040, 0x40000000,
-    0x40010040, 0x41000000, 0x01000000, 0x41010040,
-    0x00010000, 0x01000040, 0x41000040, 0x00010040,
-    0x01000040, 0x00000000, 0x41010000, 0x40000040,
-    0x41000000, 0x40010040, 0x00000040, 0x01010000},
-
-  {				/* nibble 3 */
-    0x00100402, 0x04000400, 0x00000002, 0x04100402,
-    0x00000000, 0x04100000, 0x04000402, 0x00100002,
-    0x04100400, 0x04000002, 0x04000000, 0x00000402,
-    0x04000002, 0x00100402, 0x00100000, 0x04000000,
-    0x04100002, 0x00100400, 0x00000400, 0x00000002,
-    0x00100400, 0x04000402, 0x04100000, 0x00000400,
-    0x00000402, 0x00000000, 0x00100002, 0x04100400,
-    0x04000400, 0x04100002, 0x04100402, 0x00100000,
-    0x04100002, 0x00000402, 0x00100000, 0x04000002,
-    0x00100400, 0x04000400, 0x00000002, 0x04100000,
-    0x04000402, 0x00000000, 0x00000400, 0x00100002,
-    0x00000000, 0x04100002, 0x04100400, 0x00000400,
-    0x04000000, 0x04100402, 0x00100402, 0x00100000,
-    0x04100402, 0x00000002, 0x04000400, 0x00100402,
-    0x00100002, 0x00100400, 0x04100000, 0x04000402,
-    0x00000402, 0x04000000, 0x04000002, 0x04100400},
-
-  {				/* nibble 4 */
-    0x02000000, 0x00004000, 0x00000100, 0x02004108,
-    0x02004008, 0x02000100, 0x00004108, 0x02004000,
-    0x00004000, 0x00000008, 0x02000008, 0x00004100,
-    0x02000108, 0x02004008, 0x02004100, 0x00000000,
-    0x00004100, 0x02000000, 0x00004008, 0x00000108,
-    0x02000100, 0x00004108, 0x00000000, 0x02000008,
-    0x00000008, 0x02000108, 0x02004108, 0x00004008,
-    0x02004000, 0x00000100, 0x00000108, 0x02004100,
-    0x02004100, 0x02000108, 0x00004008, 0x02004000,
-    0x00004000, 0x00000008, 0x02000008, 0x02000100,
-    0x02000000, 0x00004100, 0x02004108, 0x00000000,
-    0x00004108, 0x02000000, 0x00000100, 0x00004008,
-    0x02000108, 0x00000100, 0x00000000, 0x02004108,
-    0x02004008, 0x02004100, 0x00000108, 0x00004000,
-    0x00004100, 0x02004008, 0x02000100, 0x00000108,
-    0x00000008, 0x00004108, 0x02004000, 0x02000008},
-
-  {				/* nibble 5 */
-    0x20000010, 0x00080010, 0x00000000, 0x20080800,
-    0x00080010, 0x00000800, 0x20000810, 0x00080000,
-    0x00000810, 0x20080810, 0x00080800, 0x20000000,
-    0x20000800, 0x20000010, 0x20080000, 0x00080810,
-    0x00080000, 0x20000810, 0x20080010, 0x00000000,
-    0x00000800, 0x00000010, 0x20080800, 0x20080010,
-    0x20080810, 0x20080000, 0x20000000, 0x00000810,
-    0x00000010, 0x00080800, 0x00080810, 0x20000800,
-    0x00000810, 0x20000000, 0x20000800, 0x00080810,
-    0x20080800, 0x00080010, 0x00000000, 0x20000800,
-    0x20000000, 0x00000800, 0x20080010, 0x00080000,
-    0x00080010, 0x20080810, 0x00080800, 0x00000010,
-    0x20080810, 0x00080800, 0x00080000, 0x20000810,
-    0x20000010, 0x20080000, 0x00080810, 0x00000000,
-    0x00000800, 0x20000010, 0x20000810, 0x20080800,
-    0x20080000, 0x00000810, 0x00000010, 0x20080010},
-
-  {				/* nibble 6 */
-    0x00001000, 0x00000080, 0x00400080, 0x00400001,
-    0x00401081, 0x00001001, 0x00001080, 0x00000000,
-    0x00400000, 0x00400081, 0x00000081, 0x00401000,
-    0x00000001, 0x00401080, 0x00401000, 0x00000081,
-    0x00400081, 0x00001000, 0x00001001, 0x00401081,
-    0x00000000, 0x00400080, 0x00400001, 0x00001080,
-    0x00401001, 0x00001081, 0x00401080, 0x00000001,
-    0x00001081, 0x00401001, 0x00000080, 0x00400000,
-    0x00001081, 0x00401000, 0x00401001, 0x00000081,
-    0x00001000, 0x00000080, 0x00400000, 0x00401001,
-    0x00400081, 0x00001081, 0x00001080, 0x00000000,
-    0x00000080, 0x00400001, 0x00000001, 0x00400080,
-    0x00000000, 0x00400081, 0x00400080, 0x00001080,
-    0x00000081, 0x00001000, 0x00401081, 0x00400000,
-    0x00401080, 0x00000001, 0x00001001, 0x00401081,
-    0x00400001, 0x00401080, 0x00401000, 0x00001001},
-
-  {				/* nibble 7 */
-    0x08200020, 0x08208000, 0x00008020, 0x00000000,
-    0x08008000, 0x00200020, 0x08200000, 0x08208020,
-    0x00000020, 0x08000000, 0x00208000, 0x00008020,
-    0x00208020, 0x08008020, 0x08000020, 0x08200000,
-    0x00008000, 0x00208020, 0x00200020, 0x08008000,
-    0x08208020, 0x08000020, 0x00000000, 0x00208000,
-    0x08000000, 0x00200000, 0x08008020, 0x08200020,
-    0x00200000, 0x00008000, 0x08208000, 0x00000020,
-    0x00200000, 0x00008000, 0x08000020, 0x08208020,
-    0x00008020, 0x08000000, 0x00000000, 0x00208000,
-    0x08200020, 0x08008020, 0x08008000, 0x00200020,
-    0x08208000, 0x00000020, 0x00200020, 0x08008000,
-    0x08208020, 0x00200000, 0x08200000, 0x08000020,
-    0x00208000, 0x00008020, 0x08008020, 0x08200000,
-    0x00000020, 0x08208000, 0x00208020, 0x00000000,
-    0x08000000, 0x08200020, 0x00008000, 0x00208020}};
-
-static const unsigned long des_skb[8][64] =
-{
-  {				/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-    0x00000000, 0x00000010, 0x20000000, 0x20000010,
-    0x00010000, 0x00010010, 0x20010000, 0x20010010,
-    0x00000800, 0x00000810, 0x20000800, 0x20000810,
-    0x00010800, 0x00010810, 0x20010800, 0x20010810,
-    0x00000020, 0x00000030, 0x20000020, 0x20000030,
-    0x00010020, 0x00010030, 0x20010020, 0x20010030,
-    0x00000820, 0x00000830, 0x20000820, 0x20000830,
-    0x00010820, 0x00010830, 0x20010820, 0x20010830,
-    0x00080000, 0x00080010, 0x20080000, 0x20080010,
-    0x00090000, 0x00090010, 0x20090000, 0x20090010,
-    0x00080800, 0x00080810, 0x20080800, 0x20080810,
-    0x00090800, 0x00090810, 0x20090800, 0x20090810,
-    0x00080020, 0x00080030, 0x20080020, 0x20080030,
-    0x00090020, 0x00090030, 0x20090020, 0x20090030,
-    0x00080820, 0x00080830, 0x20080820, 0x20080830,
-    0x00090820, 0x00090830, 0x20090820, 0x20090830},
-  {				/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
-    0x00000000, 0x02000000, 0x00002000, 0x02002000,
-    0x00200000, 0x02200000, 0x00202000, 0x02202000,
-    0x00000004, 0x02000004, 0x00002004, 0x02002004,
-    0x00200004, 0x02200004, 0x00202004, 0x02202004,
-    0x00000400, 0x02000400, 0x00002400, 0x02002400,
-    0x00200400, 0x02200400, 0x00202400, 0x02202400,
-    0x00000404, 0x02000404, 0x00002404, 0x02002404,
-    0x00200404, 0x02200404, 0x00202404, 0x02202404,
-    0x10000000, 0x12000000, 0x10002000, 0x12002000,
-    0x10200000, 0x12200000, 0x10202000, 0x12202000,
-    0x10000004, 0x12000004, 0x10002004, 0x12002004,
-    0x10200004, 0x12200004, 0x10202004, 0x12202004,
-    0x10000400, 0x12000400, 0x10002400, 0x12002400,
-    0x10200400, 0x12200400, 0x10202400, 0x12202400,
-    0x10000404, 0x12000404, 0x10002404, 0x12002404,
-    0x10200404, 0x12200404, 0x10202404, 0x12202404},
-  {				/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
-    0x00000000, 0x00000001, 0x00040000, 0x00040001,
-    0x01000000, 0x01000001, 0x01040000, 0x01040001,
-    0x00000002, 0x00000003, 0x00040002, 0x00040003,
-    0x01000002, 0x01000003, 0x01040002, 0x01040003,
-    0x00000200, 0x00000201, 0x00040200, 0x00040201,
-    0x01000200, 0x01000201, 0x01040200, 0x01040201,
-    0x00000202, 0x00000203, 0x00040202, 0x00040203,
-    0x01000202, 0x01000203, 0x01040202, 0x01040203,
-    0x08000000, 0x08000001, 0x08040000, 0x08040001,
-    0x09000000, 0x09000001, 0x09040000, 0x09040001,
-    0x08000002, 0x08000003, 0x08040002, 0x08040003,
-    0x09000002, 0x09000003, 0x09040002, 0x09040003,
-    0x08000200, 0x08000201, 0x08040200, 0x08040201,
-    0x09000200, 0x09000201, 0x09040200, 0x09040201,
-    0x08000202, 0x08000203, 0x08040202, 0x08040203,
-    0x09000202, 0x09000203, 0x09040202, 0x09040203},
-  {				/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
-    0x00000000, 0x00100000, 0x00000100, 0x00100100,
-    0x00000008, 0x00100008, 0x00000108, 0x00100108,
-    0x00001000, 0x00101000, 0x00001100, 0x00101100,
-    0x00001008, 0x00101008, 0x00001108, 0x00101108,
-    0x04000000, 0x04100000, 0x04000100, 0x04100100,
-    0x04000008, 0x04100008, 0x04000108, 0x04100108,
-    0x04001000, 0x04101000, 0x04001100, 0x04101100,
-    0x04001008, 0x04101008, 0x04001108, 0x04101108,
-    0x00020000, 0x00120000, 0x00020100, 0x00120100,
-    0x00020008, 0x00120008, 0x00020108, 0x00120108,
-    0x00021000, 0x00121000, 0x00021100, 0x00121100,
-    0x00021008, 0x00121008, 0x00021108, 0x00121108,
-    0x04020000, 0x04120000, 0x04020100, 0x04120100,
-    0x04020008, 0x04120008, 0x04020108, 0x04120108,
-    0x04021000, 0x04121000, 0x04021100, 0x04121100,
-    0x04021008, 0x04121008, 0x04021108, 0x04121108},
-  {				/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-    0x00000000, 0x10000000, 0x00010000, 0x10010000,
-    0x00000004, 0x10000004, 0x00010004, 0x10010004,
-    0x20000000, 0x30000000, 0x20010000, 0x30010000,
-    0x20000004, 0x30000004, 0x20010004, 0x30010004,
-    0x00100000, 0x10100000, 0x00110000, 0x10110000,
-    0x00100004, 0x10100004, 0x00110004, 0x10110004,
-    0x20100000, 0x30100000, 0x20110000, 0x30110000,
-    0x20100004, 0x30100004, 0x20110004, 0x30110004,
-    0x00001000, 0x10001000, 0x00011000, 0x10011000,
-    0x00001004, 0x10001004, 0x00011004, 0x10011004,
-    0x20001000, 0x30001000, 0x20011000, 0x30011000,
-    0x20001004, 0x30001004, 0x20011004, 0x30011004,
-    0x00101000, 0x10101000, 0x00111000, 0x10111000,
-    0x00101004, 0x10101004, 0x00111004, 0x10111004,
-    0x20101000, 0x30101000, 0x20111000, 0x30111000,
-    0x20101004, 0x30101004, 0x20111004, 0x30111004},
-  {				/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
-    0x00000000, 0x08000000, 0x00000008, 0x08000008,
-    0x00000400, 0x08000400, 0x00000408, 0x08000408,
-    0x00020000, 0x08020000, 0x00020008, 0x08020008,
-    0x00020400, 0x08020400, 0x00020408, 0x08020408,
-    0x00000001, 0x08000001, 0x00000009, 0x08000009,
-    0x00000401, 0x08000401, 0x00000409, 0x08000409,
-    0x00020001, 0x08020001, 0x00020009, 0x08020009,
-    0x00020401, 0x08020401, 0x00020409, 0x08020409,
-    0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
-    0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
-    0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
-    0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
-    0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
-    0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
-    0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
-    0x02020401, 0x0A020401, 0x02020409, 0x0A020409},
-  {				/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
-    0x00000000, 0x00000100, 0x00080000, 0x00080100,
-    0x01000000, 0x01000100, 0x01080000, 0x01080100,
-    0x00000010, 0x00000110, 0x00080010, 0x00080110,
-    0x01000010, 0x01000110, 0x01080010, 0x01080110,
-    0x00200000, 0x00200100, 0x00280000, 0x00280100,
-    0x01200000, 0x01200100, 0x01280000, 0x01280100,
-    0x00200010, 0x00200110, 0x00280010, 0x00280110,
-    0x01200010, 0x01200110, 0x01280010, 0x01280110,
-    0x00000200, 0x00000300, 0x00080200, 0x00080300,
-    0x01000200, 0x01000300, 0x01080200, 0x01080300,
-    0x00000210, 0x00000310, 0x00080210, 0x00080310,
-    0x01000210, 0x01000310, 0x01080210, 0x01080310,
-    0x00200200, 0x00200300, 0x00280200, 0x00280300,
-    0x01200200, 0x01200300, 0x01280200, 0x01280300,
-    0x00200210, 0x00200310, 0x00280210, 0x00280310,
-    0x01200210, 0x01200310, 0x01280210, 0x01280310},
-  {				/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
-    0x00000000, 0x04000000, 0x00040000, 0x04040000,
-    0x00000002, 0x04000002, 0x00040002, 0x04040002,
-    0x00002000, 0x04002000, 0x00042000, 0x04042000,
-    0x00002002, 0x04002002, 0x00042002, 0x04042002,
-    0x00000020, 0x04000020, 0x00040020, 0x04040020,
-    0x00000022, 0x04000022, 0x00040022, 0x04040022,
-    0x00002020, 0x04002020, 0x00042020, 0x04042020,
-    0x00002022, 0x04002022, 0x00042022, 0x04042022,
-    0x00000800, 0x04000800, 0x00040800, 0x04040800,
-    0x00000802, 0x04000802, 0x00040802, 0x04040802,
-    0x00002800, 0x04002800, 0x00042800, 0x04042800,
-    0x00002802, 0x04002802, 0x00042802, 0x04042802,
-    0x00000820, 0x04000820, 0x00040820, 0x04040820,
-    0x00000822, 0x04000822, 0x00040822, 0x04040822,
-    0x00002820, 0x04002820, 0x00042820, 0x04042820,
-    0x00002822, 0x04002822, 0x00042822, 0x04042822},
-};
-
-#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
-			 l|=((unsigned long)(*((c)++)))<< 8, \
-			 l|=((unsigned long)(*((c)++)))<<16, \
-			 l|=((unsigned long)(*((c)++)))<<24)
-
-#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff), \
-			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
-			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
-			 *((c)++)=(unsigned char)(((l)>>24)&0xff))
-
-/*
- * IP and FP
- * The problem is more of a geometric problem that random bit fiddling.
- *  0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
- *  8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
- * 16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
- * 24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
- *
- * 32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
- * 40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
- * 48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
- * 56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
- *
- * The output has been subject to swaps of the form
- * 0 1 -> 3 1 but the odd and even bits have been put into
- * 2 3    2 0
- * different words.  The main trick is to remember that
- * t=((l>>size)^r)&(mask);
- * r^=t;
- * l^=(t<<size);
- * can be used to swap and move bits between words.
- *
- * So l =  0  1  2  3  r = 16 17 18 19
- *         4  5  6  7      20 21 22 23
- *         8  9 10 11      24 25 26 27
- *        12 13 14 15      28 29 30 31
- * becomes (for size == 2 and mask == 0x3333)
- * t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
- *       6^20  7^21 -- --        4  5 20 21       6  7 22 23
- *      10^24 11^25 -- --        8  9 24 25      10 11 24 25
- *      14^28 15^29 -- --       12 13 28 29      14 15 28 29
- *
- * Thanks for hints from Richard Outerbridge - he told me IP&FP
- * could be done in 15 xor, 10 shifts and 5 ands.
- * When I finally started to think of the problem in 2D
- * I first got ~42 operations without xors.  When I remembered
- * how to use xors :-) I got it to its final state.
- */
-
-#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-	(b)^=(t),\
-	(a)^=((t)<<(n)))
-
-#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
-	(a)=(a)^(t)^(t>>(16-(n))))
-
-
-/* The changes to this macro may help or hinder, depending on the
- * compiler and the achitecture.  gcc2 always seems to do well :-).
- * Inspired by Dana How <how@isl.stanford.edu>
- * DO NOT use the alternative version on machines with 8 byte longs.
- */
-#ifdef ALT_ECB
-#define D_ENCRYPT(L,R,S) \
-	u=((R^s[S  ])<<2);	\
-	t= R^s[S+1]; \
-	t=((t>>2)+(t<<30)); \
-	L^= \
-	*(const unsigned long *)(des_SP+0x0100+((t    )&0xfc))+ \
-	*(const unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
-	*(const unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
-	*(const unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
-	*(const unsigned long *)(des_SP+       ((u    )&0xfc))+ \
-  	*(const unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
-  	*(const unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
- 	*(const unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
-#else /* original version */
-#define D_ENCRYPT(L,R,S)	\
-	u=(R^s[S  ]); \
-	t=R^s[S+1]; \
-	t=((t>>4)+(t<<28)); \
-	L^=	des_SPtrans[1][(t    )&0x3f]| \
-		des_SPtrans[3][(t>> 8)&0x3f]| \
-		des_SPtrans[5][(t>>16)&0x3f]| \
-		des_SPtrans[7][(t>>24)&0x3f]| \
-		des_SPtrans[0][(u    )&0x3f]| \
-		des_SPtrans[2][(u>> 8)&0x3f]| \
-		des_SPtrans[4][(u>>16)&0x3f]| \
-		des_SPtrans[6][(u>>24)&0x3f];
-#endif
-
-#define ITERATIONS 16
-
-static const char shifts2[16] =
-{0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
-
-static void des_set_key (char *, unsigned long *) internal_function;
-static void des_encrypt (unsigned long *, unsigned long *, int)
-     internal_function;
-int _des_crypt (char *, unsigned, struct desparams *);
-
-static void
-internal_function
-des_set_key (char *key, unsigned long *schedule)
-{
-  register unsigned long c, d, t, s;
-  register unsigned char *in;
-  register unsigned long *k;
-  register int i;
-
-  k = (unsigned long *) schedule;
-  in = (unsigned char *) key;
-
-  c2l (in, c);
-  c2l (in, d);
-
-  /* I now do it in 47 simple operations :-)
-   * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
-   * for the inspiration. :-) */
-  PERM_OP (d, c, t, 4, 0x0f0f0f0f);
-  HPERM_OP (c, t, -2, 0xcccc0000);
-  HPERM_OP (d, t, -2, 0xcccc0000);
-  PERM_OP (d, c, t, 1, 0x55555555);
-  PERM_OP (c, d, t, 8, 0x00ff00ff);
-  PERM_OP (d, c, t, 1, 0x55555555);
-  d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
-       ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
-  c &= 0x0fffffff;
-
-  for (i = 0; i < ITERATIONS; i++)
-    {
-      if (shifts2[i])
-	{
-	  c = ((c >> 2) | (c << 26));
-	  d = ((d >> 2) | (d << 26));
-	}
-      else
-	{
-	  c = ((c >> 1) | (c << 27));
-	  d = ((d >> 1) | (d << 27));
-	}
-      c &= 0x0fffffff;
-      d &= 0x0fffffff;
-      /* could be a few less shifts but I am to lazy at this
-       * point in time to investigate */
-      s = des_skb[0][(c) & 0x3f] |
-	des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
-	des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
-	des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
-      t = des_skb[4][(d) & 0x3f] |
-	des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
-	des_skb[6][(d >> 15) & 0x3f] |
-	des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
-
-      /* table contained 0213 4657 */
-      *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
-      s = ((s >> 16) | (t & 0xffff0000));
-
-      s = (s << 4) | (s >> 28);
-      *(k++) = s & 0xffffffff;
-    }
-}
-
-
-static void
-internal_function
-des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
-{
-  register unsigned long l, r, t, u;
-#ifdef ALT_ECB
-  register const unsigned char *des_SP = (const unsigned char *) des_SPtrans;
-#endif
-  register int i;
-  register unsigned long *s;
-
-  l = buf[0];
-  r = buf[1];
-
-  /* do IP */
-  PERM_OP (r, l, t, 4, 0x0f0f0f0f);
-  PERM_OP (l, r, t, 16, 0x0000ffff);
-  PERM_OP (r, l, t, 2, 0x33333333);
-  PERM_OP (l, r, t, 8, 0x00ff00ff);
-  PERM_OP (r, l, t, 1, 0x55555555);
-  /* r and l are reversed - remember that :-) - fix
-   * it in the next step */
-
-  /* Things have been modified so that the initial rotate is
-   * done outside the loop.  This required the
-   * des_SPtrans values in sp.h to be rotated 1 bit to the right.
-   * One perl script later and things have a 5% speed up on a sparc2.
-   * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
-   * for pointing this out. */
-  t = (r << 1) | (r >> 31);
-  r = (l << 1) | (l >> 31);
-  l = t;
-
-  /* clear the top bits on machines with 8byte longs */
-  l &= 0xffffffff;
-  r &= 0xffffffff;
-
-  s = (unsigned long *) schedule;
-  /* I don't know if it is worth the effort of loop unrolling the
-   * inner loop */
-  if (encrypt)
-    {
-      for (i = 0; i < 32; i += 4)
-	{
-	  D_ENCRYPT (l, r, i + 0);	/*  1 */
-	  D_ENCRYPT (r, l, i + 2);	/*  2 */
-	}
-    }
-  else
-    {
-      for (i = 30; i > 0; i -= 4)
-	{
-	  D_ENCRYPT (l, r, i - 0);	/* 16 */
-	  D_ENCRYPT (r, l, i - 2);	/* 15 */
-	}
-    }
-  l = (l >> 1) | (l << 31);
-  r = (r >> 1) | (r << 31);
-  /* clear the top bits on machines with 8byte longs */
-  l &= 0xffffffff;
-  r &= 0xffffffff;
-
-  /* swap l and r
-   * we will not do the swap so just remember they are
-   * reversed for the rest of the subroutine
-   * luckily FP fixes this problem :-) */
-
-  PERM_OP (r, l, t, 1, 0x55555555);
-  PERM_OP (l, r, t, 8, 0x00ff00ff);
-  PERM_OP (r, l, t, 2, 0x33333333);
-  PERM_OP (l, r, t, 16, 0x0000ffff);
-  PERM_OP (r, l, t, 4, 0x0f0f0f0f);
-
-  buf[0] = l;
-  buf[1] = r;
-
-  l = r = t = u = 0;
-}
-
-
-int
-_des_crypt (char *buf, unsigned len, struct desparams *desp)
-{
-  unsigned long schedule[32];
-  register unsigned long tin0, tin1;
-  register unsigned long tout0, tout1, xor0, xor1;
-  register unsigned char *in, *out;
-  unsigned long tbuf[2];
-  unsigned char *iv, *oiv;
-  int cbc_mode;
-
-  cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
-
-  in = (unsigned char *) buf;
-  out = (unsigned char *) buf;
-  oiv = iv = (unsigned char *) desp->des_ivec;
-
-  des_set_key (desp->des_key, schedule);
-
-  tin0 = tin1 = 0;		/* For GCC */
-  if (desp->des_dir == ENCRYPT)
-    {
-      c2l (iv, tout0);
-      c2l (iv, tout1);
-      for (; len > 0; len -= 8)
-	{
-	  c2l (in, tin0);
-	  c2l (in, tin1);
-	  if (cbc_mode)
-	    {
-	      tin0 ^= tout0;
-	      tin1 ^= tout1;
-	    }
-	  tbuf[0] = tin0;
-	  tbuf[1] = tin1;
-	  des_encrypt (tbuf, schedule, 1);
-	  tout0 = tbuf[0];
-	  tout1 = tbuf[1];
-	  l2c (tout0, out);
-	  l2c (tout1, out);
-	}
-      l2c (tout0, oiv);
-      l2c (tout1, oiv);
-    }
-  else
-    {
-      c2l (iv, xor0);
-      c2l (iv, xor1);
-      for (; len > 0; len -= 8)
-	{
-	  c2l (in, tin0);
-	  c2l (in, tin1);
-	  tbuf[0] = tin0;
-	  tbuf[1] = tin1;
-	  des_encrypt (tbuf, schedule, 0);
-	  if (cbc_mode)
-	    {
-	      tout0 = tbuf[0] ^ xor0;
-	      tout1 = tbuf[1] ^ xor1;
-	      xor0 = tin0;
-	      xor1 = tin1;
-	    }
-	  else
-	    {
-	      tout0 = tbuf[0];
-	      tout1 = tbuf[1];
-	    }
-	  l2c (tout0, out);
-	  l2c (tout1, out);
-	}
-      l2c (tin0, oiv);
-      l2c (tin1, oiv);
-    }
-  tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-  tbuf[0] = tbuf[1] = 0;
-  __bzero (schedule, sizeof (schedule));
-
-  return (1);
-}
diff --git a/crypt/sysdeps/unix/patchlevel.h b/crypt/sysdeps/unix/patchlevel.h
deleted file mode 100644
index 450c091f60..0000000000
--- a/crypt/sysdeps/unix/patchlevel.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * UFC-crypt: ultra fast crypt(3) implementation
- *
- * Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; see the file COPYING.LIB.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * @(#)patchlevel.h	1.13 9/10/96
- *
- */
-
-#define PATCHLEVEL "UFC-crypt, patchlevel 1e, @(#)patchlevel.h	1.13 9/10/96"
diff --git a/crypt/sysdeps/unix/ufc-crypt.h b/crypt/ufc-crypt.h
index 879211afec..879211afec 100644
--- a/crypt/sysdeps/unix/ufc-crypt.h
+++ b/crypt/ufc-crypt.h