LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - pgp-s2k.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 91.2 % 148 135 13 135
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 7 7 7
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 91.2 % 148 135 13 135
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 7 7 7

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  * pgp-s2k.c
                                  3                 :  *    OpenPGP string2key functions.
                                  4                 :  *
                                  5                 :  * Copyright (c) 2005 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/pgp-s2k.c
                                 30                 :  */
                                 31                 : 
                                 32                 : #include "postgres.h"
                                 33                 : 
                                 34                 : #include "pgp.h"
                                 35                 : #include "px.h"
                                 36                 : 
                                 37                 : static int
 5050 bruce                      38 CBC           5 : calc_s2k_simple(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
                                 39                 :                 unsigned key_len)
                                 40                 : {
                                 41                 :     unsigned    md_rlen;
                                 42                 :     uint8       buf[PGP_MAX_DIGEST];
                                 43                 :     unsigned    preload;
                                 44                 :     unsigned    remain;
 6482                            45               5 :     uint8      *dst = s2k->key;
                                 46                 : 
                                 47               5 :     md_rlen = px_md_result_size(md);
                                 48                 : 
                                 49               5 :     remain = s2k->key_len;
                                 50               5 :     preload = 0;
                                 51              12 :     while (remain > 0)
                                 52                 :     {
                                 53               7 :         px_md_reset(md);
                                 54                 : 
                                 55               7 :         if (preload)
                                 56                 :         {
                                 57               2 :             memset(buf, 0, preload);
                                 58               2 :             px_md_update(md, buf, preload);
                                 59                 :         }
                                 60               7 :         preload++;
                                 61                 : 
                                 62               7 :         px_md_update(md, key, key_len);
                                 63               7 :         px_md_finish(md, buf);
                                 64                 : 
                                 65               7 :         if (remain > md_rlen)
                                 66                 :         {
                                 67               2 :             memcpy(dst, buf, md_rlen);
                                 68               2 :             dst += md_rlen;
                                 69               2 :             remain -= md_rlen;
                                 70                 :         }
                                 71                 :         else
                                 72                 :         {
                                 73               5 :             memcpy(dst, buf, remain);
                                 74               5 :             remain = 0;
                                 75                 :         }
                                 76                 :     }
 3279                            77               5 :     px_memset(buf, 0, sizeof(buf));
 6482                            78               5 :     return 0;
                                 79                 : }
                                 80                 : 
                                 81                 : static int
 5050                            82               5 : calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
                                 83                 : {
                                 84                 :     unsigned    md_rlen;
                                 85                 :     uint8       buf[PGP_MAX_DIGEST];
 6482                            86               5 :     unsigned    preload = 0;
                                 87                 :     uint8      *dst;
                                 88                 :     unsigned    remain;
                                 89                 : 
                                 90               5 :     md_rlen = px_md_result_size(md);
                                 91                 : 
                                 92               5 :     dst = s2k->key;
                                 93               5 :     remain = s2k->key_len;
                                 94              12 :     while (remain > 0)
                                 95                 :     {
                                 96               7 :         px_md_reset(md);
                                 97                 : 
                                 98               7 :         if (preload > 0)
                                 99                 :         {
                                100               2 :             memset(buf, 0, preload);
                                101               2 :             px_md_update(md, buf, preload);
                                102                 :         }
                                103               7 :         preload++;
                                104                 : 
                                105               7 :         px_md_update(md, s2k->salt, PGP_S2K_SALT);
                                106               7 :         px_md_update(md, key, key_len);
                                107               7 :         px_md_finish(md, buf);
                                108                 : 
                                109               7 :         if (remain > md_rlen)
                                110                 :         {
                                111               2 :             memcpy(dst, buf, md_rlen);
                                112               2 :             remain -= md_rlen;
                                113               2 :             dst += md_rlen;
                                114                 :         }
                                115                 :         else
                                116                 :         {
                                117               5 :             memcpy(dst, buf, remain);
                                118               5 :             remain = 0;
                                119                 :         }
                                120                 :     }
 3279                           121               5 :     px_memset(buf, 0, sizeof(buf));
 6482                           122               5 :     return 0;
                                123                 : }
                                124                 : 
                                125                 : static int
 5050                           126              83 : calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
                                127                 :                      unsigned key_len)
                                128                 : {
                                129                 :     unsigned    md_rlen;
                                130                 :     uint8       buf[PGP_MAX_DIGEST];
                                131                 :     uint8      *dst;
 6482                           132              83 :     unsigned    preload = 0;
                                133                 :     unsigned    remain,
                                134                 :                 c,
                                135                 :                 curcnt,
                                136                 :                 count;
                                137                 : 
 2587 alvherre                  138              83 :     count = s2k_decode_count(s2k->iter);
                                139                 : 
 6482 bruce                     140              83 :     md_rlen = px_md_result_size(md);
                                141                 : 
                                142              83 :     remain = s2k->key_len;
                                143              83 :     dst = s2k->key;
                                144             179 :     while (remain > 0)
                                145                 :     {
                                146              96 :         px_md_reset(md);
                                147                 : 
                                148              96 :         if (preload)
                                149                 :         {
                                150              13 :             memset(buf, 0, preload);
                                151              13 :             px_md_update(md, buf, preload);
                                152                 :         }
                                153              96 :         preload++;
                                154                 : 
                                155              96 :         px_md_update(md, s2k->salt, PGP_S2K_SALT);
                                156              96 :         px_md_update(md, key, key_len);
                                157              96 :         curcnt = PGP_S2K_SALT + key_len;
                                158                 : 
                                159        12719390 :         while (curcnt < count)
                                160                 :         {
                                161        12719363 :             if (curcnt + PGP_S2K_SALT < count)
                                162        12719294 :                 c = PGP_S2K_SALT;
                                163                 :             else
                                164              69 :                 c = count - curcnt;
                                165        12719363 :             px_md_update(md, s2k->salt, c);
                                166        12719363 :             curcnt += c;
                                167                 : 
                                168        12719363 :             if (curcnt + key_len < count)
                                169        12719267 :                 c = key_len;
                                170              96 :             else if (curcnt < count)
                                171              27 :                 c = count - curcnt;
                                172                 :             else
                                173              69 :                 break;
                                174        12719294 :             px_md_update(md, key, c);
                                175        12719294 :             curcnt += c;
                                176                 :         }
                                177              96 :         px_md_finish(md, buf);
                                178                 : 
                                179              96 :         if (remain > md_rlen)
                                180                 :         {
                                181              13 :             memcpy(dst, buf, md_rlen);
                                182              13 :             remain -= md_rlen;
                                183              13 :             dst += md_rlen;
                                184                 :         }
                                185                 :         else
                                186                 :         {
                                187              83 :             memcpy(dst, buf, remain);
                                188              83 :             remain = 0;
                                189                 :         }
                                190                 :     }
 3279                           191              83 :     px_memset(buf, 0, sizeof(buf));
 6482                           192              83 :     return 0;
                                193                 : }
                                194                 : 
                                195                 : /*
                                196                 :  * Decide PGP_S2K_ISALTED iteration count (in OpenPGP one-byte representation)
                                197                 :  *
                                198                 :  * Too small: weak
                                199                 :  * Too big: slow
                                200                 :  * gpg defaults to 96 => 65536 iters
                                201                 :  *
                                202                 :  * For our default (count=-1) we let it float a bit: 96 + 32 => between 65536
                                203                 :  * and 262144 iterations.
                                204                 :  *
                                205                 :  * Otherwise, find the smallest number which provides at least the specified
                                206                 :  * iteration count.
                                207                 :  */
                                208                 : static uint8
 2587 alvherre                  209              28 : decide_s2k_iter(unsigned rand_byte, int count)
                                210                 : {
                                211                 :     int         iter;
                                212                 : 
                                213              28 :     if (count == -1)
                                214              26 :         return 96 + (rand_byte & 0x1F);
                                215                 :     /* this is a bit brute-force, but should be quick enough */
                                216             257 :     for (iter = 0; iter <= 255; iter++)
                                217             257 :         if (s2k_decode_count(iter) >= count)
                                218               2 :             return iter;
 2587 alvherre                  219 UBC           0 :     return 255;
                                220                 : }
                                221                 : 
                                222                 : int
 2587 alvherre                  223 CBC          30 : pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
                                224                 : {
 6385 bruce                     225              30 :     int         res = 0;
                                226                 :     uint8       tmp;
                                227                 : 
 6482                           228              30 :     s2k->mode = mode;
                                229              30 :     s2k->digest_algo = digest_algo;
                                230                 : 
 6385                           231              30 :     switch (s2k->mode)
                                232                 :     {
 2587 alvherre                  233               1 :         case PGP_S2K_SIMPLE:
 6482 bruce                     234               1 :             break;
 2587 alvherre                  235               1 :         case PGP_S2K_SALTED:
 1559 michael                   236               1 :             if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
 2316 heikki.linnakangas        237 UBC           0 :                 return PXE_NO_RANDOM;
 6482 bruce                     238 CBC           1 :             break;
 2587 alvherre                  239              28 :         case PGP_S2K_ISALTED:
 1559 michael                   240              28 :             if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
 2316 heikki.linnakangas        241 UBC           0 :                 return PXE_NO_RANDOM;
 1559 michael                   242 CBC          28 :             if (!pg_strong_random(&tmp, 1))
 2316 heikki.linnakangas        243 UBC           0 :                 return PXE_NO_RANDOM;
 2587 alvherre                  244 CBC          28 :             s2k->iter = decide_s2k_iter(tmp, count);
 6482 bruce                     245              28 :             break;
 6482 bruce                     246 UBC           0 :         default:
                                247               0 :             res = PXE_PGP_BAD_S2K_MODE;
                                248                 :     }
 6482 bruce                     249 CBC          30 :     return res;
                                250                 : }
                                251                 : 
                                252                 : int
 5050                           253              63 : pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
                                254                 : {
 6385                           255              63 :     int         res = 0;
                                256                 : 
 6482                           257              63 :     GETBYTE(src, s2k->mode);
                                258              63 :     GETBYTE(src, s2k->digest_algo);
 6385                           259              63 :     switch (s2k->mode)
                                260                 :     {
 6482                           261               4 :         case 0:
                                262               4 :             break;
                                263               4 :         case 1:
                                264               4 :             res = pullf_read_fixed(src, 8, s2k->salt);
                                265               4 :             break;
                                266              55 :         case 3:
                                267              55 :             res = pullf_read_fixed(src, 8, s2k->salt);
                                268              55 :             if (res < 0)
 6482 bruce                     269 UBC           0 :                 break;
 6482 bruce                     270 CBC          55 :             GETBYTE(src, s2k->iter);
                                271              55 :             break;
 6482 bruce                     272 UBC           0 :         default:
                                273               0 :             res = PXE_PGP_BAD_S2K_MODE;
                                274                 :     }
 6482 bruce                     275 CBC          63 :     return res;
                                276                 : }
                                277                 : 
                                278                 : int
 5050                           279              93 : pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
                                280                 : {
                                281                 :     int         res;
                                282                 :     PX_MD      *md;
                                283                 : 
 6482                           284              93 :     s2k->key_len = pgp_get_cipher_key_size(cipher);
                                285              93 :     if (s2k->key_len <= 0)
 6482 bruce                     286 UBC           0 :         return PXE_PGP_UNSUPPORTED_CIPHER;
                                287                 : 
 6482 bruce                     288 CBC          93 :     res = pgp_load_digest(s2k->digest_algo, &md);
                                289              93 :     if (res < 0)
 6482 bruce                     290 UBC           0 :         return res;
                                291                 : 
 6385 bruce                     292 CBC          93 :     switch (s2k->mode)
                                293                 :     {
 6482                           294               5 :         case 0:
                                295               5 :             res = calc_s2k_simple(s2k, md, key, key_len);
                                296               5 :             break;
                                297               5 :         case 1:
                                298               5 :             res = calc_s2k_salted(s2k, md, key, key_len);
                                299               5 :             break;
                                300              83 :         case 3:
                                301              83 :             res = calc_s2k_iter_salted(s2k, md, key, key_len);
                                302              83 :             break;
 6482 bruce                     303 UBC           0 :         default:
                                304               0 :             res = PXE_PGP_BAD_S2K_MODE;
                                305                 :     }
 6482 bruce                     306 CBC          93 :     px_md_free(md);
                                307              93 :     return res;
                                308                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a