]> git.pld-linux.org Git - packages/glibc.git/blobdiff - glibc-crypt-blowfish.patch
- rel 12; fixes CVE-2017-16997
[packages/glibc.git] / glibc-crypt-blowfish.patch
index af3a4d3001d5c5fc06a0d2cb92defbab92624464..961a44a77abf12ace2f5620eadabc079f36b6cfe 100644 (file)
-diff -urN glibc-2.1.91.orig/crypt/Makefile glibc-2.1.91/crypt/Makefile
---- glibc-2.1.91.orig/crypt/Makefile   Wed Jun 14 05:49:02 2000
-+++ glibc-2.1.91/crypt/Makefile        Sat Jul 15 00:58:39 2000
-@@ -28,7 +28,7 @@
- extra-libs := libcrypt
- extra-libs-others := $(extra-libs)
--libcrypt-routines := crypt-entry md5-crypt md5 crypt crypt_util
-+libcrypt-routines := crypt-entry md5-crypt md5 arc4random bcrypt blowfish crypt crypt_util
- tests = cert md5test md5c-test
-diff -urN glibc-2.1.91.orig/crypt/arc4random.c glibc-2.1.91/crypt/arc4random.c
---- glibc-2.1.91.orig/crypt/arc4random.c       Thu Jan  1 01:00:00 1970
-+++ glibc-2.1.91/crypt/arc4random.c    Sat Jul 15 00:56:30 2000
-@@ -0,0 +1,174 @@
+Index: crypt/crypt_blowfish.c
+===================================================================
+--- /dev/null
++++ crypt/crypt_blowfish.c
+@@ -0,0 +1,743 @@
 +/*
 +/*
-+ * Arc4 random number generator for OpenBSD.
-+ * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
++ * This code comes from John the Ripper password cracker, with reentrant
++ * and crypt(3) interfaces added, but optimizations specific to password
++ * cracking removed.
 + *
 + *
-+ * Modification and redistribution in source and binary forms is
-+ * permitted provided that due credit is given to the author and the
-+ * OpenBSD project (for instance by leaving this copyright notice
-+ * intact).
-+ */
-+
-+/*
-+ * This code is derived from section 17.1 of Applied Cryptography,
-+ * second edition, which describes a stream cipher allegedly
-+ * compatible with RSA Labs "RC4" cipher (the actual description of
-+ * which is a trade secret).  The same algorithm is used as a stream
-+ * cipher called "arcfour" in Tatu Ylonen's ssh package.
++ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
++ * placed in the public domain.
 + *
 + *
-+ * Here the stream cipher has been modified always to include the time
-+ * when initializing the state.  That makes it impossible to
-+ * regenerate the same random sequence twice, so this can't be used
-+ * for encryption, but will generate good random numbers.
++ * There's absolutely no warranty.
 + *
 + *
-+ * RC4 is a registered trademark of RSA Laboratories.
-+ */
-+
-+#include <fcntl.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <sys/types.h>
-+#include <sys/time.h>
-+
-+#ifdef __GNUC__
-+#define inline __inline
-+#else                         /* !__GNUC__ */
-+#define inline
-+#endif                                /* !__GNUC__ */
-+
-+struct arc4_stream {
-+      u_int8_t i;
-+      u_int8_t j;
-+      u_int8_t s[256];
-+};
-+
-+int     rs_initialized;
-+static struct arc4_stream rs;
-+
-+static inline void
-+arc4_init(as)
-+      struct arc4_stream *as;
-+{
-+      int     n;
-+
-+      for (n = 0; n < 256; n++)
-+              as->s[n] = n;
-+      as->i = 0;
-+      as->j = 0;
-+}
-+
-+static inline void
-+arc4_addrandom(as, dat, datlen)
-+      struct arc4_stream *as;
-+      u_char *dat;
-+      int     datlen;
-+{
-+      int     n;
-+      u_int8_t si;
-+
-+      as->i--;
-+      for (n = 0; n < 256; n++) {
-+              as->i = (as->i + 1);
-+              si = as->s[as->i];
-+              as->j = (as->j + si + dat[n % datlen]);
-+              as->s[as->i] = as->s[as->j];
-+              as->s[as->j] = si;
-+      }
-+}
-+
-+static void
-+arc4_stir(as)
-+      struct arc4_stream *as;
-+{
-+      int     fd;
-+      struct {
-+              struct timeval tv;
-+              u_int8_t rnd[128 - sizeof(struct timeval)];
-+      }       rdat;
-+
-+      gettimeofday(&rdat.tv, NULL);
-+      fd = open("/dev/random", O_RDONLY);
-+      if (fd >= 0) {
-+              read(fd, rdat.rnd, sizeof(rdat.rnd));
-+              close(fd);
-+      }
-+      /* fd < 0?  Ah, what the heck. We'll just take whatever was on the
-+       * stack... */
-+
-+      arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
-+}
-+
-+static inline u_int8_t
-+arc4_getbyte(as)
-+      struct arc4_stream *as;
-+{
-+      u_int8_t si, sj;
-+
-+      as->i = (as->i + 1);
-+      si = as->s[as->i];
-+      as->j = (as->j + si);
-+      sj = as->s[as->j];
-+      as->s[as->i] = sj;
-+      as->s[as->j] = si;
-+      return (as->s[(si + sj) & 0xff]);
-+}
-+
-+static inline u_int32_t
-+arc4_getword(as)
-+      struct arc4_stream *as;
-+{
-+      u_int32_t val;
-+      val = arc4_getbyte(as) << 24;
-+      val |= arc4_getbyte(as) << 16;
-+      val |= arc4_getbyte(as) << 8;
-+      val |= arc4_getbyte(as);
-+      return val;
-+}
-+
-+void
-+arc4random_stir()
-+{
-+      if (!rs_initialized) {
-+              arc4_init(&rs);
-+              rs_initialized = 1;
-+      }
-+      arc4_stir(&rs);
-+}
-+
-+void
-+arc4random_addrandom(dat, datlen)
-+      u_char *dat;
-+      int     datlen;
-+{
-+      if (!rs_initialized)
-+              arc4random_stir();
-+      arc4_addrandom(&rs, dat, datlen);
-+}
-+
-+u_int32_t
-+arc4random()
-+{
-+      if (!rs_initialized)
-+              arc4random_stir();
-+      return arc4_getword(&rs);
-+}
-+
-+#if 0
-+/*-------- Test code for i386 --------*/
-+#include <stdio.h>
-+#include <machine/pctr.h>
-+int
-+main(int argc, char **argv)
-+{
-+      const int iter = 1000000;
-+      int     i;
-+      pctrval v;
-+
-+      v = rdtsc();
-+      for (i = 0; i < iter; i++)
-+              arc4random();
-+      v = rdtsc() - v;
-+      v /= iter;
-+
-+      printf("%qd cycles\n", v);
-+}
-+#endif
-diff -urN glibc-2.1.91.orig/crypt/bcrypt.c glibc-2.1.91/crypt/bcrypt.c
---- glibc-2.1.91.orig/crypt/bcrypt.c   Thu Jan  1 01:00:00 1970
-+++ glibc-2.1.91/crypt/bcrypt.c        Sat Jul 15 00:56:30 2000
-@@ -0,0 +1,360 @@
-+/*
-+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
-+ * All rights reserved.
++ * It is my intent that you should be able to use this on your system,
++ * as a part of a software package, or anywhere else to improve security,
++ * ensure compatibility, or for any other purpose. I would appreciate
++ * it if you give credit where it is due and keep your modifications in
++ * the public domain as well, but I don't require that in order to let
++ * you place this code and any modifications you make under a license
++ * of your choice.
 + *
 + *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ *    must display the following acknowledgement:
-+ *      This product includes software developed by Niels Provos.
-+ * 4. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
++ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
++ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
++ * ideas. The password hashing algorithm was designed by David Mazieres
++ * <dm at lcs.mit.edu>.
 + *
 + *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* This password hashing algorithm was designed by David Mazieres
-+ * <dm@lcs.mit.edu> and works as follows:
++ * There's a paper on the algorithm that explains its design decisions:
 + *
 + *
-+ * 1. state := InitState ()
-+ * 2. state := ExpandKey (state, salt, password) 3.
-+ * REPEAT rounds:
-+ *    state := ExpandKey (state, 0, salt)
-+ *      state := ExpandKey(state, 0, password)
-+ * 4. ctext := "OrpheanBeholderScryDoubt"
-+ * 5. REPEAT 64:
-+ *    ctext := Encrypt_ECB (state, ctext);
-+ * 6. RETURN Concatenate (salt, ctext);
++ *    http://www.usenix.org/events/usenix99/provos.html
 + *
 + *
++ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
++ * Blowfish library (I can't be sure if I would think of something if I
++ * hadn't seen his code).
 + */
 +
 + */
 +
