22 #define INVALID_HASH "1234567890$"
23 #ifndef CRYPT_GENSALT_OUTPUT_SIZE
24 #define CRYPT_GENSALT_OUTPUT_SIZE 192
27 #ifndef CRYPT_OUTPUT_SIZE
28 #define CRYPT_OUTPUT_SIZE 384
41 #ifndef EXTERNAL_CRYPT_GENSALT_R
45 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
51 FILE *fp = fopen (
"/dev/urandom",
"r");
58 size_t nread = fread (buf, 1, buflen, fp);
82 crypt_gensalt_r (
const char *prefix,
unsigned long count,
const char *rbytes,
83 int nrbytes,
char *output,
int output_size);
86 int nrbytes,
char *output,
int output_size)
88 char *internal_rbytes = NULL;
89 unsigned int written = 0, used = 0;
90 unsigned long value = 0;
91 if ((rbytes != NULL && nrbytes < 3) || output_size < 16
99 internal_rbytes = malloc (16);
106 rbytes = internal_rbytes;
108 written = snprintf (output, output_size,
"%srounds=%lu$",
110 while (written + 5 < (
unsigned int) output_size
111 && used + 3 < (
unsigned int) nrbytes && (used * 4 / 3) < 16)
113 value = ((
unsigned long) rbytes[used + 0] << 0)
114 | ((
unsigned long) rbytes[used + 1] << 8)
115 | ((
unsigned long) rbytes[used + 2] << 16);
116 output[written] =
ascii64[value & 0x3f];
117 output[written + 1] =
ascii64[(value >> 6) & 0x3f];
118 output[written + 2] =
ascii64[(value >> 12) & 0x3f];
119 output[written + 3] =
ascii64[(value >> 18) & 0x3f];
123 output[written] =
'\0';
125 if (internal_rbytes != NULL)
126 free (internal_rbytes);
127 return output[0] ==
'*' ? 0 : output;
164 return strlen (setting) > 1 && setting[0] ==
'$';
170 char *result = NULL, *settings = NULL, *tmp, *rslt;
172 struct crypt_data *data = NULL;
174 if (!setting || !password)
183 tmp = settings + strlen (settings) - 1;
186 if (setting->
pepper[i] != 0)
187 tmp[0] = setting->
pepper[i];
191 data = calloc (1,
sizeof (
struct crypt_data));
192 rslt = crypt_r (password, settings, data);
199 tmp = result + (tmp - settings);
203 if (setting->
pepper[i] != 0)
209 if (settings != NULL)
216 const char *password)
218 char *cmp, *tmp = NULL;
219 struct crypt_data *data = NULL;
234 hash_size = hash ? strlen (hash) : strlen (invalid_hash);
236 data = calloc (1,
sizeof (
struct crypt_data));
241 memcpy (tmp, hash ? hash : invalid_hash,
244 cmp = strrchr (tmp,
'$');
248 if (setting->
pepper[i] != 0)
249 cmp[0] = setting->
pepper[i];
254 cmp = crypt_r (password ? password :
"", tmp, data);
255 if (strcmp (tmp, cmp) == 0)