@@ -132,12 +132,10 @@ calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
132132 unsigned preload = 0 ;
133133 unsigned remain ,
134134 c ,
135- cval ,
136135 curcnt ,
137136 count ;
138137
139- cval = s2k -> iter ;
140- count = ((unsigned ) 16 + (cval & 15 )) << ((cval >> 4 ) + 6 );
138+ count = s2k_decode_count (s2k -> iter );
141139
142140 md_rlen = px_md_result_size (md );
143141
@@ -195,21 +193,34 @@ calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
195193}
196194
197195/*
198- * Decide S2K_ISALTED iteration count
196+ * Decide PGP_S2K_ISALTED iteration count (in OpenPGP one-byte representation)
199197 *
200198 * Too small: weak
201199 * Too big: slow
202200 * gpg defaults to 96 => 65536 iters
203- * let it float a bit: 96 + 32 => 262144 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.
204207 */
205- static int
206- decide_count (unsigned rand_byte )
208+ static uint8
209+ decide_s2k_iter (unsigned rand_byte , int count )
207210{
208- return 96 + (rand_byte & 0x1F );
211+ int iter ;
212+
213+ if (count == -1 )
214+ return 96 + (rand_byte & 0x1F );
215+ /* this is a bit brute-force, but should be quick enough */
216+ for (iter = 0 ; iter <= 255 ; iter ++ )
217+ if (s2k_decode_count (iter ) >= count )
218+ return iter ;
219+ return 255 ;
209220}
210221
211222int
212- pgp_s2k_fill (PGP_S2K * s2k , int mode , int digest_algo )
223+ pgp_s2k_fill (PGP_S2K * s2k , int mode , int digest_algo , int count )
213224{
214225 int res = 0 ;
215226 uint8 tmp ;
@@ -219,19 +230,19 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
219230
220231 switch (s2k -> mode )
221232 {
222- case 0 :
233+ case PGP_S2K_SIMPLE :
223234 break ;
224- case 1 :
235+ case PGP_S2K_SALTED :
225236 res = px_get_pseudo_random_bytes (s2k -> salt , PGP_S2K_SALT );
226237 break ;
227- case 3 :
238+ case PGP_S2K_ISALTED :
228239 res = px_get_pseudo_random_bytes (s2k -> salt , PGP_S2K_SALT );
229240 if (res < 0 )
230241 break ;
231242 res = px_get_pseudo_random_bytes (& tmp , 1 );
232243 if (res < 0 )
233244 break ;
234- s2k -> iter = decide_count (tmp );
245+ s2k -> iter = decide_s2k_iter (tmp , count );
235246 break ;
236247 default :
237248 res = PXE_PGP_BAD_S2K_MODE ;
0 commit comments