-+#if 0
-+#include <stdio.h>
-+#endif
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
 +#include <string.h>
 +#include <string.h>
-+#include <pwd.h>
-+#include "blf.h"
-+
-+/* This implementation is adaptable to current computing power.
-+ * You can have up to 2^31 rounds which should be enough for some
-+ * time to come.
-+ */
-+
-+#define BCRYPT_VERSION '2'
-+#define BCRYPT_MAXSALT 16     /* Precomputation is just so nice */
-+#define BCRYPT_BLOCKS 6               /* Ciphertext blocks */
-+#define BCRYPT_MINROUNDS 16   /* we have log2(rounds) in salt */
-+
-+char   *bcrypt_gensalt __P((u_int8_t));
-+
-+static void encode_salt __P((char *, u_int8_t *, u_int16_t, u_int8_t));
-+static void encode_base64 __P((u_int8_t *, u_int8_t *, u_int16_t));
-+static void decode_base64 __P((u_int8_t *, u_int16_t, u_int8_t *));
-+
-+static char    encrypted[128];
-+static char    gsalt[BCRYPT_MAXSALT * 4 / 3 + 1];
-+static char    error[] = ":";
-+
-+const static u_int8_t Base64Code[] =
-+"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-+
-+const static u_int8_t index_64[128] =
-+{
-+      255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-+      255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-+      255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-+      255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-+      255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
-+      56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
-+      255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
-+      7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-+      17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-+      255, 255, 255, 255, 255, 255, 28, 29, 30,
-+      31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-+      41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
-+      51, 52, 53, 255, 255, 255, 255, 255
-+};
-+#define CHAR64(c)  ( (c) > 127 ? 255 : index_64[(c)])
-+
-+#ifdef __STDC__
-+static void
-+decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
-+#else
-+static void
-+decode_base64(buffer, len, data)
-+      u_int8_t *buffer;
-+      u_int16_t len;
-+      u_int8_t *data;
-+#endif
-+{
-+      u_int8_t *bp = buffer;
-+      u_int8_t *p = data;
-+      u_int8_t c1, c2, c3, c4;
-+      while (bp < buffer + len) {
-+              c1 = CHAR64(*p);
-+              c2 = CHAR64(*(p + 1));
-+
-+              /* Invalid data */
-+              if (c1 == 255 || c2 == 255)
-+                      break;
-+
-+              *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
-+              if (bp >= buffer + len)
-+                      break;
-+
-+              c3 = CHAR64(*(p + 2));
-+              if (c3 == 255)
-+                      break;
-+
-+              *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
-+              if (bp >= buffer + len)
-+                      break;
-+
-+              c4 = CHAR64(*(p + 3));
-+              if (c4 == 255)
-+                      break;
-+              *bp++ = ((c3 & 0x03) << 6) | c4;
 +
 +
-+              p += 4;
-+      }
-+}
-+
-+#ifdef __STDC__
-+static void
-+encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
-+#else
-+static void
-+encode_salt(salt, csalt, clen, logr)
-+      char   *salt;
-+      u_int8_t *csalt;
-+      u_int16_t clen;
-+      u_int8_t logr;
++#include <errno.h>
++#ifndef __set_errno
++#define __set_errno(val) errno = (val)
 +#endif
 +#endif
-+{
-+      salt[0] = '$';
-+      salt[1] = BCRYPT_VERSION;
-+      salt[2] = 'a';
-+      salt[3] = '$';
-+
-+      snprintf(salt + 4, 4, "%2.2u$", logr);
 +
 +
-+      encode_base64((u_int8_t *) salt + 7, csalt, clen);
-+}
-+/* Generates a salt for this version of crypt.
-+   Since versions may change. Keeping this here
-+   seems sensible.
-+ */
-+
-+#ifdef __STDC__
-+char *
-+bcrypt_gensalt(u_int8_t log_rounds)
++#undef __CONST
++#ifdef __GNUC__
++#define __CONST __const
 +#else
 +#else
-+char *
-+bcrypt_gensalt(log_rounds)
-+      u_int8_t log_rounds;
++#define __CONST
 +#endif
 +#endif
-+{
-+      u_int8_t csalt[BCRYPT_MAXSALT];
-+      u_int16_t i;
-+      u_int32_t seed = 0;
-+
-+      for (i = 0; i < BCRYPT_MAXSALT; i++) {
-+              if (i % 4 == 0)
-+                      seed = arc4random();
-+              csalt[i] = seed & 0xff;
-+              seed = seed >> 8;
-+      }
-+
-+      if (log_rounds < 4)
-+              log_rounds = 4;
-+
-+      encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
-+      return gsalt;
-+}
-+/* We handle $Vers$log2(NumRounds)$salt+passwd$
-+   i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
-+
-+char   *
-+bcrypt(key, salt)
-+      const char   *key;
-+      const char   *salt;
-+{
-+      blf_ctx state;
-+      u_int32_t rounds, i, k;
-+      u_int16_t j;
-+      u_int8_t key_len, salt_len, logr, minor;
-+      u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
-+      u_int8_t csalt[BCRYPT_MAXSALT];
-+      u_int32_t cdata[BCRYPT_BLOCKS];
-+
-+      /* Discard "$" identifier */
-+      salt++;
-+
-+      if (*salt > BCRYPT_VERSION) {
-+              /* How do I handle errors ? Return ':' */
-+              return error;
-+      }
-+
-+      /* Check for minor versions */
-+      if (salt[1] != '$') {
-+               switch (salt[1]) {
-+               case 'a':
-+                       /* 'ab' should not yield the same as 'abab' */
-+                       minor = salt[1];
-+                       salt++;
-+                       break;
-+               default:
-+                       return error;
-+               }
-+      } else
-+               minor = 0;
-+
-+      /* Discard version + "$" identifier */
-+      salt += 2;
 +
 +
