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