diff options
author | David Sommerseth <dazo@users.sourceforge.net> | 2009-03-22 11:24:36 +0100 |
---|---|---|
committer | David Sommerseth <dazo@users.sourceforge.net> | 2009-03-22 11:24:36 +0100 |
commit | 20f4b70c6f47b4a48197e05691de67225512f36f (patch) | |
tree | 7dcf17a7d268c5518e69eadf7a07b72eece1ff27 | |
parent | 2d01e7ab1312d28207b9ae63f1e35b6e9f8e560c (diff) | |
download | eurephia-20f4b70c6f47b4a48197e05691de67225512f36f.tar.gz eurephia-20f4b70c6f47b4a48197e05691de67225512f36f.tar.xz eurephia-20f4b70c6f47b4a48197e05691de67225512f36f.zip |
Added benchmarking to suggest minimum and maximum rounds for hashes
-rw-r--r-- | common/passwd.c | 41 | ||||
-rw-r--r-- | utils/benchmark.c | 115 |
2 files changed, 156 insertions, 0 deletions
diff --git a/common/passwd.c b/common/passwd.c index 2006602..6c5eda2 100644 --- a/common/passwd.c +++ b/common/passwd.c @@ -471,3 +471,44 @@ char *eurephia_quick_hash(const char *salt, const char *pwd) { return ret; } + + +#ifdef BENCHMARK +// This function is only used by the eurephia_init program to benchmark +// the SHA512 performance, to suggest recommended minimum and maximum +// hashing rounds. +void benchmark_hashing(int rounds) { + + char *buffer = NULL; + char *pwdhash = NULL; + static char randstr[34]; + static int rand_set = 0; + char pwdsalt[64], saltstr[32]; + + // Get random data for our salt + if( rand_set == 0 ) { + memset(&randstr, 0, 34); + if( gen_randsaltstr(NULL, randstr, 32) == 0 ) { + fprintf(stderr, "Could not retrieve enough random data for hashing"); + exit(19); + }; + rand_set = 1; + } + + // Prepare a salt package + memset(&pwdsalt, 0, 64); + memset(&saltstr, 0, 32); + pack_saltinfo(saltstr, 30, rounds, 32, "benchmarkpassword"); + strncpy(pwdsalt, saltstr, strlen(saltstr)); + strncat(pwdsalt, randstr, 62 - strlen(saltstr)); + memset(&randstr, 0, 32); + + buffer = (char *) malloc(1024); + assert( buffer != NULL ); + memset(buffer, 0, 1024); + + pwdhash = sha512_crypt_r("benchmarkpassword", pwdsalt, buffer, 1024); + + free_nullsafe(buffer); +} +#endif diff --git a/utils/benchmark.c b/utils/benchmark.c new file mode 100644 index 0000000..fe56c51 --- /dev/null +++ b/utils/benchmark.c @@ -0,0 +1,115 @@ +/* benchmark.c -- Benchmarks how quickly the computer does SHA512 hashing + * + * GPLv2 - Copyright (C) 2009 David Sommerseth <dazo@users.sourceforge.net> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <sys/time.h> + +void benchmark_hashing(int rounds); + +int timeval_subtract (result, x, y) + struct timeval *result, *x, *y; +{ + /* Perform the carry for the later subtraction by updating y. */ + if (x->tv_usec < y->tv_usec) { + int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; + y->tv_usec -= 1000000 * nsec; + y->tv_sec += nsec; + } + if (x->tv_usec - y->tv_usec > 1000000) { + int nsec = (y->tv_usec - x->tv_usec) / 1000000; + y->tv_usec += 1000000 * nsec; + y->tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + tv_usec is certainly positive. */ + result->tv_sec = x->tv_sec - y->tv_sec; + result->tv_usec = x->tv_usec - y->tv_usec; + + /* Return 1 if result is negative. */ + return x->tv_sec < y->tv_sec; +} + +struct timeval *do_benchmark(int rounds) { + struct timeval start, end, *timediff = NULL; + + timediff = (struct timeval *) malloc(sizeof(struct timeval)+2); + memset(timediff, 0, sizeof(struct timeval)+2); + + gettimeofday(&start, NULL); + benchmark_hashing(rounds); + gettimeofday(&end, NULL); + timeval_subtract(timediff, &end, &start); + + return timediff; +} + +// This function will try to find the best minium and maximum rounds for +// the SHA512 hashing. The values are returned in the min and max variables +// and the thr_min and thr_max defines the minimum and maximum thresholds in +// milliseconds the hashing algorithm should use. +int benchmark(int *min, int *max, int thr_min, int thr_max) { + int i = 0, success = 0; + struct timeval *time = NULL, min_time, max_time ; + + printf("Benchmarking "); + for( i = 1000; i < 100000000; i += 1000 ) { + printf("."); + fflush(stdout); + time = do_benchmark(i); + // printf("%i rounds: %ld sec %ld ms\n", i, time->tv_sec, time->tv_usec); + if( time->tv_usec > (thr_max * 1000) ) { + success = 1; + break; + } + if( (*min == 0) && (time->tv_usec > (thr_min * 1000)) ) { + *min = i; + min_time.tv_usec = time->tv_usec; + } + if( (time->tv_usec < (thr_max * 1000)) ) { + *max = i; + max_time.tv_usec = time->tv_usec; + } + free(time); + } + printf(" Done\n"); + if( success == 1 ) { + printf("Suggested minimum rounds: %i (takes %ldms)\n", *min, min_time.tv_usec/1000); + printf("Suggested maximum rounds: %i (takes %ldms)\n", *max, max_time.tv_usec/1000); + } else { + *min = 0; + *max = 0; + printf("Could not find any good times, as your computer is too fast for this test.\n"); + } + return success; +} + +#if 0 +int main() { + int min, max; + + benchmark(&min, &max, 90, 220); + printf("---> %i - %i\n", min, max); + return 0; +} +#endif |