PostgreSQL Source Code  git master
pgp-s2k.c File Reference
#include "postgres.h"
#include "pgp.h"
#include "px.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 126 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().

128 {
129  unsigned md_rlen;
131  uint8 *dst;
132  unsigned preload = 0;
133  unsigned remain,
134  c,
135  curcnt,
136  count;
137 
138  count = s2k_decode_count(s2k->iter);
139 
140  md_rlen = px_md_result_size(md);
141 
142  remain = s2k->key_len;
143  dst = s2k->key;
144  while (remain > 0)
145  {
146  px_md_reset(md);
147 
148  if (preload)
149  {
150  memset(buf, 0, preload);
151  px_md_update(md, buf, preload);
152  }
153  preload++;
154 
155  px_md_update(md, s2k->salt, PGP_S2K_SALT);
156  px_md_update(md, key, key_len);
157  curcnt = PGP_S2K_SALT + key_len;
158 
159  while (curcnt < count)
160  {
161  if (curcnt + PGP_S2K_SALT < count)
162  c = PGP_S2K_SALT;
163  else
164  c = count - curcnt;
165  px_md_update(md, s2k->salt, c);
166  curcnt += c;
167 
168  if (curcnt + key_len < count)
169  c = key_len;
170  else if (curcnt < count)
171  c = count - curcnt;
172  else
173  break;
174  px_md_update(md, key, c);
175  curcnt += c;
176  }
177  px_md_finish(md, buf);
178 
179  if (remain > md_rlen)
180  {
181  memcpy(dst, buf, md_rlen);
182  remain -= md_rlen;
183  dst += md_rlen;
184  }
185  else
186  {
187  memcpy(dst, buf, remain);
188  remain = 0;
189  }
190  }
191  px_memset(buf, 0, sizeof(buf));
192  return 0;
193 }
#define px_md_update(md, data, dlen)
Definition: px.h:205
unsigned char uint8
Definition: c.h:357
#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:67
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 82 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().

83 {
84  unsigned md_rlen;
86  unsigned preload = 0;
87  uint8 *dst;
88  unsigned remain;
89 
90  md_rlen = px_md_result_size(md);
91 
92  dst = s2k->key;
93  remain = s2k->key_len;
94  while (remain > 0)
95  {
96  px_md_reset(md);
97 
98  if (preload > 0)
99  {
100  memset(buf, 0, preload);
101  px_md_update(md, buf, preload);
102  }
103  preload++;
104 
105  px_md_update(md, s2k->salt, PGP_S2K_SALT);
106  px_md_update(md, key, key_len);
107  px_md_finish(md, buf);
108 
109  if (remain > md_rlen)
110  {
111  memcpy(dst, buf, md_rlen);
112  remain -= md_rlen;
113  dst += md_rlen;
114  }
115  else
116  {
117  memcpy(dst, buf, remain);
118  remain = 0;
119  }
120  }
121  px_memset(buf, 0, sizeof(buf));
122  return 0;
123 }
#define px_md_update(md, data, dlen)
Definition: px.h:205
unsigned char uint8
Definition: c.h:357
#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:67
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 38 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().

40 {
41  unsigned md_rlen;
43  unsigned preload;
44  unsigned remain;
45  uint8 *dst = s2k->key;
46 
47  md_rlen = px_md_result_size(md);
48 
49  remain = s2k->key_len;
50  preload = 0;
51  while (remain > 0)
52  {
53  px_md_reset(md);
54 
55  if (preload)
56  {
57  memset(buf, 0, preload);
58  px_md_update(md, buf, preload);
59  }
60  preload++;
61 
62  px_md_update(md, key, key_len);
63  px_md_finish(md, buf);
64 
65  if (remain > md_rlen)
66  {
67  memcpy(dst, buf, md_rlen);
68  dst += md_rlen;
69  remain -= md_rlen;
70  }
71  else
72  {
73  memcpy(dst, buf, remain);
74  remain = 0;
75  }
76  }
77  px_memset(buf, 0, sizeof(buf));
78  return 0;
79 }
#define px_md_update(md, data, dlen)
Definition: px.h:205
unsigned char uint8
Definition: c.h:357
#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:67
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 209 of file pgp-s2k.c.

References s2k_decode_count.

Referenced by pgp_s2k_fill().

210 {
211  int iter;
212 
213  if (count == -1)
214  return 96 + (rand_byte & 0x1F);
215  /* this is a bit brute-force, but should be quick enough */
216  for (iter = 0; iter <= 255; iter++)
217  if (s2k_decode_count(iter) >= count)
218  return iter;
219  return 255;
220 }
#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 223 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().

224 {
225  int res = 0;
226  uint8 tmp;
227 
228  s2k->mode = mode;
229  s2k->digest_algo = digest_algo;
230 
231  switch (s2k->mode)
232  {
233  case PGP_S2K_SIMPLE:
234  break;
235  case PGP_S2K_SALTED:
236  if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
237  return PXE_NO_RANDOM;
238  break;
239  case PGP_S2K_ISALTED:
240  if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
241  return PXE_NO_RANDOM;
242  if (!pg_strong_random(&tmp, 1))
243  return PXE_NO_RANDOM;
244  s2k->iter = decide_s2k_iter(tmp, count);
245  break;
246  default:
247  res = PXE_PGP_BAD_S2K_MODE;
248  }
249  return res;
250 }
uint8 mode
Definition: pgp.h:124
static PgChecksumMode mode
Definition: pg_checksums.c:61
unsigned char uint8
Definition: c.h:357
#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:209
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 279 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().

280 {
281  int res;
282  PX_MD *md;
283 
284  s2k->key_len = pgp_get_cipher_key_size(cipher);
285  if (s2k->key_len <= 0)
287 
288  res = pgp_load_digest(s2k->digest_algo, &md);
289  if (res < 0)
290  return res;
291 
292  switch (s2k->mode)
293  {
294  case 0:
295  res = calc_s2k_simple(s2k, md, key, key_len);
296  break;
297  case 1:
298  res = calc_s2k_salted(s2k, md, key, key_len);
299  break;
300  case 3:
301  res = calc_s2k_iter_salted(s2k, md, key, key_len);
302  break;
303  default:
304  res = PXE_PGP_BAD_S2K_MODE;
305  }
306  px_md_free(md);
307  return res;
308 }
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:38
#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:82
#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:126
#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 253 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().

254 {
255  int res = 0;
256 
257  GETBYTE(src, s2k->mode);
258  GETBYTE(src, s2k->digest_algo);
259  switch (s2k->mode)
260  {
261  case 0:
262  break;
263  case 1:
264  res = pullf_read_fixed(src, 8, s2k->salt);
265  break;
266  case 3:
267  res = pullf_read_fixed(src, 8, s2k->salt);
268  if (res < 0)
269  break;
270  GETBYTE(src, s2k->iter);
271  break;
272  default:
273  res = PXE_PGP_BAD_S2K_MODE;
274  }
275  return res;
276 }
uint8 mode
Definition: pgp.h:124
int pullf_read_fixed(PullFilter *src, int len, uint8 *dst)
Definition: mbuf.c:315
#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:28
uint8 salt[8]
Definition: pgp.h:126
uint8 iter
Definition: pgp.h:127