1 /****************************************************************************
2 *																			*
3 *							  PGP Support Routines							*
4 *						Copyright Peter Gutmann 1992-2007					*
5 *																			*
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9   #include "crypt.h"
10   #include "misc_rw.h"
11   #include "pgp.h"
12 #else
13   #include "crypt.h"
14   #include "enc_dec/misc_rw.h"
15   #include "misc/pgp.h"
16 #endif /* Compiler-specific includes */
17 
18 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
19 
20 /****************************************************************************
21 *																			*
22 *						PGP <-> Cryptlib Algorithm Conversion				*
23 *																			*
24 ****************************************************************************/
25 
26 /* Convert algorithm IDs from cryptlib to PGP and back */
27 
28 typedef struct {
29 	const int pgpAlgo;
30 	const PGP_ALGOCLASS_TYPE pgpAlgoClass;
31 	const CRYPT_ALGO_TYPE cryptlibAlgo;
32 	const int cryptlibAlgoParam;
33 	} PGP_ALGOMAP_INFO;
34 static const PGP_ALGOMAP_INFO FAR_BSS pgpAlgoMap[] = {
35 	/* Encryption algos */
36 	{ PGP_ALGO_3DES, PGP_ALGOCLASS_CRYPT, CRYPT_ALGO_3DES },
37 #ifdef USE_CAST
38 	{ PGP_ALGO_CAST5, PGP_ALGOCLASS_CRYPT, CRYPT_ALGO_CAST },
39 #endif /* USE_CAST */
40 #ifdef USE_IDEA
41 	{ PGP_ALGO_IDEA, PGP_ALGOCLASS_CRYPT, CRYPT_ALGO_IDEA },
42 #endif /* USE_IDEA */
43 	{ PGP_ALGO_AES_128, PGP_ALGOCLASS_CRYPT, CRYPT_ALGO_AES },
44 	{ PGP_ALGO_AES_192, PGP_ALGOCLASS_CRYPT, CRYPT_ALGO_AES },
45 	{ PGP_ALGO_AES_256, PGP_ALGOCLASS_CRYPT, CRYPT_ALGO_AES },
46 
47 	/* Password-based encryption algos */
48 	{ PGP_ALGO_3DES, PGP_ALGOCLASS_PWCRYPT, CRYPT_ALGO_3DES },
49 #ifdef USE_CAST
50 	{ PGP_ALGO_CAST5, PGP_ALGOCLASS_PWCRYPT, CRYPT_ALGO_CAST },
51 #endif /* USE_CAST */
52 #ifdef USE_IDEA
53 	{ PGP_ALGO_IDEA, PGP_ALGOCLASS_PWCRYPT, CRYPT_ALGO_IDEA },
54 #endif /* USE_IDEA */
55 	{ PGP_ALGO_AES_128, PGP_ALGOCLASS_PWCRYPT, CRYPT_ALGO_AES, 16 },
56 	{ PGP_ALGO_AES_192, PGP_ALGOCLASS_PWCRYPT, CRYPT_ALGO_AES, 24 },
57 	{ PGP_ALGO_AES_256, PGP_ALGOCLASS_PWCRYPT, CRYPT_ALGO_AES, 32 },
58 
59 	/* PKC encryption algos */
60 	{ PGP_ALGO_RSA, PGP_ALGOCLASS_PKCCRYPT, CRYPT_ALGO_RSA },
61 	{ PGP_ALGO_RSA_ENCRYPT, PGP_ALGOCLASS_PKCCRYPT, CRYPT_ALGO_RSA },
62 #ifdef USE_ELGAMAL
63 	{ PGP_ALGO_ELGAMAL, PGP_ALGOCLASS_PKCCRYPT, CRYPT_ALGO_ELGAMAL },
64 #endif /* USE_ELGAMAL */
65 
66 	/* PKC sig algos */
67 	{ PGP_ALGO_RSA, PGP_ALGOCLASS_SIGN, CRYPT_ALGO_RSA },
68 	{ PGP_ALGO_RSA_SIGN, PGP_ALGOCLASS_SIGN, CRYPT_ALGO_RSA },
69 	{ PGP_ALGO_DSA, PGP_ALGOCLASS_SIGN, CRYPT_ALGO_DSA },
70 
71 	/* Hash algos */
72 #ifdef USE_MD5
73 	{ PGP_ALGO_MD5, PGP_ALGOCLASS_HASH, CRYPT_ALGO_MD5 },
74 #endif /* USE_MD5 */
75 	{ PGP_ALGO_SHA, PGP_ALGOCLASS_HASH, CRYPT_ALGO_SHA1 },
76 	{ PGP_ALGO_SHA2_256, PGP_ALGOCLASS_HASH, CRYPT_ALGO_SHA2, 32 },
77 
78 	{ PGP_ALGO_NONE, 0, CRYPT_ALGO_NONE },
79 	{ PGP_ALGO_NONE, 0, CRYPT_ALGO_NONE }
80 	};
81 
82 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
83 int pgpToCryptlibAlgo( IN_RANGE( PGP_ALGO_NONE, 0xFF ) const int pgpAlgo,
84 					   IN_ENUM( PGP_ALGOCLASS ) \
85 							const PGP_ALGOCLASS_TYPE pgpAlgoClass,
86 					   OUT_ALGO_Z CRYPT_ALGO_TYPE *cryptAlgo,
87 					   OUT_OPT_INT_Z int *cryptAlgoParam )
88 	{
89 	int i;
90 
91 	assert( isWritePtr( cryptAlgo, sizeof( CRYPT_ALGO_TYPE ) ) );
92 	assert( cryptAlgoParam == NULL || \
93 			isWritePtr( cryptAlgoParam, sizeof( int ) ) );
94 
95 	REQUIRES( pgpAlgo >= 0 && pgpAlgo <= 0xFF );
96 	REQUIRES( pgpAlgoClass > PGP_ALGOCLASS_NONE && \
97 			  pgpAlgoClass < PGP_ALGOCLASS_LAST );
98 
99 	/* Clear return values */
100 	*cryptAlgo = CRYPT_ALGO_NONE;
101 	if( cryptAlgoParam != NULL )
102 		*cryptAlgoParam = 0;
103 
104 	for( i = 0;
105 		 ( pgpAlgoMap[ i ].pgpAlgo != pgpAlgo || \
106 		   pgpAlgoMap[ i ].pgpAlgoClass != pgpAlgoClass ) && \
107 			pgpAlgoMap[ i ].pgpAlgo != PGP_ALGO_NONE && \
108 			i < FAILSAFE_ARRAYSIZE( pgpAlgoMap, PGP_ALGOMAP_INFO );
109 		 i++ );
110 	ENSURES( i < FAILSAFE_ARRAYSIZE( pgpAlgoMap, PGP_ALGOMAP_INFO ) );
111 	if( pgpAlgoMap[ i ].cryptlibAlgo == PGP_ALGO_NONE )
112 		return( CRYPT_ERROR_NOTAVAIL );
113 	*cryptAlgo = pgpAlgoMap[ i ].cryptlibAlgo;
114 	if( cryptAlgoParam != NULL )
115 		*cryptAlgoParam = pgpAlgoMap[ i ].cryptlibAlgoParam;
116 
117 	return( CRYPT_OK );
118 	}
119 
120 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
cryptlibToPgpAlgo(IN_ALGO const CRYPT_ALGO_TYPE cryptlibAlgo,OUT_RANGE (PGP_ALGO_NONE,PGP_ALGO_LAST)int * pgpAlgo)121 int cryptlibToPgpAlgo( IN_ALGO const CRYPT_ALGO_TYPE cryptlibAlgo,
122 					   OUT_RANGE( PGP_ALGO_NONE, PGP_ALGO_LAST ) \
123 							int *pgpAlgo )
124 	{
125 	int i;
126 
127 	assert( isWritePtr( pgpAlgo, sizeof( int ) ) );
128 
129 	REQUIRES( cryptlibAlgo > CRYPT_ALGO_NONE && \
130 			  cryptlibAlgo < CRYPT_ALGO_LAST );
131 
132 	/* Clear return value */
133 	*pgpAlgo = PGP_ALGO_NONE;
134 
135 	for( i = 0;
136 		 pgpAlgoMap[ i ].cryptlibAlgo != cryptlibAlgo && \
137 			pgpAlgoMap[ i ].cryptlibAlgo != CRYPT_ALGO_NONE && \
138 			i < FAILSAFE_ARRAYSIZE( pgpAlgoMap, PGP_ALGOMAP_INFO );
139 		 i++ );
140 	ENSURES( i < FAILSAFE_ARRAYSIZE( pgpAlgoMap, PGP_ALGOMAP_INFO ) );
141 	if( pgpAlgoMap[ i ].cryptlibAlgo == CRYPT_ALGO_NONE )
142 		return( CRYPT_ERROR_NOTAVAIL );
143 	*pgpAlgo = pgpAlgoMap[ i ].pgpAlgo;
144 
145 	return( CRYPT_OK );
146 	}
147 
148 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readPgpAlgo(INOUT STREAM * stream,OUT_ALGO_Z CRYPT_ALGO_TYPE * cryptAlgo,OUT_OPT_INT_Z int * cryptAlgoParam,IN_ENUM (PGP_ALGOCLASS)const PGP_ALGOCLASS_TYPE pgpAlgoClass)149 int readPgpAlgo( INOUT STREAM *stream,
150 				 OUT_ALGO_Z CRYPT_ALGO_TYPE *cryptAlgo,
151 				 OUT_OPT_INT_Z int *cryptAlgoParam,
152 				 IN_ENUM( PGP_ALGOCLASS ) \
153 						const PGP_ALGOCLASS_TYPE pgpAlgoClass )
154 	{
155 	int value;
156 
157 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
158 	assert( isWritePtr( cryptAlgo, sizeof( CRYPT_ALGO_TYPE ) ) );
159 	assert( cryptAlgoParam == NULL || \
160 			isWritePtr( cryptAlgoParam, sizeof( int ) ) );
161 
162 	REQUIRES( pgpAlgoClass > PGP_ALGOCLASS_NONE && \
163 			  pgpAlgoClass < PGP_ALGOCLASS_LAST );
164 
165 	/* Clear return values */
166 	*cryptAlgo = CRYPT_ALGO_NONE;
167 	if( cryptAlgoParam != NULL )
168 		*cryptAlgoParam = 0;
169 
170 	value = sgetc( stream );
171 	if( cryptStatusError( value ) )
172 		return( value );
173 	return( pgpToCryptlibAlgo( value, pgpAlgoClass, cryptAlgo,
174 							   cryptAlgoParam ) );
175 	}
176 
177 /****************************************************************************
178 *																			*
179 *							Misc. PGP-related Routines						*
180 *																			*
181 ****************************************************************************/
182 
183 /* Create an encryption key from a password */
184 
185 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
186 int pgpPasswordToKey( IN_HANDLE const CRYPT_CONTEXT iCryptContext,
187 					  IN_LENGTH_SHORT_OPT const int optKeyLength,
188 					  IN_BUFFER( passwordLength ) const char *password,
189 					  IN_DATALENGTH const int passwordLength,
190 					  IN_ALGO const CRYPT_ALGO_TYPE hashAlgo,
191 					  IN_BUFFER_OPT( saltSize ) const BYTE *salt,
192 					  IN_RANGE( 0, CRYPT_MAX_HASHSIZE ) const int saltSize,
193 					  IN_INT const int iterations )
194 	{
195 	MESSAGE_DATA msgData;
196 	BYTE hashedKey[ CRYPT_MAX_KEYSIZE + 8 ];
197 	int algorithm, keySize DUMMY_INIT, status;	/* int vs.enum */
198 
199 	assert( isReadPtr( password, passwordLength ) );
200 	assert( ( salt == NULL && saltSize == 0 ) || \
201 			isReadPtr( salt, saltSize ) );
202 
203 	REQUIRES( isHandleRangeValid( iCryptContext ) );
204 	REQUIRES( passwordLength > 0 && passwordLength < MAX_BUFFER_SIZE );
205 	REQUIRES( ( optKeyLength == CRYPT_UNUSED ) || \
206 			  ( optKeyLength >= MIN_KEYSIZE && \
207 				optKeyLength <= CRYPT_MAX_KEYSIZE ) );
208 	REQUIRES( isHashAlgo( hashAlgo ) );
209 	REQUIRES( ( salt == NULL && saltSize == 0 ) || \
210 			  ( saltSize > 0 && saltSize <= CRYPT_MAX_HASHSIZE ) );
211 	REQUIRES( iterations >= 0 && iterations < MAX_INTLENGTH );
212 
213 	/* Get various parameters needed to process the password */
214 	status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE,
215 							  &algorithm, CRYPT_CTXINFO_ALGO );
216 	if( cryptStatusOK( status ) )
217 		status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE,
218 								  &keySize, CRYPT_CTXINFO_KEYSIZE );
219 	if( cryptStatusError( status ) )
220 		return( status );
221 	if( algorithm == CRYPT_ALGO_AES && optKeyLength != CRYPT_UNUSED )
222 		{
223 		/* PGP allows various AES key sizes and then encodes the size in the
224 		   algorithm ID (ugh), to handle this we allow the caller to specify
225 		   the actual size */
226 		keySize = optKeyLength;
227 		}
228 	ENSURES( keySize >= MIN_KEYSIZE && keySize <= CRYPT_MAX_KEYSIZE );
229 
230 	/* Hash the password */
231 	if( salt != NULL )
232 		{
233 		MECHANISM_DERIVE_INFO mechanismInfo;
234 
235 		/* Turn the user key into an encryption context key */
236 		setMechanismDeriveInfo( &mechanismInfo, hashedKey, keySize,
237 								password, passwordLength, hashAlgo,
238 								salt, saltSize, iterations );
239 		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_DERIVE,
240 								  &mechanismInfo, MECHANISM_DERIVE_PGP );
241 		if( cryptStatusError( status ) )
242 			return( status );
243 
244 		/* Save the derivation info with the context */
245 		setMessageData( &msgData, ( MESSAGE_CAST ) salt, saltSize );
246 		status = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
247 								  &msgData, CRYPT_CTXINFO_KEYING_SALT );
248 		if( cryptStatusOK( status ) && \
249 			iterations > 0 && iterations <= MAX_KEYSETUP_ITERATIONS )
250 			{
251 			/* The number of key setup iterations may be zero for non-
252 			   iterated hashing, and may be some ridiculous value for
253 			   passwords used to protect private keys created by newer
254 			   versions of GPG.  In the former case we leave the iteration
255 			   count at zero, in the latter case we don't have to set the
256 			   iteration count (or indeed any of the key setup values)
257 			   because for private-key decryption keys they're never used
258 			   once the user key has been converted into the decryption
259 			   key */
260 			status = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
261 									  ( MESSAGE_CAST ) &iterations,
262 									  CRYPT_CTXINFO_KEYING_ITERATIONS );
263 			}
264 		if( cryptStatusOK( status ) )
265 			{
266 			const int value = hashAlgo;	/* int vs.enum */
267 			status = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
268 									  ( MESSAGE_CAST ) &value,
269 									  CRYPT_CTXINFO_KEYING_ALGO );
270 			}
271 		if( cryptStatusError( status ) )
272 			{
273 			zeroise( hashedKey, CRYPT_MAX_KEYSIZE );
274 			return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
275 			}
276 		}
277 	else
278 		{
279 		HASH_FUNCTION_ATOMIC hashFunctionAtomic;
280 
281 		getHashAtomicParameters( hashAlgo, 0, &hashFunctionAtomic, NULL );
282 		hashFunctionAtomic( hashedKey, CRYPT_MAX_HASHSIZE, password,
283 							passwordLength );
284 		}
285 
286 	/* Load the key into the context */
287 	setMessageData( &msgData, hashedKey, keySize );
288 	status = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
289 							  &msgData, CRYPT_CTXINFO_KEY );
290 	zeroise( hashedKey, CRYPT_MAX_KEYSIZE );
291 
292 	return( status );
293 	}
294 
295 /* Process a PGP-style IV.  This isn't a standard IV but contains an extra
296    two bytes of check value, which is why it's denoted as 'ivInfo' rather
297    than a pure 'iv' */
298 
299 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
300 int pgpProcessIV( IN_HANDLE const CRYPT_CONTEXT iCryptContext,
301 				  INOUT_BUFFER_FIXED( ivInfoSize ) BYTE *ivInfo,
302 				  IN_RANGE( 8 + 2, CRYPT_MAX_IVSIZE + 2 ) const int ivInfoSize,
303 				  IN_LENGTH_IV const int ivDataSize,
304 				  IN_HANDLE_OPT const CRYPT_CONTEXT iMdcContext,
305 				  const BOOLEAN isEncrypt )
306 	{
307 	static const BYTE zeroIV[ CRYPT_MAX_IVSIZE ] = { 0 };
308 	MESSAGE_DATA msgData;
309 	int status;
310 
311 	assert( isReadPtr( ivInfo, ivInfoSize ) );
312 
313 	REQUIRES( isHandleRangeValid( iCryptContext ) );
314 	REQUIRES( ivDataSize >= 8 && ivDataSize <= CRYPT_MAX_IVSIZE );
315 	REQUIRES( ivInfoSize == ivDataSize + 2 );
316 	REQUIRES( iMdcContext == CRYPT_UNUSED || \
317 			  isHandleRangeValid( iCryptContext ) );
318 
319 	/* PGP uses a bizarre way of handling IVs that resyncs the data on some
320 	   boundaries and doesn't actually use an IV but instead prefixes the
321 	   data with ivSize bytes of random information (which is effectively
322 	   the IV) followed by two bytes of key check value after which there's a
323 	   resync boundary that requires reloading the IV from the last ivSize
324 	   bytes of ciphertext.  Two exceptions are the encrypted private key,
325 	   which does use an IV (although this can also be regarded as an
326 	   ivSize-byte prefix) without a key check or resync, and an encrypted
327 	   packet with MDC, which doesn't do the resync (if it weren't for that
328 	   it would be trivial to roll an MDC packet back to a non-MDC packet,
329 	   only the non-resync prevents this since the first bytes of the
330 	   encapsulated data packet will be corrupted).
331 
332 	   First, we load the all-zero IV */
333 	setMessageData( &msgData, ( MESSAGE_CAST ) zeroIV, ivDataSize );
334 	status = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
335 							  &msgData, CRYPT_CTXINFO_IV );
336 	if( cryptStatusError( status ) )
337 		return( status );
338 
339 	/* Then we encrypt or decrypt the IV info, which consists of the actual
340 	   IV data plus two bytes of check value */
341 	if( isEncrypt )
342 		{
343 		/* Get some random data to serve as the IV and duplicate the last
344 		   two bytes to create the check value */
345 		setMessageData( &msgData, ivInfo, ivDataSize );
346 		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
347 								  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
348 		if( cryptStatusError( status ) )
349 			return( status );
350 		memcpy( ivInfo + ivDataSize, ivInfo + ivDataSize - 2, 2 );
351 
352 		/* If the caller is using an MDC then the plaintext IV data has to
353 		   be hashed into the MDC value, effectively turning the straight
354 		   hash into a basic secret-prefix MAC */
355 		if( iMdcContext != CRYPT_UNUSED )
356 			{
357 			status = krnlSendMessage( iMdcContext, IMESSAGE_CTX_HASH,
358 									  ivInfo, ivInfoSize );
359 			if( cryptStatusError( status ) )
360 				return( status );
361 			}
362 
363 		/* Encrypt the IV and check value */
364 		status = krnlSendMessage( iCryptContext, IMESSAGE_CTX_ENCRYPT,
365 								  ivInfo, ivInfoSize );
366 		}
367 	else
368 		{
369 		BYTE ivInfoBuffer[ CRYPT_MAX_IVSIZE + 2 + 8 ];
370 
371 		/* Decrypt the first ivSize bytes (the IV data) and the following 2-
372 		   byte check value.  There's a potential problem here in which an
373 		   attacker that convinces us to act as an oracle for the valid/not
374 		   valid status of the checksum can determine the contents of 16
375 		   bits of the encrypted data in 2^15 queries on average.  This is
376 		   incredibly unlikely (which implementation would auto-respond to
377 		   32,000 reqpeated queries on a block of data and return the
378 		   results to an external agent?), however if it's a concern then
379 		   one ameliorating change would be to not perform the check for
380 		   keys that were PKC-encrypted, because the PKC decryption process
381 		   would check the key for us */
382 		memcpy( ivInfoBuffer, ivInfo, ivInfoSize );
383 		status = krnlSendMessage( iCryptContext, IMESSAGE_CTX_DECRYPT,
384 								  ivInfoBuffer, ivInfoSize );
385 		if( cryptStatusError( status ) )
386 			return( status );
387 		if( ivInfoBuffer[ ivDataSize - 2 ] != ivInfoBuffer[ ivDataSize + 0 ] || \
388 			ivInfoBuffer[ ivDataSize - 1 ] != ivInfoBuffer[ ivDataSize + 1 ] )
389 			return( CRYPT_ERROR_WRONGKEY );
390 
391 		/* If the caller is using an MDC then the plaintext IV data has to
392 		   be hashed into the MDC value, effectively turning the straight
393 		   hash into a basic secret-prefix MAC */
394 		if( iMdcContext != CRYPT_UNUSED )
395 			status = krnlSendMessage( iMdcContext, IMESSAGE_CTX_HASH,
396 									  ivInfoBuffer, ivInfoSize );
397 		}
398 	if( cryptStatusError( status ) )
399 		return( status );
400 
401 	/* The IV-resync is only done if traditional PGP encryption is used, the
402 	   processing was changed when MDC handling was added to skip this step,
403 	   so we only perform the resync if we're using non-MDC encryption */
404 	if( iMdcContext != CRYPT_UNUSED )
405 		return( CRYPT_OK );
406 
407 	/* Finally we've got the data the way that we want it, resync the IV by
408 	   setting it to the last ivSize bytes of data processed */
409 	setMessageData( &msgData, ivInfo + 2, ivDataSize );
410 	return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
411 							 &msgData, CRYPT_CTXINFO_IV ) );
412 	}
413 
414 /* Read PGP S2K information:
415 
416 	byte	stringToKey specifier, 0, 1, or 3
417 	byte[]	stringToKey data
418 			0x00: byte		hashAlgo	-- S2K = 0, 1, 3
419 			0x01: byte[8]	salt		-- S2K = 1, 3
420 			0x03: byte		iterations	-- S2K = 3 */
421 
422 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 4, 6 ) ) \
readPgpS2K(INOUT STREAM * stream,OUT_ALGO_Z CRYPT_ALGO_TYPE * hashAlgo,OUT_INT_Z int * hashAlgoParam,OUT_BUFFER (saltMaxLen,* saltLen)BYTE * salt,IN_LENGTH_SHORT_MIN (PGP_SALTSIZE)const int saltMaxLen,OUT_LENGTH_BOUNDED_Z (saltMaxLen)int * saltLen,OUT_INT_SHORT_Z int * iterations)423 int readPgpS2K( INOUT STREAM *stream,
424 				OUT_ALGO_Z CRYPT_ALGO_TYPE *hashAlgo,
425 				OUT_INT_Z int *hashAlgoParam,
426 				OUT_BUFFER( saltMaxLen, *saltLen ) BYTE *salt,
427 				IN_LENGTH_SHORT_MIN( PGP_SALTSIZE ) const int saltMaxLen,
428 				OUT_LENGTH_BOUNDED_Z( saltMaxLen ) int *saltLen,
429 				OUT_INT_SHORT_Z int *iterations )
430 	{
431 	long hashSpecifier;
432 	int value, status;
433 
434 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
435 	assert( isWritePtr( hashAlgo, sizeof( CRYPT_ALGO_TYPE ) ) );
436 	assert( isWritePtr( salt, saltMaxLen ) );
437 	assert( isWritePtr( saltLen, sizeof( int ) ) );
438 	assert( isWritePtr( iterations, sizeof( int ) ) );
439 
440 	REQUIRES( saltMaxLen >= PGP_SALTSIZE && \
441 			  saltMaxLen < MAX_INTLENGTH_SHORT );
442 
443 	/* Clear return values */
444 	*hashAlgo = CRYPT_ALGO_NONE;
445 	*hashAlgoParam = 0;
446 	memset( salt, 0, min( 16, saltMaxLen ) );
447 	*saltLen = 0;
448 	*iterations = 0;
449 
450 	/* Read the S2K information */
451 	status = value = sgetc( stream );
452 	if( cryptStatusError( status ) )
453 		return( status );
454 	if( value != 0 && value != 1 && value != 3 )
455 		return( CRYPT_ERROR_BADDATA );
456 	status = readPgpAlgo( stream, hashAlgo, hashAlgoParam,
457 						  PGP_ALGOCLASS_HASH );
458 	if( cryptStatusError( status ) )
459 		 return( status );
460 
461 	/* If it's a straight hash, we're done */
462 	if( value <= 0 )
463 		return( CRYPT_OK );
464 
465 	/* It's a salted hash, read the salt */
466 	status = sread( stream, salt, saltMaxLen );
467 	if( cryptStatusError( status ) )
468 		return( status );
469 	*saltLen = PGP_SALTSIZE;
470 
471 	/* If it's a non-iterated hash, we're done */
472 	if( value < 3 )
473 		return( CRYPT_OK );
474 
475 	/* It's a salted iterated hash, get the iteration count from the bizarre
476 	   fixed-point encoded value, limited to a sane value:
477 
478 		count = ( ( Int32 ) 16 + ( c & 15 ) ) << ( ( c >> 4 ) + 6 )
479 
480 	   The "iteration count" is actually a count of how many bytes are
481 	   hashed, this is because the "iterated hashing" treats the salt +
482 	   password as an infinitely-repeated sequence of values and hashes the
483 	   resulting string for PGP-iteration-count bytes worth.  The value that
484 	   we calculate here (to prevent overflow on 16-bit machines) is the
485 	   count without the base * 64 scaling, this also puts the range within
486 	   the value of the standard sanity check.  When we do the range check
487 	   we knock a further four bits off the maximum allowed length to avoid
488 	   performing calculations too close to INT_MAX in the S2K code.
489 
490 	   Note that there's a mutant GPG build used with loop-AES that uses 8M
491 	   setup iterations for PGP private keys, why this is used and why it
492 	   writes PGP keys with this setting is uncertain but cryptlib will
493 	   reject keys with this value as being outside the range of sane values
494 	   (for an 8-byte salt and a typical 8-byte password this would lead to
495 	   8M / 16 = 512K iterations of the PRF, a value so extreme that it'd
496 	   normally only be used in a DoS attack).
497 
498 	   Unfortunately PGP Desktop 9 (apparently) in its default config will
499 	   use values up to 4M (= 256K iterations of the PRF), which the sanity-
500 	   check code would also reject.  It's uncertain at which point we
501 	   should draw the line here, on the one hand we want to be able to
502 	   handle PGP Desktop's data but we also want some protection against
503 	   DoS attacks due to ridiculously high iteration counts.  For now we
504 	   reject obviously invalid values (ones less than zero or which could
505 	   cause an overflow once the scaling is applied) and in addition alert
506 	   the caller (and return a less fatal error code) if the iteration
507 	   count would be larger than 128K for the typical 8-byte password case
508 	   above */
509 	value = sgetc( stream );
510 	if( cryptStatusError( value ) )
511 		return( value );
512 	hashSpecifier = ( 16 + ( ( long ) value & 0x0F ) ) << ( value >> 4 );
513 	if( hashSpecifier <= 0 || \
514 		hashSpecifier >= ( MAX_INTLENGTH >> 4 ) / 64 )
515 		return( CRYPT_ERROR_BADDATA );
516 	if( hashSpecifier > MAX_KEYSETUP_HASHSPECIFIER )
517 		{
518 		/* The key requires more than 32K * 64 = 2M bytes of hashing or 128K
519 		   iterations for 8 bytes salt + 8 bytes password, this is more
520 		   likely a DoS than a genuine hash count */
521 		DEBUG_DIAG(( "Encountered key with an S2K hash count parameter "
522 					 "of %d, max.allowed is %d", hashSpecifier * 64,
523 					 MAX_KEYSETUP_HASHSPECIFIER * 64 ));
524 		assert_nofuzz( DEBUG_WARN );
525 		return( CRYPT_ERROR_NOTAVAIL );
526 		}
527 	*iterations = ( int ) hashSpecifier;
528 
529 	return( CRYPT_OK );
530 	}
531 #endif /* USE_PGP || USE_PGPKEYS */
532