Age Owner TLA Line data Source code
1 : /*
2 : * pgp-s2k.c
3 : * OpenPGP string2key functions.
4 : *
5 : * Copyright (c) 2005 Marko Kreen
6 : * All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
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.
16 : *
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
27 : * SUCH DAMAGE.
28 : *
29 : * contrib/pgcrypto/pgp-s2k.c
30 : */
31 :
32 : #include "postgres.h"
33 :
34 : #include "pgp.h"
35 : #include "px.h"
36 :
37 : static int
5050 bruce 38 CBC 5 : calc_s2k_simple(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
39 : unsigned key_len)
40 : {
41 : unsigned md_rlen;
42 : uint8 buf[PGP_MAX_DIGEST];
43 : unsigned preload;
44 : unsigned remain;
6482 45 5 : uint8 *dst = s2k->key;
46 :
47 5 : md_rlen = px_md_result_size(md);
48 :
49 5 : remain = s2k->key_len;
50 5 : preload = 0;
51 12 : while (remain > 0)
52 : {
53 7 : px_md_reset(md);
54 :
55 7 : if (preload)
56 : {
57 2 : memset(buf, 0, preload);
58 2 : px_md_update(md, buf, preload);
59 : }
60 7 : preload++;
61 :
62 7 : px_md_update(md, key, key_len);
63 7 : px_md_finish(md, buf);
64 :
65 7 : if (remain > md_rlen)
66 : {
67 2 : memcpy(dst, buf, md_rlen);
68 2 : dst += md_rlen;
69 2 : remain -= md_rlen;
70 : }
71 : else
72 : {
73 5 : memcpy(dst, buf, remain);
74 5 : remain = 0;
75 : }
76 : }
3279 77 5 : px_memset(buf, 0, sizeof(buf));
6482 78 5 : return 0;
79 : }
80 :
81 : static int
5050 82 5 : calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
83 : {
84 : unsigned md_rlen;
85 : uint8 buf[PGP_MAX_DIGEST];
6482 86 5 : unsigned preload = 0;
87 : uint8 *dst;
88 : unsigned remain;
89 :
90 5 : md_rlen = px_md_result_size(md);
91 :
92 5 : dst = s2k->key;
93 5 : remain = s2k->key_len;
94 12 : while (remain > 0)
95 : {
96 7 : px_md_reset(md);
97 :
98 7 : if (preload > 0)
99 : {
100 2 : memset(buf, 0, preload);
101 2 : px_md_update(md, buf, preload);
102 : }
103 7 : preload++;
104 :
105 7 : px_md_update(md, s2k->salt, PGP_S2K_SALT);
106 7 : px_md_update(md, key, key_len);
107 7 : px_md_finish(md, buf);
108 :
109 7 : if (remain > md_rlen)
110 : {
111 2 : memcpy(dst, buf, md_rlen);
112 2 : remain -= md_rlen;
113 2 : dst += md_rlen;
114 : }
115 : else
116 : {
117 5 : memcpy(dst, buf, remain);
118 5 : remain = 0;
119 : }
120 : }
3279 121 5 : px_memset(buf, 0, sizeof(buf));
6482 122 5 : return 0;
123 : }
124 :
125 : static int
5050 126 83 : calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
127 : unsigned key_len)
128 : {
129 : unsigned md_rlen;
130 : uint8 buf[PGP_MAX_DIGEST];
131 : uint8 *dst;
6482 132 83 : unsigned preload = 0;
133 : unsigned remain,
134 : c,
135 : curcnt,
136 : count;
137 :
2587 alvherre 138 83 : count = s2k_decode_count(s2k->iter);
139 :
6482 bruce 140 83 : md_rlen = px_md_result_size(md);
141 :
142 83 : remain = s2k->key_len;
143 83 : dst = s2k->key;
144 179 : while (remain > 0)
145 : {
146 96 : px_md_reset(md);
147 :
148 96 : if (preload)
149 : {
150 13 : memset(buf, 0, preload);
151 13 : px_md_update(md, buf, preload);
152 : }
153 96 : preload++;
154 :
155 96 : px_md_update(md, s2k->salt, PGP_S2K_SALT);
156 96 : px_md_update(md, key, key_len);
157 96 : curcnt = PGP_S2K_SALT + key_len;
158 :
159 12719390 : while (curcnt < count)
160 : {
161 12719363 : if (curcnt + PGP_S2K_SALT < count)
162 12719294 : c = PGP_S2K_SALT;
163 : else
164 69 : c = count - curcnt;
165 12719363 : px_md_update(md, s2k->salt, c);
166 12719363 : curcnt += c;
167 :
168 12719363 : if (curcnt + key_len < count)
169 12719267 : c = key_len;
170 96 : else if (curcnt < count)
171 27 : c = count - curcnt;
172 : else
173 69 : break;
174 12719294 : px_md_update(md, key, c);
175 12719294 : curcnt += c;
176 : }
177 96 : px_md_finish(md, buf);
178 :
179 96 : if (remain > md_rlen)
180 : {
181 13 : memcpy(dst, buf, md_rlen);
182 13 : remain -= md_rlen;
183 13 : dst += md_rlen;
184 : }
185 : else
186 : {
187 83 : memcpy(dst, buf, remain);
188 83 : remain = 0;
189 : }
190 : }
3279 191 83 : px_memset(buf, 0, sizeof(buf));
6482 192 83 : return 0;
193 : }
194 :
195 : /*
196 : * Decide PGP_S2K_ISALTED iteration count (in OpenPGP one-byte representation)
197 : *
198 : * Too small: weak
199 : * Too big: slow
200 : * gpg defaults to 96 => 65536 iters
201 : *
202 : * For our default (count=-1) we let it float a bit: 96 + 32 => between 65536
203 : * and 262144 iterations.
204 : *
205 : * Otherwise, find the smallest number which provides at least the specified
206 : * iteration count.
207 : */
208 : static uint8
2587 alvherre 209 28 : decide_s2k_iter(unsigned rand_byte, int count)
210 : {
211 : int iter;
212 :
213 28 : if (count == -1)
214 26 : return 96 + (rand_byte & 0x1F);
215 : /* this is a bit brute-force, but should be quick enough */
216 257 : for (iter = 0; iter <= 255; iter++)
217 257 : if (s2k_decode_count(iter) >= count)
218 2 : return iter;
2587 alvherre 219 UBC 0 : return 255;
220 : }
221 :
222 : int
2587 alvherre 223 CBC 30 : pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
224 : {
6385 bruce 225 30 : int res = 0;
226 : uint8 tmp;
227 :
6482 228 30 : s2k->mode = mode;
229 30 : s2k->digest_algo = digest_algo;
230 :
6385 231 30 : switch (s2k->mode)
232 : {
2587 alvherre 233 1 : case PGP_S2K_SIMPLE:
6482 bruce 234 1 : break;
2587 alvherre 235 1 : case PGP_S2K_SALTED:
1559 michael 236 1 : if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
2316 heikki.linnakangas 237 UBC 0 : return PXE_NO_RANDOM;
6482 bruce 238 CBC 1 : break;
2587 alvherre 239 28 : case PGP_S2K_ISALTED:
1559 michael 240 28 : if (!pg_strong_random(s2k->salt, PGP_S2K_SALT))
2316 heikki.linnakangas 241 UBC 0 : return PXE_NO_RANDOM;
1559 michael 242 CBC 28 : if (!pg_strong_random(&tmp, 1))
2316 heikki.linnakangas 243 UBC 0 : return PXE_NO_RANDOM;
2587 alvherre 244 CBC 28 : s2k->iter = decide_s2k_iter(tmp, count);
6482 bruce 245 28 : break;
6482 bruce 246 UBC 0 : default:
247 0 : res = PXE_PGP_BAD_S2K_MODE;
248 : }
6482 bruce 249 CBC 30 : return res;
250 : }
251 :
252 : int
5050 253 63 : pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
254 : {
6385 255 63 : int res = 0;
256 :
6482 257 63 : GETBYTE(src, s2k->mode);
258 63 : GETBYTE(src, s2k->digest_algo);
6385 259 63 : switch (s2k->mode)
260 : {
6482 261 4 : case 0:
262 4 : break;
263 4 : case 1:
264 4 : res = pullf_read_fixed(src, 8, s2k->salt);
265 4 : break;
266 55 : case 3:
267 55 : res = pullf_read_fixed(src, 8, s2k->salt);
268 55 : if (res < 0)
6482 bruce 269 UBC 0 : break;
6482 bruce 270 CBC 55 : GETBYTE(src, s2k->iter);
271 55 : break;
6482 bruce 272 UBC 0 : default:
273 0 : res = PXE_PGP_BAD_S2K_MODE;
274 : }
6482 bruce 275 CBC 63 : return res;
276 : }
277 :
278 : int
5050 279 93 : pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
280 : {
281 : int res;
282 : PX_MD *md;
283 :
6482 284 93 : s2k->key_len = pgp_get_cipher_key_size(cipher);
285 93 : if (s2k->key_len <= 0)
6482 bruce 286 UBC 0 : return PXE_PGP_UNSUPPORTED_CIPHER;
287 :
6482 bruce 288 CBC 93 : res = pgp_load_digest(s2k->digest_algo, &md);
289 93 : if (res < 0)
6482 bruce 290 UBC 0 : return res;
291 :
6385 bruce 292 CBC 93 : switch (s2k->mode)
293 : {
6482 294 5 : case 0:
295 5 : res = calc_s2k_simple(s2k, md, key, key_len);
296 5 : break;
297 5 : case 1:
298 5 : res = calc_s2k_salted(s2k, md, key, key_len);
299 5 : break;
300 83 : case 3:
301 83 : res = calc_s2k_iter_salted(s2k, md, key, key_len);
302 83 : break;
6482 bruce 303 UBC 0 : default:
304 0 : res = PXE_PGP_BAD_S2K_MODE;
305 : }
6482 bruce 306 CBC 93 : px_md_free(md);
307 93 : return res;
308 : }
|