Fix a few typos.
[kopensolaris-gnu/glibc.git] / crypt / md5-crypt.c
index 1261035..2ca1021 100644 (file)
@@ -1,5 +1,5 @@
 /* One way encryption based on MD5 sum.
-   Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -18,6 +18,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
@@ -37,9 +38,9 @@ static const char b64t[64] =
 
 
 /* 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));
+extern char *__md5_crypt_r (const char *key, const char *salt,
+                           char *buffer, int buflen);
+extern char *__md5_crypt (const char *key, const char *salt);
 
 
 /* This entry point is equivalent to the `crypt' function in Unix
@@ -51,13 +52,16 @@ __md5_crypt_r (key, salt, buffer, buflen)
      char *buffer;
      int buflen;
 {
-  unsigned char alt_result[16];
+  unsigned char alt_result[16]
+    __attribute__ ((__aligned__ (__alignof__ (md5_uint32))));
   struct md5_ctx ctx;
   struct md5_ctx alt_ctx;
   size_t salt_len;
   size_t key_len;
   size_t cnt;
   char *cp;
+  char *copied_key = NULL;
+  char *copied_salt = NULL;
 
   /* Find beginning of salt string.  The prefix should normally always
      be present.  Just in case it is not.  */
@@ -68,6 +72,26 @@ __md5_crypt_r (key, salt, buffer, buflen)
   salt_len = MIN (strcspn (salt, "$"), 8);
   key_len = strlen (key);
 
+  if ((key - (char *) 0) % __alignof__ (md5_uint32) != 0)
+    {
+      char *tmp = (char *) alloca (key_len + __alignof__ (md5_uint32));
+      key = copied_key =
+       memcpy (tmp + __alignof__ (md5_uint32)
+               - (tmp - (char *) 0) % __alignof__ (md5_uint32),
+               key, key_len);
+      assert ((key - (char *) 0) % __alignof__ (md5_uint32) == 0);
+    }
+
+  if ((salt - (char *) 0) % __alignof__ (md5_uint32) != 0)
+    {
+      char *tmp = (char *) alloca (salt_len + __alignof__ (md5_uint32));
+      salt = copied_salt =
+       memcpy (tmp + __alignof__ (md5_uint32)
+               - (tmp - (char *) 0) % __alignof__ (md5_uint32),
+               salt, salt_len);
+      assert ((salt - (char *) 0) % __alignof__ (md5_uint32) == 0);
+    }
+
   /* Prepare for the real work.  */
   __md5_init_ctx (&ctx);
 
@@ -195,21 +219,30 @@ __md5_crypt_r (key, salt, buffer, buflen)
 
   /* 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));
+     information.  We do it in this way to clear correct_words[]
+     inside the MD5 implementation as well.  */
+  __md5_init_ctx (&ctx);
+  __md5_finish_ctx (&ctx, alt_result);
+  memset (&ctx, '\0', sizeof (ctx));
+  memset (&alt_ctx, '\0', sizeof (alt_ctx));
+  if (copied_key != NULL)
+    memset (copied_key, '\0', key_len);
+  if (copied_salt != NULL)
+    memset (copied_salt, '\0', salt_len);
 
   return buffer;
 }
 
 
+static char *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;
+  static int buflen;
   int needed = 3 + strlen (salt) + 1 + 26 + 1;
 
   if (buflen < needed)
@@ -221,3 +254,11 @@ __md5_crypt (const char *key, const char *salt)
 
   return __md5_crypt_r (key, salt, buffer, buflen);
 }
+
+
+static void
+__attribute__ ((__destructor__))
+free_mem (void)
+{
+  free (buffer);
+}