18 #include "my_config.h"
24 #include <openssl/ssl.h>
26 #include <openssl/sha.h>
27 #include <openssl/rand.h>
30 #include "crypt_genhash_impl.h"
37 typedef unsigned long uint32_t;
40 typedef unsigned char uint8_t;
42 #endif // !HAVE_STDINT_H
50 #define DIGEST_CTX SHA256_CTX
51 #define DIGESTInit SHA256_Init
52 #define DIGESTUpdate SHA256_Update
53 #define DIGESTFinal SHA256_Final
54 #define DIGEST_LEN SHA256_DIGEST_LENGTH
56 #define DIGEST_CTX TaoCrypt::SHA256
58 void DIGESTInit(DIGEST_CTX *ctx)
63 void DIGESTUpdate(DIGEST_CTX *ctx,
const void *plaintext,
int len)
65 ctx->Update((
const TaoCrypt::byte *)plaintext, len);
68 void DIGESTFinal(
void *txt, DIGEST_CTX *ctx)
70 ctx->Final((TaoCrypt::byte *)txt);
75 static const char crypt_alg_magic[] =
"$5";
78 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
81 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
91 strlcat(
char *dst,
const char *src,
size_t siz)
98 while (n-- != 0 && *d !=
'\0')
114 return(dlen + (s - src));
117 static const int crypt_alg_magic_len =
sizeof (crypt_alg_magic) - 1;
119 static unsigned char b64t[] =
120 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
122 #define b64_from_24bit(B2, B1, B0, N) \
124 uint32_t w = ((B2) << 16) | ((B1) << 8) | (B0); \
126 while (--n >= 0 && ctbufflen > 0) { \
127 *p++ = b64t[w & 0x3f]; \
133 #define ROUNDS "rounds="
134 #define ROUNDSLEN (sizeof (ROUNDS) - 1)
141 static uint getrounds(
const char *s)
151 if ((r = strstr(s, ROUNDS)) == NULL)
156 if (strncmp(r, ROUNDS, ROUNDSLEN) != 0)
163 val= strtol(p, &e, 10);
168 if (errno != 0 || val < 0 || !(*e ==
'\0' || *e ==
',' || *e ==
'$'))
173 return ((uint32_t) val);
189 int extract_user_salt(
char **salt_begin,
192 char *it= *salt_begin;
193 int delimiter_count= 0;
194 while(it != *salt_end)
199 if (delimiter_count == 2)
203 if (delimiter_count == 3)
209 return *salt_end - *salt_begin;
212 const char *sha256_find_digest(
char *pass)
214 int sz= strlen(pass);
215 return pass + sz - SHA256_HASH_LENGTH;
251 my_crypt_genhash(
char *ctbuffer,
253 const char *plaintext,
255 const char *switchsalt,
260 unsigned char A[DIGEST_LEN];
261 unsigned char B[DIGEST_LEN];
262 unsigned char DP[DIGEST_LEN];
263 unsigned char DS[DIGEST_LEN];
264 DIGEST_CTX ctxA, ctxB, ctxC, ctxDP, ctxDS;
265 int rounds = ROUNDS_DEFAULT;
267 bool custom_rounds=
false;
273 salt = (
char *)switchsalt;
276 if (strncmp((
char *)salt, crypt_alg_magic, crypt_alg_magic_len) == 0)
278 salt += crypt_alg_magic_len + 1;
281 srounds = getrounds(salt);
283 rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
285 p = strchr(salt,
'$');
290 salt_len = MIN(strcspn(salt,
"$"), CRYPT_SALT_LENGTH);
297 DIGESTUpdate(&ctxA, plaintext, plaintext_len);
300 DIGESTUpdate(&ctxA, salt, salt_len);
304 DIGESTUpdate(&ctxB, plaintext, plaintext_len);
305 DIGESTUpdate(&ctxB, salt, salt_len);
306 DIGESTUpdate(&ctxB, plaintext, plaintext_len);
307 DIGESTFinal(B, &ctxB);
310 for (i= plaintext_len; i > MIXCHARS; i -= MIXCHARS)
311 DIGESTUpdate(&ctxA, B, MIXCHARS);
312 DIGESTUpdate(&ctxA, B, i);
315 for (i= plaintext_len; i > 0; i >>= 1) {
318 DIGESTUpdate(&ctxA, B, MIXCHARS);
322 DIGESTUpdate(&ctxA, plaintext, plaintext_len);
327 DIGESTFinal(A, &ctxA);
331 for (i= 0; i < plaintext_len; i++)
332 DIGESTUpdate(&ctxDP, plaintext, plaintext_len);
333 DIGESTFinal(DP, &ctxDP);
336 Pp= P= (
char *)alloca(plaintext_len);
337 for (i= plaintext_len; i >= MIXCHARS; i -= MIXCHARS)
339 Pp= (
char *)(memcpy(Pp, DP, MIXCHARS)) + MIXCHARS;
341 (void) memcpy(Pp, DP, i);
345 for (i= 0; i < 16 + (uint8_t)A[0]; i++)
346 DIGESTUpdate(&ctxDS, salt, salt_len);
347 DIGESTFinal(DS, &ctxDS);
350 Sp= S= (
char *)alloca(salt_len);
351 for (i= salt_len; i >= MIXCHARS; i -= MIXCHARS)
353 Sp= (
char *)(memcpy(Sp, DS, MIXCHARS)) + MIXCHARS;
355 (void) memcpy(Sp, DS, i);
358 for (i= 0; i < rounds; i++)
364 DIGESTUpdate(&ctxC, P, plaintext_len);
369 DIGESTUpdate(&ctxC, A, MIXCHARS);
371 DIGESTUpdate(&ctxC, DP, MIXCHARS);
375 DIGESTUpdate(&ctxC, S, salt_len);
379 DIGESTUpdate(&ctxC, P, plaintext_len);
385 DIGESTUpdate(&ctxC, A, MIXCHARS);
387 DIGESTUpdate(&ctxC, DP, MIXCHARS);
391 DIGESTUpdate(&ctxC, P, plaintext_len);
393 DIGESTFinal(DP, &ctxC);
399 (void) snprintf(ctbuffer, ctbufflen,
400 "%s$rounds=%zu$", crypt_alg_magic, (
size_t)rounds);
404 (void) snprintf(ctbuffer, ctbufflen,
405 "%s$", crypt_alg_magic);
407 (void) strncat(ctbuffer, (
const char *)salt, salt_len);
408 (void) strlcat(ctbuffer,
"$", ctbufflen);
410 p= ctbuffer + strlen(ctbuffer);
411 ctbufflen -= strlen(ctbuffer);
413 b64_from_24bit(DP[ 0], DP[10], DP[20], 4);
414 b64_from_24bit(DP[21], DP[ 1], DP[11], 4);
415 b64_from_24bit(DP[12], DP[22], DP[ 2], 4);
416 b64_from_24bit(DP[ 3], DP[13], DP[23], 4);
417 b64_from_24bit(DP[24], DP[ 4], DP[14], 4);
418 b64_from_24bit(DP[15], DP[25], DP[ 5], 4);
419 b64_from_24bit(DP[ 6], DP[16], DP[26], 4);
420 b64_from_24bit(DP[27], DP[ 7], DP[17], 4);
421 b64_from_24bit(DP[18], DP[28], DP[ 8], 4);
422 b64_from_24bit(DP[ 9], DP[19], DP[29], 4);
423 b64_from_24bit(0, DP[31], DP[30], 3);
426 (void) memset(A, 0,
sizeof (A));
427 (void) memset(B, 0,
sizeof (B));
428 (void) memset(DP, 0,
sizeof (DP));
429 (void) memset(DS, 0,
sizeof (DS));
441 void generate_user_salt(
char *buffer,
int buffer_len)
443 char *end= buffer + buffer_len - 1;
445 yaSSL::RAND_bytes((
unsigned char *) buffer, buffer_len);
447 RAND_bytes((
unsigned char *) buffer, buffer_len);
451 for (; buffer < end; buffer++)
454 if (*buffer ==
'\0' || *buffer ==
'$')
455 *buffer= *buffer + 1;
461 void xor_string(
char *
to,
int to_len,
char *pattern,
int pattern_len)
464 while(loop <= to_len)
466 *(to + loop) ^= *(pattern + loop % pattern_len);
471 #endif // HAVE_OPENSSL