aboutsummaryrefslogtreecommitdiff
path: root/crypt
diff options
context:
space:
mode:
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 nw