-+      if (salt[2] != '$')
-+              /* Out of sync with passwd entry */
-+              return error;
-+
-+      /* Computer power doesnt increase linear, 2^x should be fine */
-+      if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
-+              return error;
-+
-+      /* Discard num rounds + "$" identifier */
-+      salt += 3;
-+
-+      /* We dont want the base64 salt but the raw data */
-+      decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
-+      salt_len = BCRYPT_MAXSALT;
-+      key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
-+
-+      /* Setting up S-Boxes and Subkeys */
-+      Blowfish_initstate(&state);
-+      Blowfish_expandstate(&state, csalt, salt_len,
-+          (u_int8_t *) key, key_len);
-+      for (k = 0; k < rounds; k++) {
-+              Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
-+              Blowfish_expand0state(&state, csalt, salt_len);
-+      }
-+
-+      /* This can be precomputed later */
-+      j = 0;
-+      for (i = 0; i < BCRYPT_BLOCKS; i++)
-+              cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
-+
-+      /* Now do the encryption */
-+      for (k = 0; k < 64; k++)
-+              blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
-+
-+      for (i = 0; i < BCRYPT_BLOCKS; i++) {
-+              ciphertext[4 * i + 3] = cdata[i] & 0xff;
-+              cdata[i] = cdata[i] >> 8;
-+              ciphertext[4 * i + 2] = cdata[i] & 0xff;
-+              cdata[i] = cdata[i] >> 8;
-+              ciphertext[4 * i + 1] = cdata[i] & 0xff;
-+              cdata[i] = cdata[i] >> 8;
-+              ciphertext[4 * i + 0] = cdata[i] & 0xff;
-+      }
-+
-+
-+      i = 0;
-+      encrypted[i++] = '$';
-+      encrypted[i++] = BCRYPT_VERSION;
-+      if (minor)
-+              encrypted[i++] = minor;
-+      encrypted[i++] = '$';
-+
-+      snprintf(encrypted + i, 4, "%2.2u$", logr);
-+
-+      encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
-+      encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
-+          4 * BCRYPT_BLOCKS - 1);
-+      return encrypted;
-+}
-+
-+#ifdef __STDC__
-+static void
-+encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
++#ifdef __i386__
++#define BF_ASM                                0 /* original OW patch has 1 */
++#define BF_SCALE                      1
++#elif defined(__alpha__) || defined(__hppa__) || defined(__x86_64__)
++#define BF_ASM                                0
++#define BF_SCALE                      1
 +#else
 +#else
-+static void
-+encode_base64(buffer, data, len)
-+      u_int8_t *buffer;
-+      u_int8_t *data;
-+      u_int16_t len;
++#define BF_ASM                                0
++#define BF_SCALE                      0
 +#endif
 +#endif
-+{
-+      u_int8_t *bp = buffer;
-+      u_int8_t *p = data;
-+      u_int8_t c1, c2;
-+      while (p < data + len) {
-+              c1 = *p++;
-+              *bp++ = Base64Code[(c1 >> 2)];
-+              c1 = (c1 & 0x03) << 4;
-+              if (p >= data + len) {
-+                      *bp++ = Base64Code[c1];
-+                      break;
-+              }
-+              c2 = *p++;
-+              c1 |= (c2 >> 4) & 0x0f;
-+              *bp++ = Base64Code[c1];
-+              c1 = (c2 & 0x0f) << 2;
-+              if (p >= data + len) {
-+                      *bp++ = Base64Code[c1];
-+                      break;
-+              }
-+              c2 = *p++;
-+              c1 |= (c2 >> 6) & 0x03;
-+              *bp++ = Base64Code[c1];
-+              *bp++ = Base64Code[c2 & 0x3f];
-+      }
-+      *bp = '\0';
-+}
-+#if 0
-+void
-+main()
-+{
-+      char    blubber[73];
-+      char    salt[100];
-+      char   *p;
-+      salt[0] = '$';
-+      salt[1] = BCRYPT_VERSION;
-+      salt[2] = '$';
-+
-+      snprintf(salt + 3, 4, "%2.2u$", 5);
-+
-+      printf("24 bytes of salt: ");
-+      fgets(salt + 6, 94, stdin);
-+      salt[99] = 0;
-+      printf("72 bytes of password: ");
-+      fpurge(stdin);
-+      fgets(blubber, 73, stdin);
-+      blubber[72] = 0;
-+
-+      p = crypt(blubber, salt);
-+      printf("Passwd entry: %s\n\n", p);
-+
-+      p = bcrypt_gensalt(5);
-+      printf("Generated salt: %s\n", p);
-+      p = crypt(blubber, p);
-+      printf("Passwd entry: %s\n", p);
-+}
-+#endif
-diff -urN glibc-2.1.91.orig/crypt/blf.h glibc-2.1.91/crypt/blf.h
---- glibc-2.1.91.orig/crypt/blf.h      Thu Jan  1 01:00:00 1970
-+++ glibc-2.1.91/crypt/blf.h   Sat Jul 15 00:56:30 2000
-@@ -0,0 +1,80 @@
-+/*
-+ * Blowfish - a fast block cipher designed by Bruce Schneier
-+ *
-+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ *    must display the following acknowledgement:
-+ *      This product includes software developed by Niels Provos.
-+ * 4. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#ifndef _BLF_H_
-+#define _BLF_H_
-+
-+/* Schneier states the maximum key length to be 56 bytes.
-+ * The way how the subkeys are initalized by the key up
-+ * to (N+2)*4 i.e. 72 bytes are utilized.
-+ * Warning: For normal blowfish encryption only 56 bytes
-+ * of the key affect all cipherbits.
-+ */
-+
-+#define BLF_N 16                      /* Number of Subkeys */
-+#define BLF_MAXKEYLEN ((BLF_N-2)*4)   /* 448 bits */
-+
-+/* Blowfish context */
-+typedef struct BlowfishContext {
-+      u_int32_t S[4][256];    /* S-Boxes */
-+      u_int32_t P[BLF_N + 2]; /* Subkeys */
-+} blf_ctx;
-+
-+/* Raw access to customized Blowfish
-+ *    blf_key is just:
-+ *    Blowfish_initstate( state )
-+ *    Blowfish_expand0state( state, key, keylen )
-+ */
-+
-+void Blowfish_encipher __P((blf_ctx *, u_int32_t *, u_int32_t *));
-+void Blowfish_decipher __P((blf_ctx *, u_int32_t *, u_int32_t *));
-+void Blowfish_initstate __P((blf_ctx *));
-+void Blowfish_expand0state __P((blf_ctx *, const u_int8_t *, u_int16_t));
-+void Blowfish_expandstate
-+    __P((blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t));
 +
 +
-+/* Standard Blowfish */
++typedef unsigned int BF_word;
 +
 +
-+void blf_key __P((blf_ctx *, const u_int8_t *, u_int16_t));
-+void blf_enc __P((blf_ctx *, u_int32_t *, u_int16_t));
-+void blf_dec __P((blf_ctx *, u_int32_t *, u_int16_t));
++/* Number of Blowfish rounds, this is also hardcoded into a few places */
++#define BF_N                          16
 +
 +
-+void blf_ecb_encrypt __P((blf_ctx *, u_int8_t *, u_int32_t));
-+void blf_ecb_decrypt __P((blf_ctx *, u_int8_t *, u_int32_t));
++typedef BF_word BF_key[BF_N + 2];
 +
 +
