File crypt_blowfish-1.2-sha.diff of Package glibc

From 1c581a8364ab18a6938f3153d7bea793d06a4652 Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Thu, 25 Aug 2011 14:00:38 +0200
Subject: [PATCH crypt_blowfish] support for sha256 and sha512

---
 crypt.3         |   14 +++++++++++++
 crypt_gensalt.c |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 wrapper.c       |   23 +++++++++++++++++++++
 3 files changed, 95 insertions(+), 0 deletions(-)

Index: crypt_blowfish-1.2/crypt.3
===================================================================
--- crypt_blowfish-1.2.orig/crypt.3
+++ crypt_blowfish-1.2/crypt.3
@@ -399,6 +399,20 @@ too low for the currently available hard
 .hash "$1$" "\e$1\e$[^$]{1,8}\e$[./0-9A-Za-z]{22}" unlimited 8 "" 128 "6 to 48" 1000
 .PP
 .ti -2
+.B SHA256 based
+.br
+This is Ulrich Drepper's SHA256-based password hashing method originally
+developed for Linux.
+.hash "$5$" "\e$5\e$(rounds=[0-9]{1,9}\e$)?([./0-9A-Za-z]{1,16})?\e$[./0-9A-Za-z]{43}" unlimited 8 "" 256 "0 to 96" "1000 to 999999999 (default 5000)"
+.PP
+.ti -2
+.B SHA512 based
+.br
+This is Ulrich Drepper's SHA512-based password hashing method originally
+developed for Linux.
+.hash "$6$" "\e$6\e$(rounds=[0-9]{1,9}\e$)?([./0-9A-Za-z]{1,16})?\e$[./0-9A-Za-z]{86}" unlimited 8 "" 512 "0 to 96" "1000 to 999999999 (default 5000)"
+.PP
+.ti -2
 .BR "OpenBSD-style Blowfish-based" " (" bcrypt )
 .br
 .B bcrypt
Index: crypt_blowfish-1.2/crypt_gensalt.c
===================================================================
--- crypt_blowfish-1.2.orig/crypt_gensalt.c
+++ crypt_blowfish-1.2/crypt_gensalt.c
@@ -19,6 +19,7 @@
  */
 
 #include <string.h>
+#include <stdio.h>
 
 #include <errno.h>
 #ifndef __set_errno
@@ -122,3 +123,60 @@ char *_crypt_gensalt_md5_rn(const char *
 
 	return output;
 }
+
+#define SHA2_SALT_LEN_MAX 16
+#define SHA2_ROUNDS_MIN   1000
+#define SHA2_ROUNDS_MAX   999999999
+char *_crypt_gensalt_sha2_rn (const char *prefix, unsigned long count,
+	const char *input, int size, char *output, int output_size)
+
+{
+	char *o = output;
+	const char *i = input;
+	unsigned needed = 3 + MIN(size/3*4, SHA2_SALT_LEN_MAX) + 1;
+
+	if (size < 3 || output_size < needed)
+		goto error;
+
+	size = MIN(size, SHA2_SALT_LEN_MAX/4*3);
+
+	o[0] = prefix[0];
+	o[1] = prefix[1];
+	o[2] = prefix[2];
+	o += 3;
+
+	if (count) {
+		count = MAX(SHA2_ROUNDS_MIN, MIN(count, SHA2_ROUNDS_MAX));
+		int n = snprintf (o, output_size-3, "rounds=%ld$", count);
+		if (n < 0 || n >= output_size-3)
+			goto error;
+		needed += n;
+		o += n;
+	}
+
+	if (output_size < needed)
+		goto error;
+
+	while (size >= 3) {
+		unsigned long value =
+			(unsigned long)(unsigned char)i[0] |
+			((unsigned long)(unsigned char)i[1] << 8) |
+			((unsigned long)(unsigned char)i[2] << 16);
+		o[0] = _crypt_itoa64[value & 0x3f];
+		o[1] = _crypt_itoa64[(value >> 6) & 0x3f];
+		o[2] = _crypt_itoa64[(value >> 12) & 0x3f];
+		o[3] = _crypt_itoa64[(value >> 18) & 0x3f];
+		size -= 3;
+		i += 3;
+		o += 3;
+	}
+	o[0] = '\0';
+
+	return output;
+
+error:
+	if (output_size > 0)
+		output[0] = '\0';
+	errno = ENOMEM;
+	return NULL;
+}
Index: crypt_blowfish-1.2/crypt_gensalt.h
===================================================================
--- crypt_blowfish-1.2.orig/crypt_gensalt.h
+++ crypt_blowfish-1.2/crypt_gensalt.h
@@ -26,5 +26,7 @@ extern char *_crypt_gensalt_extended_rn(
 	const char *input, int size, char *output, int output_size);
 extern char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count,
 	const char *input, int size, char *output, int output_size);
+extern char *_crypt_gensalt_sha2_rn(const char *prefix, unsigned long count,
+	const char *input, int size, char *output, int output_size);
 
 #endif
Index: crypt_blowfish-1.2/wrapper.c
===================================================================
--- crypt_blowfish-1.2.orig/wrapper.c
+++ crypt_blowfish-1.2/wrapper.c
@@ -50,6 +50,10 @@
 #include "crypt.h"
 extern char *__md5_crypt_r(const char *key, const char *salt,
 	char *buffer, int buflen);
+extern char *__sha256_crypt_r (const char *key, const char *salt,
+	char *buffer, int buflen);
+extern char *__sha512_crypt_r (const char *key, const char *salt,
+	char *buffer, int buflen);
 /* crypt-entry.c needs to be patched to define __des_crypt_r rather than
  * __crypt_r, and not define crypt_r and crypt at all */
 extern char *__des_crypt_r(const char *key, const char *salt,
@@ -112,6 +116,10 @@ static char *_crypt_retval_magic(char *r
 char *__crypt_rn(__const char *key, __const char *setting,
 	void *data, int size)
 {
+	if (setting[0] == '$' && setting[1] == '6')
+		return __sha512_crypt_r(key, setting, (char *)data, size);
+	if (setting[0] == '$' && setting[1] == '5')
+		return __sha256_crypt_r(key, setting, (char *)data, size);
 	if (setting[0] == '$' && setting[1] == '2')
 		return _crypt_blowfish_rn(key, setting, (char *)data, size);
 	if (setting[0] == '$' && setting[1] == '1')
@@ -129,6 +137,16 @@ char *__crypt_rn(__const char *key, __co
 char *__crypt_ra(__const char *key, __const char *setting,
 	void **data, int *size)
 {
+	if (setting[0] == '$' && setting[1] == '6') {
+		if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
+			return NULL;
+		return __sha512_crypt_r(key, setting, (char *)*data, *size);
+	}
+	if (setting[0] == '$' && setting[1] == '5') {
+		if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
+			return NULL;
+		return __sha256_crypt_r(key, setting, (char *)*data, *size);
+	}
 	if (setting[0] == '$' && setting[1] == '2') {
 		if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
 			return NULL;
@@ -210,6 +228,9 @@ char *__crypt_gensalt_rn(const char *pre
 		return NULL;
 	}
 
+	if (!strncmp(prefix, "$5$", 3) || !strncmp(prefix, "$6$", 3))
+		use = _crypt_gensalt_sha2_rn;
+	else
 	if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2y$", 4))
 		use = _crypt_gensalt_blowfish_rn;
 	else
openSUSE Build Service is sponsored by