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
* contrib/pgcrypto/pgp-s2k.c
39
calc_s2k_simple(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
43
uint8 buf[PGP_MAX_DIGEST];
46
uint8 *dst = s2k->key;
48
md_rlen = px_md_result_size(md);
50
remain = s2k->key_len;
58
memset(buf, 0, preload);
59
px_md_update(md, buf, preload);
63
px_md_update(md, key, key_len);
64
px_md_finish(md, buf);
68
memcpy(dst, buf, md_rlen);
74
memcpy(dst, buf, remain);
82
calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
85
uint8 buf[PGP_MAX_DIGEST];
90
md_rlen = px_md_result_size(md);
93
remain = s2k->key_len;
100
memset(buf, 0, preload);
101
px_md_update(md, buf, preload);
105
px_md_update(md, s2k->salt, PGP_S2K_SALT);
106
px_md_update(md, key, key_len);
107
px_md_finish(md, buf);
109
if (remain > md_rlen)
111
memcpy(dst, buf, md_rlen);
117
memcpy(dst, buf, remain);
125
calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
129
uint8 buf[PGP_MAX_DIGEST];
131
unsigned preload = 0;
139
count = ((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6);
141
md_rlen = px_md_result_size(md);
143
remain = s2k->key_len;
151
memset(buf, 0, preload);
152
px_md_update(md, buf, preload);
156
px_md_update(md, s2k->salt, PGP_S2K_SALT);
157
px_md_update(md, key, key_len);
158
curcnt = PGP_S2K_SALT + key_len;
160
while (curcnt < count)
162
if (curcnt + PGP_S2K_SALT < count)
166
px_md_update(md, s2k->salt, c);
169
if (curcnt + key_len < count)
171
else if (curcnt < count)
175
px_md_update(md, key, c);
178
px_md_finish(md, buf);
180
if (remain > md_rlen)
182
memcpy(dst, buf, md_rlen);
188
memcpy(dst, buf, remain);
196
* Decide S2K_ISALTED iteration count
200
* gpg defaults to 96 => 65536 iters
201
* let it float a bit: 96 + 32 => 262144 iters
204
decide_count(unsigned rand_byte)
206
return 96 + (rand_byte & 0x1F);
210
pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
216
s2k->digest_algo = digest_algo;
223
res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
226
res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
229
res = px_get_pseudo_random_bytes(&tmp, 1);
232
s2k->iter = decide_count(tmp);
235
res = PXE_PGP_BAD_S2K_MODE;
241
pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
245
GETBYTE(src, s2k->mode);
246
GETBYTE(src, s2k->digest_algo);
252
res = pullf_read_fixed(src, 8, s2k->salt);
255
res = pullf_read_fixed(src, 8, s2k->salt);
258
GETBYTE(src, s2k->iter);
261
res = PXE_PGP_BAD_S2K_MODE;
267
pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
272
s2k->key_len = pgp_get_cipher_key_size(cipher);
273
if (s2k->key_len <= 0)
274
return PXE_PGP_UNSUPPORTED_CIPHER;
276
res = pgp_load_digest(s2k->digest_algo, &md);
283
res = calc_s2k_simple(s2k, md, key, key_len);
286
res = calc_s2k_salted(s2k, md, key, key_len);
289
res = calc_s2k_iter_salted(s2k, md, key, key_len);
292
res = PXE_PGP_BAD_S2K_MODE;