3 * OpenPGP string2key functions.
5 * Copyright (c) 2005 Marko Kreen
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
29 * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-s2k.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
39 calc_s2k_simple(PGP_S2K * s2k, PX_MD *md, const uint8 *key,
44 uint8 buf[PGP_MAX_DIGEST];
47 uint8 *dst = s2k->key;
49 md_bs = px_md_block_size(md);
50 md_rlen = px_md_result_size(md);
52 remain = s2k->key_len;
60 memset(buf, 0, preload);
61 px_md_update(md, buf, preload);
65 px_md_update(md, key, key_len);
66 px_md_finish(md, buf);
70 memcpy(dst, buf, md_rlen);
76 memcpy(dst, buf, remain);
84 calc_s2k_salted(PGP_S2K * s2k, PX_MD *md, const uint8 *key, unsigned key_len)
88 uint8 buf[PGP_MAX_DIGEST];
93 md_bs = px_md_block_size(md);
94 md_rlen = px_md_result_size(md);
97 remain = s2k->key_len;
104 memset(buf, 0, preload);
105 px_md_update(md, buf, preload);
109 px_md_update(md, s2k->salt, PGP_S2K_SALT);
110 px_md_update(md, key, key_len);
111 px_md_finish(md, buf);
113 if (remain > md_rlen)
115 memcpy(dst, buf, md_rlen);
121 memcpy(dst, buf, remain);
129 calc_s2k_iter_salted(PGP_S2K * s2k, PX_MD *md, const uint8 *key,
134 uint8 buf[PGP_MAX_DIGEST];
136 unsigned preload = 0;
144 count = ((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6);
146 md_bs = px_md_block_size(md);
147 md_rlen = px_md_result_size(md);
149 remain = s2k->key_len;
157 memset(buf, 0, preload);
158 px_md_update(md, buf, preload);
162 px_md_update(md, s2k->salt, PGP_S2K_SALT);
163 px_md_update(md, key, key_len);
164 curcnt = PGP_S2K_SALT + key_len;
166 while (curcnt < count)
168 if (curcnt + PGP_S2K_SALT < count)
172 px_md_update(md, s2k->salt, c);
175 if (curcnt + key_len < count)
177 else if (curcnt < count)
181 px_md_update(md, key, c);
184 px_md_finish(md, buf);
186 if (remain > md_rlen)
188 memcpy(dst, buf, md_rlen);
194 memcpy(dst, buf, remain);
202 * Decide S2K_ISALTED iteration count
206 * gpg defaults to 96 => 65536 iters
207 * let it float a bit: 96 + 32 => 262144 iters
210 decide_count(unsigned rand_byte)
212 return 96 + (rand_byte & 0x1F);
216 pgp_s2k_fill(PGP_S2K *s2k, int mode,int digest_algo)
222 s2k->digest_algo = digest_algo;
228 res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
231 res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
234 res = px_get_random_bytes(&tmp, 1);
237 s2k->iter = decide_count(tmp);
240 res = PXE_PGP_BAD_S2K_MODE;
246 pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
250 GETBYTE(src, s2k->mode);
251 GETBYTE(src, s2k->digest_algo);
256 res = pullf_read_fixed(src, 8, s2k->salt);
259 res = pullf_read_fixed(src, 8, s2k->salt);
262 GETBYTE(src, s2k->iter);
265 res = PXE_PGP_BAD_S2K_MODE;
270 int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
275 s2k->key_len = pgp_get_cipher_key_size(cipher);
276 if (s2k->key_len <= 0)
277 return PXE_PGP_UNSUPPORTED_CIPHER;
279 res = pgp_load_digest(s2k->digest_algo, &md);
285 res = calc_s2k_simple(s2k, md, key, key_len);
288 res = calc_s2k_salted(s2k, md, key, key_len);
291 res = calc_s2k_iter_salted(s2k, md, key, key_len);
294 res = PXE_PGP_BAD_S2K_MODE;