PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pgp-s2k.c File Reference
#include "postgres.h"
#include "px.h"
#include "pgp.h"
#include "utils/backend_random.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

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

Definition at line 128 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().

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

Definition at line 84 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().

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

Definition at line 40 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().

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

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

References s2k_decode_count.

Referenced by pgp_s2k_fill().

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

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

References decide_s2k_iter(), PGP_S2K::digest_algo, PGP_S2K::iter, PGP_S2K::mode, pg_backend_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().

226 {
227  int res = 0;
228  uint8 tmp;
229 
230  s2k->mode = mode;
231  s2k->digest_algo = digest_algo;
232 
233  switch (s2k->mode)
234  {
235  case PGP_S2K_SIMPLE:
236  break;
237  case PGP_S2K_SALTED:
238  if (!pg_backend_random((char *) s2k->salt, PGP_S2K_SALT))
239  return PXE_NO_RANDOM;
240  break;
241  case PGP_S2K_ISALTED:
242  if (!pg_backend_random((char *) s2k->salt, PGP_S2K_SALT))
243  return PXE_NO_RANDOM;
244  if (!pg_backend_random((char *) &tmp, 1))
245  return PXE_NO_RANDOM;
246  s2k->iter = decide_s2k_iter(tmp, count);
247  break;
248  default:
249  res = PXE_PGP_BAD_S2K_MODE;
250  }
251  return res;
252 }
uint8 mode
Definition: pgp.h:124
unsigned char uint8
Definition: c.h:256
#define PXE_NO_RANDOM
Definition: px.h:78
#define PXE_PGP_BAD_S2K_MODE
Definition: px.h:102
uint8 digest_algo
Definition: pgp.h:125
bool pg_backend_random(char *dst, int len)
uint8 salt[8]
Definition: pgp.h:126
#define PGP_S2K_SALT
Definition: pgp.h:115
static uint8 decide_s2k_iter(unsigned rand_byte, int count)
Definition: pgp-s2k.c:211
uint8 iter
Definition: pgp.h:127
int pgp_s2k_process ( PGP_S2K s2k,
int  cipher,
const uint8 key,
int  key_len 
)

Definition at line 281 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().

282 {
283  int res;
284  PX_MD *md;
285 
286  s2k->key_len = pgp_get_cipher_key_size(cipher);
287  if (s2k->key_len <= 0)
289 
290  res = pgp_load_digest(s2k->digest_algo, &md);
291  if (res < 0)
292  return res;
293 
294  switch (s2k->mode)
295  {
296  case 0:
297  res = calc_s2k_simple(s2k, md, key, key_len);
298  break;
299  case 1:
300  res = calc_s2k_salted(s2k, md, key, key_len);
301  break;
302  case 3:
303  res = calc_s2k_iter_salted(s2k, md, key, key_len);
304  break;
305  default:
306  res = PXE_PGP_BAD_S2K_MODE;
307  }
308  px_md_free(md);
309  return res;
310 }
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:40
#define PXE_PGP_UNSUPPORTED_CIPHER
Definition: px.h:84
static int calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
Definition: pgp-s2k.c:84
#define PXE_PGP_BAD_S2K_MODE
Definition: px.h:102
uint8 digest_algo
Definition: pgp.h:125
Definition: px.h:113
int pgp_get_cipher_key_size(int code)
Definition: pgp.c:148
static int calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
Definition: pgp-s2k.c:128
#define px_md_free(md)
Definition: px.h:210
int pgp_load_digest(int code, PX_MD **res)
Definition: pgp.c:184
uint8 key_len
Definition: pgp.h:130
int pgp_s2k_read ( PullFilter src,
PGP_S2K s2k 
)

Definition at line 255 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().

256 {
257  int res = 0;
258 
259  GETBYTE(src, s2k->mode);
260  GETBYTE(src, s2k->digest_algo);
261  switch (s2k->mode)
262  {
263  case 0:
264  break;
265  case 1:
266  res = pullf_read_fixed(src, 8, s2k->salt);
267  break;
268  case 3:
269  res = pullf_read_fixed(src, 8, s2k->salt);
270  if (res < 0)
271  break;
272  GETBYTE(src, s2k->iter);
273  break;
274  default:
275  res = PXE_PGP_BAD_S2K_MODE;
276  }
277  return res;
278 }
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:102
uint8 digest_algo
Definition: pgp.h:125
#define GETBYTE(x, i)
Definition: hstore_gist.c:32
uint8 salt[8]
Definition: pgp.h:126
uint8 iter
Definition: pgp.h:127