packages: glibc/glibc-crypt-blowfish.patch - rel 4; blowfish patch from sus...

arekm arekm at pld-linux.org
Fri Apr 1 22:11:35 CEST 2011


Author: arekm                        Date: Fri Apr  1 20:11:35 2011 GMT
Module: packages                      Tag: HEAD
---- Log message:
- rel 4; blowfish patch from suse; this one handles invalid salt correctly (aka returns NULL)

---- Files affected:
packages/glibc:
   glibc-crypt-blowfish.patch (1.4 -> 1.5) 

---- Diffs:

================================================================
Index: packages/glibc/glibc-crypt-blowfish.patch
diff -u packages/glibc/glibc-crypt-blowfish.patch:1.4 packages/glibc/glibc-crypt-blowfish.patch:1.5
--- packages/glibc/glibc-crypt-blowfish.patch:1.4	Sun May 10 22:00:48 2009
+++ packages/glibc/glibc-crypt-blowfish.patch	Fri Apr  1 22:11:30 2011
@@ -1,771 +1,91 @@
-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 @@
-+/*
-+ * Arc4 random number generator for OpenBSD.
-+ * Copyright 1996 David Mazieres <dm at lcs.mit.edu>.
-+ *
-+ * 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.
-+ *
-+ * 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.
-+ *
-+ * 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 @@
+Index: crypt/crypt_blowfish.c
+===================================================================
+--- /dev/null
++++ crypt/crypt_blowfish.c
+@@ -0,0 +1,743 @@
 +/*
-+ * Copyright 1997 Niels Provos <provos at 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.
-+ */
-+
-+/* This password hashing algorithm was designed by David Mazieres
-+ * <dm at lcs.mit.edu> and works as follows:
-+ *
-+ * 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);
-+ *
++ * This code comes from John the Ripper password cracker, with reentrant
++ * and crypt(3) interfaces added, but optimizations specific to password
++ * cracking removed.
++ *
++ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
++ * placed in the public domain.
++ *
++ * There's absolutely no warranty.
++ *
++ * 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.
++ *
++ * 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>.
++ *
++ * There's a paper on the algorithm that explains its design decisions:
++ *
++ *	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;
++#include <errno.h>
++#ifndef __set_errno
++#define __set_errno(val) errno = (val)
 +#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)
++#undef __CONST
++#ifdef __GNUC__
++#define __CONST __const
 +#else
-+static void
-+encode_salt(salt, csalt, clen, logr)
-+	char   *salt;
-+	u_int8_t *csalt;
-+	u_int16_t clen;
-+	u_int8_t logr;
++#define __CONST
 +#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)
++#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
-+char *
-+bcrypt_gensalt(log_rounds)
-+	u_int8_t log_rounds;
++#define BF_ASM				0
++#define BF_SCALE			0
 +#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)
-+#else
-+static void
-+encode_base64(buffer, data, len)
-+	u_int8_t *buffer;
-+	u_int8_t *data;
-+	u_int16_t len;
-+#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);
<<Diff was trimmed, longer than 597 lines>>

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/glibc/glibc-crypt-blowfish.patch?r1=1.4&r2=1.5&f=u



More information about the pld-cvs-commit mailing list