PostgreSQL Source Code: contrib/pgcrypto/crypt-sha.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
47
51
53#include "px.h"
54
55typedef enum
56{
61
63"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
64
65
66
67
68char *
69px_crypt_shacrypt(const char *pw, const char *salt, char *passwd, unsigned dstlen)
70{
71 static const char rounds_prefix[] = "rounds=";
72 static const char *magic_bytes[2] = {"$5$", "$6$"};
73
74
76
78 PX_MD *digestA = NULL;
79 PX_MD *digestB = NULL;
81
82 const char *dec_salt_binary;
83 StringInfo decoded_salt = NULL;
85
86
88 char rounds_custom = 0;
89 char *p_bytes = NULL;
90 char *s_bytes = NULL;
91 char *cp = NULL;
92 const char *fp = NULL;
93 const char *ep = NULL;
94 size_t buf_size = 0;
95 unsigned int block;
97 unsigned int len,
98 salt_len = 0;
99
100
101 if (!passwd)
102 return NULL;
103
104 if (pw == NULL)
105 elog(ERROR, "null value for password rejected");
106
107 if (salt == NULL)
108 elog(ERROR, "null value for salt rejected");
109
110
111
112
114 elog(ERROR, "insufficient result buffer size to encrypt password");
115
116
119
120
121 memset(&sha_buf, '\0', sizeof(sha_buf));
122 memset(&sha_buf_tmp, '\0', sizeof(sha_buf_tmp));
123
124
125
126
127
128 len = strlen(pw);
129 dec_salt_binary = salt;
130
131
132
133
134
135
136
137 if (strlen(dec_salt_binary) < 3)
139 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
140 errmsg("invalid salt"));
141
142
143
144
145
146 if ((dec_salt_binary[0] != '$') || (dec_salt_binary[2] != '$'))
148 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
149 errmsg("invalid format of salt"),
150 errhint("magic byte format for shacrypt is either \"$5$\" or \"$6$\""));
151
152
153
154
155
156
157
158 if (strncmp(dec_salt_binary, magic_bytes[0], strlen(magic_bytes[0])) == 0)
159 {
161 dec_salt_binary += strlen(magic_bytes[0]);
162 }
163 else if (strncmp(dec_salt_binary, magic_bytes[1], strlen(magic_bytes[1])) == 0)
164 {
166 dec_salt_binary += strlen(magic_bytes[1]);
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 if (strncmp(dec_salt_binary,
185 rounds_prefix, sizeof(rounds_prefix) - 1) == 0)
186 {
187 const char *num = dec_salt_binary + sizeof(rounds_prefix) - 1;
188 char *endp;
189 int srounds = strtoint(num, &endp, 10);
190
191 if (*endp != '$')
193 errcode(ERRCODE_SYNTAX_ERROR),
194 errmsg("could not parse salt options"));
195
196 dec_salt_binary = endp + 1;
197
198
199
200
201
202
203
204
205
206
207
208
210 {
212 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
213 errmsg("rounds=%d exceeds maximum supported value (%d), using %d instead",
217 }
219 {
221 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
222 errmsg("rounds=%d is below supported value (%d), using %d instead",
226 }
227
228 rounds = (uint32) srounds;
229 rounds_custom = 1;
230 }
231
232
233
234
235
236 switch (type)
237 {
239 {
240
244
248
249
250 buf_size = 32;
251
253 break;
254 }
255
257 {
258
262
266
268
270 break;
271 }
272
274 elog(ERROR, "unknown crypt identifier \"%c\"", salt[1]);
275 }
276
277 if (rounds_custom > 0)
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 for (ep = dec_salt_binary;
295 ep++)
296 {
297
298
299
300
301
302
303
304
305
306
307 fp = strstr(dec_salt_binary, magic_bytes[0]);
308 if (fp != NULL)
309 elog(ERROR, "bogus magic byte found in salt string");
310
311 fp = strstr(dec_salt_binary, magic_bytes[1]);
312 if (fp != NULL)
313 elog(ERROR, "bogus magic byte found in salt string");
314
315
316
317
318
319 fp = strstr(dec_salt_binary, rounds_prefix);
320 if (fp != NULL)
321 elog(ERROR, "invalid rounds option specified in salt string");
322
323 if (*ep != '$')
324 {
327 else
329 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
330 errmsg("invalid character in salt string: \"%.*s\"",
332 }
333 else
334 {
335
336
337
338
339
340
341
342
343
344 if (decoded_salt->len > 0)
345 break;
346 }
347 }
348
349 salt_len = decoded_salt->len;
351 elog(DEBUG1, "using salt \"%s\", salt len = %d, rounds = %u",
352 decoded_salt->data, decoded_salt->len, rounds);
353
354
355
356
357
358 if (out_buf->len > (3 + 17 * rounds_custom + salt_len))
359 elog(ERROR, "unexpected length of salt string");
360
361
362
363
364
365
367 px_md_update(digestA, (const unsigned char *) decoded_salt->data, salt_len);
368
369
370
371
372
373
374
375
377 px_md_update(digestB, (const unsigned char *) dec_salt_binary, salt_len);
380
381
382
383
384 for (block = len; block > buf_size; block -= buf_size)
386
387
388
389
390
392
393
394
395
396
397
398
399
400
401 block = len;
402 while (block)
403 {
405 (block & 1) ? sha_buf : (const unsigned char *) pw,
406 (block & 1) ? buf_size : len);
407
408
409 block >>= 1;
410 }
411
412
414
415
417
418
419
420
421
422 for (block = len; block > 0; block--)
424
425
427
428
429
430
431
432
433
434
435 if ((p_bytes = palloc0(len)) == NULL)
436 {
438 }
439
440
441 for (cp = p_bytes, block = len; block > buf_size; block -= buf_size, cp += buf_size)
442 memcpy(cp, sha_buf_tmp, buf_size);
443 memcpy(cp, sha_buf_tmp, block);
444
445
446
447
449
450
451
452
453
454
455 for (block = 16 + sha_buf[0]; block > 0; block--)
456 px_md_update(digestB, (const unsigned char *) dec_salt_binary, salt_len);
457
458
459
460
462
463
464
465
466
467
468
469
470
471
472 if ((s_bytes = palloc0(salt_len)) == NULL)
474
475 for (cp = s_bytes, block = salt_len; block > buf_size; block -= buf_size, cp += buf_size)
476 memcpy(cp, sha_buf_tmp, buf_size);
477 memcpy(cp, sha_buf_tmp, block);
478
479
480 px_memset(&sha_buf_tmp, 0, sizeof sha_buf);
481
482
483
484
485
486
487
488
489
490
491
492 for (block = 0; block < rounds; block++)
493 {
494
495
496
497
499
500
502
503
504
505
506
508 (block & 1) ? (const unsigned char *) p_bytes : sha_buf,
509 (block & 1) ? len : buf_size);
510
511
512 if ((block % 3) != 0)
513 px_md_update(digestB, (const unsigned char *) s_bytes, salt_len);
514
515
516 if ((block % 7) != 0)
517 px_md_update(digestB, (const unsigned char *) p_bytes, len);
518
519
520
521
522
524 (block & 1) ? sha_buf : (const unsigned char *) p_bytes,
525 (block & 1) ? buf_size : len);
526
527
529 }
530
533
534 digestA = NULL;
535 digestB = NULL;
536
539
540 s_bytes = NULL;
541 p_bytes = NULL;
542
543
545
546#define b64_from_24bit(B2, B1, B0, N) \
547 do { \
548 unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
549 int i = (N); \
550 while (i-- > 0) \
551 { \
552 appendStringInfoCharMacro(out_buf, _crypt_itoa64[w & 0x3f]); \
553 w >>= 6; \
554 } \
555 } while (0)
556
557 switch (type)
558 {
560 {
561 b64_from_24bit(sha_buf[0], sha_buf[10], sha_buf[20], 4);
562 b64_from_24bit(sha_buf[21], sha_buf[1], sha_buf[11], 4);
563 b64_from_24bit(sha_buf[12], sha_buf[22], sha_buf[2], 4);
564 b64_from_24bit(sha_buf[3], sha_buf[13], sha_buf[23], 4);
565 b64_from_24bit(sha_buf[24], sha_buf[4], sha_buf[14], 4);
566 b64_from_24bit(sha_buf[15], sha_buf[25], sha_buf[5], 4);
567 b64_from_24bit(sha_buf[6], sha_buf[16], sha_buf[26], 4);
568 b64_from_24bit(sha_buf[27], sha_buf[7], sha_buf[17], 4);
569 b64_from_24bit(sha_buf[18], sha_buf[28], sha_buf[8], 4);
570 b64_from_24bit(sha_buf[9], sha_buf[19], sha_buf[29], 4);
572
573 break;
574 }
575
577 {
578 b64_from_24bit(sha_buf[0], sha_buf[21], sha_buf[42], 4);
579 b64_from_24bit(sha_buf[22], sha_buf[43], sha_buf[1], 4);
580 b64_from_24bit(sha_buf[44], sha_buf[2], sha_buf[23], 4);
581 b64_from_24bit(sha_buf[3], sha_buf[24], sha_buf[45], 4);
582 b64_from_24bit(sha_buf[25], sha_buf[46], sha_buf[4], 4);
583 b64_from_24bit(sha_buf[47], sha_buf[5], sha_buf[26], 4);
584 b64_from_24bit(sha_buf[6], sha_buf[27], sha_buf[48], 4);
585 b64_from_24bit(sha_buf[28], sha_buf[49], sha_buf[7], 4);
586 b64_from_24bit(sha_buf[50], sha_buf[8], sha_buf[29], 4);
587 b64_from_24bit(sha_buf[9], sha_buf[30], sha_buf[51], 4);
588 b64_from_24bit(sha_buf[31], sha_buf[52], sha_buf[10], 4);
589 b64_from_24bit(sha_buf[53], sha_buf[11], sha_buf[32], 4);
590 b64_from_24bit(sha_buf[12], sha_buf[33], sha_buf[54], 4);
591 b64_from_24bit(sha_buf[34], sha_buf[55], sha_buf[13], 4);
592 b64_from_24bit(sha_buf[56], sha_buf[14], sha_buf[35], 4);
593 b64_from_24bit(sha_buf[15], sha_buf[36], sha_buf[57], 4);
594 b64_from_24bit(sha_buf[37], sha_buf[58], sha_buf[16], 4);
595 b64_from_24bit(sha_buf[59], sha_buf[17], sha_buf[38], 4);
596 b64_from_24bit(sha_buf[18], sha_buf[39], sha_buf[60], 4);
597 b64_from_24bit(sha_buf[40], sha_buf[61], sha_buf[19], 4);
598 b64_from_24bit(sha_buf[62], sha_buf[20], sha_buf[41], 4);
600
601 break;
602 }
603
605
606 elog(ERROR, "unsupported digest length");
607 }
608
609
610
611
612
613
614
615
616
617
618 memcpy(passwd, out_buf->data, out_buf->len);
619
620
621 px_memset(&sha_buf, 0, sizeof sha_buf);
624
625
626 return passwd;
627
629 if (digestA != NULL)
631
632 if (digestB != NULL)
634
637
639 errcode(ERRCODE_INTERNAL_ERROR),
640 errmsg("cannot create encrypted password"));
641 return NULL;
642}
char * px_crypt_shacrypt(const char *pw, const char *salt, char *passwd, unsigned dstlen)
#define b64_from_24bit(B2, B1, B0, N)
static const char _crypt_itoa64[64+1]
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void err(int eval, const char *fmt,...)
int pg_mblen(const char *mbstr)
void pfree(void *pointer)
void * palloc0(Size size)
#define CHECK_FOR_INTERRUPTS()
int px_find_digest(const char *name, PX_MD **res)
#define PX_SHACRYPT_ROUNDS_MAX
#define PX_SHACRYPT_BUF_LEN
#define PX_SHACRYPT_ROUNDS_MIN
#define PX_SHACRYPT_DIGEST_MAX_LEN
#define PX_SHACRYPT_SALT_MAX_LEN
#define PX_SHACRYPT_ROUNDS_DEFAULT
void px_memset(void *ptr, int c, size_t len)
#define px_md_finish(md, buf)
#define px_md_update(md, data, dlen)
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
void destroyStringInfo(StringInfo str)
void appendStringInfo(StringInfo str, const char *fmt,...)
StringInfo makeStringInfoExt(int initsize)
void appendStringInfoString(StringInfo str, const char *s)
#define appendStringInfoCharMacro(str, ch)