174 lines
5.3 KiB
Diff
174 lines
5.3 KiB
Diff
|
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(-)
|
||
|
|
||
|
diff --git a/crypt.3 b/crypt.3
|
||
|
index e2f25bd..40a3538 100644
|
||
|
--- a/crypt.3
|
||
|
+++ b/crypt.3
|
||
|
@@ -399,6 +399,20 @@ too low for the currently available hardware.
|
||
|
.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
|
||
|
diff --git a/crypt_gensalt.c b/crypt_gensalt.c
|
||
|
index 73c15a1..5cf9812 100644
|
||
|
--- a/crypt_gensalt.c
|
||
|
+++ b/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 *prefix, unsigned long count,
|
||
|
|
||
|
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;
|
||
|
+}
|
||
|
diff --git a/wrapper.c b/wrapper.c
|
||
|
index 344053b..070d91d 100644
|
||
|
--- a/wrapper.c
|
||
|
+++ b/wrapper.c
|
||
|
@@ -44,12 +44,18 @@
|
||
|
|
||
|
#include "crypt_blowfish.h"
|
||
|
#include "crypt_gensalt.h"
|
||
|
+extern char *_crypt_gensalt_sha2_rn(const char *prefix, unsigned long count,
|
||
|
+ const char *input, int size, char *output, int output_size);
|
||
|
|
||
|
#if defined(__GLIBC__) && defined(_LIBC)
|
||
|
/* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */
|
||
|
#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 +118,10 @@ static char *_crypt_retval_magic(char *retval, const char *setting,
|
||
|
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 +139,16 @@ char *__crypt_rn(__const char *key, __const char *setting,
|
||
|
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 +230,9 @@ char *__crypt_gensalt_rn(const char *prefix, unsigned long count,
|
||
|
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
|
||
|
--
|
||
|
1.7.3.4
|
||
|
|