LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - px.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: f76c13edadc2b319036e0d238703ed56bb23f934 vs 9e17d25e79d4756be08b4a5521b4b58450217137 Lines: 86.7 % 113 98 15 1 97 4
Current Date: 2026-09-20 14:13:17 +0900 Functions: 100.0 % 13 13 1 12 1
Baseline: lcov-20260920-baseline Branches: 65.4 % 52 34 18 34
Baseline Date: 2026-09-20 14:13:13 +0900 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 1 1 1
(30,360] days: 100.0 % 2 2 2
(360..) days: 86.4 % 110 95 15 95
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 100.0 % 12 12 1 11
Branch coverage date bins:
(360..) days: 65.4 % 52 34 18 34

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * px.c
                                  3                 :                :  *      Various cryptographic stuff for PostgreSQL.
                                  4                 :                :  *
                                  5                 :                :  * Copyright (c) 2001 Marko Kreen
                                  6                 :                :  * All rights reserved.
                                  7                 :                :  *
                                  8                 :                :  * Redistribution and use in source and binary forms, with or without
                                  9                 :                :  * modification, are permitted provided that the following conditions
                                 10                 :                :  * are met:
                                 11                 :                :  * 1. Redistributions of source code must retain the above copyright
                                 12                 :                :  *    notice, this list of conditions and the following disclaimer.
                                 13                 :                :  * 2. Redistributions in binary form must reproduce the above copyright
                                 14                 :                :  *    notice, this list of conditions and the following disclaimer in the
                                 15                 :                :  *    documentation and/or other materials provided with the distribution.
                                 16                 :                :  *
                                 17                 :                :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                                 18                 :                :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                                 19                 :                :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                                 20                 :                :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                                 21                 :                :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                                 22                 :                :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                                 23                 :                :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                                 24                 :                :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                                 25                 :                :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                                 26                 :                :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                                 27                 :                :  * SUCH DAMAGE.
                                 28                 :                :  *
                                 29                 :                :  * contrib/pgcrypto/px.c
                                 30                 :                :  */
                                 31                 :                : 
                                 32                 :                : #include "postgres.h"
                                 33                 :                : 
                                 34                 :                : #include "px.h"
                                 35                 :                : 
                                 36                 :                : struct error_desc
                                 37                 :                : {
                                 38                 :                :     int         err;
                                 39                 :                :     const char *desc;
                                 40                 :                : };
                                 41                 :                : 
                                 42                 :                : static const struct error_desc px_err_list[] = {
                                 43                 :                :     {PXE_OK, "Everything ok"},
                                 44                 :                :     {PXE_NO_HASH, "No such hash algorithm"},
                                 45                 :                :     {PXE_NO_CIPHER, "No such cipher algorithm"},
                                 46                 :                :     {PXE_BAD_OPTION, "Unknown option"},
                                 47                 :                :     {PXE_BAD_FORMAT, "Badly formatted type"},
                                 48                 :                :     {PXE_KEY_TOO_BIG, "Key was too big"},
                                 49                 :                :     {PXE_CIPHER_INIT, "Cipher cannot be initialized"},
                                 50                 :                :     {PXE_HASH_UNUSABLE_FOR_HMAC, "This hash algorithm is unusable for HMAC"},
                                 51                 :                :     {PXE_BUG, "pgcrypto bug"},
                                 52                 :                :     {PXE_ARGUMENT_ERROR, "Illegal argument to function"},
                                 53                 :                :     {PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"},
                                 54                 :                :     {PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"},
                                 55                 :                :     {PXE_NO_RANDOM, "Failed to generate strong random bits"},
                                 56                 :                :     {PXE_DECRYPT_FAILED, "Decryption failed"},
                                 57                 :                :     {PXE_ENCRYPT_FAILED, "Encryption failed"},
                                 58                 :                :     {PXE_PGP_CORRUPT_DATA, "Wrong key or corrupt data"},
                                 59                 :                :     {PXE_PGP_CORRUPT_ARMOR, "Corrupt ascii-armor"},
                                 60                 :                :     {PXE_PGP_UNSUPPORTED_COMPR, "Unsupported compression algorithm"},
                                 61                 :                :     {PXE_PGP_UNSUPPORTED_CIPHER, "Unsupported cipher algorithm"},
                                 62                 :                :     {PXE_PGP_UNSUPPORTED_HASH, "Unsupported digest algorithm"},
                                 63                 :                :     {PXE_PGP_COMPRESSION_ERROR, "Compression error"},
                                 64                 :                :     {PXE_PGP_NOT_TEXT, "Not text data"},
                                 65                 :                :     {PXE_PGP_UNEXPECTED_PKT, "Unexpected packet in key data"},
                                 66                 :                :     {PXE_PGP_MATH_FAILED, "Math operation failed"},
                                 67                 :                :     {PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
                                 68                 :                :     {PXE_PGP_KEY_TOO_BIG, "Session key too big"},
                                 69                 :                :     {PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
                                 70                 :                :     {PXE_PGP_WRONG_KEY, "Wrong key"},
                                 71                 :                :     {PXE_PGP_MULTIPLE_KEYS,
                                 72                 :                :     "Several keys given - pgcrypto does not handle keyring"},
                                 73                 :                :     {PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
                                 74                 :                :     {PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
                                 75                 :                :     {PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
                                 76                 :                :     {PXE_PGP_KEYPKT_CORRUPT, "Corrupt key packet"},
                                 77                 :                :     {PXE_PGP_NO_USABLE_KEY, "No encryption key found"},
                                 78                 :                :     {PXE_PGP_NEED_SECRET_PSW, "Need password for secret key"},
                                 79                 :                :     {PXE_PGP_BAD_S2K_MODE, "Bad S2K mode"},
                                 80                 :                :     {PXE_PGP_UNSUPPORTED_PUBALGO, "Unsupported public key algorithm"},
                                 81                 :                :     {PXE_PGP_MULTIPLE_SUBKEYS, "Several subkeys not supported"},
                                 82                 :                : 
                                 83                 :                :     {0, NULL},
                                 84                 :                : };
                                 85                 :                : 
                                 86                 :                : /*
                                 87                 :                :  * Call ereport(ERROR, ...), with an error code and message corresponding to
                                 88                 :                :  * the PXE_* error code given as argument.
                                 89                 :                :  *
                                 90                 :                :  * This is similar to px_strerror(err), but for some errors, we fill in the
                                 91                 :                :  * error code and detail fields more appropriately.
                                 92                 :                :  */
                                 93                 :                : void
 3576 heikki.linnakangas@i       94                 :CBC          21 : px_THROW_ERROR(int err)
                                 95                 :                : {
                                 96         [ -  + ]:             21 :     if (err == PXE_NO_RANDOM)
                                 97                 :                :     {
 3576 heikki.linnakangas@i       98         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 99                 :                :                 (errcode(ERRCODE_INTERNAL_ERROR),
                                100                 :                :                  errmsg("could not generate a random number")));
                                101                 :                :     }
                                102                 :                :     else
                                103                 :                :     {
                                104                 :                :         /* For other errors, use the message from the above list. */
 3576 heikki.linnakangas@i      105         [ +  - ]:CBC          21 :         ereport(ERROR,
                                106                 :                :                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
                                107                 :                :                  errmsg("%s", px_strerror(err))));
                                108                 :                :     }
                                109                 :                : }
                                110                 :                : 
                                111                 :                : const char *
 7645 bruce@momjian.us          112                 :             76 : px_strerror(int err)
                                113                 :                : {
                                114                 :                :     const struct error_desc *e;
                                115                 :                : 
 7853 neilc@samurai.com         116         [ +  - ]:            899 :     for (e = px_err_list; e->desc; e++)
                                117         [ +  + ]:            899 :         if (e->err == err)
                                118                 :             76 :             return e->desc;
 7853 neilc@samurai.com         119                 :UBC           0 :     return "Bad error code";
                                120                 :                : }
                                121                 :                : 
                                122                 :                : const char *
 6310 bruce@momjian.us          123                 :CBC         211 : px_resolve_alias(const PX_Alias *list, const char *name)
                                124                 :                : {
 9096                           125         [ +  + ]:           2981 :     while (list->name)
                                126                 :                :     {
 8171 tgl@sss.pgh.pa.us         127         [ +  + ]:           2816 :         if (pg_strcasecmp(list->alias, name) == 0)
 9161 bruce@momjian.us          128                 :             46 :             return list->name;
                                129                 :           2770 :         list++;
                                130                 :                :     }
                                131                 :            165 :     return name;
                                132                 :                : }
                                133                 :                : 
                                134                 :                : static void (*debug_handler) (const char *) = NULL;
                                135                 :                : 
                                136                 :                : void
 7645                           137                 :            117 : px_set_debug_handler(void (*handler) (const char *))
                                138                 :                : {
 7742                           139                 :            117 :     debug_handler = handler;
                                140                 :            117 : }
                                141                 :                : 
                                142                 :                : void
  130 tgl@sss.pgh.pa.us         143                 :             17 : px_debug(const char *fmt, ...)
                                144                 :                : {
                                145                 :                :     va_list     ap;
                                146                 :                : 
 7742 bruce@momjian.us          147                 :             17 :     va_start(ap, fmt);
 7645                           148         [ +  + ]:             17 :     if (debug_handler)
                                149                 :                :     {
                                150                 :                :         char        buf[512];
                                151                 :                : 
 7742                           152                 :              8 :         vsnprintf(buf, sizeof(buf), fmt, ap);
                                153                 :              8 :         debug_handler(buf);
                                154                 :                :     }
                                155                 :             17 :     va_end(ap);
                                156                 :             17 : }
                                157                 :                : 
                                158                 :                : /*
                                159                 :                :  * combo - cipher + padding (+ checksum)
                                160                 :                :  */
                                161                 :                : 
                                162                 :                : static unsigned
 6310                           163                 :             72 : combo_encrypt_len(PX_Combo *cx, unsigned dlen)
                                164                 :                : {
 9161                           165                 :             72 :     return dlen + 512;
                                166                 :                : }
                                167                 :                : 
                                168                 :                : static unsigned
 6310                           169                 :             16 : combo_decrypt_len(PX_Combo *cx, unsigned dlen)
                                170                 :                : {
 9161                           171                 :             16 :     return dlen;
                                172                 :                : }
                                173                 :                : 
                                174                 :                : static int
 6310                           175                 :             88 : combo_init(PX_Combo *cx, const uint8 *key, unsigned klen,
                                176                 :                :            const uint8 *iv, unsigned ivlen)
                                177                 :                : {
                                178                 :                :     int         err;
                                179                 :                :     unsigned    ks,
                                180                 :                :                 ivs;
 9096                           181                 :             88 :     PX_Cipher  *c = cx->cipher;
                                182                 :             88 :     uint8      *ivbuf = NULL;
                                183                 :                :     uint8      *keybuf;
                                184                 :                : 
 9161                           185                 :             88 :     ks = px_cipher_key_size(c);
                                186                 :                : 
                                187                 :             88 :     ivs = px_cipher_iv_size(c);
 9096                           188         [ +  - ]:             88 :     if (ivs > 0)
                                189                 :                :     {
 2186 michael@paquier.xyz       190                 :             88 :         ivbuf = palloc0(ivs);
 9161 bruce@momjian.us          191         [ -  + ]:             88 :         if (ivlen > ivs)
 9161 bruce@momjian.us          192                 :UBC           0 :             memcpy(ivbuf, iv, ivs);
 1662 tgl@sss.pgh.pa.us         193         [ +  + ]:CBC          88 :         else if (ivlen > 0)
 9161 bruce@momjian.us          194                 :             14 :             memcpy(ivbuf, iv, ivlen);
                                195                 :                :     }
                                196                 :                : 
 9082                           197         [ -  + ]:             88 :     if (klen > ks)
 9082 bruce@momjian.us          198                 :UBC           0 :         klen = ks;
 2186 michael@paquier.xyz       199                 :CBC          88 :     keybuf = palloc0(ks);
 9161 bruce@momjian.us          200                 :             88 :     memcpy(keybuf, key, klen);
                                201                 :                : 
                                202                 :             88 :     err = px_cipher_init(c, keybuf, klen, ivbuf);
                                203                 :                : 
                                204         [ +  - ]:             88 :     if (ivbuf)
 2186 michael@paquier.xyz       205                 :             88 :         pfree(ivbuf);
                                206                 :             88 :     pfree(keybuf);
                                207                 :                : 
 9161 bruce@momjian.us          208                 :             88 :     return err;
                                209                 :                : }
                                210                 :                : 
                                211                 :                : static int
 6310                           212                 :             68 : combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
                                213                 :                :               uint8 *res, unsigned *rlen)
                                214                 :                : {
 1643 peter@eisentraut.org      215                 :             68 :     return px_cipher_encrypt(cx->cipher, cx->padding, data, dlen, res, rlen);
                                216                 :                : }
                                217                 :                : 
                                218                 :                : static int
 6310 bruce@momjian.us          219                 :             16 : combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
                                220                 :                :               uint8 *res, unsigned *rlen)
                                221                 :                : {
 1643 peter@eisentraut.org      222                 :             16 :     return px_cipher_decrypt(cx->cipher, cx->padding, data, dlen, res, rlen);
                                223                 :                : }
                                224                 :                : 
                                225                 :                : static void
 6310 bruce@momjian.us          226                 :             88 : combo_free(PX_Combo *cx)
                                227                 :                : {
 9161                           228         [ +  - ]:             88 :     if (cx->cipher)
                                229                 :             88 :         px_cipher_free(cx->cipher);
   26 peter@eisentraut.org      230                 :GNC          88 :     explicit_bzero(cx, sizeof(*cx));
 2186 michael@paquier.xyz       231                 :CBC          88 :     pfree(cx);
 9161 bruce@momjian.us          232                 :             88 : }
                                233                 :                : 
                                234                 :                : /* PARSER */
                                235                 :                : 
                                236                 :                : static int
                                237                 :             89 : parse_cipher_name(char *full, char **cipher, char **pad)
                                238                 :                : {
                                239                 :                :     char       *p,
                                240                 :                :                *p2,
                                241                 :                :                *q;
                                242                 :                : 
                                243                 :             89 :     *cipher = full;
                                244                 :             89 :     *pad = NULL;
                                245                 :                : 
                                246                 :             89 :     p = strchr(full, '/');
                                247         [ +  + ]:             89 :     if (p != NULL)
                                248                 :             21 :         *p++ = 0;
 9096                           249         [ +  + ]:            110 :     while (p != NULL)
                                250                 :                :     {
 9161                           251         [ -  + ]:             21 :         if ((q = strchr(p, '/')) != NULL)
 9161 bruce@momjian.us          252                 :UBC           0 :             *q++ = 0;
                                253                 :                : 
 9096 bruce@momjian.us          254         [ -  + ]:CBC          21 :         if (!*p)
                                255                 :                :         {
 9161 bruce@momjian.us          256                 :UBC           0 :             p = q;
                                257                 :              0 :             continue;
                                258                 :                :         }
 9161 bruce@momjian.us          259                 :CBC          21 :         p2 = strchr(p, ':');
 9096                           260         [ +  - ]:             21 :         if (p2 != NULL)
                                261                 :                :         {
 9161                           262                 :             21 :             *p2++ = 0;
 5381 peter_e@gmx.net           263         [ +  - ]:             21 :             if (strcmp(p, "pad") == 0)
 9161 bruce@momjian.us          264                 :             21 :                 *pad = p2;
                                265                 :                :             else
 7853 neilc@samurai.com         266                 :UBC           0 :                 return PXE_BAD_OPTION;
                                267                 :                :         }
                                268                 :                :         else
                                269                 :              0 :             return PXE_BAD_FORMAT;
                                270                 :                : 
 9161 bruce@momjian.us          271                 :CBC          21 :         p = q;
                                272                 :                :     }
 9145                           273                 :             89 :     return 0;
                                274                 :                : }
                                275                 :                : 
                                276                 :                : /* provider */
                                277                 :                : 
                                278                 :                : int
 6310                           279                 :             89 : px_find_combo(const char *name, PX_Combo **res)
                                280                 :                : {
                                281                 :                :     int         err;
                                282                 :                :     char       *buf,
                                283                 :                :                *s_cipher,
                                284                 :                :                *s_pad;
                                285                 :                : 
                                286                 :                :     PX_Combo   *cx;
                                287                 :                : 
  289 michael@paquier.xyz       288                 :             89 :     cx = palloc0_object(PX_Combo);
 2186                           289                 :             89 :     buf = pstrdup(name);
                                290                 :                : 
 9145 bruce@momjian.us          291                 :             89 :     err = parse_cipher_name(buf, &s_cipher, &s_pad);
 9096                           292         [ -  + ]:             89 :     if (err)
                                293                 :                :     {
 2186 michael@paquier.xyz       294                 :UBC           0 :         pfree(buf);
                                295                 :              0 :         pfree(cx);
 9145 bruce@momjian.us          296                 :              0 :         return err;
                                297                 :                :     }
                                298                 :                : 
 9161 bruce@momjian.us          299                 :CBC          89 :     err = px_find_cipher(s_cipher, &cx->cipher);
                                300         [ +  + ]:             89 :     if (err)
                                301                 :              1 :         goto err1;
                                302                 :                : 
 9096                           303         [ +  + ]:             88 :     if (s_pad != NULL)
                                304                 :                :     {
 5381 peter_e@gmx.net           305         [ -  + ]:             21 :         if (strcmp(s_pad, "pkcs") == 0)
 9161 bruce@momjian.us          306                 :UBC           0 :             cx->padding = 1;
 5381 peter_e@gmx.net           307         [ +  - ]:CBC          21 :         else if (strcmp(s_pad, "none") == 0)
 9161 bruce@momjian.us          308                 :             21 :             cx->padding = 0;
                                309                 :                :         else
 9161 bruce@momjian.us          310                 :UBC           0 :             goto err1;
                                311                 :                :     }
                                312                 :                :     else
 9161 bruce@momjian.us          313                 :CBC          67 :         cx->padding = 1;
                                314                 :                : 
                                315                 :             88 :     cx->init = combo_init;
                                316                 :             88 :     cx->encrypt = combo_encrypt;
                                317                 :             88 :     cx->decrypt = combo_decrypt;
                                318                 :             88 :     cx->encrypt_len = combo_encrypt_len;
                                319                 :             88 :     cx->decrypt_len = combo_decrypt_len;
                                320                 :             88 :     cx->free = combo_free;
                                321                 :                : 
 2186 michael@paquier.xyz       322                 :             88 :     pfree(buf);
                                323                 :                : 
 9161 bruce@momjian.us          324                 :             88 :     *res = cx;
                                325                 :                : 
                                326                 :             88 :     return 0;
                                327                 :                : 
                                328                 :              1 : err1:
                                329         [ -  + ]:              1 :     if (cx->cipher)
 9161 bruce@momjian.us          330                 :UBC           0 :         px_cipher_free(cx->cipher);
 2186 michael@paquier.xyz       331                 :CBC           1 :     pfree(cx);
                                332                 :              1 :     pfree(buf);
 7853 neilc@samurai.com         333                 :              1 :     return PXE_NO_CIPHER;
                                334                 :                : }
        

Generated by: LCOV version 2.0-1