-+void blf_cbc_encrypt __P((blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t));
-+void blf_cbc_decrypt __P((blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t));
++typedef struct {
++      BF_word S[4][0x100];
++      BF_key P;
++} BF_ctx;
 +
 +
-+/* Converts u_int8_t to u_int32_t */
-+u_int32_t Blowfish_stream2word __P((const u_int8_t *, u_int16_t , u_int16_t *));
-+
-+#endif
-diff -urN glibc-2.1.91.orig/crypt/blowfish.c glibc-2.1.91/crypt/blowfish.c
---- glibc-2.1.91.orig/crypt/blowfish.c Thu Jan  1 01:00:00 1970
-+++ glibc-2.1.91/crypt/blowfish.c      Sat Jul 15 00:56:30 2000
-@@ -0,0 +1,773 @@
 +/*
 +/*
-+ * Blowfish block cipher for OpenBSD
-+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
-+ * All rights reserved.
-+ *
-+ * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ *    must display the following acknowledgement:
-+ *      This product includes software developed by Niels Provos.
-+ * 4. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ * Magic IV for 64 Blowfish encryptions that we do at the end.
++ * The string is "OrpheanBeholderScryDoubt" on big-endian.
 + */
 + */
++static BF_word BF_magic_w[6] = {
++      0x4F727068, 0x65616E42, 0x65686F6C,
++      0x64657253, 0x63727944, 0x6F756274
++};
 +
 +/*
 +
 +/*
-+ * This code is derived from section 14.3 and the given source
-+ * in section V of Applied Cryptography, second edition.
-+ * Blowfish is an unpatented fast block cipher designed by
-+ * Bruce Schneier.
++ * P-box and S-box tables initialized with digits of Pi.
 + */
 + */
