diff --git a/contrib/pgcrypto/expected/pgp-encrypt.out b/contrib/pgcrypto/expected/pgp-encrypt.out
new file mode 100644
index b35de79..2bf999f
*** a/contrib/pgcrypto/expected/pgp-encrypt.out
--- b/contrib/pgcrypto/expected/pgp-encrypt.out
*************** select pgp_sym_decrypt(
*** 103,108 ****
--- 103,126 ----
   Secret.
  (1 row)
  
+ -- s2k count change
+ select pgp_sym_decrypt(
+ 	pgp_sym_encrypt('Secret.', 'key', 's2k-count=1024'),
+ 	'key', 'expect-s2k-count=1024');
+  pgp_sym_decrypt 
+ -----------------
+  Secret.
+ (1 row)
+ 
+ select pgp_sym_decrypt(
+ 	pgp_sym_encrypt('Secret.', 'key', 's2k-count=65000000'),
+ 	'key', 'expect-s2k-count=65000000'); -- rounded up
+ NOTICE:  pgp_decrypt: unexpected s2k_count: expected 65000000 got 65011712
+  pgp_sym_decrypt 
+ -----------------
+  Secret.
+ (1 row)
+ 
  -- s2k digest change
  select pgp_sym_decrypt(
  	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
diff --git a/contrib/pgcrypto/pgp-decrypt.c b/contrib/pgcrypto/pgp-decrypt.c
new file mode 100644
index 5c69745..3d16033
*** a/contrib/pgcrypto/pgp-decrypt.c
--- b/contrib/pgcrypto/pgp-decrypt.c
*************** parse_symenc_sesskey(PGP_Context *ctx, P
*** 643,648 ****
--- 643,649 ----
  	if (res < 0)
  		return res;
  	ctx->s2k_mode = ctx->s2k.mode;
+ 	ctx->s2k_count = iter_to_count(ctx->s2k.iter);
  	ctx->s2k_digest_algo = ctx->s2k.digest_algo;
  
  	/*
diff --git a/contrib/pgcrypto/pgp-encrypt.c b/contrib/pgcrypto/pgp-encrypt.c
new file mode 100644
index 2320c75..c9148fd
*** a/contrib/pgcrypto/pgp-encrypt.c
--- b/contrib/pgcrypto/pgp-encrypt.c
*************** init_s2k_key(PGP_Context *ctx)
*** 567,573 ****
  	if (ctx->s2k_cipher_algo < 0)
  		ctx->s2k_cipher_algo = ctx->cipher_algo;
  
! 	res = pgp_s2k_fill(&ctx->s2k, ctx->s2k_mode, ctx->s2k_digest_algo);
  	if (res < 0)
  		return res;
  
--- 567,573 ----
  	if (ctx->s2k_cipher_algo < 0)
  		ctx->s2k_cipher_algo = ctx->cipher_algo;
  
! 	res = pgp_s2k_fill(&ctx->s2k, ctx->s2k_mode, ctx->s2k_digest_algo, ctx->s2k_count);
  	if (res < 0)
  		return res;
  
diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c
new file mode 100644
index 1842985..1b55bc9
*** a/contrib/pgcrypto/pgp-pgsql.c
--- b/contrib/pgcrypto/pgp-pgsql.c
*************** struct debug_expect
*** 181,186 ****
--- 181,187 ----
  	int			expect;
  	int			cipher_algo;
  	int			s2k_mode;
+ 	int			s2k_count;
  	int			s2k_cipher_algo;
  	int			s2k_digest_algo;
  	int			compress_algo;
*************** fill_expect(struct debug_expect * ex, in
*** 196,201 ****
--- 197,203 ----
  	ex->expect = 0;
  	ex->cipher_algo = -1;
  	ex->s2k_mode = -1;
+ 	ex->s2k_count= -1;
  	ex->s2k_cipher_algo = -1;
  	ex->s2k_digest_algo = -1;
  	ex->compress_algo = -1;
*************** check_expect(PGP_Context *ctx, struct de
*** 218,223 ****
--- 220,226 ----
  {
  	EX_CHECK(cipher_algo);
  	EX_CHECK(s2k_mode);
+ 	EX_CHECK(s2k_count);
  	EX_CHECK(s2k_digest_algo);
  	EX_CHECK(use_sess_key);
  	if (ctx->use_sess_key)
*************** set_arg(PGP_Context *ctx, char *key, cha
*** 247,252 ****
--- 250,257 ----
  		res = pgp_set_sess_key(ctx, atoi(val));
  	else if (strcmp(key, "s2k-mode") == 0)
  		res = pgp_set_s2k_mode(ctx, atoi(val));
+ 	else if (strcmp(key, "s2k-count") == 0)
+ 		res = pgp_set_s2k_count(ctx, atoi(val));
  	else if (strcmp(key, "s2k-digest-algo") == 0)
  		res = pgp_set_s2k_digest_algo(ctx, val);
  	else if (strcmp(key, "s2k-cipher-algo") == 0)
*************** set_arg(PGP_Context *ctx, char *key, cha
*** 286,291 ****
--- 291,301 ----
  		ex->expect = 1;
  		ex->s2k_mode = atoi(val);
  	}
+ 	else if (ex != NULL && strcmp(key, "expect-s2k-count") == 0)
+ 	{
+ 		ex->expect = 1;
+ 		ex->s2k_count = atoi(val);
+ 	}
  	else if (ex != NULL && strcmp(key, "expect-s2k-digest-algo") == 0)
  	{
  		ex->expect = 1;
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
new file mode 100644
index 193dd95..baa8e88
*** a/contrib/pgcrypto/pgp-s2k.c
--- b/contrib/pgcrypto/pgp-s2k.c
*************** calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD
*** 137,143 ****
  				count;
  
  	cval = s2k->iter;
! 	count = ((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6);
  
  	md_rlen = px_md_result_size(md);
  
--- 137,143 ----
  				count;
  
  	cval = s2k->iter;
! 	count = iter_to_count(cval);
  
  	md_rlen = px_md_result_size(md);
  
*************** calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD
*** 200,215 ****
   * Too small: weak
   * Too big: slow
   * gpg defaults to 96 => 65536 iters
!  * let it float a bit: 96 + 32 => 262144 iters
   */
  static int
! decide_count(unsigned rand_byte)
  {
! 	return 96 + (rand_byte & 0x1F);
  }
  
  int
! pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
  {
  	int			res = 0;
  	uint8		tmp;
--- 200,223 ----
   * Too small: weak
   * Too big: slow
   * gpg defaults to 96 => 65536 iters
!  * For our default let it float a bit: 96 + 32 => 262144 iters
!  * Otherwise, find the smallest iteration which provides
!  * at least the specified count.
   */
  static int
! decide_count(unsigned rand_byte,int count)
  {
! 	int iter;
! 	if (count == -1)
! 		return 96 + (rand_byte & 0x1F);
! 	for (iter=0; iter<=255; iter++)
! 	if (iter_to_count(iter) >= count)
! 		return iter;
! 	return 255;
  }
  
  int
! pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
  {
  	int			res = 0;
  	uint8		tmp;
*************** pgp_s2k_fill(PGP_S2K *s2k, int mode, int
*** 231,237 ****
  			res = px_get_pseudo_random_bytes(&tmp, 1);
  			if (res < 0)
  				break;
! 			s2k->iter = decide_count(tmp);
  			break;
  		default:
  			res = PXE_PGP_BAD_S2K_MODE;
--- 239,245 ----
  			res = px_get_pseudo_random_bytes(&tmp, 1);
  			if (res < 0)
  				break;
! 			s2k->iter = decide_count(tmp,count);
  			break;
  		default:
  			res = PXE_PGP_BAD_S2K_MODE;
diff --git a/contrib/pgcrypto/pgp.c b/contrib/pgcrypto/pgp.c
new file mode 100644
index 03fe48f..f0e016c
*** a/contrib/pgcrypto/pgp.c
--- b/contrib/pgcrypto/pgp.c
***************
*** 40,45 ****
--- 40,46 ----
  static int	def_cipher_algo = PGP_SYM_AES_128;
  static int	def_s2k_cipher_algo = -1;
  static int	def_s2k_mode = PGP_S2K_ISALTED;
+ static int	def_s2k_count = -1;
  static int	def_s2k_digest_algo = PGP_DIGEST_SHA1;
  static int	def_compress_algo = PGP_COMPR_NONE;
  static int	def_compress_level = 6;
*************** pgp_init(PGP_Context **ctx_p)
*** 206,211 ****
--- 207,213 ----
  	ctx->cipher_algo = def_cipher_algo;
  	ctx->s2k_cipher_algo = def_s2k_cipher_algo;
  	ctx->s2k_mode = def_s2k_mode;
+ 	ctx->s2k_count = def_s2k_count;
  	ctx->s2k_digest_algo = def_s2k_digest_algo;
  	ctx->compress_algo = def_compress_algo;
  	ctx->compress_level = def_compress_level;
*************** pgp_set_s2k_mode(PGP_Context *ctx, int m
*** 270,275 ****
--- 272,288 ----
  }
  
  int
+ pgp_set_s2k_count(PGP_Context *ctx, int count)
+ {
+ 	if (ctx->s2k_mode == PGP_S2K_ISALTED && count >= 1024 && count <= 65011712) 
+ 	{
+ 		ctx->s2k_count = count;
+ 		return PXE_OK;
+ 	}
+ 	return PXE_ARGUMENT_ERROR;
+ }
+ 
+ int
  pgp_set_compress_algo(PGP_Context *ctx, int algo)
  {
  	switch (algo)
diff --git a/contrib/pgcrypto/pgp.h b/contrib/pgcrypto/pgp.h
new file mode 100644
index 62b8517..c3e86e3
*** a/contrib/pgcrypto/pgp.h
--- b/contrib/pgcrypto/pgp.h
***************
*** 34,39 ****
--- 34,41 ----
  #include "mbuf.h"
  #include "px.h"
  
+ #define iter_to_count(cval) (((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6))
+ 
  enum PGP_S2K_TYPE
  {
  	PGP_S2K_SIMPLE = 0,
*************** struct PGP_Context
*** 138,143 ****
--- 140,146 ----
  	 */
  	PGP_S2K		s2k;
  	int			s2k_mode;
+ 	int			s2k_count;
  	int			s2k_digest_algo;
  	int			s2k_cipher_algo;
  	int			cipher_algo;
*************** const char *pgp_get_cipher_name(int code
*** 243,248 ****
--- 246,252 ----
  
  int			pgp_set_cipher_algo(PGP_Context *ctx, const char *name);
  int			pgp_set_s2k_mode(PGP_Context *ctx, int type);
+ int			pgp_set_s2k_count(PGP_Context *ctx, int count);
  int			pgp_set_s2k_cipher_algo(PGP_Context *ctx, const char *name);
  int			pgp_set_s2k_digest_algo(PGP_Context *ctx, const char *name);
  int			pgp_set_convert_crlf(PGP_Context *ctx, int doit);
*************** int			pgp_load_cipher(int c, PX_Cipher *
*** 267,273 ****
  int			pgp_get_cipher_key_size(int c);
  int			pgp_get_cipher_block_size(int c);
  
! int			pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo);
  int			pgp_s2k_read(PullFilter *src, PGP_S2K *s2k);
  int			pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int klen);
  
--- 271,277 ----
  int			pgp_get_cipher_key_size(int c);
  int			pgp_get_cipher_block_size(int c);
  
! 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 klen);
  
diff --git a/contrib/pgcrypto/sql/pgp-encrypt.sql b/contrib/pgcrypto/sql/pgp-encrypt.sql
new file mode 100644
index a9ac0b9..1dd575d
*** a/contrib/pgcrypto/sql/pgp-encrypt.sql
--- b/contrib/pgcrypto/sql/pgp-encrypt.sql
*************** select pgp_sym_decrypt(
*** 55,60 ****
--- 55,68 ----
  	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'),
  	'key', 'expect-s2k-mode=3');
  
+ -- s2k count change
+ select pgp_sym_decrypt(
+ 	pgp_sym_encrypt('Secret.', 'key', 's2k-count=1024'),
+ 	'key', 'expect-s2k-count=1024');
+ select pgp_sym_decrypt(
+ 	pgp_sym_encrypt('Secret.', 'key', 's2k-count=65000000'),
+ 	'key', 'expect-s2k-count=65000000'); -- rounded up
+ 
  -- s2k digest change
  select pgp_sym_decrypt(
  	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
new file mode 100644
index bfcbe02..21a884b
*** a/doc/src/sgml/pgcrypto.sgml
--- b/doc/src/sgml/pgcrypto.sgml
*************** Applies to: pgp_sym_encrypt
*** 859,864 ****
--- 859,877 ----
    </sect4>
  
    <sect4>
+    <title>s2k-count</title>
+ 
+    <para>
+     The number of iterations of the S2K algorithm to use.  It must
+     be a value between 1024 and 65011712, inclusive.
+    </para>
+ <literallayout>
+ Default: A random value bewteen 65536 and 253952
+ Applies to: pgp_sym_encrypt, only with s2k-mode=3
+ </literallayout>
+   </sect4>
+ 
+   <sect4>
     <title>s2k-digest-algo</title>
  
     <para>
