LCOV - code coverage report
Current view: top level - contrib/pgcrypto - crypt-sha.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 219 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 1 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * contrib/pgcrypto/crypt-sha.c
       3              :  *
       4              :  * This implements shacrypt password hash functions and follows the
       5              :  * public available reference implementation from
       6              :  *
       7              :  * https://www.akkadia.org/drepper/SHA-crypt.txt
       8              :  *
       9              :  * This code is public domain.
      10              :  *
      11              :  * Please see the inline comments for details about the algorithm.
      12              :  *
      13              :  * Basically the following code implements password hashing with sha256 and
      14              :  * sha512 digest via OpenSSL. Additionally, an extended salt generation (see
      15              :  * crypt-gensalt.c for details) is provided, which generates a salt suitable
      16              :  * for either sha256crypt and sha512crypt password hash generation.
      17              :  *
      18              :  * Official identifiers for suitable password hashes used in salts are
      19              :  * 5 : sha256crypt and
      20              :  * 6 : sha512crypt
      21              :  *
      22              :  * The hashing code below supports and uses salt length up to 16 bytes. Longer
      23              :  * input is possible, but any additional byte of the input is disregarded.
      24              :  * gen_salt(), when called with a sha256crypt or sha512crypt identifier will
      25              :  * always generate a 16 byte long salt string.
      26              :  *
      27              :  * Output is compatible with any sha256crypt and sha512crypt output
      28              :  * generated by e.g. OpenSSL or libc crypt().
      29              :  *
      30              :  * The described algorithm uses default computing rounds of 5000. Currently,
      31              :  * even when no specific rounds specification is used, we always explicitly
      32              :  * print out the rounds option flag with the final hash password string.
      33              :  *
      34              :  * The length of the specific password hash (without magic bytes and salt
      35              :  * string) is:
      36              :  *
      37              :  * sha256crypt: 43 bytes and
      38              :  * sha512crypt: 86 bytes.
      39              :  *
      40              :  * Overall hashed password length is:
      41              :  *
      42              :  * sha256crypt: 80 bytes and
      43              :  * sha512crypt: 123 bytes
      44              :  *
      45              :  */
      46              : #include "postgres.h"
      47              : 
      48              : #include "common/string.h"
      49              : #include "mb/pg_wchar.h"
      50              : #include "miscadmin.h"
      51              : 
      52              : #include "px-crypt.h"
      53              : #include "px.h"
      54              : 
      55              : typedef enum
      56              : {
      57              :         PGCRYPTO_SHA256CRYPT = 0,
      58              :         PGCRYPTO_SHA512CRYPT = 1,
      59              :         PGCRYPTO_SHA_UNKOWN
      60              : } PGCRYPTO_SHA_t;
      61              : 
      62              : static const char _crypt_itoa64[64 + 1] =
      63              : "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
      64              : 
      65              : /*
      66              :  * Modern UNIX password, based on SHA crypt hashes
      67              :  */
      68              : char *
      69            0 : px_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              :         /* Used to create the password hash string */
      75            0 :         StringInfo      out_buf = NULL;
      76              : 
      77            0 :         PGCRYPTO_SHA_t type = PGCRYPTO_SHA_UNKOWN;
      78            0 :         PX_MD      *digestA = NULL;
      79            0 :         PX_MD      *digestB = NULL;
      80            0 :         int                     err;
      81              : 
      82            0 :         const char *dec_salt_binary;    /* pointer into the real salt string */
      83            0 :         StringInfo      decoded_salt = NULL;    /* decoded salt string */
      84            0 :         unsigned char sha_buf[PX_SHACRYPT_DIGEST_MAX_LEN];
      85              : 
      86              :         /* temporary buffer for digests */
      87            0 :         unsigned char sha_buf_tmp[PX_SHACRYPT_DIGEST_MAX_LEN];
      88            0 :         char            rounds_custom = 0;
      89            0 :         char       *p_bytes = NULL;
      90            0 :         char       *s_bytes = NULL;
      91            0 :         char       *cp = NULL;
      92            0 :         const char *fp = NULL;          /* intermediate pointer within salt string */
      93            0 :         const char *ep = NULL;          /* holds pointer to the end of the salt string */
      94            0 :         size_t          buf_size = 0;   /* buffer size for sha256crypt/sha512crypt */
      95            0 :         unsigned int block;                     /* number of bytes processed */
      96            0 :         uint32          rounds = PX_SHACRYPT_ROUNDS_DEFAULT;
      97            0 :         unsigned int len,
      98            0 :                                 salt_len = 0;
      99              : 
     100              :         /* Sanity checks */
     101            0 :         if (!passwd)
     102            0 :                 return NULL;
     103              : 
     104            0 :         if (pw == NULL)
     105            0 :                 elog(ERROR, "null value for password rejected");
     106              : 
     107            0 :         if (salt == NULL)
     108            0 :                 elog(ERROR, "null value for salt rejected");
     109              : 
     110              :         /*
     111              :          * Make sure result buffers are large enough.
     112              :          */
     113            0 :         if (dstlen < PX_SHACRYPT_BUF_LEN)
     114            0 :                 elog(ERROR, "insufficient result buffer size to encrypt password");
     115              : 
     116              :         /* Init result buffer */
     117            0 :         out_buf = makeStringInfoExt(PX_SHACRYPT_BUF_LEN);
     118            0 :         decoded_salt = makeStringInfoExt(PX_SHACRYPT_SALT_MAX_LEN);
     119              : 
     120              :         /* Init contents of buffers properly */
     121            0 :         memset(&sha_buf, '\0', sizeof(sha_buf));
     122            0 :         memset(&sha_buf_tmp, '\0', sizeof(sha_buf_tmp));
     123              : 
     124              :         /*
     125              :          * Decode the salt string. We need to know how many rounds and which
     126              :          * digest we have to use to hash the password.
     127              :          */
     128            0 :         len = strlen(pw);
     129            0 :         dec_salt_binary = salt;
     130              : 
     131              :         /*
     132              :          * Analyze and prepare the salt string
     133              :          *
     134              :          * The magic string should be specified in the first three bytes of the
     135              :          * salt string.  Do some sanity checks first.
     136              :          */
     137            0 :         if (strlen(dec_salt_binary) < 3)
     138            0 :                 ereport(ERROR,
     139              :                                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     140              :                                 errmsg("invalid salt"));
     141              : 
     142              :         /*
     143              :          * Check format of magic bytes. These should define either 5=sha256crypt
     144              :          * or 6=sha512crypt in the second byte, enclosed by ascii dollar signs.
     145              :          */
     146            0 :         if ((dec_salt_binary[0] != '$') || (dec_salt_binary[2] != '$'))
     147            0 :                 ereport(ERROR,
     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              :          * Check magic byte for supported shacrypt digest.
     154              :          *
     155              :          * We're just interested in the very first 3 bytes of the salt string,
     156              :          * since this defines the digest length to use.
     157              :          */
     158            0 :         if (strncmp(dec_salt_binary, magic_bytes[0], strlen(magic_bytes[0])) == 0)
     159              :         {
     160            0 :                 type = PGCRYPTO_SHA256CRYPT;
     161            0 :                 dec_salt_binary += strlen(magic_bytes[0]);
     162            0 :         }
     163            0 :         else if (strncmp(dec_salt_binary, magic_bytes[1], strlen(magic_bytes[1])) == 0)
     164              :         {
     165            0 :                 type = PGCRYPTO_SHA512CRYPT;
     166            0 :                 dec_salt_binary += strlen(magic_bytes[1]);
     167            0 :         }
     168              : 
     169              :         /*
     170              :          * dec_salt_binary pointer is positioned after the magic bytes now
     171              :          *
     172              :          * We extract any options in the following code branch. The only optional
     173              :          * setting we need to take care of is the "rounds" option. Note that the
     174              :          * salt generator already checked for invalid settings before, but we need
     175              :          * to do it here again to protect against injection of wrong values when
     176              :          * called without the generator.
     177              :          *
     178              :          * If there is any garbage added after the magic byte and the options/salt
     179              :          * string, we don't treat this special: This is just absorbed as part of
     180              :          * the salt with up to PX_SHACRYPT_SALT_LEN_MAX.
     181              :          *
     182              :          * Unknown magic byte is handled further below.
     183              :          */
     184            0 :         if (strncmp(dec_salt_binary,
     185            0 :                                 rounds_prefix, sizeof(rounds_prefix) - 1) == 0)
     186              :         {
     187            0 :                 const char *num = dec_salt_binary + sizeof(rounds_prefix) - 1;
     188            0 :                 char       *endp;
     189            0 :                 int                     srounds = strtoint(num, &endp, 10);
     190              : 
     191            0 :                 if (*endp != '$')
     192            0 :                         ereport(ERROR,
     193              :                                         errcode(ERRCODE_SYNTAX_ERROR),
     194              :                                         errmsg("could not parse salt options"));
     195              : 
     196            0 :                 dec_salt_binary = endp + 1;
     197              : 
     198              :                 /*
     199              :                  * We violate supported lower or upper bound of rounds, but in this
     200              :                  * case we change this value to the supported lower or upper value. We
     201              :                  * don't do this silently and print a NOTICE in such a case.
     202              :                  *
     203              :                  * Note that a salt string generated with gen_salt() would never
     204              :                  * generated such a salt string, since it would error out.
     205              :                  *
     206              :                  * But Drepper's upstream reference implementation supports this when
     207              :                  * passing the salt string directly, so we maintain compatibility.
     208              :                  */
     209            0 :                 if (srounds > PX_SHACRYPT_ROUNDS_MAX)
     210              :                 {
     211            0 :                         ereport(NOTICE,
     212              :                                         errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     213              :                                         errmsg("rounds=%d exceeds maximum supported value (%d), using %d instead",
     214              :                                                    srounds, PX_SHACRYPT_ROUNDS_MAX,
     215              :                                                    PX_SHACRYPT_ROUNDS_MAX));
     216            0 :                         srounds = PX_SHACRYPT_ROUNDS_MAX;
     217            0 :                 }
     218            0 :                 else if (srounds < PX_SHACRYPT_ROUNDS_MIN)
     219              :                 {
     220            0 :                         ereport(NOTICE,
     221              :                                         errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     222              :                                         errmsg("rounds=%d is below supported value (%d), using %d instead",
     223              :                                                    srounds, PX_SHACRYPT_ROUNDS_MIN,
     224              :                                                    PX_SHACRYPT_ROUNDS_MIN));
     225            0 :                         srounds = PX_SHACRYPT_ROUNDS_MIN;
     226            0 :                 }
     227              : 
     228            0 :                 rounds = (uint32) srounds;
     229            0 :                 rounds_custom = 1;
     230            0 :         }
     231              : 
     232              :         /*
     233              :          * Choose the correct digest length and add the magic bytes to the result
     234              :          * buffer. Also handle possible invalid magic byte we've extracted above.
     235              :          */
     236            0 :         switch (type)
     237              :         {
     238              :                 case PGCRYPTO_SHA256CRYPT:
     239              :                         {
     240              :                                 /* Two PX_MD objects required */
     241            0 :                                 err = px_find_digest("sha256", &digestA);
     242            0 :                                 if (err)
     243            0 :                                         goto error;
     244              : 
     245            0 :                                 err = px_find_digest("sha256", &digestB);
     246            0 :                                 if (err)
     247            0 :                                         goto error;
     248              : 
     249              :                                 /* digest buffer length is 32 for sha256 */
     250            0 :                                 buf_size = 32;
     251              : 
     252            0 :                                 appendStringInfoString(out_buf, magic_bytes[0]);
     253            0 :                                 break;
     254              :                         }
     255              : 
     256              :                 case PGCRYPTO_SHA512CRYPT:
     257              :                         {
     258              :                                 /* Two PX_MD objects required */
     259            0 :                                 err = px_find_digest("sha512", &digestA);
     260            0 :                                 if (err)
     261            0 :                                         goto error;
     262              : 
     263            0 :                                 err = px_find_digest("sha512", &digestB);
     264            0 :                                 if (err)
     265            0 :                                         goto error;
     266              : 
     267            0 :                                 buf_size = PX_SHACRYPT_DIGEST_MAX_LEN;
     268              : 
     269            0 :                                 appendStringInfoString(out_buf, magic_bytes[1]);
     270            0 :                                 break;
     271              :                         }
     272              : 
     273              :                 case PGCRYPTO_SHA_UNKOWN:
     274            0 :                         elog(ERROR, "unknown crypt identifier \"%c\"", salt[1]);
     275            0 :         }
     276              : 
     277            0 :         if (rounds_custom > 0)
     278            0 :                 appendStringInfo(out_buf, "rounds=%u$", rounds);
     279              : 
     280              :         /*
     281              :          * We need the real decoded salt string from salt input, this is every
     282              :          * character before the last '$' in the preamble. Append every compatible
     283              :          * character up to PX_SHACRYPT_SALT_MAX_LEN to the result buffer. Note
     284              :          * that depending on the input, there might be no '$' marker after the
     285              :          * salt, when there is no password hash attached at the end.
     286              :          *
     287              :          * We try hard to recognize mistakes, but since we might get an input
     288              :          * string which might also have the password hash after the salt string
     289              :          * section we give up as soon we reach the end of the input or if there
     290              :          * are any bytes consumed for the salt string until we reach the first '$'
     291              :          * marker thereafter.
     292              :          */
     293            0 :         for (ep = dec_salt_binary;
     294            0 :                  *ep && ep < (dec_salt_binary + PX_SHACRYPT_SALT_MAX_LEN);
     295            0 :                  ep++)
     296              :         {
     297              :                 /*
     298              :                  * Filter out any string which shouldn't be here.
     299              :                  *
     300              :                  * First check for accidentally embedded magic strings here. We don't
     301              :                  * support '$' in salt strings anyways and seeing a magic byte trying
     302              :                  * to identify shacrypt hashes might indicate that something went
     303              :                  * wrong when generating this salt string. Note that we later check
     304              :                  * for non-supported literals anyways, but any '$' here confuses us at
     305              :                  * this point.
     306              :                  */
     307            0 :                 fp = strstr(dec_salt_binary, magic_bytes[0]);
     308            0 :                 if (fp != NULL)
     309            0 :                         elog(ERROR, "bogus magic byte found in salt string");
     310              : 
     311            0 :                 fp = strstr(dec_salt_binary, magic_bytes[1]);
     312            0 :                 if (fp != NULL)
     313            0 :                         elog(ERROR, "bogus magic byte found in salt string");
     314              : 
     315              :                 /*
     316              :                  * This looks very strict, but we assume the caller did something
     317              :                  * wrong when we see a "rounds=" option here.
     318              :                  */
     319            0 :                 fp = strstr(dec_salt_binary, rounds_prefix);
     320            0 :                 if (fp != NULL)
     321            0 :                         elog(ERROR, "invalid rounds option specified in salt string");
     322              : 
     323            0 :                 if (*ep != '$')
     324              :                 {
     325            0 :                         if (strchr(_crypt_itoa64, *ep) != NULL)
     326            0 :                                 appendStringInfoCharMacro(decoded_salt, *ep);
     327              :                         else
     328            0 :                                 ereport(ERROR,
     329              :                                                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     330              :                                                 errmsg("invalid character in salt string: \"%.*s\"",
     331              :                                                            pg_mblen(ep), ep));
     332            0 :                 }
     333              :                 else
     334              :                 {
     335              :                         /*
     336              :                          * We encountered a '$' marker. Check if we already absorbed some
     337              :                          * bytes from input. If true, we are optimistic and terminate at
     338              :                          * this stage. If not, we try further.
     339              :                          *
     340              :                          * If we already consumed enough bytes for the salt string,
     341              :                          * everything that is after this marker is considered to be part
     342              :                          * of an optionally specified password hash and ignored.
     343              :                          */
     344            0 :                         if (decoded_salt->len > 0)
     345            0 :                                 break;
     346              :                 }
     347            0 :         }
     348              : 
     349            0 :         salt_len = decoded_salt->len;
     350            0 :         appendStringInfoString(out_buf, decoded_salt->data);
     351            0 :         elog(DEBUG1, "using salt \"%s\", salt len = %d, rounds = %u",
     352              :                  decoded_salt->data, decoded_salt->len, rounds);
     353              : 
     354              :         /*
     355              :          * Sanity check: at this point the salt string buffer must not exceed
     356              :          * expected size.
     357              :          */
     358            0 :         if (out_buf->len > (3 + 17 * rounds_custom + salt_len))
     359            0 :                 elog(ERROR, "unexpected length of salt string");
     360              : 
     361              :         /*-
     362              :          * 1. Start digest A
     363              :          * 2. Add the password string to digest A
     364              :          * 3. Add the salt to digest A
     365              :          */
     366            0 :         px_md_update(digestA, (const unsigned char *) pw, len);
     367            0 :         px_md_update(digestA, (const unsigned char *) decoded_salt->data, salt_len);
     368              : 
     369              :         /*-
     370              :          * 4. Create digest B
     371              :          * 5. Add password to digest B
     372              :          * 6. Add the salt string to digest B
     373              :          * 7. Add the password again to digest B
     374              :          * 8. Finalize digest B
     375              :          */
     376            0 :         px_md_update(digestB, (const unsigned char *) pw, len);
     377            0 :         px_md_update(digestB, (const unsigned char *) dec_salt_binary, salt_len);
     378            0 :         px_md_update(digestB, (const unsigned char *) pw, len);
     379            0 :         px_md_finish(digestB, sha_buf);
     380              : 
     381              :         /*
     382              :          * 9. For each block (excluding the NULL byte), add digest B to digest A.
     383              :          */
     384            0 :         for (block = len; block > buf_size; block -= buf_size)
     385            0 :                 px_md_update(digestA, sha_buf, buf_size);
     386              : 
     387              :         /*-
     388              :          * 10. For the remaining N bytes of the password string, add the first N
     389              :          * bytes of digest B to A.
     390              :          */
     391            0 :         px_md_update(digestA, sha_buf, block);
     392              : 
     393              :         /*-
     394              :          * 11. For each bit of the binary representation of the length of the
     395              :          * password string up to and including the highest 1-digit, starting from
     396              :          * to lowest bit position (numeric value 1)
     397              :          *
     398              :          * a) for a 1-digit add digest B (sha_buf) to digest A
     399              :          * b) for a 0-digit add the password string
     400              :          */
     401            0 :         block = len;
     402            0 :         while (block)
     403              :         {
     404            0 :                 px_md_update(digestA,
     405              :                                          (block & 1) ? sha_buf : (const unsigned char *) pw,
     406              :                                          (block & 1) ? buf_size : len);
     407              : 
     408              :                 /* right shift to next byte */
     409            0 :                 block >>= 1;
     410              :         }
     411              : 
     412              :         /* 12. Finalize digest A */
     413            0 :         px_md_finish(digestA, sha_buf);
     414              : 
     415              :         /* 13. Start digest DP */
     416            0 :         px_md_reset(digestB);
     417              : 
     418              :         /*-
     419              :          * 14 Add every byte of the password string (excluding trailing NULL)
     420              :          * to the digest DP
     421              :          */
     422            0 :         for (block = len; block > 0; block--)
     423            0 :                 px_md_update(digestB, (const unsigned char *) pw, len);
     424              : 
     425              :         /* 15. Finalize digest DP */
     426            0 :         px_md_finish(digestB, sha_buf_tmp);
     427              : 
     428              :         /*-
     429              :          * 16. produce byte sequence P with same length as password.
     430              :          *     a) for each block of 32 or 64 bytes of length of the password
     431              :          *        string the entire digest DP is used
     432              :          *     b) for the remaining N (up to  31 or 63) bytes use the
     433              :          *        first N bytes of digest DP
     434              :          */
     435            0 :         if ((p_bytes = palloc0(len)) == NULL)
     436              :         {
     437            0 :                 goto error;
     438              :         }
     439              : 
     440              :         /* N step of 16, copy over the bytes from password */
     441            0 :         for (cp = p_bytes, block = len; block > buf_size; block -= buf_size, cp += buf_size)
     442            0 :                 memcpy(cp, sha_buf_tmp, buf_size);
     443            0 :         memcpy(cp, sha_buf_tmp, block);
     444              : 
     445              :         /*
     446              :          * 17. Start digest DS
     447              :          */
     448            0 :         px_md_reset(digestB);
     449              : 
     450              :         /*-
     451              :          * 18. Repeat the following 16+A[0] times, where A[0] represents the first
     452              :          *    byte in digest A interpreted as an 8-bit unsigned value
     453              :          *    add the salt to digest DS
     454              :          */
     455            0 :         for (block = 16 + sha_buf[0]; block > 0; block--)
     456            0 :                 px_md_update(digestB, (const unsigned char *) dec_salt_binary, salt_len);
     457              : 
     458              :         /*
     459              :          * 19. Finalize digest DS
     460              :          */
     461            0 :         px_md_finish(digestB, sha_buf_tmp);
     462              : 
     463              :         /*-
     464              :          * 20. Produce byte sequence S of the same length as the salt string where
     465              :          *
     466              :          * a) for each block of 32 or 64 bytes of length of the salt string the
     467              :          *    entire digest DS is used
     468              :          *
     469              :          * b) for the remaining N (up to  31 or 63) bytes use the first N
     470              :          *    bytes of digest DS
     471              :          */
     472            0 :         if ((s_bytes = palloc0(salt_len)) == NULL)
     473            0 :                 goto error;
     474              : 
     475            0 :         for (cp = s_bytes, block = salt_len; block > buf_size; block -= buf_size, cp += buf_size)
     476            0 :                 memcpy(cp, sha_buf_tmp, buf_size);
     477            0 :         memcpy(cp, sha_buf_tmp, block);
     478              : 
     479              :         /* Make sure we don't leave something important behind */
     480            0 :         px_memset(&sha_buf_tmp, 0, sizeof sha_buf);
     481              : 
     482              :         /*-
     483              :          * 21. Repeat a loop according to the number specified in the rounds=<N>
     484              :          *     specification in the salt (or the default value if none is
     485              :          *     present).  Each round is numbered, starting with 0 and up to N-1.
     486              :          *
     487              :          *     The loop uses a digest as input.  In the first round it is the
     488              :          *     digest produced in step 12.  In the latter steps it is the digest
     489              :          *     produced in step 21.h of the previous round.  The following text
     490              :          *     uses the notation "digest A/B" to describe this behavior.
     491              :          */
     492            0 :         for (block = 0; block < rounds; block++)
     493              :         {
     494              :                 /*
     495              :                  * Make it possible to abort in case large values for "rounds" are
     496              :                  * specified.
     497              :                  */
     498            0 :                 CHECK_FOR_INTERRUPTS();
     499              : 
     500              :                 /* a) start digest B */
     501            0 :                 px_md_reset(digestB);
     502              : 
     503              :                 /*-
     504              :                  * b) for odd round numbers add the byte sequence P to digest B
     505              :                  * c) for even round numbers add digest A/B
     506              :                  */
     507            0 :                 px_md_update(digestB,
     508              :                                          (block & 1) ? (const unsigned char *) p_bytes : sha_buf,
     509              :                                          (block & 1) ? len : buf_size);
     510              : 
     511              :                 /* d) for all round numbers not divisible by 3 add the byte sequence S */
     512            0 :                 if ((block % 3) != 0)
     513            0 :                         px_md_update(digestB, (const unsigned char *) s_bytes, salt_len);
     514              : 
     515              :                 /* e) for all round numbers not divisible by 7 add the byte sequence P */
     516            0 :                 if ((block % 7) != 0)
     517            0 :                         px_md_update(digestB, (const unsigned char *) p_bytes, len);
     518              : 
     519              :                 /*-
     520              :                  * f) for odd round numbers add digest A/C
     521              :                  * g) for even round numbers add the byte sequence P
     522              :                  */
     523            0 :                 px_md_update(digestB,
     524              :                                          (block & 1) ? sha_buf : (const unsigned char *) p_bytes,
     525              :                                          (block & 1) ? buf_size : len);
     526              : 
     527              :                 /* h) finish digest C. */
     528            0 :                 px_md_finish(digestB, sha_buf);
     529            0 :         }
     530              : 
     531            0 :         px_md_free(digestA);
     532            0 :         px_md_free(digestB);
     533              : 
     534            0 :         digestA = NULL;
     535            0 :         digestB = NULL;
     536              : 
     537            0 :         pfree(s_bytes);
     538            0 :         pfree(p_bytes);
     539              : 
     540            0 :         s_bytes = NULL;
     541            0 :         p_bytes = NULL;
     542              : 
     543              :         /* prepare final result buffer */
     544            0 :         appendStringInfoCharMacro(out_buf, '$');
     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            0 :         switch (type)
     558              :         {
     559              :                 case PGCRYPTO_SHA256CRYPT:
     560              :                         {
     561            0 :                                 b64_from_24bit(sha_buf[0], sha_buf[10], sha_buf[20], 4);
     562            0 :                                 b64_from_24bit(sha_buf[21], sha_buf[1], sha_buf[11], 4);
     563            0 :                                 b64_from_24bit(sha_buf[12], sha_buf[22], sha_buf[2], 4);
     564            0 :                                 b64_from_24bit(sha_buf[3], sha_buf[13], sha_buf[23], 4);
     565            0 :                                 b64_from_24bit(sha_buf[24], sha_buf[4], sha_buf[14], 4);
     566            0 :                                 b64_from_24bit(sha_buf[15], sha_buf[25], sha_buf[5], 4);
     567            0 :                                 b64_from_24bit(sha_buf[6], sha_buf[16], sha_buf[26], 4);
     568            0 :                                 b64_from_24bit(sha_buf[27], sha_buf[7], sha_buf[17], 4);
     569            0 :                                 b64_from_24bit(sha_buf[18], sha_buf[28], sha_buf[8], 4);
     570            0 :                                 b64_from_24bit(sha_buf[9], sha_buf[19], sha_buf[29], 4);
     571            0 :                                 b64_from_24bit(0, sha_buf[31], sha_buf[30], 3);
     572              : 
     573            0 :                                 break;
     574              :                         }
     575              : 
     576              :                 case PGCRYPTO_SHA512CRYPT:
     577              :                         {
     578            0 :                                 b64_from_24bit(sha_buf[0], sha_buf[21], sha_buf[42], 4);
     579            0 :                                 b64_from_24bit(sha_buf[22], sha_buf[43], sha_buf[1], 4);
     580            0 :                                 b64_from_24bit(sha_buf[44], sha_buf[2], sha_buf[23], 4);
     581            0 :                                 b64_from_24bit(sha_buf[3], sha_buf[24], sha_buf[45], 4);
     582            0 :                                 b64_from_24bit(sha_buf[25], sha_buf[46], sha_buf[4], 4);
     583            0 :                                 b64_from_24bit(sha_buf[47], sha_buf[5], sha_buf[26], 4);
     584            0 :                                 b64_from_24bit(sha_buf[6], sha_buf[27], sha_buf[48], 4);
     585            0 :                                 b64_from_24bit(sha_buf[28], sha_buf[49], sha_buf[7], 4);
     586            0 :                                 b64_from_24bit(sha_buf[50], sha_buf[8], sha_buf[29], 4);
     587            0 :                                 b64_from_24bit(sha_buf[9], sha_buf[30], sha_buf[51], 4);
     588            0 :                                 b64_from_24bit(sha_buf[31], sha_buf[52], sha_buf[10], 4);
     589            0 :                                 b64_from_24bit(sha_buf[53], sha_buf[11], sha_buf[32], 4);
     590            0 :                                 b64_from_24bit(sha_buf[12], sha_buf[33], sha_buf[54], 4);
     591            0 :                                 b64_from_24bit(sha_buf[34], sha_buf[55], sha_buf[13], 4);
     592            0 :                                 b64_from_24bit(sha_buf[56], sha_buf[14], sha_buf[35], 4);
     593            0 :                                 b64_from_24bit(sha_buf[15], sha_buf[36], sha_buf[57], 4);
     594            0 :                                 b64_from_24bit(sha_buf[37], sha_buf[58], sha_buf[16], 4);
     595            0 :                                 b64_from_24bit(sha_buf[59], sha_buf[17], sha_buf[38], 4);
     596            0 :                                 b64_from_24bit(sha_buf[18], sha_buf[39], sha_buf[60], 4);
     597            0 :                                 b64_from_24bit(sha_buf[40], sha_buf[61], sha_buf[19], 4);
     598            0 :                                 b64_from_24bit(sha_buf[62], sha_buf[20], sha_buf[41], 4);
     599            0 :                                 b64_from_24bit(0, 0, sha_buf[63], 2);
     600              : 
     601            0 :                                 break;
     602              :                         }
     603              : 
     604              :                 case PGCRYPTO_SHA_UNKOWN:
     605              :                         /* we shouldn't land here ... */
     606            0 :                         elog(ERROR, "unsupported digest length");
     607            0 :         }
     608              : 
     609              :         /*
     610              :          * Copy over result to specified buffer.
     611              :          *
     612              :          * The passwd character buffer should have at least PX_SHACRYPT_BUF_LEN
     613              :          * allocated, since we checked above if dstlen is smaller than
     614              :          * PX_SHACRYPT_BUF_LEN (which also includes the NULL byte).
     615              :          *
     616              :          * In that case we would have failed above already.
     617              :          */
     618            0 :         memcpy(passwd, out_buf->data, out_buf->len);
     619              : 
     620              :         /* make sure nothing important is left behind */
     621            0 :         px_memset(&sha_buf, 0, sizeof sha_buf);
     622            0 :         destroyStringInfo(out_buf);
     623            0 :         destroyStringInfo(decoded_salt);
     624              : 
     625              :         /* ...and we're done */
     626            0 :         return passwd;
     627              : 
     628              : error:
     629            0 :         if (digestA != NULL)
     630            0 :                 px_md_free(digestA);
     631              : 
     632            0 :         if (digestB != NULL)
     633            0 :                 px_md_free(digestB);
     634              : 
     635            0 :         destroyStringInfo(out_buf);
     636            0 :         destroyStringInfo(decoded_salt);
     637              : 
     638            0 :         ereport(ERROR,
     639              :                         errcode(ERRCODE_INTERNAL_ERROR),
     640              :                         errmsg("cannot create encrypted password"));
     641            0 :         return NULL;                            /* keep compiler quiet */
     642            0 : }
        

Generated by: LCOV version 2.3.2-1