]> git.pld-linux.org Git - packages/glibc.git/commitdiff
- rel 4; blowfish patch from suse; this one handles invalid salt correctly (aka retur... auto/th/glibc-2_13-4
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Fri, 1 Apr 2011 20:11:30 +0000 (20:11 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    glibc-crypt-blowfish.patch -> 1.5
    glibc.spec -> 1.901

glibc-crypt-blowfish.patch
glibc.spec

index 012e228dcbb7e6f305bcd0d8e125a0e4b7d11585..872754695c1b727cf29b7bbdcf0dd1209a7e14c1 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
-@@ -26,7 +26,7 @@
- extra-libs := libcrypt
- extra-libs-others := $(extra-libs)
--libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
-+libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt arc4random bcrypt blowfish crypt \
-                    crypt_util
- tests := cert md5c-test sha256c-test sha512c-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 <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
-+{
-+      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
-+char *
-+bcrypt_gensalt(log_rounds)
-+      u_int8_t log_rounds;
++#define __CONST
 +#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
-+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
-+{
-+      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 )
-+ */
++typedef unsigned int BF_word;
 +
-+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));
++/* Number of Blowfish rounds, this is also hardcoded into a few places */
++#define BF_N                          16
 +
-+/* Standard Blowfish */
++typedef BF_word BF_key[BF_N + 2];
 +
-+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));
++typedef struct {
++      BF_word S[4][0x100];
++      BF_key P;
++} BF_ctx;
 +
-+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));
-+
-+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));
-+
-+/* 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,
@@ -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,
-+              0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
-+              {
++                      0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
++              }, {
 +                      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,
-+              0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
-+              {
++                      0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
++              }, {
 +                      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,
-+              0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
-+              {
++                      0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
++              }, {
 +                      0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
 +                      0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
 +                      0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
@@ -1025,447 +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,
-+              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
-+      } };
++      }
++};
 +
-+      *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
-+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
-+{
-+      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
-+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
-+{
-+      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 |= *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 @@
-    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";
++      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
+@@ -61,6 +61,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);
+ #endif
  
+ /* Define our magic string to mark salt for MD5 encryption
+@@ -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;
-@@ -109,6 +109,10 @@
+@@ -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)
-+    return bcrypt (key, salt);
++    return _crypt_blowfish_rn (key, salt, (char *) data,
++                           sizeof (struct crypt_data));
  #endif
  
    /*
-@@ -159,6 +163,9 @@
-   /* Try to find out whether we have to use SHA512 encryption replacement.  */
-   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
-     return __sha512_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);
-
index e7ffc00ff9b2b54d650da3d6c6d1972f9dfd9678..d15bf5212f249b360e55eb8c79b3b13c585450e3 100644 (file)
@@ -34,7 +34,7 @@ Summary(tr.UTF-8):    GNU libc
 Summary(uk.UTF-8):     GNU libc версії
 Name:          glibc
 Version:       2.13
-Release:       3
+Release:       4
 Epoch:         6
 License:       LGPL v2.1+
 Group:         Libraries
@@ -905,7 +905,7 @@ Zabawka.
 mv %{name}-ports-%{ports_version} ports
 #%patch1 -p1
 %patch2 -p1
-%patch3 -p1
+%patch3 -p0
 %patch5 -p1
 %patch6 -p1
 %patch7 -p1
This page took 0.596435 seconds and 4 git commands to generate.