-+
-+#if 0
-+#include <stdio.h>            /* used for debugging */
-+#include <string.h>
-+#endif
-+
-+#include <sys/types.h>
-+#include "blf.h"
-+
-+#undef inline
-+#ifdef __GNUC__
-+#define inline __inline
-+#else                         /* !__GNUC__ */
-+#define inline
-+#endif                                /* !__GNUC__ */
-+
-+/* Function for Feistel Networks */
-+
-+#define F(bc, x) ((((bc)->S[0][((x) & 0xFF000000) >> 24] \
-+                  + (bc)->S[1][((x) &0xFF0000 ) >> 16]) \
-+                 ^ (bc)->S[2][((x) & 0xFF00) >> 8]) \
-+                + (bc)->S[3][(x) & 0x00FF])
-+
-+#define BLFRND(bc,i,j,n) (i ^= F(bc,j) ^ (bc)->P[n])
-+
-+void
-+Blowfish_encipher(c, xl, xr)
-+      blf_ctx *c;
-+      u_int32_t *xl;
-+      u_int32_t *xr;
-+{
-+      u_int32_t Xl;
-+      u_int32_t Xr;
-+
-+      Xl = *xl;
-+      Xr = *xr;
-+
-+      Xl ^= c->P[0];
-+      BLFRND(c, Xr, Xl, 1); BLFRND(c, Xl, Xr, 2);
-+      BLFRND(c, Xr, Xl, 3); BLFRND(c, Xl, Xr, 4);
-+      BLFRND(c, Xr, Xl, 5); BLFRND(c, Xl, Xr, 6);
-+      BLFRND(c, Xr, Xl, 7); BLFRND(c, Xl, Xr, 8);
-+      BLFRND(c, Xr, Xl, 9); BLFRND(c, Xl, Xr, 10);
-+      BLFRND(c, Xr, Xl, 11); BLFRND(c, Xl, Xr, 12);
-+      BLFRND(c, Xr, Xl, 13); BLFRND(c, Xl, Xr, 14);
-+      BLFRND(c, Xr, Xl, 15); BLFRND(c, Xl, Xr, 16);
-+
-+      *xl = Xr ^ c->P[17];
-+      *xr = Xl;
-+}
-+
-+void
-+Blowfish_decipher(c, xl, xr)
-+      blf_ctx *c;
-+      u_int32_t *xl;
-+      u_int32_t *xr;
-+{
-+      u_int32_t Xl;
-+      u_int32_t Xr;
-+
-+      Xl = *xl;
-+      Xr = *xr;
-+
-+      Xl ^= c->P[17];
-+      BLFRND(c, Xr, Xl, 16); BLFRND(c, Xl, Xr, 15);
-+      BLFRND(c, Xr, Xl, 14); BLFRND(c, Xl, Xr, 13);
-+      BLFRND(c, Xr, Xl, 12); BLFRND(c, Xl, Xr, 11);
-+      BLFRND(c, Xr, Xl, 10); BLFRND(c, Xl, Xr, 9);
-+      BLFRND(c, Xr, Xl, 8); BLFRND(c, Xl, Xr, 7);
-+      BLFRND(c, Xr, Xl, 6); BLFRND(c, Xl, Xr, 5);
-+      BLFRND(c, Xr, Xl, 4); BLFRND(c, Xl, Xr, 3);
-+      BLFRND(c, Xr, Xl, 2); BLFRND(c, Xl, Xr, 1);
-+
-+      *xl = Xr ^ c->P[0];
-+      *xr = Xl;
-+}
-+
-+void
-+Blowfish_initstate(c)
-+      blf_ctx *c;
-+{
-+
-+/* P-box and S-box tables initialized with digits of Pi */
-+
-+      const blf_ctx initstate =
-+
-+      { {
++static BF_ctx BF_init_state = {
++      {
 +              {
 +                      0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
 +                      0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
 +              {
 +                      0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
 +                      0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
@@ -830,8 +150,8 @@ diff -urN glibc-2.1.91.orig/crypt/blowfish.c glibc-2.1.91/crypt/blowfish.c
 +                      0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
 +                      0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
 +                      0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
 +                      0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
 +                      0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
 +                      0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
-+              0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
-+              {
++                      0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
++              }, {
 +                      0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
 +                      0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
 +                      0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
 +                      0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
 +                      0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
 +                      0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
@@ -895,8 +215,8 @@ diff -urN glibc-2.1.91.orig/crypt/blowfish.c glibc-2.1.91/crypt/blowfish.c
 +                      0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
 +                      0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
 +                      0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
 +                      0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
 +                      0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
 +                      0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
-+              0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
-+              {
++                      0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
++              }, {
 +                      0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
 +                      0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
 +                      0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
 +                      0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
 +                      0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
 +                      0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
@@ -960,8 +280,8 @@ diff -urN glibc-2.1.91.orig/crypt/blowfish.c glibc-2.1.91/crypt/blowfish.c
 +                      0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
 +                      0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
 +                      0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
 +                      0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
 +                      0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
 +                      0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
-+              0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
-+              {
++                      0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
++              }, {
 +                      0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
 +                      0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
 +                      0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
 +                      0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
 +                      0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
 +                      0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
@@ -1025,445 +345,452 @@ diff -urN glibc-2.1.91.orig/crypt/blowfish.c glibc-2.1.91/crypt/blowfish.c
 +                      0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
 +                      0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
 +                      0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
 +                      0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
 +                      0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
 +                      0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
-+              0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
-+      },
-+      {
++                      0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
++              }
++      }, {
 +              0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
 +              0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
 +              0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
 +              0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
 +              0x9216d5d9, 0x8979fb1b
 +              0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
 +              0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
 +              0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
 +              0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
 +              0x9216d5d9, 0x8979fb1b
-+      } };
++      }
++};
 +
 +
-+      *c = initstate;
++static unsigned char BF_itoa64[64 + 1] =
++      "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 +
 +
-+}
++static unsigned char BF_atoi64[0x60] = {
++      64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
++      54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
++      64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
++      17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
++      64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
++      43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
++};
 +
 +
-+#ifdef __STDC__
-+u_int32_t
-+Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, u_int16_t *current)
-+#else
-+u_int32_t
-+Blowfish_stream2word(data, databytes, current)
-+      const u_int8_t *data;
-+      u_int16_t databytes;
-+      u_int16_t *current;
-+#endif
++/*
++ * This may be optimized out if built with function inlining and no BF_ASM.
++ */
++static void clean(void *data, int size)
 +{
 +{
-+      u_int8_t i;
-+      u_int16_t j;
-+      u_int32_t temp;
-+
-+      temp = 0x00000000;
-+      j = *current;
-+
-+      for (i = 0; i < 4; i++, j++) {
-+              if (j >= databytes)
-+                      j = 0;
-+              temp = (temp << 8) | data[j];
-+      }
++#if BF_ASM
++      extern void _BF_clean(void *data);
++#endif
++      memset(data, 0, size);
++#if BF_ASM
++      _BF_clean(data);
++#endif
++}
 +
 +
-+      *current = j;
-+      return temp;
++#define BF_safe_atoi64(dst, src) \
++{ \
++      tmp = (unsigned char)(src); \
++      if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
++      tmp = BF_atoi64[tmp]; \
++      if (tmp > 63) return -1; \
++      (dst) = tmp; \
 +}
 +
 +}
 +
-+#if __STDC__
-+void
-+Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
-+#else
-+void
-+Blowfish_expand0state(c, key, keybytes)
-+      blf_ctx *c;
-+      const u_int8_t *key;
-+      u_int16_t keybytes;
-+#endif
++static int BF_decode(BF_word *dst, __CONST char *src, int size)
 +{
 +{
-+      u_int16_t i;
-+      u_int16_t j;
-+      u_int16_t k;
-+      u_int32_t temp;
-+      u_int32_t datal;
-+      u_int32_t datar;
-+
-+      j = 0;
-+      for (i = 0; i < BLF_N + 2; i++) {
-+              /* Extract 4 int8 to 1 int32 from keystream */
-+              temp = Blowfish_stream2word(key, keybytes, &j);
-+              c->P[i] = c->P[i] ^ temp;
-+      }
-+
-+      j = 0;
-+      datal = 0x00000000;
-+      datar = 0x00000000;
-+      for (i = 0; i < BLF_N + 2; i += 2) {
-+              Blowfish_encipher(c, &datal, &datar);
-+
-+              c->P[i] = datal;
-+              c->P[i + 1] = datar;
-+      }
-+
-+      for (i = 0; i < 4; i++) {
-+              for (k = 0; k < 256; k += 2) {
-+                      Blowfish_encipher(c, &datal, &datar);
-+
-+                      c->S[i][k] = datal;
-+                      c->S[i][k + 1] = datar;
-+              }
-+      }
++      unsigned char *dptr = (unsigned char *)dst;
++      unsigned char *end = dptr + size;
++      unsigned char *sptr = (unsigned char *)src;
++      unsigned int tmp, c1, c2, c3, c4;
++
++      do {
++              BF_safe_atoi64(c1, *sptr++);
++              BF_safe_atoi64(c2, *sptr++);
++              *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
++              if (dptr >= end) break;
++
++              BF_safe_atoi64(c3, *sptr++);
++              *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
++              if (dptr >= end) break;
++
++              BF_safe_atoi64(c4, *sptr++);
++              *dptr++ = ((c3 & 0x03) << 6) | c4;
++      } while (dptr < end);
++
++      return 0;
 +}
 +
 +}
 +
-+
-+#if __STDC__
-+void
-+Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
-+                   const u_int8_t *key, u_int16_t keybytes)
-+#else
-+void
-+Blowfish_expandstate(c, data, databytes, key, keybytes)
-+      blf_ctx *c;
-+      const u_int8_t *data;
-+      u_int16_t databytes;
-+      const u_int8_t *key;
-+      u_int16_t keybytes;
-+#endif
++static void BF_encode(char *dst, __CONST BF_word *src, int size)
 +{
 +{
-+      u_int16_t i;
-+      u_int16_t j;
-+      u_int16_t k;
-+      u_int32_t temp;
-+      u_int32_t datal;
-+      u_int32_t datar;
-+
-+      j = 0;
-+      for (i = 0; i < BLF_N + 2; i++) {
-+              /* Extract 4 int8 to 1 int32 from keystream */
-+              temp = Blowfish_stream2word(key, keybytes, &j);
-+              c->P[i] = c->P[i] ^ temp;
-+      }
-+
-+      j = 0;
-+      datal = 0x00000000;
-+      datar = 0x00000000;
-+      for (i = 0; i < BLF_N + 2; i += 2) {
-+              datal ^= Blowfish_stream2word(data, databytes, &j);
-+              datar ^= Blowfish_stream2word(data, databytes, &j);
-+              Blowfish_encipher(c, &datal, &datar);
-+
-+              c->P[i] = datal;
-+              c->P[i + 1] = datar;
-+      }
-+
-+      for (i = 0; i < 4; i++) {
-+              for (k = 0; k < 256; k += 2) {
-+                      datal ^= Blowfish_stream2word(data, databytes, &j);
-+                      datar ^= Blowfish_stream2word(data, databytes, &j);
-+                      Blowfish_encipher(c, &datal, &datar);
++      unsigned char *sptr = (unsigned char *)src;
++      unsigned char *end = sptr + size;
++      unsigned char *dptr = (unsigned char *)dst;
++      unsigned int c1, c2;
++
++      do {
++              c1 = *sptr++;
++              *dptr++ = BF_itoa64[c1 >> 2];
++              c1 = (c1 & 0x03) << 4;
++              if (sptr >= end) {
++                      *dptr++ = BF_itoa64[c1];
++                      break;
++              }
 +
 +
-+                      c->S[i][k] = datal;
-+                      c->S[i][k + 1] = datar;
++              c2 = *sptr++;
++              c1 |= c2 >> 4;
++              *dptr++ = BF_itoa64[c1];
++              c1 = (c2 & 0x0f) << 2;
++              if (sptr >= end) {
++                      *dptr++ = BF_itoa64[c1];
++                      break;
 +              }
 +              }
-+      }
 +
 +
++              c2 = *sptr++;
++              c1 |= c2 >> 6;
++              *dptr++ = BF_itoa64[c1];
++              *dptr++ = BF_itoa64[c2 & 0x3f];
++      } while (sptr < end);
 +}
 +
 +}
 +
-+#if __STDC__
-+void
-+blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
-+#else
-+void
-+blf_key(c, k, len)
-+      blf_ctx *c;
-+      const u_int8_t *k;
-+      u_int16_t len;
-+#endif
++static void BF_swap(BF_word *x, int count)
 +{
 +{
-+      /* Initalize S-boxes and subkeys with Pi */
-+      Blowfish_initstate(c);
-+
-+      /* Transform S-boxes and subkeys with key */
-+      Blowfish_expand0state(c, k, len);
++      static int endianness_check = 1;
++      char *is_little_endian = (char *)&endianness_check;
++      BF_word tmp;
++
++      if (*is_little_endian)
++      do {
++              tmp = *x;
++              tmp = (tmp << 16) | (tmp >> 16);
++              *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
++      } while (--count);
 +}
 +
 +}
 +
-+#if __STDC__
-+void
-+blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
++#if BF_SCALE
++/* Architectures which can shift addresses left by 2 bits with no extra cost */
++#define BF_ROUND(L, R, N) \
++      tmp1 = L & 0xFF; \
++      tmp2 = L >> 8; \
++      tmp2 &= 0xFF; \
++      tmp3 = L >> 16; \
++      tmp3 &= 0xFF; \
++      tmp4 = L >> 24; \
++      tmp1 = data.ctx.S[3][tmp1]; \
++      tmp2 = data.ctx.S[2][tmp2]; \
++      tmp3 = data.ctx.S[1][tmp3]; \
++      tmp3 += data.ctx.S[0][tmp4]; \
++      tmp3 ^= tmp2; \
++      R ^= data.ctx.P[N + 1]; \
++      tmp3 += tmp1; \
++      R ^= tmp3;
 +#else
 +#else
-+void
-+blf_enc(c, data, blocks)
-+      blf_ctx *c;
-+      u_int32_t *data;
-+      u_int16_t blocks;
++/* Architectures with no complicated addressing modes supported */
++#define BF_INDEX(S, i) \
++      (*((BF_word *)(((unsigned char *)S) + (i))))
++#define BF_ROUND(L, R, N) \
++      tmp1 = L & 0xFF; \
++      tmp1 <<= 2; \
++      tmp2 = L >> 6; \
++      tmp2 &= 0x3FC; \
++      tmp3 = L >> 14; \
++      tmp3 &= 0x3FC; \
++      tmp4 = L >> 22; \
++      tmp4 &= 0x3FC; \
++      tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
++      tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
++      tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
++      tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
++      tmp3 ^= tmp2; \
++      R ^= data.ctx.P[N + 1]; \
++      tmp3 += tmp1; \
++      R ^= tmp3;
 +#endif
 +#endif
-+{
-+      u_int32_t *d;
-+      u_int16_t i;
 +
 +
-+      d = data;
-+      for (i = 0; i < blocks; i++) {
-+              Blowfish_encipher(c, d, d + 1);
-+              d += 2;
-+      }
-+}
-+
-+#if __STDC__
-+void
-+blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
++/*
++ * Encrypt one block, BF_N is hardcoded here.
++ */
++#define BF_ENCRYPT \
++      L ^= data.ctx.P[0]; \
++      BF_ROUND(L, R, 0); \
++      BF_ROUND(R, L, 1); \
++      BF_ROUND(L, R, 2); \
++      BF_ROUND(R, L, 3); \
++      BF_ROUND(L, R, 4); \
++      BF_ROUND(R, L, 5); \
++      BF_ROUND(L, R, 6); \
++      BF_ROUND(R, L, 7); \
++      BF_ROUND(L, R, 8); \
++      BF_ROUND(R, L, 9); \
++      BF_ROUND(L, R, 10); \
++      BF_ROUND(R, L, 11); \
++      BF_ROUND(L, R, 12); \
++      BF_ROUND(R, L, 13); \
++      BF_ROUND(L, R, 14); \
++      BF_ROUND(R, L, 15); \
++      tmp4 = R; \
++      R = L; \
++      L = tmp4 ^ data.ctx.P[BF_N + 1];
++
++#if BF_ASM
++#define BF_body() \
++      _BF_body_r(&data.ctx);
 +#else
 +#else
-+void
-+blf_dec(c, data, blocks)
-+      blf_ctx *c;
-+      u_int32_t *data;
-+      u_int16_t blocks;
++#define BF_body() \
++      L = R = 0; \
++      ptr = data.ctx.P; \
++      do { \
++              ptr += 2; \
++              BF_ENCRYPT; \
++              *(ptr - 2) = L; \
++              *(ptr - 1) = R; \
++      } while (ptr < &data.ctx.P[BF_N + 2]); \
++\
++      ptr = data.ctx.S[0]; \
++      do { \
++              ptr += 2; \
++              BF_ENCRYPT; \
++              *(ptr - 2) = L; \
++              *(ptr - 1) = R; \
++      } while (ptr < &data.ctx.S[3][0xFF]);
 +#endif
 +#endif
-+{
-+      u_int32_t *d;
-+      u_int16_t i;
 +
 +
-+      d = data;
-+      for (i = 0; i < blocks; i++) {
-+              Blowfish_decipher(c, d, d + 1);
-+              d += 2;
-+      }
-+}
-+
-+#if __STDC__
-+void
-+blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
-+#else
-+void
-+blf_ecb_encrypt(c, data, len)
-+     blf_ctx *c;
-+     u_int8_t *data;
-+     u_int32_t len;
-+#endif
++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
 +{
 +{
-+      u_int32_t l, r;
-+      u_int32_t i;
++      __CONST char *ptr = key;
++      int i, j;
++      BF_word tmp;
 +
 +
-+      for (i = 0; i < len; i += 8) {
-+              l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
-+              r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
-+              Blowfish_encipher(c, &l, &r);
-+              data[0] = l >> 24 & 0xff;
-+              data[1] = l >> 16 & 0xff;
-+              data[2] = l >> 8 & 0xff;
-+              data[3] = l & 0xff;
-+              data[4] = r >> 24 & 0xff;
-+              data[5] = r >> 16 & 0xff;
-+              data[6] = r >> 8 & 0xff;
-+              data[7] = r & 0xff;
-+              data += 8;
-+      }
-+}
++      for (i = 0; i < BF_N + 2; i++) {
++              tmp = 0;
++              for (j = 0; j < 4; j++) {
++                      tmp <<= 8;
++                      tmp |= (unsigned char)*ptr;
 +
 +
-+#if __STDC__
-+void
-+blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
-+#else
-+void
-+blf_ecb_decrypt(c, data, len)
-+     blf_ctx *c;
-+     u_int8_t *data;
-+     u_int32_t len;
-+#endif
-+{
-+      u_int32_t l, r;
-+      u_int32_t i;
++                      if (!*ptr) ptr = key; else ptr++;
++              }
 +
 +
-+      for (i = 0; i < len; i += 8) {
-+              l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
-+              r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
-+              Blowfish_decipher(c, &l, &r);
-+              data[0] = l >> 24 & 0xff;
-+              data[1] = l >> 16 & 0xff;
-+              data[2] = l >> 8 & 0xff;
-+              data[3] = l & 0xff;
-+              data[4] = r >> 24 & 0xff;
-+              data[5] = r >> 16 & 0xff;
-+              data[6] = r >> 8 & 0xff;
-+              data[7] = r & 0xff;
-+              data += 8;
++              expanded[i] = tmp;
++              initial[i] = BF_init_state.P[i] ^ tmp;
 +      }
 +}
 +
 +      }
 +}
 +
-+#if __STDC__
-+void
-+blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
-+#else
-+void
-+blf_cbc_encrypt(c, iv, data, len)
-+     blf_ctx *c;
-+     u_int8_t *iv;
-+     u_int8_t *data;
-+     u_int32_t len;
-+#endif
++char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
++      char *output, int size)
 +{
 +{
-+      u_int32_t l, r;
-+      u_int32_t i, j;
-+
-+      for (i = 0; i < len; i += 8) {
-+              for (j = 0; j < 8; j++)
-+                      data[j] ^= iv[j];
-+              l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
-+              r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
-+              Blowfish_encipher(c, &l, &r);
-+              data[0] = l >> 24 & 0xff;
-+              data[1] = l >> 16 & 0xff;
-+              data[2] = l >> 8 & 0xff;
-+              data[3] = l & 0xff;
-+              data[4] = r >> 24 & 0xff;
-+              data[5] = r >> 16 & 0xff;
-+              data[6] = r >> 8 & 0xff;
-+              data[7] = r & 0xff;
-+              iv = data;
-+              data += 8;
++#if BF_ASM
++      extern void _BF_body_r(BF_ctx *ctx);
++#endif
++      struct {
++              BF_ctx ctx;
++              BF_key expanded_key;
++              union {
++                      BF_word salt[4];
++                      BF_word output[6];
++              } binary;
++      } data;
++      BF_word L, R;
++      BF_word tmp1, tmp2, tmp3, tmp4;
++      BF_word *ptr;
++      BF_word count;
++      int i;
++
++      if (size < 7 + 22 + 31 + 1) {
++              __set_errno(ERANGE);
++              return NULL;
 +      }
 +      }
-+}
 +
 +
-+#if __STDC__
-+void
-+blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
-+#else
-+void
-+blf_cbc_decrypt(c, iva, data, len)
-+     blf_ctx *c;
-+     u_int8_t *iva;
-+     u_int8_t *data;
-+     u_int32_t len;
-+#endif
-+{
-+      u_int32_t l, r;
-+      u_int8_t *iv;
-+      u_int32_t i, j;
++      if (setting[0] != '$' ||
++          setting[1] != '2' ||
++          setting[2] != 'a' ||
++          setting[3] != '$' ||
++          setting[4] < '0' || setting[4] > '3' ||
++          setting[5] < '0' || setting[5] > '9' ||
++          setting[6] != '$') {
++              __set_errno(EINVAL);
++              return NULL;
++      }
 +
 +
-+      iv = data + len - 16;
-+      data = data + len - 8;
-+      for (i = len - 8; i >= 8; i -= 8) {
-+              l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
-+              r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
-+              Blowfish_decipher(c, &l, &r);
-+              data[0] = l >> 24 & 0xff;
-+              data[1] = l >> 16 & 0xff;
-+              data[2] = l >> 8 & 0xff;
-+              data[3] = l & 0xff;
-+              data[4] = r >> 24 & 0xff;
-+              data[5] = r >> 16 & 0xff;
-+              data[6] = r >> 8 & 0xff;
-+              data[7] = r & 0xff;
-+              for (j = 0; j < 8; j++)
-+                      data[j] ^= iv[j];
-+              iv = data;
-+              data -= 8;
++      count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
++      if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
++              clean(data.binary.salt, sizeof(data.binary.salt));
++              __set_errno(EINVAL);
++              return NULL;
 +      }
 +      }
-+      l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
-+      r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
-+      Blowfish_decipher(c, &l, &r);
-+      data[0] = l >> 24 & 0xff;
-+      data[1] = l >> 16 & 0xff;
-+      data[2] = l >> 8 & 0xff;
-+      data[3] = l & 0xff;
-+      data[4] = r >> 24 & 0xff;
-+      data[5] = r >> 16 & 0xff;
-+      data[6] = r >> 8 & 0xff;
-+      data[7] = r & 0xff;
-+      for (j = 0; j < 8; j++)
-+              data[j] ^= iva[j];
-+}
++      BF_swap(data.binary.salt, 4);
 +
 +
-+#if 0
-+void
-+report(u_int32_t data[], u_int16_t len)
-+{
-+      u_int16_t i;
-+      for (i = 0; i < len; i += 2)
-+              printf("Block %0hd: %08lx %08lx.\n",
-+                  i / 2, data[i], data[i + 1]);
-+}
-+void
-+main(void)
-+{
++      BF_set_key(key, data.expanded_key, data.ctx.P);
 +
 +
-+      blf_ctx c;
-+      char    key[] = "AAAAA";
-+      char    key2[] = "abcdefghijklmnopqrstuvwxyz";
++      memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
 +
 +
-+      u_int32_t data[10];
-+      u_int32_t data2[] =
-+      {0x424c4f57l, 0x46495348l};
++      L = R = 0;
++      for (i = 0; i < BF_N + 2; i += 2) {
++              L ^= data.binary.salt[i & 2];
++              R ^= data.binary.salt[(i & 2) + 1];
++              BF_ENCRYPT;
++              data.ctx.P[i] = L;
++              data.ctx.P[i + 1] = R;
++      }
 +
 +
-+      u_int16_t i;
++      ptr = data.ctx.S[0];
++      do {
++              ptr += 4;
++              L ^= data.binary.salt[(BF_N + 2) & 3];
++              R ^= data.binary.salt[(BF_N + 3) & 3];
++              BF_ENCRYPT;
++              *(ptr - 4) = L;
++              *(ptr - 3) = R;
++
++              L ^= data.binary.salt[(BF_N + 4) & 3];
++              R ^= data.binary.salt[(BF_N + 5) & 3];
++              BF_ENCRYPT;
++              *(ptr - 2) = L;
++              *(ptr - 1) = R;
++      } while (ptr < &data.ctx.S[3][0xFF]);
++
++      do {
++              data.ctx.P[0] ^= data.expanded_key[0];
++              data.ctx.P[1] ^= data.expanded_key[1];
++              data.ctx.P[2] ^= data.expanded_key[2];
++              data.ctx.P[3] ^= data.expanded_key[3];
++              data.ctx.P[4] ^= data.expanded_key[4];
++              data.ctx.P[5] ^= data.expanded_key[5];
++              data.ctx.P[6] ^= data.expanded_key[6];
++              data.ctx.P[7] ^= data.expanded_key[7];
++              data.ctx.P[8] ^= data.expanded_key[8];
++              data.ctx.P[9] ^= data.expanded_key[9];
++              data.ctx.P[10] ^= data.expanded_key[10];
++              data.ctx.P[11] ^= data.expanded_key[11];
++              data.ctx.P[12] ^= data.expanded_key[12];
++              data.ctx.P[13] ^= data.expanded_key[13];
++              data.ctx.P[14] ^= data.expanded_key[14];
++              data.ctx.P[15] ^= data.expanded_key[15];
++              data.ctx.P[16] ^= data.expanded_key[16];
++              data.ctx.P[17] ^= data.expanded_key[17];
++
++              BF_body();
++
++              tmp1 = data.binary.salt[0];
++              tmp2 = data.binary.salt[1];
++              tmp3 = data.binary.salt[2];
++              tmp4 = data.binary.salt[3];
++              data.ctx.P[0] ^= tmp1;
++              data.ctx.P[1] ^= tmp2;
++              data.ctx.P[2] ^= tmp3;
++              data.ctx.P[3] ^= tmp4;
++              data.ctx.P[4] ^= tmp1;
++              data.ctx.P[5] ^= tmp2;
++              data.ctx.P[6] ^= tmp3;
++              data.ctx.P[7] ^= tmp4;
++              data.ctx.P[8] ^= tmp1;
++              data.ctx.P[9] ^= tmp2;
++              data.ctx.P[10] ^= tmp3;
++              data.ctx.P[11] ^= tmp4;
++              data.ctx.P[12] ^= tmp1;
++              data.ctx.P[13] ^= tmp2;
++              data.ctx.P[14] ^= tmp3;
++              data.ctx.P[15] ^= tmp4;
++              data.ctx.P[16] ^= tmp1;
++              data.ctx.P[17] ^= tmp2;
++
++              BF_body();
++      } while (--count);
++
++      for (i = 0; i < 6; i += 2) {
++              L = BF_magic_w[i];
++              R = BF_magic_w[i + 1];
++
++              count = 64;
++              do {
++                      BF_ENCRYPT;
++              } while (--count);
++
++              data.binary.output[i] = L;
++              data.binary.output[i + 1] = R;
++      }
++
++      memcpy(output, setting, 7 + 22 - 1);
++      output[7 + 22 - 1] = BF_itoa64[(int)
++              BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
 +
 +
-+      /* First test */
-+      for (i = 0; i < 10; i++)
-+              data[i] = i;
++/* This has to be bug-compatible with the original implementation, so
++ * only encode 23 of the 24 bytes. :-) */
++      BF_swap(data.binary.output, 6);
++      BF_encode(&output[7 + 22], data.binary.output, 23);
++      output[7 + 22 + 31] = '\0';
 +
 +
-+      blf_key(&c, (u_int8_t *) key, 5);
-+      blf_enc(&c, data, 5);
-+      blf_dec(&c, data, 1);
-+      blf_dec(&c, data + 2, 4);
-+      printf("Should read as 0 - 9.\n");
-+      report(data, 10);
++/* Overwrite the most obvious sensitive data we have on the stack. Note
++ * that this does not guarantee there's no sensitive data left on the
++ * stack and/or in registers; I'm not aware of portable code that does. */
++      clean(&data, sizeof(data));
 +
 +
-+      /* Second test */
-+      blf_key(&c, (u_int8_t *) key2, strlen(key2));
-+      blf_enc(&c, data2, 1);
-+      printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
-+      report(data2, 2);
-+      blf_dec(&c, data2, 1);
-+      report(data2, 2);
++      return output;
 +}
 +}
-+#endif
-diff -urN glibc-2.1.91.orig/crypt/blowfish.h glibc-2.1.91/crypt/blowfish.h
---- glibc-2.1.91.orig/crypt/blowfish.h Thu Jan  1 01:00:00 1970
-+++ glibc-2.1.91/crypt/blowfish.h      Sat Jul 15 00:56:30 2000
-@@ -0,0 +1,10 @@
 +
 +
-+#ifndef BLOWFISH_H
-+#define BLOWFISH_H
++char *_crypt_gensalt_blowfish_rn(unsigned long count,
++      __CONST char *input, int size, char *output, int output_size)
++{
++      if (size < 16 || output_size < 7 + 22 + 1 ||
++          (count && (count < 4 || count > 31))) {
++              if (output_size > 0) output[0] = '\0';
++              __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
++              return NULL;
++      }
 +
 +
-+#include <sys/types.h>
++      if (!count) count = 5;
 +
 +
-+char *bcrypt(const char *key, const char *salt);
-+char *bcrypt_gensalt(u_int8_t log_rounds);
++      output[0] = '$';
++      output[1] = '2';
++      output[2] = 'a';
++      output[3] = '$';
++      output[4] = '0' + count / 10;
++      output[5] = '0' + count % 10;
++      output[6] = '$';
 +
 +
-+#endif                                /* BLOWFISH_H */
-diff -urN glibc-2.1.91.orig/crypt/crypt-entry.c glibc-2.1.91/crypt/crypt-entry.c
---- glibc-2.1.91.orig/crypt/crypt-entry.c      Sat Mar  4 01:47:30 2000
-+++ glibc-2.1.91/crypt/crypt-entry.c   Sat Jul 15 00:56:30 2000
-@@ -45,6 +45,8 @@
- #include "crypt.h"
- #include "crypt-private.h"
-+#include "blowfish.h"
++      BF_encode(&output[7], (BF_word *)input, 16);
++      output[7 + 22] = '\0';
 +
 +
- /* Prototypes for local functions.  */
- #if __STDC__ - 0
- #ifndef __GNU_LIBRARY__
-@@ -61,6 +63,7 @@
++      return output;
++}
+Index: crypt/Makefile
+===================================================================
+--- crypt/Makefile.orig
++++ crypt/Makefile
+@@ -27,7 +27,7 @@ extra-libs := libcrypt
+ extra-libs-others := $(extra-libs)
+ libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
+-                   crypt_util
++                   crypt_util crypt_blowfish
+ tests := cert md5c-test sha256c-test sha512c-test
+Index: crypt/crypt-entry.c
+===================================================================
+--- crypt/crypt-entry.c.orig
++++ crypt/crypt-entry.c
+@@ -59,6 +59,8 @@ extern char *__sha256_crypt (const char
+ extern char *__sha512_crypt_r (const char *key, const char *salt,
+                              char *buffer, int buflen);
+ extern char *__sha512_crypt (const char *key, const char *salt);
++extern char *_crypt_blowfish_rn (const char *key, const char *setting,
++                              char *output, int size);
+ /* Define our magic string to mark salt for MD5 encryption
     replacement.  This is meant to be the same as for other MD5 based
     replacement.  This is meant to be the same as for other MD5 based
-    encryption implementations.  */
- static const char md5_salt_prefix[] = "$1$";
-+static const char blowfish_salt_prefix[] = "$2";
+@@ -74,6 +76,9 @@ static const char sha256_salt_prefix[] =
+ /* Magic string for SHA512 encryption.  */
+ static const char sha512_salt_prefix[] = "$6$";
  
  
++/* Magic string for Blowfish encryption.  */
++static const char blowfish_salt_prefix[] = "$2a$";
++
  /* For use by the old, non-reentrant routines (crypt/encrypt/setkey)  */
  extern struct crypt_data _ufc_foobar;
  /* For use by the old, non-reentrant routines (crypt/encrypt/setkey)  */
  extern struct crypt_data _ufc_foobar;
-@@ -84,6 +87,10 @@
-   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
-     return __md5_crypt_r (key, salt, (char *) data,
-                         sizeof (struct crypt_data));
+@@ -106,6 +111,11 @@ __crypt_r (key, salt, data)
+   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
+     return __sha512_crypt_r (key, salt, (char *) data,
+                            sizeof (struct crypt_data));
 +
 +  /* Try to find out whether we have to use Blowfish encryption replacement.  */
 +  if (strncmp (blowfish_salt_prefix, salt, sizeof (blowfish_salt_prefix) - 1) == 0)
 +
 +  /* Try to find out whether we have to use Blowfish encryption replacement.  */
 +  if (strncmp (blowfish_salt_prefix, salt, sizeof (blowfish_salt_prefix) - 1) == 0)
-+    return bcrypt (key, salt);
++    return _crypt_blowfish_rn (key, salt, (char *) data,
++                           sizeof (struct crypt_data));
  #endif
  
    /*
  #endif
  
    /*
-@@ -126,6 +133,8 @@
-   /* Try to find out whether we have to use MD5 encryption replacement.  */
-   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
-     return __md5_crypt (key, salt);
-+  if (strncmp (blowfish_salt_prefix, salt, sizeof (blowfish_salt_prefix) - 1) == 0)
-+    return bcrypt (key, salt);
- #endif
-   return __crypt_r (key, salt, &_ufc_foobar);
This page took 0.082384 seconds and 4 git commands to generate.