00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <assert.h>
00036 #include <sys/time.h>
00037
00038 #include <eurephia_nullsafe.h>
00039 #include <eurephia_context.h>
00040
00041 #define ROUNDS_MIN 1000
00042 #define ROUNDS_MAX 999999999
00044 int pack_saltinfo(char *buf, int buflen, int rounds, int saltlen, const char *pwd);
00045
00046 inline char *sha512_crypt_r(const char *key, const char *salt, size_t maxrounds_cfg, char *buffer, int buflen);
00047
00048 int gen_randsaltstr(eurephiaCTX *ctx, char *saltstr, int len);
00049
00056 void benchmark_hashing(int rounds) {
00057 char *buffer = NULL;
00058 char *pwdhash = NULL;
00059 static char randstr[34];
00060 static int rand_set = 0;
00061 char pwdsalt[64], saltstr[32];
00062
00063
00064 if( rand_set == 0 ) {
00065 memset(&randstr, 0, 34);
00066 if( gen_randsaltstr(NULL, randstr, 32) == 0 ) {
00067 fprintf(stderr, "Could not retrieve enough random data for hashing");
00068 exit(19);
00069 };
00070 rand_set = 1;
00071 }
00072
00073
00074 memset(&pwdsalt, 0, 64);
00075 memset(&saltstr, 0, 32);
00076 pack_saltinfo(saltstr, 30, rounds, 32, "benchmarkpassword");
00077 strncpy(pwdsalt, saltstr, strlen(saltstr));
00078 strncat(pwdsalt, randstr, 62 - strlen(saltstr));
00079 memset(&randstr, 0, 32);
00080
00081 buffer = (char *) malloc_nullsafe(NULL, 1024);
00082 assert( buffer != NULL );
00083
00084 pwdhash = sha512_crypt_r("benchmarkpassword", pwdsalt, ROUNDS_MAX, buffer, 1024);
00085
00086 free_nullsafe(NULL, buffer);
00087 }
00088
00089
00099 int timeval_subtract (result, x, y)
00100 struct timeval *result, *x, *y;
00101 {
00102
00103 if (x->tv_usec < y->tv_usec) {
00104 int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
00105 y->tv_usec -= 1000000 * nsec;
00106 y->tv_sec += nsec;
00107 }
00108 if (x->tv_usec - y->tv_usec > 1000000) {
00109 int nsec = (y->tv_usec - x->tv_usec) / 1000000;
00110 y->tv_usec += 1000000 * nsec;
00111 y->tv_sec -= nsec;
00112 }
00113
00114
00115
00116 result->tv_sec = x->tv_sec - y->tv_sec;
00117 result->tv_usec = x->tv_usec - y->tv_usec;
00118
00119
00120 return x->tv_sec < y->tv_sec;
00121 }
00122
00123
00131 struct timeval *do_benchmark(int rounds) {
00132 struct timeval start, end, *timediff = NULL;
00133
00134 timediff = (struct timeval *) malloc_nullsafe(NULL, sizeof(struct timeval)+2);
00135 assert( timediff != NULL );
00136
00137 gettimeofday(&start, NULL);
00138 benchmark_hashing(rounds);
00139 gettimeofday(&end, NULL);
00140 timeval_subtract(timediff, &end, &start);
00141
00142 return timediff;
00143 }
00144
00159 int benchmark(int *min, int *max, int thr_min, int thr_max) {
00160 int i = 0, success = 0;
00161 struct timeval *time = NULL, min_time, max_time ;
00162
00163 printf("Benchmarking ");
00164 *min = 1000;
00165 *max = 5000;
00166 memset(&min_time, 0, sizeof(struct timeval));
00167 memset(&max_time, 0, sizeof(struct timeval));
00168
00169 for( i = 1000; i < 100000000; i += 1000 ) {
00170 printf(".");
00171 fflush(stdout);
00172 time = do_benchmark(i);
00173
00174 if( time->tv_usec > (thr_max * 1000) ) {
00175 success = 1;
00176 free(time);
00177 break;
00178 }
00179 if( (*min == 1000) && (time->tv_usec > (thr_min * 1000)) ) {
00180 *min = i;
00181 min_time.tv_usec = time->tv_usec;
00182 }
00183 if( (time->tv_usec < (thr_max * 1000)) ) {
00184 *max = i;
00185 max_time.tv_usec = time->tv_usec;
00186 }
00187 free(time);
00188 }
00189 printf(" Done\n");
00190 if( success == 1 ) {
00191 printf("Suggested minimum rounds: %i (takes %ldms)\n", *min, min_time.tv_usec/1000);
00192 printf("Suggested maximum rounds: %i (takes %ldms)\n", *max, max_time.tv_usec/1000);
00193 } else {
00194 *min = 0;
00195 *max = 0;
00196 printf("Could not find any good times, as your computer is too fast for this test.\n");
00197 }
00198 return success;
00199 }
00200
00201 #if 0
00202 int main() {
00203 int min, max;
00204
00205 benchmark(&min, &max, 90, 220);
00206 printf("---> %i - %i\n", min, max);
00207 return 0;
00208 }
00209 #endif