PostgreSQL Source Code  git master
pgp-s2k.c File Reference
#include "postgres.h"
#include "px.h"
#include "pgp.h"
Include dependency graph for pgp-s2k.c:

Go to the source code of this file.

Functions

static int calc_s2k_simple (PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
 
static int calc_s2k_salted (PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
 
static int calc_s2k_iter_salted (PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
 
static uint8 decide_s2k_iter (unsigned rand_byte, int count)
 
int pgp_s2k_fill (PGP_S2K *s2k, int mode, int digest_algo, int count)
 
int pgp_s2k_read (PullFilter *src, PGP_S2K *s2k)
 
int pgp_s2k_process (PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
 

Function Documentation

◆ calc_s2k_iter_salted()

static int calc_s2k_iter_salted ( PGP_S2K s2k,
PX_MD md,
const uint8 key,
unsigned  key_len 
)
static

Definition at line 127 of file pgp-s2k.c.

References buf, PGP_S2K::iter, PGP_S2K::key, PGP_S2K::key_len, PGP_MAX_DIGEST, PGP_S2K_SALT, px_md_finish, px_md_reset, px_md_result_size, px_md_update, px_memset(), s2k_decode_count, and PGP_S2K::salt.

Referenced by pgp_s2k_process().

129 {
130  unsigned md_rlen;
132  uint8 *dst;
133  unsigned preload = 0;
134  unsigned remain,
135  c,
136  curcnt,
137  count;
138 
139  count = s2k_decode_count(s2k->iter);
140 
141  md_rlen = px_md_result_size(md);
142 
143  remain = s2k->key_len;
144  dst = s2k->key;
145  while (remain > 0)
146  {
147  px_md_reset(md);
148 
149  if (preload)
150  {
151  memset(buf, 0, preload);
152  px_md_update(md, buf, preload);
153  }
154  preload++;
155 
156  px_md_update(md, s2k->salt, PGP_S2K_SALT);
157  px_md_update(md, key, key_len);
158  curcnt = PGP_S2K_SALT + key_len;
159 
160  while (curcnt < count)
161  {
162  if (curcnt + PGP_S2K_SALT < count)
163  c = PGP_S2K_SALT;
164  else
165  c = count - curcnt;
166  px_md_update(md, s2k->salt, c);
167  curcnt += c;
168 
169  if (curcnt + key_len < count)
170  c = key_len;
171  else if (curcnt < count)
172  c = count - curcnt;
173  else
174  break;
175  px_md_update(md, key, c);
176  curcnt += c;
177  }
178  px_md_finish(md, buf);
179 
180  if (remain > md_rlen)
181  {
182  memcpy(dst, buf, md_rlen);
183  remain -= md_rlen;
184  dst += md_rlen;
185  }
186  else
187  {
188  memcpy(dst, buf, remain);
189  remain = 0;
190  }
191  }
192  px_memset(buf, 0, sizeof(buf));
193  return 0;
194 }
#define px_md_update(md, data, dlen)
Definition: px.h:205
unsigned char uint8
Definition: c.h:356
#define px_md_finish(md, buf)
Definition: px.h:206
#define px_md_reset(md)
Definition: px.h:204
#define px_md_result_size(md)
Definition: px.h:202
char * c
static char * buf
Definition: pg_test_fsync.c:68
uint8 salt[8]
Definition: pgp.h:126
uint8 key[PGP_MAX_KEY]
Definition: pgp.h:129
#define PGP_S2K_SALT
Definition: pgp.h:115
uint8 iter
Definition: pgp.h:127
uint8 key_len
Definition: pgp.h:130
#define s2k_decode_count(cval)
Definition: pgp.h:176
#define PGP_MAX_DIGEST
Definition: pgp.h:114
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:126

◆ calc_s2k_salted()

static int calc_s2k_salted ( PGP_S2K s2k,
PX_MD md,
const uint8 key,
unsigned  key_len 
)
static

Definition at line 83 of file pgp-s2k.c.

References buf, PGP_S2K::key, PGP_S2K::key_len, PGP_MAX_DIGEST, PGP_S2K_SALT, px_md_finish, px_md_reset, px_md_result_size, px_md_update, px_memset(), and PGP_S2K::salt.

Referenced by pgp_s2k_process().

84 {
85  unsigned md_rlen;
87  unsigned preload = 0;
88  uint8 *dst;
89  unsigned remain;
90 
91  md_rlen = px_md_result_size(md);
92 
93  dst = s2k->key;
94  remain = s2k->key_len;
95  while (remain > 0)
96  {
97  px_md_reset(md);
98 
99  if (preload > 0)
100  {
101  memset(buf, 0, preload);
102  px_md_update(md, buf, preload);
103  }
104  preload++;
105 
106  px_md_update(md, s2k->salt, PGP_S2K_SALT);
107  px_md_update(md, key, key_len);
108  px_md_finish(md, buf);
109 
110  if (remain > md_rlen)
111  {
112  memcpy(dst, buf, md_rlen);
113  remain -= md_rlen;
114  dst += md_rlen;
115  }
116  else
117  {
118  memcpy(dst, buf, remain);
119  remain = 0;
120  }
121  }
122  px_memset(buf, 0, sizeof(buf));
123  return 0;
124 }
#define px_md_update(md, data, dlen)
Definition: px.h:205
unsigned char uint8
Definition: c.h:356
#define px_md_finish(md, buf)
Definition: px.h:206
#define px_md_reset(md)
Definition: px.h:204
#define px_md_result_size(md)
Definition: px.h:202
static char * buf
Definition: pg_test_fsync.c:68
uint8 salt[8]
Definition: pgp.h:126
uint8 key[PGP_MAX_KEY]
Definition: pgp.h:129
#define PGP_S2K_SALT
Definition: pgp.h:115
uint8 key_len
Definition: pgp.h:130
#define PGP_MAX_DIGEST
Definition: pgp.h:114
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:126

◆ calc_s2k_simple()

static int calc_s2k_simple ( PGP_S2K s2k,
PX_MD md,
const uint8 key,
unsigned  key_len 
)
static

Definition at line 39 of file pgp-s2k.c.

References buf, PGP_S2K::key, PGP_S2K::key_len, PGP_MAX_DIGEST, px_md_finish, px_md_reset, px_md_result_size, px_md_update, and px_memset().

Referenced by pgp_s2k_process().

41 {
42  unsigned md_rlen;
44  unsigned preload;
45  unsigned remain;
46  uint8 *dst = s2k->key;
47 
48  md_rlen = px_md_result_size(md);
49 
50  remain = s2k->key_len;
51  preload = 0;
52  while (remain > 0)
53  {
54  px_md_reset(md);
55 
56  if (preload)
57  {
58  memset(buf, 0, preload);
59  px_md_update(md, buf, preload);
60  }
61  preload++;
62 
63  px_md_update(md, key, key_len);
64  px_md_finish(md, buf);
65 
66  if (remain > md_rlen)
67  {
68  memcpy(dst, buf, md_rlen);
69  dst += md_rlen;
70  remain -= md_rlen;
71  }
72  else
73  {
74  memcpy(dst, buf, remain);
75  remain = 0;
76  }
77  }
78  px_memset(buf, 0, sizeof(buf));
79  return 0;
80 }
#define px_md_update(md, data, dlen)
Definition: px.h:205
unsigned char uint8
Definition: c.h:356
#define px_md_finish(md, buf)
Definition: px.h:206
#define px_md_reset(md)
Definition: px.h:204
#define px_md_result_size(md)
Definition: px.h:202
static char * buf
Definition: pg_test_fsync.c:68
uint8 key[PGP_MAX_KEY]
Definition: pgp.h:129
uint8 key_len
Definition: pgp.h:130
#define PGP_MAX_DIGEST
Definition: pgp.h:114
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:126

◆ decide_s2k_iter()

static uint8 decide_s2k_iter ( unsigned  rand_byte,
int  count 
)
static

Definition at line 210 of file pgp-s2k.c.

References s2k_decode_count.

Referenced by pgp_s2k_fill().

211 {
212  int iter;
213 
214  if (count == -1)
215  return 96 + (rand_byte & 0x1F);
216  /* this is a bit brute-force, but should be quick enough */
217  for (iter = 0; iter <= 255; iter++)
218  if (s2k_decode_count(iter) >= count)
219  return iter;
220  return 255;
221 }
#define s2k_decode_count(cval)
Definition: pgp.h:176

◆ pgp_s2k_fill()

int pgp_s2k_fill ( PGP_S2K s2k,
int  mode,
int  digest_algo,
int  count 
)

Definition at line 224 of file pgp-s2k.c.

References decide_s2k_iter(), PGP_S2K::digest_algo, PGP_S2K::iter, mode, PGP_S2K::mode, pg_strong_random(), PGP_S2K_ISALTED, PGP_S2K_SALT, PGP_S2K_SALTED, PGP_S2K_SIMPLE, PXE_NO_RANDOM, PXE_PGP_BAD_S2K_MODE, and PGP_S2K::salt.

Referenced by init_s2k_key().

225 {
226  int res = 0;
227  uint8 tmp;
228 
229  s2k->mode = mode;
230  s2k->digest_algo = digest_algo;
231 
232  switch (s2k->mode)
233  {
234  case PGP_S2K_SIMPLE:
235  break;
236  case PGP_S2K_SALTED:
237  if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
238  return PXE_NO_RANDOM;
239  break;
240  case PGP_S2K_ISALTED:
241  if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
242  return PXE_NO_RANDOM;
243  if (!pg_strong_random(&tmp, 1))
244  return PXE_NO_RANDOM;
245  s2k->iter = decide_s2k_iter(tmp, count);
246  break;
247  default:
248  res = PXE_PGP_BAD_S2K_MODE;
249  }
250  return res;
251 }
uint8 mode
Definition: pgp.h:124
static PgChecksumMode mode
Definition: pg_checksums.c:61
unsigned char uint8
Definition: c.h:356
#define PXE_NO_RANDOM
Definition: px.h:75
#define PXE_PGP_BAD_S2K_MODE
Definition: px.h:99
uint8 digest_algo
Definition: pgp.h:125
uint8 salt[8]
Definition: pgp.h:126
#define PGP_S2K_SALT
Definition: pgp.h:115
bool pg_strong_random(void *buf, size_t len)
static uint8 decide_s2k_iter(unsigned rand_byte, int count)
Definition: pgp-s2k.c:210
uint8 iter
Definition: pgp.h:127

◆ pgp_s2k_process()

int pgp_s2k_process ( PGP_S2K s2k,
int  cipher,
const uint8 key,
int  key_len 
)

Definition at line 280 of file pgp-s2k.c.

References calc_s2k_iter_salted(), calc_s2k_salted(), calc_s2k_simple(), PGP_S2K::digest_algo, PGP_S2K::key_len, PGP_S2K::mode, pgp_get_cipher_key_size(), pgp_load_digest(), px_md_free, PXE_PGP_BAD_S2K_MODE, and PXE_PGP_UNSUPPORTED_CIPHER.

Referenced by init_s2k_key(), parse_symenc_sesskey(), and process_secret_key().

281 {
282  int res;
283  PX_MD *md;
284 
285  s2k->key_len = pgp_get_cipher_key_size(cipher);
286  if (s2k->key_len <= 0)
288 
289  res = pgp_load_digest(s2k->digest_algo, &md);
290  if (res < 0)
291  return res;
292 
293  switch (s2k->mode)
294  {
295  case 0:
296  res = calc_s2k_simple(s2k, md, key, key_len);
297  break;
298  case 1:
299  res = calc_s2k_salted(s2k, md, key, key_len);
300  break;
301  case 3:
302  res = calc_s2k_iter_salted(s2k, md, key, key_len);
303  break;
304  default:
305  res = PXE_PGP_BAD_S2K_MODE;
306  }
307  px_md_free(md);
308  return res;
309 }
uint8 mode
Definition: pgp.h:124
static int calc_s2k_simple(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
Definition: pgp-s2k.c:39
#define PXE_PGP_UNSUPPORTED_CIPHER
Definition: px.h:81
static int calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
Definition: pgp-s2k.c:83
#define PXE_PGP_BAD_S2K_MODE
Definition: px.h:99
uint8 digest_algo
Definition: pgp.h:125
Definition: px.h:110
int pgp_get_cipher_key_size(int code)
Definition: pgp.c:147
static int calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
Definition: pgp-s2k.c:127
#define px_md_free(md)
Definition: px.h:207
int pgp_load_digest(int code, PX_MD **res)
Definition: pgp.c:183
uint8 key_len
Definition: pgp.h:130

◆ pgp_s2k_read()

int pgp_s2k_read ( PullFilter src,
PGP_S2K s2k 
)

Definition at line 254 of file pgp-s2k.c.

References PGP_S2K::digest_algo, GETBYTE, PGP_S2K::iter, PGP_S2K::mode, pullf_read_fixed(), PXE_PGP_BAD_S2K_MODE, and PGP_S2K::salt.

Referenced by parse_symenc_sesskey(), and process_secret_key().

255 {
256  int res = 0;
257 
258  GETBYTE(src, s2k->mode);
259  GETBYTE(src, s2k->digest_algo);
260  switch (s2k->mode)
261  {
262  case 0:
263  break;
264  case 1:
265  res = pullf_read_fixed(src, 8, s2k->salt);
266  break;
267  case 3:
268  res = pullf_read_fixed(src, 8, s2k->salt);
269  if (res < 0)
270  break;
271  GETBYTE(src, s2k->iter);
272  break;
273  default:
274  res = PXE_PGP_BAD_S2K_MODE;
275  }
276  return res;
277 }
uint8 mode
Definition: pgp.h:124
int pullf_read_fixed(PullFilter *src, int len, uint8 *dst)
Definition: mbuf.c:317
#define PXE_PGP_BAD_S2K_MODE
Definition: px.h:99
uint8 digest_algo
Definition: pgp.h:125
#define GETBYTE(x, i)
Definition: hstore_gist.c:29
uint8 salt[8]
Definition: pgp.h:126
uint8 iter
Definition: pgp.h:127